3.7.1 Discriminant Constraints
Language Design Principles
Syntax
Name Resolution Rules
Each 
selector_name 
of a named 
discriminant_association 
shall resolve to denote a discriminant of the subtype being constrained; 
the discriminants so named are the 
associated 
discriminants of the named association. 
For a 
positional association, the 
associated discriminant is the one 
whose 
discriminant_specification 
occurred in the corresponding position in the 
known_discriminant_part 
that defined the discriminants of the subtype being constrained.
Legality Rules
Reason: {
AI95-00363-01} 
The second rule is necessary to prevent objects from changing so that 
they no longer match their constraint. In Ada 95, we attempted to prevent 
this by banning every case where an aliased object could be unconstrained 
or be changed by an enclosing assignment. New ways to cause this problem 
were being discovered frequently, meaning that new rules had to be dreamed 
up to cover them. Meanwhile, aliased objects and components were getting 
more and more limited. In Ada 2005, we sweep away all of that cruft and 
replace it by a simple rule “thou shalt not create an access subtype 
that can point to an item whose discriminants can be changed by assignment”. 
 
Discussion: {
AI05-0041-1} 
The second rule will only use the indefinite or dereference bullets in 
the definition of “known to be constrained”. The rule is 
worded in terms of “known to be constrained” in order to 
capture the special rules that apply in generic bodies (rather than repeating 
them and getting them subtly wrong). 
 
Ramification: In addition, 
8.6 
requires that the 
expression 
associated with an access discriminant is convertible (see 
4.6) 
to the anonymous access type. This implies both convertibility of designated 
types, and static accessibility. This implies that if an object of type 
T with an access discriminant is created by an allocator for an access 
type A, then it requires that the type of the 
expression 
associated with the access discriminant have an accessibility level that 
is not statically deeper than that of A. This is to avoid dangling references.
 
Dynamic Semantics
A 
discriminant_constraint 
is 
compatible with an unconstrained discriminated subtype if each 
discriminant value belongs to the subtype of the corresponding discriminant. 
Ramification: The "dependent compatibility 
check" has been eliminated in Ada 95. Any checking on subcomponents 
is performed when (and if) an object is created.
Discussion: There is no need to define 
compatibility with a constrained discriminated subtype, because one is 
not allowed to constrain it again.
A composite value 
satisfies 
a discriminant constraint if and only if each discriminant of the composite 
value has the value imposed by the discriminant constraint.
{
AI12-0439-1} 
For the elaboration of a 
discriminant_constraint, 
the 
expressions 
in the 
discriminant_associations 
are evaluated in an arbitrary order and converted to the type of the 
associated discriminant (which can raise Constraint_Error — see 
4.6); the 
expression 
of a named association is evaluated (and converted) once for each associated 
discriminant. 
The result of each evaluation and conversion 
is the value imposed by the constraint for the associated discriminant. 
Reason: We convert to the type, not the 
subtype, so that the definition of compatibility of discriminant constraints 
is not vacuous.
NOTE   The rules of the language ensure 
that a discriminant of an object always has a value, either from explicit 
or implicit initialization. 
Discussion: Although it is illegal to 
constrain a class-wide tagged subtype, it is possible to have a partially 
constrained class-wide subtype: If the subtype S is defined by T(A => 
B), then S'Class is partially constrained in the sense that objects of 
subtype S'Class have to have discriminants corresponding to A equal to 
B, but there can be other discriminants defined in extensions that are 
not constrained to any particular value. 
Examples
Large   : Buffer(200);  --  constrained, always 200 characters
                        --   (explicit discriminant value)
Message : Buffer;       --  unconstrained, initially 100 characters
                        --   (default discriminant value)
Basis   : Square(5);    --  constrained, always 5 by 5
Illegal : Square;       --  illegal, a Square has to be constrained
Inconsistencies With Ada 83
Dependent compatibility 
checks are no longer performed on subtype declaration. Instead they are 
deferred until object creation (see 
3.3.1). 
This is upward compatible for a program that does not raise Constraint_Error. 
Wording Changes from Ada 83
Everything in RM83-3.7.2(7-12), which specifies 
the initial values for discriminants, is now redundant with 3.3.1, 6.4.1, 
8.5.1, and 12.4. Therefore, we don't repeat it here. Since the material 
is largely intuitive, but nevertheless complicated to state formally, 
it doesn't seem worth putting it in a "NOTE". 
Incompatibilities With Ada 95
{
8652/0008} 
{
AI95-00168-01} 
{
AI95-00363-01} 
The Corrigendum added a restriction on 
discriminant_constraints 
for general access subtypes. Such constraints are prohibited if the designated 
type can be treated as constrained somewhere in the program. Ada 2005 
goes further and prohibits such 
discriminant_constraints 
if the designated type has (or might have, in the case of a formal type) 
defaults for its discriminants. The use of general access subtypes is 
rare, and this eliminates a boatload of problems that required many restrictions 
on the use of aliased objects and components (now lifted). Similarly, 
Ada 2005 prohibits 
discriminant_constraints 
on any access type whose designated type has a partial view that is constrained. 
Such a type will not be constrained in the heap to avoid privacy problems. 
Again, the use of such subtypes is rare (they can only happen within 
the package and its child units). 
Wording Changes from Ada 2005
{
AI05-0041-1} 
Correction: Revised the rules on access subtypes having discriminant 
constraints to depend on the “known to be constrained” rules. 
This centralizes the rules so that future fixes need to be made in only 
one place, as well as fixing bugs in obscure cases.
{
AI05-0102-1} 
Correction: Moved implicit conversion Legality Rule to 
8.6. 
 Ada 2005 and 2012 Editions sponsored in part by Ada-Europe
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe