3.7.1 Discriminant Constraints
1
Language Design Principles
1.a
The rules in this clause are intentionally parallel
to those given in Record Aggregates.
Syntax
2
3
4
Name Resolution Rules
5
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.
6
Legality Rules
7/3
{
8652/0008}
{
AI95-00168-01}
{
AI95-00363-01}
{
AI05-0041-1}
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 legal only if any dereference of a value
of the access type is known to be constrained (see 3.3) illegal
if the designated
type has a partial view that is constrained or, for a general access
subtype, has default_expressions
for its discriminants there
is a place within the immediate scope of the designated subtype where
the designated subtype's view is constrained.
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.
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”.
7.b/3
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).
8
9/3
This paragraph was
deleted.{
AI05-0102-1}
The expression
associated with an access discriminant shall be of a type convertible
to the anonymous access type.
9.a/3
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
10
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
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
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.
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
59 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
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}
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
15.d/3
{
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 only need to be made in one place, as well as fixing bugs in obscure
cases.
15.e/3
{
AI05-0102-1}
Correction: Moved implicit conversion Legality
Rule to 8.6.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe