Ada-Rapporteur-Group / User-Community-Input

Ada User Community Input Working Group - Github Mirror Prototype
27 stars 1 forks source link

Allow downward conversion of dynamically-tagged expression. #8

Closed sttaft closed 6 months ago

sttaft commented 2 years ago

Currently, it is not legal to convert an expression of a specific tagged type to another specific tagged type, unless the target type is an ancestor. Also, you cannot convert a specific type to a class-wide type, unless the target type the covers the operand type. One must first convert to a "covering" class-wide type, and then convert to the desired target type. This reflects the general rule that a value of a specific type doesn't conceptually "reveal" its run-time tag, unless you convert it to a class-wide type first.

However, if you apply a primitive function to a class-wide controlling operand, where the primitive function has a controlling operand, you end up with a "dynamically-tagged" expression which for all intents and purposes should be treated as class-wide, since the tag of the controlling operand effectively flows through as the tag of the controlling result, thanks to the dispatching.

The above implies that we should examine all rules that are restricted to class-wide operands, and consider shifting the wording to be "dynamically-tagged" instead. In particular, the rules in RM 4.6(23/2) and 4.6(23.1/2) should be candidates for this shift to "dynamically-tagged". Another possibility would be as a prefix to 'Tag though it would be a bit odd to call a primitive function only to examine the tag of the result.

This brings up an interesting question -- what do you get when you rename the result of a dynamically-tagged call on a primitive function? If you specify the type in the renaming (which as of Ada 2022 is no longer required), should you specify specific or class-wide? And does it retain its dynamic-tagged-ness? RM 3.9.2(9/1) effectively disallows renaming as a specific type, since the renaming would imply a specific expected type:

If the expected type for an expression or name is some specific tagged type, then the expression or name shall not be dynamically tagged unless it is a controlling operand in a call on a dispatching operation. Similarly, if the expected type for an expression is an anonymous access-to-specific tagged type, then the object designated by the expression shall not be dynamically tagged unless it is a controlling operand in a call on a dispatching operation.

Renaming as an object of a class-wide type would also be illegal, according to RM 8.5.1(3/5):

The type of the object_name shall resolve to the type determined by the subtype_mark, if present. If no subtype_mark or access_definition is present, the expected type of the object_name is any type

Here we could generalize this proposal to allow dynamically-tagged expressions in places where class-wide expressions are allowed, and allow the object_name in a class-wide renaming to resolve to the associated specific tagged type, but only if it is dynamically-tagged. If no subtype_mark is specified, then if we allow it, we would clearly want it to remain dynamically-tagged -- whether or not its type is considered specific or class-wide then becomes less important.

ARG-Editor commented 11 months ago

This is discussed in AI22-0083-1.

ARG-Editor commented 6 months ago

AI22-0083-1 was approved by the ARG at meeting #63C, so this issue is closed.