AI22-0084-1
!standard 13.1.1(8/3) 24-02-20 AI22-0084-1/03
!class Binding Interpretation 23-09-29
!status Amendment 1-2022 23-10-05
!status WG9 Approved 24-06-10
!status ARG Approved 10-0-0 23-10-05
!status work item 23-09-29
!status received 23-05-16
!submitter Stephen Baird
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Resolution of aspects that are subprograms
Unless otherwise specified, only subprograms that are in the same declarative region as an aspect specification are considered.
In general, we do not want Name Resolution to be too “smart”. For instance, we do not use properties like limitedness when doing resolution of assignment statements.
Similarly, we do not use resolution to eliminate subprograms with an incorrect profile for user-defined indexing.
However, consider the following:
package Pkg1 is
type Enum is (Aaa, Bbb, Ccc, Foo);
end Pkg1;
with Pkg1;
use Pkg1;
package Pkg2 is
type T is ... with Constant_Indexing => Foo; -- Should be
legal? (Yes.)
function Foo (X : T; Index : Positive) return Boolean;
end Pkg2;
Here, a use-visible enumeration literal is conflicting with the local Foo. As the rules are written, this is illegal - the use-visible Foo has the wrong profile.
However, this is clearly a maintenance hazard. Adding a use clause could make some unrelated aspect specification illegal. Moreover, workarounds are annoying and have downsides (using an expanded name, changing the name of the function, or removing the use clause).
Add a new resolution rule for subprograms that specify aspect values that they are required to be in the same declarative region.
Modify 13.1.1(8/3):
AARM Reason: We only consider subprograms declared in the declarative region as it is highly unlikely that outside subprograms could have the correct profile (all such Ada 2022 language-defined aspects include a parameter or result of the associated type). We do allow more nested subprograms to be considered. We need this rule to avoid a maintenance hazard: if a new use clause happens to make a callable entity with the specified name visible, the aspect specification would become illegal as the profile of a named subprogram would be incorrect. That could happen when maintaining unrelated code.
In general, we do not want to make name resolution too smart. For that reason, the “extra” rules for aspect specifications are all considered Legality Rules unless they are explicitly specified to be Name Resolution Rules.
This is important in order to avoid surprises for the programmer. For instance, if the resolution of Variable_Indexing did not consider any subprograms with “impossible” profiles, then an indexing subprogram could disappear silently. The problem would only show up when someone tried to use an associated indexing, possibly far away from the definition of the type with the user-defined indexing. It could be very difficult to see the problem.
However, since the rule is a Legality Rule, if there are any subprograms with the specified name that have the wrong profile, the specification is illegal. That makes the problem clear, and it can be quickly fixed. For instance:
type T is ... with Constant_Indexing => Foo;
-- Illegal.
function Foo (X : T; Index : Positive) return Boolean; -- Suitable
function Foo (Index : Boolean)
return Natural; -- Unsuitable (forgot T parameter)
As such, we keep the new rule to only exclude subprograms defined outside the declarative region of the entity with the aspect specification. In most circumstances, these could never match the profile (which usually has a parameter or result of the type with the aspect specification).
Because this new Name Resolution Rule is effectively replacing (part of) existing Legality Rules, this is a compatible change: it can only make currently illegal code legal. Any example that is currently legal will remain so.
However, any aspect that does not have a requirement for the profile to include a parameter or result of the type, or a requirement for the subprogram to be primitive for the type, or a requirement for the subprogram to be local in some way, should not apply the new resolution rule. We do not believe there are any such language defined aspects (there might be implementation-defined aspects, of course).
Here are all of the language-defined aspects that require a subprogram to be specified (or have subprograms in an aggregate that is specified):
Aggregate: parameter.
Constant_Indexing: parameter (also required to be local).
Variable_Indexing: parameter (also required to be local).
Stream-oriented aspects (Input/Output/Read/Write): parameter (result for Input).
Default_Iterator: parameter (also required to be local).
User-defined literals (Integer_Literal, Real_Literal, String_Literal): result.
Put_Image: parameter.
[Note: At least some of these have been required to be primitive operations by Ada 2022 AIs. Since we don’t yet have an RM draft with those rules in it, it is hard to check which those are -- the other requirements are enough for this purpose so I didn’t check further. Note that since we don’t want resolution to be too smart, we would not want to use primitiveness (as opposed to a specific declarative region) for resolution. While it is obvious where a subprogram is declared, it is not as obvious whether it is primitive. - Editor.]
(See Issue.)
@drepl
@xbullet{an aspect that denotes a subprogram, the @fa{aspect_definition} shall be a @fa{name}; the expected profile for the @fa{name} is the profile required for the aspect of the associated entity;}
@dby
@xbullet{an aspect that denotes a subprogram, the @fa{aspect_definition} shall be a @fa{name}; the expected profile for the @fa{name} is the profile required for the aspect of the associated entity; additionally, unless otherwise specified, only subprograms declared within the declarative region of the entity associated with the aspect are considered;}
The existing ACATS test B416001 treats the collision rule as a Legality Rule; that does not need to be tested further.
An ACATS C-Test similar to the example in the Issue should be constructed.
This issue was originally raised in Github Issue #45 (https://github.com/Ada-Rapporteur-Group/User-Community-Input/issues/45).