Version 1.1 of acs/ac-00246.txt

Unformatted version of acs/ac-00246.txt version 1.1
Other versions for file acs/ac-00246.txt

!standard 7.5(8.1/3)          13-05-09 AC95-00246/00
!standard 7.5(8.2/3)
!standard 7.5(8.3/3)
!standard 7.5(8.4/3)
!standard 7.5(8.5/3)
!standard 7.5(8.6/3)
!class confirmation 13-05-09
!status received no action 13-05-09
!status received 13-02-07
!subject Types with immutably limited components
!summary
!appendix

From: Gary Dismukes
Sent: Thursday, February  7, 2013  4:53 PM

In compiling the ACATS tests for Ada 2012, AdaCore found a B test concerning
legality of 'Access (B3A0001) where we don't currently flag an ERROR line that
involves applying the attribute to a current instance.  It's a case where the
record type has an immutably limited component, but the type itself is not
explicitly declared as limited.

By the rules for immutably limited (in 7.5(8.1/3-8.6/3), a type that has an
immutably limited component (or more properly, part) is not immutably limited
simply due to having such a component/part, so in the test,
current_instance'Access is not legal.

Question: Should we (re)consider making such types immutably limited?

[BTW, Steve says that he had recently noticed this in some other context, and he
and Randy discussed it a little, with both having the feeling that types with
immutably limited parts should be immutably limited.]

Since at least one compiler (GNAT) treats such types as immutably limited, that
would be a point in favor of a rule change (avoiding possible incompatibilities
for existing code).  Note that there would also be some language-use benefit to
making this change, in that it would allow some cases that are currently
illegal:

1) Such types could have access discriminants with defaults.

2) The 'aliased' keyword would be allowed for return objects of
   such types in an extended return statement.

3) 'Access would be applicable to current instances of such types.

(Admittedly, allowing those cases would not bring a large benefit.)

One question is whether there's a good reason for not making such types
immutably limited.  Based on discussion in the !appendix section of AI05-0052
("Coextensions and Distributed Overhead", which is where the definition of
immutably limited comes from), it seems clear that excluding such types was
intentional.

For reference, here's a quote of remarks from Pascal and Tuck pertinent to this:

> Pascal Leroy:
>
> This doesn't address my point that AI 52+63 makes some constructs
> legal in TC2 that were illegal in Ada 2005. There is no indication in
> any document that I have read that says that it was intended. In
> particular, I draw your attention to 3.7(10.e/2) which makes it very
> clear that the designers of Ada 95, in their infinite wisdom, decided
> that a type with an immutably limited component was not itself
> immutably limited (and I think they were right then, and wrong now).
>
> Tucker Taft:
>
> Sorry, I hadn't understood your point. Now I see and I agree there is
> no need to give special "immutably limited" status to types that get
> limitedness from their subcomponents.
>
> So we could eliminate the fourth bullet.

[Note: The "fourth bullet" refers to the following, which was being considered
at one point for inclusion in the definition of immutably limited:

  *  A type with a part that is of an immutably limited type.
]

The paragraph mentioned by Pascal is the second AARM paragraph in a list of
alternative rules considered for types that have access discriminants. The
rationale against the 10.e/2 alternative seems to have mainly to do with
readability (and maybe error-proneness).

For ease of reference, here are 3.7(10.c/2-10.e/2):

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.

The 10.e/2 paragraph also says it would "interact badly with the rules for
limited types that become nonlimited", but note that these paragraphs were
originally written for Ada 95 (the only change from 10.e to 10.e/2 was the
addition of "for Ada 95"), and that latter rationale about "limited types that
become nonlimited" doesn't seem relevant for immutably limited types.

***************************************************************

From: Robert Dewar
Sent: Thursday, February  7, 2013  5:00 PM

> Since at least one compiler (GNAT) treats such types as immutably
> limited,

or you could have said

   Since all existing Ada 2012 compilers treat such types as immutably limited,

:-)

> that would be a point in favor of a rule change (avoiding possible
> incompatibilities for existing code).  Note that there would also be
> some language-use benefit to making this change

There is definitely an advantage to making this change, I am strongly in favor
on this basis.

***************************************************************

From: Steve Baird
Sent: Thursday, February  7, 2013  5:59 PM

> [BTW, Steve says that he had recently noticed this in some other
> context, and he and Randy discussed it a little, with both having the
> feeling that types with immutably limited parts should be immutably
> limited.]

More precisely, neither of us could see any reason why they shouldn't be (I
didn't mean to misstate Randy's position).

***************************************************************

From: Randy Brukardt
Sent: Thursday, February  7, 2013  6:13 PM

> > Since at least one compiler (GNAT) treats such types as immutably
> > limited,
>
> or you could have said
>
>    Since all existing Ada 2012 compilers treat such types as immutably
> limited,
>
> :-)

But that's not relevant, because the concept of "immutably limited" types goes back to Ada 95 and the rules that Gary was quoting the notes from. The main difference with Ada 2012 is that we gave it a name, because we found that the language was repeatedly
 saying "a task or protected type or a type that is a descendant of an explicitly limited record type".

Besides, the case Gary mentioned is only one of several uses of "immutably limited" in the language. Does GNAT allow too much in *all* of these cases, or just this one? (I'd be surprised if an access discriminant with a default expression was allowed for a
 type with an immutably limited part, as this would be a change from Ada 2005 when no semantic change was made (or intended).

And, of course, the ACATS test Gary was commenting on is an Ada 2005 test.
Ada 2012 did not intend to change the semantics of 3.10(9/3), just the wording (that's how it's documented in the AARM).

What does GNAT do on such examples in Ada 2005 mode? In particular, does it pass the test in Ada 2005 mode? If so, there's hardly any reason to assume that anyone is depending on GNAT's bug in Ada 2012 mode.

> > that would be a point in favor of a rule change (avoiding possible
> > incompatibilities for existing code).  Note that there would also be
> > some language-use benefit to making this change
>
> There is definitely an advantage to making this change, I am strongly
> in favor on this basis.

I worry that this isn't as straightforward as it looks. Currently, whether a
type is immutably limited is clear from its declaration: it explicitly has the
word limited, or task, or protected, or synchronized somewhere in the
declaration (or it is derived from such a type) [or it is a partial view with
defaulted access discriminant - please ignore that!]. This is a property that
depends solely on the declaration that you can see.

But a private view of an immutably limited type might not be immutably limited
(in order to preserve privacy).

That means that whether a component of a type T is immutably limited could
depend on the visibility that the type T has on the type of the component. That
way be dragons!!

Probably, we'd want the rule to be that the type is immutably limited if it has
any parts that are immutably limited *at the point of the declaration*. But of
course that could have surprising results.

And remember that we now allow adding the keyword "limited" to record types, and
that makes it immutably limited. If we were designing Ada from scratch knowing
what we know now, we would have required that keyword on all limited types (it
improves readability and eliminates some anomalies that currently exist, such as
a limited type becoming non-limited somewhere later in its scope). So why would
we want to expand those anomalies?? Let users put "limited" on their types that
use a current instance in this way.

So I'm against expanding this, especially when we originally considered doing
this in the context of Ada 2005, and rejected it. Ada 2005 adopted this tighter
rule because the relaxed rule leads to madness (see AI95-00225-1 for details).
AI95-00225-1 was a Binding Interpretation on Ada 95, and it explicitly noted
that it might break code that depends on looser semantics. But it also noted
that Ada 95 compilers implemented this rule differently, so there was no hope of
portability of code that didn't follow the tighter rule.

***************************************************************

From: Randy Brukardt
Sent: Thursday, February  7, 2013  6:18 PM

> More precisely, neither of us could see any reason why they shouldn't
> be (I didn't mean to misstate Randy's position).

But Gary's post reminded me why it should not be. See my reply to Robert.

In the AI95-00225-1 that I referred, Tucker said:

This all seems pretty unsavory, and makes me want to suggest that the rule
should be that you may only use T'[Unchecked_]Access inside an untagged record
type if it explicitly uses the word "limited" in its definition. This has the
nice characteristic that only types that are return-by-reference have an aliased
current instance. That's good, because if they are not return-by-reference, (and
not controlled), then the object is allowed to be copied and moved around as
part of a function return, which would render the use of T'[Unchecked_]Access
pretty meaningless.

Essentially everyone agreed with this position; that's since been expanded to
the idea of "immutably limited", but the basic concept is the same.

I don't think we want to make any change here, unless we want to reintroduce the
madness that Tucker described in his original e-mail (the first one in the
!appendix of AI95-00225-1, read it here:
http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ais/ai-00225.txt?rev=1.7).

***************************************************************

From: Tucker Taft
Sent: Thursday, February  7, 2013  7:01 PM

I clearly remember having this discussion about "immutably limited"
and coming to the conclusion that allowing components to make an enclosing type
"immutably limited" added complexity to the rules.

The basic problem is that an untagged limited private type could become
non-limited in the full view, or could become immutably limited, in the full
view.  If a type has a component that is of a limited private type, we would
need rules that talk about what happens if and when it becomes immutably limited
and it is used as a component.  We know those rules are painful when talking
about becoming non-limited and the effects on containing types, it seemed
unnecessary to do the same thing for immutably limited.

I also resist the temptation to enshrine a GNAT bug as a new language rule, just
because it is the first Ada 2005 or first Ada 2012 compiler.  We had a rationale
for the current rule, and I don't see a compelling argument for reversing this
decision.

***************************************************************

From: Randy Brukardt
Sent: Thursday, February  7, 2013  7:24 PM

Thanks, Tuck. The decision was compelling enough that we created an Ada 2005
ACATS test (back in 2007) to check that the correct rule was enforced. I have to
presume that GNAT does the correct thing for Ada 2005, I can't imagine that
you've been ignoring a failing test for more than 5 years without either
bringing it up to the ACAA and/or ARG or fixing it. And no semantic change was
intended by the introduction of the "immutably limited" term (particularly in
this case, which does not apply to private types; I think the private cases were
new in Ada 2012). So what we have here is a compiler that made a mistake
somewhere and changed its checking when no change was needed or intended.
Moreover, this is a pretty obscure case and the fix for any user running into it
is to add "limited" to the record type; it doesn't make sense to tie the
language into knots to support a broken compiler when the fix is that easy (I
refuse to call it a "workaround", as the intent has been for years that
"limited" ought to be given in such cases; failing to do so is a user error
compounded by a compiler that failed to complain).

***************************************************************

From: Steve Baird
Sent: Thursday, February  7, 2013  7:32 PM

> The basic problem is that an untagged limited private type could
> become non-limited in the full view, or could become immutably
> limited, in the full view.  If a type has a component that is of a
> limited private type, we would need rules that talk about what happens
> if and when it becomes immutably limited and it is used as a
> component.  We know those rules are painful when talking about
> becoming non-limited and the effects on containing types, it seemed
> unnecessary to do the same thing for immutably limited.

I had forgotten this, but it is coming back to me now and I think you are right
(contrary to my earlier opinion).

Do we really want "immutably limited" to be defined via the "characteristics"
rules of 7.3.1(4/1) so that in this example

    package Pkg is
        type T is limited private;

        package Nested is
          type Lp is limited private;
        private
          type Lp is array (1 ..3) of Some_Task_Type;
        end;
        ...
     private
        type T is record Component : Nested.Lp; end record;
     end;

the type T is inherently limited only inside the body of Nested?
Probably not.

Do we want the replacement of a visible task type with a limited private
(untagged) type implemented as a task type to break Current_Instance'Access uses
of types which have this type as a subcomponent type (because the current
instance might no longer be aliased). Again, probably not.

To be sure, this does nothing to help in the situation where someone wants to
put "aliased" on an extended return statement for a function returning an array
type whose element type is immutably limited.

The normal solution when one wants a type to be immutably limited is to
explicitly declare it as such. Unfortunately, there is no way to do that for an
array type. Fortunately, this seems like an unimportant corner case.

***************************************************************

From: Gary Dismukes
Sent: Thursday, February  7, 2013  8:10 PM

> Thanks, Tuck. The decision was compelling enough that we created an
> Ada 2005 ACATS test (back in 2007) to check that the correct rule was
> enforced. I have to presume that GNAT does the correct thing for Ada
> 2005, I can't imagine that you've been ignoring a failing test for
> more than 5 years without either bringing it up to the ACAA and/or ARG
> or fixing it. And no semantic change was intended by the introduction of the
> "immutably limited" term (particularly in this case, which does not apply
> to private types; I think the private cases were new in Ada 2012). So what we
> have here is a compiler that made a mistake somewhere and changed its
> checking when no change was needed or intended. Moreover, this is a
> pretty obscure case and the fix for any user running into it is to add
> "limited" to the record type; it doesn't make sense to tie the
> language into knots to support a broken compiler when the fix is that
> easy (I refuse to call it a "workaround", as the intent has been for
> years that "limited" ought to be given in such cases; failing to do so
> is a user error compounded by a compiler that failed to complain).

I agree with Tuck's and your conclusions, and you're right that GNAT checks this
correctly for Ada 2005.  For some reason the processing is done differently in
the two cases, so that needs to be sorted out.  I think that the checking of
components is needed by GNAT in some dynamic semantics contexts, but that needs
to be separated from the static semantic checking implied by immutably limited.

***************************************************************

From: Robert Dewar
Sent: Friday, February  8, 2013  4:41 AM

> Thanks, Tuck. The decision was compelling enough that we created an
> Ada 2005 ACATS test (back in 2007) to check that the correct rule was
> enforced. I have to presume that GNAT does the correct thing for Ada
> 2005, I can't imagine that you've been ignoring a failing test for
> more than 5 years without either bringing it up to the ACAA and/or ARG
> or fixing it. And no semantic change was intended by the introduction of the
> "immutably limited" term (particularly in this case, which does not apply
> to private types; I think the private cases were new in Ada 2012). So what we
> have here is a compiler that made a mistake somewhere and changed its
> checking when no change was needed or intended. Moreover, this is a
> pretty obscure case and the fix for any user running into it is to add
> "limited" to the record type; it doesn't make sense to tie the
> language into knots to support a broken compiler when the fix is that
> easy (I refuse to call it a "workaround", as the intent has been for
> years that "limited" ought to be given in such cases; failing to do so
> is a user error compounded by a compiler that failed to complain).

I am convinced by Tuck and Randy's arguments, I don't think we should make this
change after all. My support for the change was based on perceiving it as a
useful language addition (not the issue of GNAT comatibility, which is easily
fixed either way). Now it does not seem like such a nice or clean addition.

***************************************************************

Questions? Ask the ACAA Technical Agent