CVS difference for ai05s/ai05-0188-1.txt

Differences between 1.15 and version 1.16
Log of other versions for file ai05s/ai05-0188-1.txt

--- ai05s/ai05-0188-1.txt	2011/02/12 04:31:12	1.15
+++ ai05s/ai05-0188-1.txt	2011/02/16 04:25:41	1.16
@@ -1686,3 +1686,524 @@
 and I think the wording I proposed yesterday would allow this.
 
 ****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, February  2, 2011  3:10 PM
+
+> If you have a case-expression in a generic package spec which cases
+> on, say, a ormal in-out object of type Integer, it must cover all the Integer values.
+>
+> If you then instantiate the generic with an object whose subtype is
+> Natural, I don't think we want to see a legality violation upon
+> rechecking the expanded spec for the instance.
+
+Randy reminded Bob and me that this issue was never resolved.
+
+In subsequent discussions, it was noticed that the same problem already exists
+for variant parts, as in
+
+   procedure Vp_In_Inst is
+      generic
+         type T is new Integer;
+      package G is
+         type Rec (Discrim : T) is record
+            case Discrim is
+               when -10 .. -1 =>
+                  Foo : Float;
+               when others =>
+                  null;
+            end case;
+         end record;
+      end G;
+
+      package I is new G (Natural); -- legal?
+    begin
+      null;
+    end Vp_In_Inst;
+
+It seems that we ought to treat the two situations (variant parts and case
+expresssions) consistently.
+
+One alternative is to do nothing: both the above example and similar examples
+involving case expressions would be illegal.
+
+This seems unfriendly (especially for case expressions), but it is well defined.
+
+Alternatively, the following wording changes would allow these constructs to be
+accepted:
+
+Add at the end of the 3.8.1 Legality Rules section:
+
+    To be honest:
+    The above rule that "each non-others discrete_choice shall cover only
+    values in that subtype" does not apply to a discrete_choice which
+    occurs within an instance of a generic unit.
+
+Similarly, immediately after the existing wording for case expressions,
+
+   All Legality Rules that apply to the discrete_choices of a
+   case_statement (see 5.4), apply to the discrete_choices of a
+   case_expression.
+
+add
+
+   To be honest:
+   The rule for case statements (see 5.4) that in certain situations,
+   "... each non-others discrete_choice shall cover only values
+   in that subtype, ..." does not apply to a discrete_choice which
+   occurs within an instance of a generic unit.
+
+What do folk think?
+
+If someone dislikes using "To Be Honest" clauses in this way, we could discuss
+that as a separate question.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, February  2, 2011  3:34 PM
+
+...
+> This seems unfriendly (especially for case expressions), but it is
+> well defined.
+
+I agree that it would be unfriendly.  I don't think that the error is likely to
+be helpful in this case.  Why limit functionality in this way for no strong
+reason?  If such constructs are allowed in bodies, they should also be legal in
+specs, I think.
+
+> add
+>
+>   To be honest:
+>   The rule for case statements (see 5.4) that in certain situations,
+>   "... each non-others discrete_choice shall cover only values
+>   in that subtype, ..." does not apply to a discrete_choice which
+>   occurs within an instance of a generic unit.
+>
+> What do folk think?
+
+I could live with that, but...
+
+> If someone dislikes using "To Be Honest" clauses in this way, we could
+> discuss that as a separate question.
+
+... I'd prefer to have normative text that addresses this.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February  2, 2011  3:42 PM
+
+These don't seem like "to-be-honest"-ish statements.
+
+I don't see this as a big enough
+issue to justify any changes.  It is also one of those things that could be done
+later if people start finding this is a significant problem, since it is only
+making illegal programs legal.
+
+The fact that no one has ever encountered this with variant parts in 30 years
+makes me a little less worried... ;-)
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, February  2, 2011  3:54 PM
+
+Gary wrote:
+> ... I'd prefer to have normative text that addresses this.
+
+Tucker wrote:
+> These don't seem like "to-be-honest"-ish statements.
+
+Fine with me.
+
+So if we decide to do anything at all about this problem, we'll use "real"
+legality rules.
+
+Tuck advocates doing nothing.
+
+A pragmatic case could be made for treating the two constructs inconsistently.
+As Tuck notes, there have never been any complaints about the variant_part
+situation. On the other hand, this seems like it might be more of a problem for
+case expressions.
+
+So alternatives include
+    1) Do nothing
+    2) Add permissive legality wording only for case expressions.
+    2) Add permissive legality wording for both case expressions and
+       variant parts.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, February  2, 2011  5:12 PM
+
+Are we really convinced it is a good idea to make this change?  If a case
+expression in the generic spec specifies what should be done with particular
+values, and the actual type doesn't have those values, doesn't that sound like
+something is awry?  Is this that different from initializing a named constant of
+the formal type to a particular literal value, when that literal value turns out
+to be outside the range of the formal subtype?
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, February  2, 2011  5:31 PM
+
+> Are we really convinced it is a good idea to make this change?
+
+I don't think we've reached a consensus on this point. I think this problem is
+worth addressing, at least for case expressions (the only real argument for
+messing with variant parts is consistency), but I agree that it is a judgment
+call and that taking no action is a reasonable alternative.
+
+You'd prefer to take no action.
+
+Gary said "I agree that it would be unfriendly" to reject the case expressions
+we've been discussing.
+
+I'd like to get other opinions.
+
+> If a case expression in the
+> generic spec specifies what should be done with particular values, and
+> the actual type doesn't have those values, doesn't that sound like
+> something is awry?
+
+This seems no worse than calling a function which takes an Integer paremeter and
+passing it the value of a variable whose subtype is Natural. The function may
+provide all sorts of support for the case where it is passed a negative value
+and, for this particular call, that code will never be exercised.
+
+> Is this that
+> different from initializing a named constant of the formal type to a
+> particular literal value, when that literal value turns out to be
+> outside the range of the formal subtype?
+
+Yes, it is different. Now you are talking about a situation where the
+instantiator requires functionality which the generic doesn't provide, as
+opposed to failing to make use of the full functionality which the generic does
+provide.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Wednesday, February  2, 2011  6:11 PM
+
+> Are we really convinced it is a good idea to make this change?
+
+In the abstract, it seems like a good idea, to me.
+The only negative, to me, is that maybe it's not worth the trouble.  Most
+variant records, and probably most case expressions, are on regular non-formal
+enumeration types.
+
+>...  If a case expression in the
+> generic spec specifies what should be done with particular  values,
+>and the actual type doesn't have those values,  doesn't that sound like
+>something is awry?  Is this that  different from initializing a named
+>constant of the  formal type to a particular literal value, when that
+>literal value turns out to be outside the range of  the formal subtype?
+
+I don't buy that analogy, for the reason Steve gave.
+
+A better analogy is a case statement, which must appear in the generic body, and
+can specify nonexistent values in an instance.  (In fact, case expressions in
+the body will work that way.)
+
+The reason to forbid "when -1" when the subtype is Natural, is that that's
+almost certainly a mistake.  But in the generic case, you don't KNOW it's
+Natural -- it just happens to be in one instance, but other instances might need
+that -1 case.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, February  2, 2011  8:22 PM
+
+> In subsequent discussions, it was noticed that the same problem
+> already exists for variant parts, as in
+...
+> What do folk think?
+
+If you had waited for me to answer your original question (which has been
+delayed by the need to dig out from 19" of snow that we've gotten since Monday
+afternoon, along with the steady 35 MPH wind), you would have already found out
+that I think that you've lost your mind. (I should have simply buried your
+original question, but I didn't think about it as I was in a hurry to leave
+before my car was too buried to move.)
+
+Let me explain the ways:
+
+(1) Using a To Be Honest note to change how legality rules work is completely
+    insane. TBHs are intended for cases where we say *almost* what we mean, but
+    leave out some something for clarity. Not for cases where we are changing
+    the rules from check to not check!
+
+(2) There is almost no similarity between the variant case and the case
+    expression/statement case. Tucker noted that no one has run into this in 30
+    years, but he didn't explain why.
+
+A variant like this in a generic body is just short of a pathology. The reason
+is that you cannot write any aggregates for such a type. The discriminant of an
+aggregate that controls variant components has to be static. But no expression
+of a generic formal type can ever be static - a generic formal subtype is never
+a static subtype, so there can be no static expressions of such a subtype. Thus
+there cannot be any aggregates.
+
+Without aggregates, constructing values of a variant record is a chore -- you
+have to declare an object of a constrained subtype and then fill in the
+components individually. I can imagine doing that if you need to export such a
+type, but not otherwise. So I don't think that there can be many such types in
+bodies.
+
+OTOH, it does make sense to export such a type from a generic specification (the
+instantiator can create objects freely). In that case, having variants that you
+can't use is not likely to be a good thing.
+
+In contrast, a case expression, even when used in a generic specification, is
+evaluated there; the instantiator can only access the value of that evaluation
+(it never uses the expression in any other way). So it doesn't matter as much
+what rules are used.
+
+(3) The primary benefit of case expressions is completeness checking. Indeed,
+    without that I would have voted against them as an unnecessary frill. But
+    you have to include an "others" clause for any case statement or expression
+    of a generic formal type. The effect is to make them much less useful;
+    meaning that if you have to convert them to if-expressions, this is not
+    going to cause any less safety in your program.
+
+(4) Darn, after reading 4.9 again, it appears that numeric literals can be
+    static even if they have a formal subtype. So (2) isn't quite right above.
+    But note that the operators of a formal subtype are NOT static functions
+    (4.9(19)), so "-1" is NOT static in this case. (Recall that we don't use the
+    universal operators if a subtype is expected for an expression, rather we
+    use the operators of that subtype.)
+
+So the variant in Steve's example is illegal in the generic:
+
+      generic
+         type T is new Integer;
+      package G is
+         type Rec (Discrim : T) is record
+            case Discrim is
+               when -10 .. -1 =>
+                  Foo : Float;
+               when others =>
+                  null;
+            end case;
+         end record;
+      end G;
+
+since neither "-10" nor "-1" are static, and that violates 3.8.1(8). The same is
+true for case statements and case expressions (5.4(5)). (It might have been
+legal in the instance, but you'll never get there.)
+
+Similarly, you can use named numbers in such cases and variants, but not
+constants (they're not static, either, in this case, nor is a type conversion
+from a static constant of some other type).
+
+So you are very limited in what you can do with such things; essentially you can
+only use positive literals.
+
+You could still construct problems, but I find it hard to believe that these are
+very common.
+
+Also note that the rules about static expressions would apply in the instance
+(4.9(33-37)). Even if you waived the case/variant  rules, you'd still have the
+possibility of illegal instances because violating one of these rules. That
+would be implementation-dependent in the case of the base range rule, which
+doesn't seem to be adding anything positive to the language!
+
+To summarize:
+
+It seems to me that there would need to be a lot of rewording to support this
+case, it would be clearly harmful for exported types, there is no bad effect
+from using an if expression instead of a case expression (no completeness check
+is possible anyway), most such case expressions are illegal anyway.
+
+So I think leaving the rules as they are is best.
+
+Note that I wouldn't object strongly to changing this for case
+expressions/statements only, but I don't think it is worth the effort.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Thursday, February  3, 2011  12:36 PM
+
+> ... I think that you've lost your mind.
+
+As I mentioned earlier, there seems to be general agreement that
+    1) We don't want to make any changes relating
+       to variant parts.
+    2) If we do make a change relating to case expressions,
+       we want to do it via a first-class legality rule,
+       not via a TBH note.
+
+Given that I agree with the above and feel that the only remaining question is
+whether we should do anything at all for case expressions, do you think that I
+need to continue the search for my missing mind?
+
+> The primary benefit of case expressions is completeness checking.
+
+Agreed. I think that there are others-less case expressions that can run afoul
+of this problem:
+
+    generic
+       X : in out Integer;
+    package G is
+       Inc_X_Towards_Zero : constant Integer :=
+         (case X is
+            when Integer'First .. -1 =>  X + 1,
+            when 0 => 0,
+            when 1 .. Integer'Last => X - 1
+          end case);
+     end G;
+
+     Z : Natural := ...;
+
+     package I is new G (Z); -- legal?
+
+Hopefully I got the syntax right, but you get the idea in any case.
+
+> Also note that the rules about static expressions would apply in the
+> instance (4.9(33-37)). Even if you waived the case/variant  rules,
+> you'd still have the possibility of illegal instances because
+> violating one of these rules.
+
+You bring up an interesting point.
+I'm not proposing this, but this could be used as an argument for modifying the
+definition of "statically unevaluated" to handle this case. Right now we have
+
+   a dependent_expression of a case_expression whose expression is
+   static and not covered by the corresponding discrete_choice_list.
+
+This could be somehow generalized so that the "X + 1" expression in the above
+example (in the instance, not in the generic) is statically unevaluated.
+
+I say wait until someone complains about this one.
+
+****************************************************************
+
+From: Jean-Pieere Rosen
+Sent: Thursday, February  3, 2011  3:20 AM
+
+> Gary said "I agree that it would be unfriendly" to reject the case
+> expressions we've been discussing.
+>
+> I'd like to get other opinions.
+>
+I side with Gary on this one.
+
+Nothing bad can happen from the instantiation, why reject it?
+Note that it is different from the case of a variable when the actual type is
+Natural, and the variable is initialized to a negative value: Constraint_Error
+has to be raised. And still, the instantiation is allowed.
+
+Does anybody really want to reject a case that works perfectly, while not
+rejecting a case which is statically known to raise constraint_Error?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, February  3, 2011  3:36 PM
+
+> > ... I think that you've lost your mind.
+>
+> As I mentioned earlier, there seems to be general agreement that
+>     1) We don't want to make any changes relating
+>        to variant parts.
+>     2) If we do make a change relating to case expressions,
+>        we want to do it via a first-class legality rule,
+>        not via a TBH note.
+>
+> Given that I agree with the above and feel that the only remaining
+> question is whether we should do anything at all for case expressions,
+> do you think that I need to continue the search for my missing mind?
+
+Perhaps it is I who has lost his mind. :-) See below.
+
+> > The primary benefit of case expressions is completeness checking.
+>
+> Agreed. I think that there are others-less case expressions that can
+> run afoul of this problem:
+>
+>     generic
+>        X : in out Integer;
+>     package G is
+>        Inc_X_Towards_Zero : constant Integer :=
+>          (case X is
+>             when Integer'First .. -1 =>  X + 1,
+>             when 0 => 0,
+>             when 1 .. Integer'Last => X - 1
+>           end case);
+>      end G;
+>
+>      Z : Natural := ...;
+>
+>      package I is new G (Z); -- legal?
+>
+> Hopefully I got the syntax right, but you get the idea in any case.
+
+Interesting. This example exists because the case choices complete the base
+range of the type of the selector expression (the subtype of a formal in out is
+never considered static).
+
+I don't much care about formal in outs (they're rarely used). I do care about
+the similar cases in generic formal subprograms.
+
+I was concerned that there was a new hole here, but I think it is already
+plugged.
+
+    subtype Short_Int is Integer range 0 .. 100;
+
+    generic
+        with function Foobar (A : Short_Int) return Short_Int;
+    package Gen is
+        Something : constant Boolean :=
+            (case Foobar (1) is
+                when 1 .. 100 => True,
+                when 0 => False); -- (1)
+    end Gen;
+
+This case expression is illegal, as not all of the values of the base range of
+the type of the selector expression are covered. That's because the result
+subtype of a formal function is never considered static. That's good, as the
+actual could have been
+
+    function "-" (Right : in Integer) return Integer;
+
+and it would return "-1" in this case.
+
+I was concerned that there was a way to do this with other sorts of formals (in
+particular, parameter subtypes of a formal subprogram), but I can't seem to
+construct an example.
+
+...
+> This could be somehow generalized so that the "X + 1"
+> expression in the above example (in the instance, not in the
+> generic) is statically unevaluated.
+>
+> I say wait until someone complains about this one.
+
+I was just thinking that your mind was leaving you again... :-)
+
+One side thought:
+Even if we don't formally adopt a rule saying that there is no recheck here, in
+the absence of an ACATS test I wouldn't expect there to be any recheck here.
+That's because these rechecks usually take explicit work, and in the absence of
+some reminder (either a bug report or an ACATS test), it is rare that they get
+implemented. In Janus/Ada specifically, we have to write explicit code for any
+rechecks needed. A lot of the time when implementing a new legality rule, we
+forgot to handle the recheck (and a good part of the time, no recheck is needed,
+which makes even less likely to think of it the next time). Moreover, a lot of
+those rechecks require saving information that otherwise would be discarded
+(like the exact contents of a default expression in a generic - since we code
+share, these have already been code generated and thus have no need -- other
+than rechecks -- to be saved).
+
+The net effect is that I suspect that this "recheck" will hardly ever be
+implemented (especially as no bug can result from omitting it). That seems like
+the best reason for actually making an explicit exception in this case: the
+recheck will take a lot of work to implement.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent