3.7.1 Discriminant Constraints
1
A discriminant_constraint 
specifies the values of the discriminants for a given discriminated type. 
Language Design Principles
1.a
The rules in this clause are intentionally parallel 
to those given in Record Aggregates. 
Syntax
2
discriminant_constraint ::= 
   (
discriminant_association {, 
discriminant_association})
 
3
discriminant_association ::= 
   [
discriminant_selector_name {| 
discriminant_selector_name} =>] 
expression 
4
{named discriminant 
association} A 
discriminant_association 
is said to be 
named if it has one or more 
discriminant_selector_names; 
{positional discriminant association} 
it is otherwise said to be 
positional. In 
a 
discriminant_constraint, any positional 
associations shall precede any named associations. 
 
Name Resolution Rules
5
Each 
selector_name of 
a named 
discriminant_association shall resolve 
to denote a discriminant of the subtype being constrained; 
{associated 
discriminants (of a named discriminant_association)} the 
discriminants so named are the 
associated discriminants of the 
named association. 
{associated discriminants 
(of a positional discriminant_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.
 
6
{expected type (discriminant_association 
expression) [partial]} The expected type 
for the 
expression in a 
discriminant_association 
is that of the associated discriminant(s). 
 
Legality Rules
7/2
{
8652/0008} 
{
AI95-00168-01} 
{
AI95-00363-01} 
A 
discriminant_constraint is only allowed 
in a 
subtype_indication whose 
subtype_mark 
denotes either an unconstrained discriminated subtype, or an unconstrained 
access subtype whose designated subtype is an unconstrained discriminated 
subtype. 
However, in the case of an a 
general access subtype, a discriminant_constraint 
is illegal if the designated type has a 
partial view that is constrained or, for a general access subtype, has 
default_expressions for its discriminants. 
In addition to the places where Legality Rules normally apply (see 12.3), 
these rules apply also in the private part of an instance of a generic 
unit. In a generic body, this rule is checked presuming all formal access 
types of the generic might be general access types, and all untagged 
discriminated formal types of the generic might have default_expressions 
for their discriminants. {generic contract 
issue [partial]} there 
is a place within the immediate scope of the designated subtype where 
the designated subtype's view is constrained. 
7.a.1/2
This paragraph 
was deleted.Reason: {
8652/0008} 
{
AI95-00168-01} 
{
AI95-00363-01} 
The 
second rule is necessary to prevent assignments that change the discriminant 
of a constrained object. See the defect report for examples. 
 
7.a/2
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”.  
8
A named discriminant_association 
with more than one selector_name is allowed 
only if the named discriminants are all of the same type. A discriminant_constraint 
shall provide exactly one value for each discriminant of the subtype 
being constrained.
9
The 
expression associated 
with an access discriminant shall be of a type convertible to the anonymous 
access type. 
{convertible (required) 
[partial]}  
9.a
Ramification: 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
10
{compatibility (discriminant 
constraint with a subtype) [partial]} A 
discriminant_constraint is 
compatible 
with an unconstrained discriminated subtype if each discriminant value 
belongs to the subtype of the corresponding discriminant. 
 
10.a
Ramification: The "dependent compatibility 
check" has been eliminated in Ada 95. Any checking on subcomponents 
is performed when (and if) an object is created.
10.b
Discussion: There is no need to define 
compatibility with a constrained discriminated subtype, because one is 
not allowed to constrain it again.
11
{satisfies (a discriminant 
constraint) [partial]} 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.
 
12
{elaboration (discriminant_constraint) 
[partial]} 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 might raise Constraint_Error — see 
4.6); the 
expression 
of a named association is evaluated (and converted) once for each associated 
discriminant. 
{implicit subtype conversion 
(discriminant values) [partial]} The result 
of each evaluation and conversion is the value imposed by the constraint 
for the associated discriminant. 
 
12.a
Reason: We convert to the type, not the 
subtype, so that the definition of compatibility of discriminant constraints 
is not vacuous.
13
56  The rules of the language ensure that 
a discriminant of an object always has a value, either from explicit 
or implicit initialization. 
13.a
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
14
Examples (using 
types declared above in clause 3.7):  
15
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
15.a
{
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
15.b
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
15.c/2
{
8652/0008} 
{
AI95-00168-01} 
{
AI95-00363-01} 
{incompatibilities with Ada 95} 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).