!standard 4.9.1 (02) 02-09-26 AI95-00311/01 !standard 12.5.2 (01) !class binding interpretation 02-09-26 !status work item 02-09-26 !status received 02-08-28 !qualifier Omission !priority Low !difficulty Easy !subject Static matching of formal scalar subtypes !summary If T1 is a generic formal scalar type, T1 does not statically match T1'Base. !question Is the following legal? generic type T1 is range <>; package Pak1 is procedure P1 (Left : T1); end Pak1; package body Pak1 is procedure P1 (Left : T1'Base) is begin null; end P1; end Pak1; If T1 is considered to have a null constraint, then the subtypes T1 and T1'Base statically match and the above example is legal; if T1's constraint is nonstatic, then the constraints do not statically match by 4.9.1(2), and thus the example is illegal. !recommendation (See summary.) !wording (* TBD *) !discussion Intuitively, T1's constraint should be nonstatic by definition, since it is not known what the actual constraint will be and the actual subtype can have any legal constraint whatsoever. However, the standard does not say this. We would like the wording to allow generic type T1 is range <>; package Pak1 is subtype S1 is T1; procedure P1 (Left : T1); end Pak1; package body Pak1 is procedure P1 (Left : S1) is begin null; end P1; end Pak1; to be legal. That eliminates the obvious fix of saying that a generic formal subtype only matches itself in 4.9.1(2). Another fix, to say that a formal subtype always has nonstatic constraints (after 4.9(31)), also fails this test. (At this point I gave up - ED). !ACATS test A B-Test should possibly be created to check this case. !appendix !topic Constraint of formal scalar type !reference RM95 12.5.2, 4.9(27), 4.9.1(2), 6.3(4), 6.3.1(17-18) !from Adam Beneschan 08-30-02 !discussion In this fragment: generic type T1 is range <>; package pak1 is ... What is the status of T1's constraint? Is it null, static, nonstatic, unknown, or what? The reason this matters is because I can't figure out whether this is legal: generic type T1 is range <>; package Pak1 is procedure P1 (Left : T1); end Pak1; package body Pak1 is procedure P1 (Left : T1'Base) is begin null; end P1; end Pak1; If T1 is considered to have a null constraint, then the subtypes T1 and T1'Base statically match and the above example is legal; if T1's constraint is nonstatic, then I believe the constraints to not statically match by 4.9.1(2), and thus the example is illegal. Intuitively, it seems to me that T1's constraint should be nonstatic by definition, since it is not known what the actual constraint will be and the actual subtype can have any legal constraint whatsoever. However, I can't find support in the RM for this. Perhaps something should be added to 4.9 or 4.9.1 to indicate that the constraint on a generic formal first subtype is considered to be nonstatic? **************************************************************** From: Robert A Duff Sent: Friday, September 6, 2002 4:36 PM > The reason this matters is because I can't figure out whether this is > legal: This should be illegal, IMHO, since the actual for T1 might impose a constraint, which makes the body a lie. Whether the RM says so, I don't know. Can I invoke Robert's Rule, which says that no matter what the RM says, it "really" says what we mean? ;-) **************************************************************** From: Tucker Taft Sent: Friday, September 6, 2002 9:18 PM >If T1 is considered to have a null constraint, then the subtypes T1 >and T1'Base statically match and the above example is legal; if T1's >constraint is nonstatic, then I believe the constraints to not >statically match by 4.9.1(2), and thus the example is illegal. Neither T1 nor T1'Base is static, according to 4.9(25-26). They don't match because they aren't the result of the elaboration of the same constraint or range (cf. 4.9.1(1)). >Intuitively, it seems to me that T1's constraint should be nonstatic >by definition, since it is not known what the actual constraint will >be and the actual subtype can have any legal constraint whatsoever. >However, I can't find support in the RM for this. Perhaps something >should be added to 4.9 or 4.9.1 to indicate that the constraint on a >generic formal first subtype is considered to be nonstatic? I don't see any hole here. **************************************************************** From: Adam Beneschan Sent: Monday, September 9, 2002 1:45 PM It still looks like a hole to me. The important thing here isn't whether the subtypes are static, but whether the subtypes statically match (6.3.1(17)). So 4.9(26) isn't relevant here. 4.9(25) isn't relevant either. It says "A static range is a _range_ whose bounds are static expressions ...". The definition of a _range_ in 3.5(3) is either two expressions with .. in between, or a 'Range attribute; "<>" is not a _range_, by this definition, and thus 4.9(25) doesn't apply. The key question here, I believe, is: what, exactly, *is* the constraint on T1 (particularly for the purposes of applying 4.9.1(1))? "range <>" doesn't meet the definition of a _constraint_ given in 3.2.2(5), so it doesn't appear to be technically correct to call "range <>" a constraint; but if this isn't a constraint, then the generic formal T1 has a null constraint (since I can't find anything in the RM that decrees otherwise), and thus it would seem to say that T1 and T1'Base do statically match, since their constraints are both null constraints and thus match by 4.9.1(1). **************************************************************** From: Tucker Taft Sent: Monday, September 9, 2002 3:19 PM In general, the properties of a formal (sub)type are determined by the range of potential properties of the allowed actual subtypes. Given that the actual subtype might or might not be constrained, it is not determined at compile-time whether a formal scalar type is constrained or unconstrained. I realize that is a bit of an uncomfortable position to be in, but it doesn't actually affect legality except in the case of statically matching subtypes, as you point out. The RM explicitly says the base range is non-static, and we know that T1'Base is unconstrained, but T1 itself might or might not be constrained. It would seem there are two possibilities, either we assume the "best" in the spec and then recheck upon instantiation, or we say that they clearly don't statically match, even though they might dynamically match. So I guess I agree with you now that there is a hole, and we need to specify which possibility is to be chosen. It seems clear that in the body, the two subtypes don't statically match. But in the spec, there seems some case for saying that the static matching check is deferred until instantiation time. With my implementation hat on I will have to say "yuck"... ;-) Note that a similar situation arises with formal access subtypes, where it is not known at compile time whether the actual will be constrained or unconstrained. However, since there is no 'Base attribute, this particular problem doesn't arise. However, since it is illegal to apply a constraint to an already-constrained access subtype, the legality of applying a constraint would seem to depend on an unknown-at-compile-time characteristic, bringing up the same assume-the-best vs. assume-the-worst situation. I wonder how we have handled that case? It sounds familiar... **************************************************************** From: Randy Brukardt Sent: Thursday, September 26, 2002 9:56 PM Tucker wrote: > So I guess I agree with you now that there is a hole, > and we need to specify which possibility is to be > chosen. It seems clear that in the body, the two > subtypes don't statically match. But in the spec, > there seems some case for saying that the static > matching check is deferred until instantiation time. > With my implementation hat on I will have to say "yuck"... ;-) I'm strongly in favor of this always not matching, unless someone can find an example where matching would be valuable in practice. Certainly Adam's example isn't it. :-) > Note that a similar situation arises with formal access > subtypes, where it is not known at compile time whether > the actual will be constrained or unconstrained. However, > since there is no 'Base attribute, this particular problem > doesn't arise. However, since it is illegal to apply a > constraint to an already-constrained access subtype, the > legality of applying a constraint would seem to depend on > an unknown-at-compile-time characteristic, bringing up > the same assume-the-best vs. assume-the-worst situation. > I wonder how we have handled that case? It sounds familiar... That's AI-34, which is a confirmation. (Wow!) It says that the check is not performed in the body of the generic, because legality rules don't apply there. I suppose the check is performed in the private part on instantiation, but no check is ever done in the body. Thus, its possible to doubly constrain an access subtype; supposedly the meaning is that the original constraint is dropped. There is no runtime check, either. I'm *certain* we don't want to follow this model here! ****************************************************************