3.7 Discriminants
1/2
{
AI95-00251-01} 
{
AI95-00326-01} 
[
{discriminant} {type 
parameter: See discriminant} {parameter: 
See also discriminant} A composite type 
(other than an array
 or interface type) 
can have discriminants, which parameterize the type. A 
known_discriminant_part 
specifies the discriminants of a composite type. A discriminant of an 
object is a component of the object, and is either of a discrete type 
or an access type. An 
unknown_discriminant_part 
in the declaration of a
 partial view of 
a type specifies that the discriminants of the type are unknown for the 
given view; all subtypes of such a
 partial 
view are indefinite subtypes.] 
 
1.a/2
Glossary entry: {Discriminant} 
A discriminant is a parameter for of 
a composite type. It can control, for example, the bounds of a component 
of the type if the component is that 
type is an array type. A discriminant 
for of a task 
type can be used to pass data to a task of the type upon creation.
1.b/2
Discussion: {
AI95-00114-01} 
{
unknown discriminants [partial]} 
{
discriminants 
(unknown) [partial]} 
A 
view 
of a type, and all 
of its subtypes
 of the view, have 
unknown discriminants when the number 
or names of the discriminants, if any, are unknown at the point of the 
type declaration
 for the view. A 
discriminant_part 
of (<>) is used to indicate unknown discriminants. 
 
Language Design Principles
1.c/2
{
AI95-00402-01} 
When an access discriminant is initialized at the 
time of object creation with an allocator of an anonymous type, the allocated 
object and the object with the discriminant are tied together for their 
lifetime. They should be allocated out of the same storage pool, and 
then at the end of the lifetime of the enclosing object, finalized and 
reclaimed together. In this case, the allocated object is called a coextension 
(see 3.10.2).  
1.d/2
Discussion: The 
above principle when applied to a nonlimited type implies that such an 
object may be copied only to a shorter-lived object, because attempting 
to assign it to a longer-lived object would fail because the access discriminants 
would not match. In a copy, the lifetime connection between the enclosing 
object and the allocated object does not exist. The allocated object 
is tied in the above sense only to the original object. Other copies 
have only secondary references to it.
1.e/2
Note that when an allocator 
appears as a constraint on an access discriminant in a subtype_indication 
that is elaborated independently from object creation, no such connection 
exists. For example, if a named constrained subtype is declared via "subtype 
Constr is Rec(Acc_Discrim => new T);" or if such 
an allocator appears in the subtype_indication 
for a component, the allocator is evaluated when the subtype_indication 
is elaborated, and hence its lifetime is typically longer than the objects 
or components that will later be subject to the constraint. In these 
cases, the allocated object should not be reclaimed until the subtype_indication 
goes out of scope. 
Syntax
2
discriminant_part ::= unknown_discriminant_part | 
known_discriminant_part 
3
unknown_discriminant_part ::= (<>)
 
4
known_discriminant_part ::= 
   (
discriminant_specification {; 
discriminant_specification})
 
5/2
{
AI95-00231-01} 
discriminant_specification ::= 
   defining_identifier_list : 
[null_exclusion] subtype_mark [:= 
default_expression]
 | 
defining_identifier_list : 
access_definition [:= 
default_expression]
 
6
default_expression ::= expression 
Name Resolution Rules
7
{expected type (discriminant 
default_expression) [partial]} The expected 
type for the 
default_expression of a 
discriminant_specification 
is that of the corresponding discriminant. 
 
Legality Rules
8/2
{
8652/0007} 
{
AI95-00098-01} 
{
AI95-00251-01} 
A 
discriminant_part known_discriminant_part 
is only permitted in a declaration for a composite type that is not an 
array
 or interface type [(this includes 
generic formal types)]
. A; 
a type declared with a 
known_discriminant_part 
is called a 
discriminated type,
{discriminated 
type}  as is a type that inherits (known) 
discriminants. 
 
8.a
Implementation Note: Discriminants on 
array types were considered, but were omitted to ease (existing) implementations. 
8.b
Discussion: Note that the above definition 
for “discriminated type” does not include types declared 
with an unknown_discriminant_part. This seems 
consistent with Ada 83, where such types (in a generic formal part) would 
not be considered discriminated types. Furthermore, the full type for 
a type with unknown discriminants need not even be composite, much less 
have any discriminants.
8.b.1/1
{
8652/0007} 
{
AI95-00098-01} 
On the other hand, unknown_discriminant_parts 
cannot be applied to type declarations that cannot have a known_discriminant_part. 
There is no point in having unknown discriminants on a type that can 
never have discriminants (for instance, a formal modular type), even 
when these are allowed syntactically.  
9/2
{
AI95-00231-01} 
{
AI95-00254-01} 
The subtype of a discriminant may be defined by
 an optional null_exclusion and a 
subtype_mark, 
in which case the 
subtype_mark shall denote 
a discrete or access subtype, or it may be defined by an 
access_definition [(in which case the subtype_mark of the access_definition 
may denote any kind of subtype)]. 
{access 
discriminant} A discriminant that is defined 
by an 
access_definition is called an 
access 
discriminant and is of an anonymous 
access general 
access-to-variable type
 whose designated 
subtype is denoted by the subtype_mark of 
the access_definition. 
 
9.a/2
This paragraph 
was deleted.Reason: {
AI95-00230-01} 
In an early version of Ada 9X, we allowed access 
discriminants on nonlimited types, but this created unpleasant complexities. 
It turned out to be simpler and more uniform to allow discriminants of 
a named access type on any discriminated type, and keep access discriminants 
just for limited types. 
9.b
Note that discriminants of a named access type 
are not considered “access discriminants.” Similarly, “access 
parameter” only refers to a formal parameter defined by an access_definition. 
9.1/2
  {
AI95-00402-01} 
Default_expressions 
shall be provided either for all or for none of the discriminants of 
a known_discriminant_part. No default_expressions 
are permitted in a known_discriminant_part 
in a declaration of a tagged type [or a generic formal type]. 
9.c/2
Reason: The all-or-none 
rule is related to the rule that a discriminant constraint shall specify 
values for all discriminants. One could imagine a different rule that 
allowed a constraint to specify only some of the discriminants, with 
the others provided by default. Having defaults for discriminants has 
a special significance — it allows objects of the type to be unconstrained, 
with the discriminants alterable as part of assigning to the object.
9.d/2
Defaults for discriminants 
of tagged types are disallowed so that every object of a tagged type 
is constrained, either by an explicit constraint, or by its initial discriminant 
values. This substantially simplifies the semantic rules and the implementation 
of inherited dispatching operations. For generic formal types, the restriction 
simplifies the type matching rules. If one simply wants a "default" 
value for the discriminants, a constrained subtype can be declared for 
future use. 
10/2
 {
AI95-00230-01} 
{
AI95-00402-01} 
{
AI95-00419-01} 
A 
discriminant_specification for an access 
discriminant 
may have a default_expression shall 
appear only in the declaration for a task or protected type, or 
for a type 
that is a descendant of an explicitly 
limited record type with the reserved word 
limited in its [(full)] definition or in that of one of its ancestors. 
In addition to the places where Legality Rules normally apply (see 
12.3), 
this rule applies also in the private part of an instance of a generic 
unit.
{generic contract issue [partial]} 
 
10.a/2
Discussion: This rule implies that a 
type can have 
a default for an access discriminant 
if the type is limited, but not if the only reason it's limited is because 
of a limited component. Compare with the definition of limited type in 
7.5.
 Also, recall that 
a “descendant’ includes the type itself, so an explicitly 
limited record type can have defaults.  
10.b/2
This paragraph 
was deleted.Ramification: It 
is a consequence of this rule that only a return-by-reference type can 
have an access discriminant (see 6.5). This 
is important to avoid dangling references to local variables. 
 
10.c/2
Reason: {
AI95-00230-01} 
We 
also considered the following rules
 for access discriminants: 
 
10.d
- If a type has an access discriminant, 
this automatically makes it limited, just like having a limited component 
automatically makes a type limited. This was rejected because it decreases 
program readability, and because it seemed error prone (two bugs in a 
previous version of the RM9X were attributable to this rule).
 
10.e/2
- A type with an access discriminant 
shall be limited. This is equivalent to the rule we actually chose for Ada 95, except that it allows a type to have an access discriminant 
if it is limited just because of a limited component. For example, any 
record containing a task would be allowed to have an access discriminant, 
whereas the actual rule requires “limited record”. 
This rule was also rejected due to readability concerns, and because 
would interact badly with the rules for limited types that “become 
nonlimited”.
 
10.f/2
- A type 
may have an access discriminant if it is a limited partial view, or a 
task, protected, or explicitly limited record type. This was the rule 
chosen for Ada 95.
 
10.g/2
- Any type 
may have an access discriminant. For nonlimited type, there is no special 
accessibility for access discriminants; they're the same as any other 
anonymous access component. For a limited type, they have the special 
accessibility of Ada 95. However, this doesn't work because a limited 
partial view can have a nonlimited full view -- giving the two views 
different accessibility.
 
10.h/2
- Any type 
may have an access discriminant, as above. However, special accessibility 
rules only apply to types that are “really” limited (task, 
protected, and explicitly limited records). However, this breaks privacy; 
worse, Legality Rules depend on the definition of accessibility.
 
10.i/2
- Any type 
may have an access discriminant, as above. Limited types have special 
accessibility, while nonlimited types have normal accessibility. However, 
a limited partial view with an access discriminant can only be completed 
by a task, protected, or explicitly limited record type. That prevents 
accessibility from changing. A runtime accessibility check is required 
on generic formal types with access discriminants. However, changing 
between limited and nonlimited types would have far-reaching consequences 
for access discriminants — which is uncomfortable.
 
10.j/2
- Any type 
may have an access discriminant. All types have special accessibility. 
This was considered early during the Ada 9X process, but was dropped 
for “unpleasant complexities”, which unfortunately aren't 
recorded. It does seem that an accessibility check would be needed on 
assignment of such a type, to avoid copying an object with a discriminant 
pointing to a local object into a more global object (and thus creating 
a dangling pointer).
 
10.k/2
- Any type 
may have an access discriminant, but access discriminants cannot have 
defaults. All types have special accessibility. This gets rid of the 
problems on assignment (you couldn't change such a discriminant), but 
it would be horribly incompatible with Ada 95.
 
10.l/2
- Any type 
may have an access discriminant, but access discriminants may have defaults 
only if they are a “really” limited type. This is the rule 
chosen for Ada 2005, as it is not incompatible, and it doesn't require 
weird accessibility checks. 
 
11/2
 This paragraph was 
deleted.{
AI95-00402-01} 
Default_expressions 
shall be provided either for all or for none of the discriminants of 
a known_discriminant_part. No default_expressions 
are permitted in a known_discriminant_part 
in a declaration of a tagged type [or a generic formal type]. 
 
11.a/2
This paragraph 
was deleted.Reason: The all-or-none 
rule is related to the rule that a discriminant constraint shall specify 
values for all discriminants. One could imagine a different rule that 
allowed a constraint to specify only some of the discriminants, with 
the others provided by default. Having defaults for discriminants has 
a special significance — it allows objects of the type to be unconstrained, 
with the discriminants alterable as part of assigning to the object.
11.b/2
This paragraph 
was deleted.Defaults for discriminants 
of tagged types are disallowed so that every object of a tagged type 
is constrained, either by an explicit constraint, or by its initial discriminant 
values. This substantially simplifies the semantic rules and the implementation 
of inherited dispatching operations. For generic formal types, the restriction 
simplifies the type matching rules. If one simply wants a "default" 
value for the discriminants, a constrained subtype can be declared for 
future use. 
12
For a type defined 
by a derived_type_definition, if a known_discriminant_part 
is provided in its declaration, then: 
13
- The parent subtype shall be constrained;
 
14
- If the parent type is not a tagged 
type, then each discriminant of the derived type shall be used in the 
constraint defining the parent subtype;
 
14.a
Implementation Note: This ensures that 
the new discriminant can share storage with an existing discriminant.
15
- If a discriminant is used in the constraint 
defining the parent subtype, the subtype of the discriminant shall be 
statically compatible (see 4.9.1) with the 
subtype of the corresponding parent discriminant. 
 
15.a
Reason: This ensures that on conversion 
(or extension via an extension aggregate) to a distantly related type, 
if the discriminants satisfy the target type's requirements they satisfy 
all the intermediate types' requirements as well. 
15.b
Ramification: There is no requirement 
that the new discriminant have the same (or any) default_expression 
as the parent's discriminant. 
16
The type of the 
default_expression, 
if any, for an access discriminant shall be convertible to the anonymous 
access type of the discriminant (see 
4.6). 
{convertible (required) [partial]} 
 
16.a
Ramification: This requires convertibility 
of the designated subtypes. 
Static Semantics
17
A discriminant_specification 
declares a discriminant; the subtype_mark 
denotes its subtype unless it is an access discriminant, in which case 
the discriminant's subtype is the anonymous access-to-variable subtype 
defined by the access_definition.
18
[For a type defined by a 
derived_type_definition, 
each discriminant of the parent type is either inherited, constrained 
to equal some new discriminant of the derived type, or constrained to 
the value of an expression.] 
{corresponding 
discriminants} When inherited or constrained 
to equal some new discriminant, the parent discriminant and the discriminant 
of the derived type are said to 
correspond. Two discriminants 
also correspond if there is some common discriminant to which they both 
correspond. A discriminant corresponds to itself as well. 
{specified 
discriminant} If a discriminant of a parent 
type is constrained to a specific value by a 
derived_type_definition, 
then that discriminant is said to be 
specified by that 
derived_type_definition. 
 
18.a
Ramification: The correspondence relationship 
is transitive, symmetric, and reflexive. That is, if A corresponds to 
B, and B corresponds to C, then A, B, and C each corresponds to A, B, 
and C in all combinations.
19
{depend on a discriminant 
(for a constraint or component_definition)} A 
constraint that appears within the definition 
of a discriminated type 
depends on a discriminant of the type 
if it names the discriminant as a bound or discriminant value. A 
component_definition 
depends on a discriminant if its 
constraint 
depends on the discriminant, or on a discriminant that corresponds to 
it. 
 
19.a
Ramification: A constraint 
in a task_body is not considered to depend 
on a discriminant of the task type, even if it names it. It is only the 
constraints in the type definition itself 
that are considered dependents. Similarly for protected types. 
20
{depend 
on a discriminant (for a component)} A 
component 
depends on a discriminant if: 
 
21
- Its component_definition 
depends on the discriminant; or 
 
21.a
Ramification: A component does not 
depend on a discriminant just because its default_expression 
refers to the discriminant.
22
- It is declared in a variant_part 
that is governed by the discriminant; or
 
23
- It is a component inherited as part 
of a derived_type_definition, and the constraint 
of the parent_subtype_indication depends 
on the discriminant; or 
 
23.a
Reason: When the parent subtype depends 
on a discriminant, the parent part of the derived type is treated like 
a discriminant-dependent component. 
23.b
Ramification: Because of this rule, we 
don't really need to worry about “corresponding” discriminants, 
since all the inherited components will be discriminant-dependent if 
there is a new known_discriminant_part whose 
discriminants are used to constrain the old discriminants. 
24
- It is a subcomponent of a component 
that depends on the discriminant. 
 
24.a
Reason: The concept of discriminant-dependent 
(sub)components is primarily used in various rules that disallow renaming 
or 'Access, or specify that certain discriminant-changing assignments 
are erroneous. The goal is to allow implementations to move around or 
change the size of discriminant-dependent subcomponents upon a discriminant-changing 
assignment to an enclosing object. The above definition specifies that 
all subcomponents of a discriminant-dependent component or parent part 
are themselves discriminant-dependent, even though their presence or 
size does not in fact depend on a discriminant. This is because it is 
likely that they will move in a discriminant-changing assignment if they 
are a component of one of several discriminant-dependent parts of the 
same record. 
25
Each value of a discriminated type includes a value 
for each component of the type that does not depend on a discriminant[; 
this includes the discriminants themselves]. The values of discriminants 
determine which other component values are present in the value of the 
discriminated type. 
25.a
To be honest: Which values are present 
might depend on discriminants of some ancestor type that are constrained 
in an intervening derived_type_definition. 
That's why we say "values of discriminants" instead of "values 
of the discriminants" — a subtle point.
26
{known discriminants} 
{discriminants (known)} 
{constrained (subtype)} 
{unconstrained (subtype)} 
A type declared with a 
known_discriminant_part 
is said to have 
known discriminants; its first subtype is unconstrained. 
{unknown discriminants} {discriminants 
(unknown)} A type declared with an 
unknown_discriminant_part 
is said to have 
unknown discriminants. A type declared without 
a 
discriminant_part has no discriminants, 
unless it is a derived type; if derived, such a type has the same sort 
of discriminants (known, unknown, or none) as its parent (or ancestor) 
type. A tagged class-wide type also has unknown discriminants. 
{class-wide 
type} {indefinite 
subtype} [Any subtype of a type with unknown 
discriminants is an unconstrained and indefinite subtype (see 
3.2 
and 
3.3).] 
 
26.a/2
Discussion: {
AI95-00114-01} 
An 
unknown_discriminant_part “(<>)” 
is only permitted in the declaration of a (generic or nongeneric) private 
type, private extension, 
incomplete type, or 
formal derived type. Hence, only such types, descendants thereof, and 
class-wide types can have unknown discriminants. An 
unknown_discriminant_part 
is used to indicate that the corresponding actual or full type might 
have discriminants without defaults, or be an unconstrained array subtype. 
Tagged class-wide types are also considered to have unknown discriminants 
because discriminants can be added by type extensions, so the total number 
of discriminants of any given value of a tagged class-wide type is not 
known at compile time.
 
26.b/2
{
AI95-00287-01} 
A subtype with unknown discriminants is indefinite, and hence an object 
of such a subtype needs explicit initialization.
 If the subtype is limited, no (stand-alone) objects can be declared since 
initialization is not permitted (though formal parameters are permitted, 
and objects of the actual/full type will generally be declarable). 
A limited private type with unknown discriminants is “extremely” 
limited;
 objects of such a type 
 can be initialized only by subprograms (either procedures with a parameter 
of the type, or a function returning the type) declared in the package. 
Subprograms declared elsewhere can operate on and even return the type, 
but they can only initialize the object by calling (ultimately) a subprogram 
in the package declaring the type. Such a type is useful for keeping 
complete control over object creation within the package declaring the 
type.
 
26.c
A partial view of a type might have unknown 
discriminants, while the full view of the same type might have known, 
unknown, or no discriminants., 
Dynamic Semantics
27/2
 {
AI95-00230-01} 
{
AI95-00416-01} 
For an access discriminant, its An 
access_definition is elaborated when the value 
of 
the a corresponding 
access discriminant is defined
:, 
either by evaluation of its 
default_expression, or by elaboration of a 
discriminant_constraint, 
or by an assignment that initializes the enclosing object.. 
[The elaboration of an access_definition creates 
the anonymous access type. When the expression defining the access discriminant 
is evaluated, it is converted to this anonymous access type (see 4.6).] 
{implicit subtype conversion (access 
discriminant) [partial]}  
27.a/2
Ramification: {
AI95-00231-01} 
{
AI95-00416-01} 
The This conversion
 of the expression defining the access discriminant 
to the anonymous access type raises 
Program_Error Constraint_Error 
if the initial value is null, or, for an object created 
by an allocator of an access type T, if the initial value is an access 
parameter that designates a view whose accessibility level is deeper 
than that of T. 
 
28
52  If a discriminated type has default_expressions 
for its discriminants, then unconstrained variables of the type are permitted, 
and the values of the discriminants can be changed by an assignment to 
such a variable. If defaults are not provided for the discriminants, 
then all variables of the type are constrained, either by explicit constraint 
or by their initial value; the values of the discriminants of such a 
variable cannot be changed after initialization. 
28.a
Discussion: This connection between discriminant 
defaults and unconstrained variables can be a source of confusion. For 
Ada 95, we considered various ways to break the connection between defaults 
and unconstrainedness, but ultimately gave up for lack of a sufficiently 
simple and intuitive alternative.
28.b
{
mutable} 
An unconstrained 
discriminated subtype with defaults is called a 
mutable subtype, 
and a variable of such a subtype is called a mutable variable, because 
the discriminants of such a variable can change. There are no mutable 
arrays (that is, the bounds of an array object can never change), because 
there is no way in the language to define default values for the bounds. 
Similarly, there are no mutable class-wide subtypes, because there is 
no way to define the default tag, and defaults for discriminants are 
not allowed in the tagged case. Mutable tags would also require a way 
for the maximum possible size of such a class-wide subtype to be known. 
(In some implementations, all mutable variables are allocated with the 
maximum possible size. This approach is appropriate for real-time applications 
where implicit use of the heap is inappropriate.)
 
29
53  The default_expression 
for a discriminant of a type is evaluated when an object of an unconstrained 
subtype of the type is created.
30
54  Assignment to a discriminant of an object 
(after its initialization) is not allowed, since the name of a discriminant 
is a constant; neither assignment_statements 
nor assignments inherent in passing as an in out or out 
parameter are allowed. Note however that the value of a discriminant 
can be changed by assigning to the enclosing object, presuming it is 
an unconstrained variable. 
30.a/2
Discussion: {
AI95-00114-01} 
An 
unknown_discriminant_part is permitted 
only in the declaration of a private type (including generic formal private), 
private extension, 
incomplete type, or generic 
formal derived type. These are the things that will have a corresponding 
completion or generic actual, which will either define the discriminants, 
or say there are none. The (<>) indicates that the actual/full 
subtype might be an indefinite subtype. An 
unknown_discriminant_part 
is not permitted in a normal untagged derived type declaration, because 
there is no separate full type declaration for such a type. Note that 
(<>) allows unconstrained array bounds; those are somewhat like 
undefaulted discriminants.
 
30.b
For a derived type, either the discriminants 
are inherited as is, or completely respecified in a new discriminant_part. 
In this latter case, each discriminant of the parent type shall be constrained, 
either to a specific value, or to equal one of the new discriminants. 
Constraining a parent type's discriminant to equal one of the new discriminants 
is like a renaming of the discriminant, except that the subtype of the 
new discriminant can be more restrictive than that of the parent's one. 
In any case, the new discriminant can share storage with the parent's 
discriminant. 
31
55  A discriminant that is of a named access 
type is not called an access discriminant; that term is used only for 
discriminants defined by an access_definition. 
Examples
32
Examples of discriminated 
types: 
33
type Buffer(Size : Buffer_Size := 100)  
is        --
 see 3.5.4
   record
      Pos   : Buffer_Size := 0;
      Value : String(1 .. Size);
   
end record;
 
34
type Matrix_Rec(Rows, Columns : Integer) 
is
   record
      Mat : Matrix(1 .. Rows, 1 .. Columns);       --
 see 3.6
   end record;
 
35
type Square(Side : Integer) is new
   Matrix_Rec(Rows => Side, Columns => Side);
36
type Double_Square(Number : Integer) is
   record
      Left  : Square(Number);
      Right : Square(Number);
   end record;
37/2
{
AI-00433-01} 
task type Worker(Prio : System.Priority; Buf : access Buffer) is
   -- discriminants used to parameterize the task type (see 9.1)
   pragma Priority(Prio);  -- see D.1
   entry Fill;
   entry Drain;
end Worker; type Item(Number : Positive) is
   record
      Content : Integer;
      --  no component depends on the discriminant
   end record; 
Extensions to Ada 83
37.a
{
extensions to Ada 83} 
The 
syntax for a 
discriminant_specification is 
modified to allow an 
access discriminant, with a type specified 
by an 
access_definition (see 
3.10).
 
37.b/2
{
AI95-00251-01} 
Discriminants are allowed on all composite types other than array
 and interface types.
 
37.c
Discriminants may be of an access type. 
Wording Changes from Ada 83
37.d
Discriminant_parts 
are not elaborated, though an access_definition 
is elaborated when the discriminant is initialized.
Extensions to Ada 95
37.e/2
{
AI95-00230-01} 
{
AI95-00402-01} 
{
AI95-00416-01} 
Access discriminants (anonymous access types used 
as a discriminant) can be used on any type allowing discriminants. Defaults 
aren't allowed on discriminants of non-limited types, however, so that 
accessibility problems don't happen on assignment. 
37.f/2
{
AI95-00231-01} 
null_exclusion can be 
used in the declaration of a discriminant.  
Wording Changes from Ada 95
37.g/2
{
8652/0007} 
{
AI95-00098-01} 
Corrigendum: The wording was clarified so 
that types that cannot have discriminants cannot have an unknown_discriminant_part. 
37.h/2
{
AI95-00251-01} 
Added wording to prevent interfaces from having 
discriminants. We don't want interfaces to have any components. 
37.i/2
{
AI95-00254-01} 
Removed wording which implied or required an access 
discriminant to have an access-to-object type (anonymous access types 
can now be access-to-subprogram types as well). 
37.j/2
{
AI95-00326-01} 
Fixed the wording of the introduction to this clause 
to reflect that both incomplete and partial views can have unknown discriminants. 
That was always true, but for some reason this wording specified partial 
views. 
37.k/2
{
AI95-00419-01} 
Changed the wording to use the new term “explicitly 
limited record”, which makes the intent much clearer (and eliminates 
confusion with derived types that happen to contain the reserved word 
limited.