!standard 4.6(24.12/2) 08-07-03 AI05-0102-1/02 !standard 5.2(11) !class binding interpretation 08-06-15 !status work item 08-06-15 !status received 06-04-24 !priority Low !difficulty Medium !qualifier Omission !subject Some implicit conversions ought to be illegal !summary A legality rule is added to 8.6 to ensure that all implicit conversions are between types that are convertible. !question Consider the following: declare VObj : access Designated := ...; CObj : access constant Designated := ...; Cnst : aliased constant Designated := ...; begin VObj := Cnst'Access; -- (1) VObj := CObj; -- (2) end; (1) is illegal by 3.10.2(25). Surely we want (2) to be illegal, too, but there doesn't seem to be any rule that covers it. !wording Add after 8.6(32): If the expected type of a construct is T1 and the actual type of the construct is T2, then T2 shall be convertible to T1 (see 4.6). AARM Reason: This is needed to prevent implicit conversions which would be illegal if they were explicit conversions. For instance, we do not want to implicitly convert an access-to-constant value to an anonymous access-to-variable type. We do not want to make the resolution rules specific enough to prevent these sorts of issues, so we need a separate legality rule. !discussion 5.2 has no legality rule that applies in this case. The closest we have is 5.2(11), which is a dynamic semantics rule, and it is uncomfortable to have legality depending on a dynamic rule. Thus, a new legality rule is needed somewhere. 4.6 defines the term "convertible" for rules like this. Indeed, some implicit conversion contexts (3.7, 3.7.1, and 6.4.1) already have legality rules. This appears to have been an early Ada 95 attempt to fix this problem. (Ada 95 ultimately did not have this problem, as resolution did not allow an access-to-constant value to match an anonymous access type. But that will not work for Ada 2005, as we now have anonymous access-to-constant types.) We could try a similar fix for Ada 2005. However, the index lists 30 places that use implicit conversion, and it would be silly to add legality rules in 27 more places. Besides the sheer volume of change, there would be a lingering maintenance problem where any new implicit conversion contexts could easily forget to add the needed legality rule. Implicit conversion is implicitly defined in 8.6 (by the definition of which types match an expected type T). So that seems to be the best place for a blanket legality rule. The three existing rules (3.7(16), 3.7.1(9), and 6.4.1(6)) can then be marked as redundant in the AARM. The new rule should be indexed to "implicit conversion, legality" and to "convertible (required)" (the latter to match the existing rules). !corrigendum 8.6(32) @dinsa A complete context that is a @fa is allowed to be ambiguous (unless otherwise specified for the particular pragma), but only if every acceptable interpretation of the pragma argument is as a @fa that statically denotes a callable entity. Such a @fa denotes all of the declarations determined by its interpretations, and all of the views declared by these declarations. @dinst If the expected type of a construct is @i and the actual type of the construct is @i, then @i shall be convertible to @i (see 4.6). !ACATS Test An ACATS test should check that implicit conversions like the one in the question are illegal. !appendix From: Randy Brukardt Sent: Thursday, April 24, 2008 10:01 PM Can an implicit subtype conversion be illegal (not just raise an exception)? Channeling Adam, I'm not sure. (I am sure what answer we want, so the only question is whether the Standard actually justifies that answer.) Consider the following from an ACATS test now under construction: declare VObj : access Designated := ...; CObj : access constant Designated := ...; Cnst : aliased constant Designated := ...; begin VObj := Cnst'Access; -- ERROR: (1) VObj := CObj; -- ERROR: (2) end; While I'm certain that we want (2) to be illegal, I'm having trouble justifying it based on the wording of the Standard. (1) resolves because the type of the access attribute is that of the expected type; but it is illegal because it violates 3.10.2(25). (2) resolves because of 8.6(25/2), which allows these otherwise different types to match. So no error there. We turn to 5.2's Legality Rules. 5.2(5/2) is satisfied because the target is a variable. 5.2(6) doesn't apply (VObj isn't tagged). So why is this illegal? The only hope resides in the Dynamic Semantics rules, which is not a likely place to look for rules that make things illegal! The rule is 5.2(11): the value is converted to the subtype of the target. One can then say that the legality rule 4.6(24.12/2) applies. But this is weird, because (a) it mentions the possibility of an exception, but not illegality; (b) it's not clear if the original type of the value is considered or not; (c) it's not clear that an actual *type* conversion is possible. (Yes, I know that there are no named types in Ada [everything is a subtype], but these aren't named anyway... :-). I think we should at least have a To Be Honest note in the AARM that this implicit subtype conversion can be illegal in cases involving anonymous types, and it can convert types, not just subtypes, in such cases. It would be better for there to be an explicit statement of that fact somewhere (it probably isn't practical to put it everywhere that it can happen: there is a half a column of references for "implicit subtype conversion" in the RM's index; but the assignment case is the most common one). Do I have the intent right here, or have I missed something?? **************************************************************** From: Robert A. Duff Sent: Friday, April 25, 2008 7:47 AM > The only hope resides in the Dynamic Semantics rules, which is not a > likely place to look for rules that make things illegal! Indeed, we can't use Dynamic Semantics to say something is illegal! Implicit things being illegal seems uncomfortable anyway. Seems like we're missing a rule. The fact that converting to a subtype can convert the type as well is not new. It is used for example in the semantics of calls to inherited subprograms. 4.6(58) seems relevant: 58 Conversion to a type is the same as conversion to an unconstrained subtype of the type. 58.a Reason: This definition is needed because the semantics of various constructs involves converting to a type, whereas an explicit type_conversion actually converts to a subtype. For example, the evaluation of a range is defined to convert the values of the expressions to the type of the range. ****************************************************************