Why can't you use Predicate_Failure on a vector?

-- this works:
   
subtype Even_Integer is Integer
with
  Dynamic_Predicate => Even_Integer mod 2 = 0,
  Predicate_Failure => "Even_Integer must be a multiple of 2";

-- but this doesn't, it gives
-- "Predicate_failure requires accompanying noninherited predicate specification":

package Test_Vectors is new
  Ada.Containers.Vectors (Index_Type => Positive, Element_Type => Positive);

subtype Test_Vector is Test_Vectors.Vector
with
  Dynamic_Predicate => Long_Long_Integer (Test_Vector.Length) < 5,
  Predicate_Failure => "test";

I read the relevant parts of the RM and GNAT source code and I think it’s something to do with Dynamic_Predicate not being directly specified on the second one, but I’m not sure what that actually means in this context. There was something about operational aspects and type-related or subtype-specific aspects, but to be honest, I don’t quite get it. Can someone who understands Ada’s type system better explain it to me? I know Vector is a tagged type, is that the issue?

It means that you’re trying to add new behavior to the type, sneaking it in as a subtype. In order to correct this you need to make a new type, via inheritance (or derivation).

This boils down to the definition of type:a set of values, and a set of operations on those values”, subtype:a [possibly null] set of constraints upon a [sub]type.”.

One possible workaround is this, possibly wrapped in a private type:

Type Restricted_Vector_Handle( Data : Not Null Access Test_Vector.Vector )
  with Dynamic_Predicate => Do_Check( Restricted_Vector_Handle.Data.All ),
       Predicate_Failure => Raise Constraint_Error with "EVERYTHING IS WRONG!";

Essentially.
I don’t recall the exact details, though.