AI22-0110-1
!standard 4.10(4/5) 24-08-08 AI22-0110-1/02
!class Binding Interpretation 24-07-01
!status Amendment 1-2022 24-07-18
!status WG9 Approved 24-10-10
!status ARG Approved 8-0-0 24-07-18
!status work item 24-07-01
!status received 24-07-01
!submitter Stephen Baird
!priority Low
!difficulty Easy
!qualifier Omission
!subject Disallow Put_Image aspect specifications for interface types
Put_Image aspect specifications for interface types are disallowed because they can be used to violate the language design principle described in AARM 3.9.4.
The "Language Design Principles" section of AARM 3.9.4(1.b/2) says:
The rules are designed so that an interface can be used as either a parent type or a progenitor type without changing the meaning. That's important so that the order that interfaces are specified in a derived_type_definition is not significant. In particular, we want:
type Con1 is new Int1 and Int2 with null
record;
type Con2 is new Int2 and Int1 with null record;
to mean exactly the same thing.
A Put_Image aspect specification for an interface type can be used to violate this principle. To see why this is so, suppose we have calls to Con1'Put_Image and Con2'Put_Image. Suppose further that at least one of the two interface types Int1 and Int2 has a Put_Image aspect specification.
Consider how RM 4.10(7/5) applies in the case of this example:
For an untagged derived type, or a null extension, the default implementation of T'Put_Image invokes the Put_Image for its parent type on a conversion of the parameter of type T to the parent type.
It makes a user-visible difference whether Int1 or Int2 is the parent type.
Disallow Put_Image aspect specifications for interface types.
Modify 4.10(4/5):
The Put_Image attribute may be specified for any specific {noninterface} type T either via an attribute_definition_clause or via an aspect_specification specifying the Put_Image aspect of the type.[Redundant: The Put_Image aspect is not inherited, but rather is implicitly composed for derived types, as defined below.]
The proposed change only disallows a construct that is already unlikely to occur in production code. Given that an interface type is both componentless and abstract (so it cannot be used as a component type of some enclosing type), why would a user (as opposed to a compiler-test author) ever want to specify its Put_Image aspect?
This change is technically incompatible, but not only does the construct seem useless, the compiler with the only known implementation of Put_Image gets an internal error on the example below. It’s fairly safe to say that no one has ever tried to use Put_Image with an interface type, so there is no practical incompatibility.
package Example is
type Ifc is interface with Put_Image => Nested.PI;
-- Now illegal
package Nested is
procedure PI (...);
end Nested;
end Example;
@drepl
The Put_Image attribute may be specified for any specific type T either via an @fa{attribute_definition_clause} or via an @fa{aspect_specification} specifying the Put_Image aspect of the type. The Put_Image aspect is not inherited, but rather is implicitly composed for derived types, as defined below.
@dby
The Put_Image attribute may be specified for any specific noninterface type T either via an @fa{attribute_definition_clause} or via an @fa{aspect_specification} specifying the Put_Image aspect of the type. The Put_Image aspect is not inherited, but rather is implicitly composed for derived types, as defined below.
A B-test containing examples of Put_Image aspect specification for an interface type would be appropriate.