modula3 / cm3

Critical Mass Modula-3
http://modula3.github.io/cm3/
Other
133 stars 26 forks source link

Typechecker divergence #11

Open ajcz opened 8 years ago

ajcz commented 8 years ago

I’m trying to build a project of mine that contains something like the following.

INTERFACE AbsType; TYPE T <: ROOT; END AbsType.

INTERFACE AbsTypeRep;
  IMPORT AbsType;
  REVEAL AbsType.T <: Rep;
  TYPE Rep = AbsType.T OBJECT END;
  PROCEDURE proc (obj: T);
END AbsTypeRep.

MODULE AbsType EXPORTS AbsType, AbsTypeRep;
  REVEAL T = Rep BRANDED OBJECT END;
  PROCEDURE proc (<*UNUSED*> obj: T) = BEGIN END proc;
BEGIN
END AbsType.

The compiler enters into an infinite loop while compiling AbsType.m3. Here’s one of the possible stacks traces.

--- building in ..\NT386 ---

new source -> compiling AbsType.i3
new source -> compiling AbsTypeRep.i3
new source -> compiling AbsType.m3

***
*** runtime error:
***    A runtime error occurred.
***    pc = 0xc21fe0 = Equal in ..\src\types\Brand.m3
***

Stack trace:
   FP         PC      Procedure
---------  ---------  -------------------------------
  0x92fec   0xe0659b  SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3
  0x9303c   0xc21fe0  GenFPrint + 0x463 in ..\src\types\Brand.m3
  0x93078   0xbf9cf0  IsEqual + 0x2d5 in ..\src\types\Type.m3
  0x930ac   0xbf9ead  IsSubtype + 0x132 in ..\src\types\Type.m3
  0x93118   0xc672a3  Subtyper + 0x6e in ..\src\types\OpaqueType.m3
  0x93148   0xbf9f12  IsSubtype + 0x197 in ..\src\types\Type.m3
  0x93180   0xc5abb4  Subtyper + 0x19e in ..\src\types\ObjectType.m3
  0x931b0   0xbf9f12  IsSubtype + 0x197 in ..\src\types\Type.m3
  0x9321c   0xc6735c  Subtyper + 0x127 in ..\src\types\OpaqueType.m3
  0x9324c   0xbf9f12  IsSubtype + 0x197 in ..\src\types\Type.m3
.........  .........  ... more frames ...

If the redundant revelation AbsType.T <: Rep is removed in AbsTypeRep.i3, the compiler crashes when compiling from scratch, but subsequent runs are fine.

--- building in NT386 ---

new source -> compiling AbsType.i3
new source -> compiling AbsTypeRep.i3
new source -> compiling AbsType.m3
new exporters -> recompiling AbsTypeRep.i3

***
*** runtime error:
***    A runtime error occurred.
***    pc = 0xdc9d14 = KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg
***

Stack trace:
   FP         PC      Procedure
---------  ---------  -------------------------------
  0x92fec   0xe0659b  SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3
  0x9300c   0xdc9d14  KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg
  0x93048   0xdc949b  Get + 0x74 in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg
  0x9308c   0xb1e0bb  Pass0_FindMagic + 0xbe in ..\src\Builder.m3
  0x930e4   0xc5b918  FindMagic + 0x19c in ..\src\types\ObjectType.m3
  0x93130   0xc5b944  FindMagic + 0x1c8 in ..\src\types\ObjectType.m3
  0x9317c   0xc5b944  FindMagic + 0x1c8 in ..\src\types\ObjectType.m3
  0x931c8   0xc5b944  FindMagic + 0x1c8 in ..\src\types\ObjectType.m3
  0x93214   0xc5b944  FindMagic + 0x1c8 in ..\src\types\ObjectType.m3
  0x93260   0xc5b944  FindMagic + 0x1c8 in ..\src\types\ObjectType.m3
.........  .........  ... more frames ...

(According to my compiler its version is d5.10.0 and it was last updated 2015-05-21. I built it this January.)

darko20 commented 8 years ago

It's a bug, obviously, but it's caused by a misdefinition of the type via subtypes. The problem is that you're defining the type as a subtype of itself. Although it might be logically true, the compiler doesn't like it as a declaration (the language definition has a rule that forbids such a construction). In your example Rep should inherit what AbsType.T is a subtype of (ROOT in your case, which you can of course omit), not AbsType.T.

On Mon, Mar 28, 2016 at 4:00 PM, jcchu notifications@github.com wrote:

I’m trying to build a project of mine that contains something like the following.

INTERFACE AbsType; TYPE T <: ROOT; END AbsType.

INTERFACE AbsTypeRep; IMPORT AbsType; REVEAL AbsType.T <: Rep; TYPE Rep = AbsType.T OBJECT END; PROCEDURE proc (obj: T); END AbsTypeRep.

MODULE AbsType EXPORTS AbsType, AbsTypeRep; REVEAL T = Rep BRANDED OBJECT END; PROCEDURE proc (<_UNUSED_> obj: T) = BEGIN END proc; BEGIN END AbsType.

The compiler enters into an infinite loop while compiling AbsType.m3. Here’s one of the possible stacks traces.

--- building in ..\NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3


* runtime error: * A runtime error occurred. *\ pc = 0xc21fe0 = Equal in ..\src\types\Brand.m3


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9303c 0xc21fe0 GenFPrint + 0x463 in ..\src\types\Brand.m3 0x93078 0xbf9cf0 IsEqual + 0x2d5 in ..\src\types\Type.m3 0x930ac 0xbf9ead IsSubtype + 0x132 in ..\src\types\Type.m3 0x93118 0xc672a3 Subtyper + 0x6e in ..\src\types\OpaqueType.m3 0x93148 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x93180 0xc5abb4 Subtyper + 0x19e in ..\src\types\ObjectType.m3 0x931b0 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x9321c 0xc6735c Subtyper + 0x127 in ..\src\types\OpaqueType.m3 0x9324c 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 ......... ......... ... more frames ...

If the redundant revelation AbsType.T <: Rep is removed in AbsTypeRep.i3, the compiler crashes when compiling from scratch, but subsequent runs are fine.

--- building in NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3 new exporters -> recompiling AbsTypeRep.i3


* runtime error: * A runtime error occurred. *\ pc = 0xdc9d14 = KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9300c 0xdc9d14 KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x93048 0xdc949b Get + 0x74 in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x9308c 0xb1e0bb Pass0_FindMagic + 0xbe in ..\src\Builder.m3 0x930e4 0xc5b918 FindMagic + 0x19c in ..\src\types\ObjectType.m3 0x93130 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x9317c 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x931c8 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93214 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93260 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 ......... ......... ... more frames ...

(According to my compiler its version is d5.10.0 and it was last updated 2015-05-21. I built it this January.)

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/modula3/cm3/issues/11

ajcz commented 8 years ago

OK I think I understand it now. Actually the (mis)definition of Rep implies Rep <: T, which is inconsistent with the complete revelation that T = Rep BRANDED OBJECT ... END, if I understand brands correctly.

— JC

[quoted message removed]

RodneyBates commented 8 years ago

On 03/28/2016 09:00 AM, jcchu wrote:

I’m trying to build a project of mine that contains something like the following.

|INTERFACE AbsType; TYPE T <: ROOT; END AbsType.

INTERFACE AbsTypeRep; IMPORT AbsType; REVEAL AbsType.T <: Rep; TYPE Rep = AbsType.T OBJECT END; PROCEDURE proc (obj: T); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ T is undeclared here. Compiler should give an error message. And my compiler does:

rodney@allegheny:~/proj/m3/exp/revealBugs/src$ cm3 --- building in ../AMD64_LINUX ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 "../src/AbsTypeRep.i3", line 5: undefined (T) 1 error encountered m3front failed compiling: ../src/AbsTypeRep.i3 new source -> compiling AbsType.m3 "../src/AbsType.m3", line 2: imported interface contains errors (AbsTypeRep) 1 error encountered m3front failed compiling: ../src/AbsType.m3 new exporters -> recompiling AbsType.i3 compilation failed => not building program "prog" Fatal Error: package build failed

It's the git head compiler, but I find it difficult to believe that any compiler later than early DEC SRC would fail to catch this.

If I change the subject line to : PROCEDURE proc (obj: AbsType.T); (Is this what you meant?),

I get a segfault compiling AbsType.m3, which I suppose is the same failure, (Did you mean infinite recursion?)

The compiler should give an error message on the illegal recursive declaration, as Darko said. The compiler rule is in section 2.4.8, "Recursive Declarations".

Note that an object subtype definition, even if it has no fields, methods, or overrides creates a distinct type, i.e., in TYPE T = U OBJECT END, T <: U, but NOT T = U. Even without this, the presence of BRANDED also makes for a different type, i.e. in TYPE S = U BRANDED OBJECT END , S # U. In fact, no type can be defined, anywhere in the entire link closure, that is equal to U, because the language-provided implicit brand string is unique to this one occurrence of the type definition U BRANDED OBJECT END.

This is really needed so that the language can assume two structurally identical opaque type declarations ,, e.g., <: ROOT and T <: ROOT are not equal. (which it does.) Otherwise, type checking would totally collapse in the presence of multiple, not-fully-revealed opaque types.

But T and U could be equal types if both were branded with identical explicit brand strings, i.e, in W = U BRANDED "UBrand"OBJECT END and X = U BRANDED "UBrand"OBJECT END, W = X.

END AbsTypeRep.

MODULE AbsType EXPORTS AbsType, AbsTypeRep; REVEAL T = Rep BRANDED OBJECT END; PROCEDURE proc (<_UNUSED_> obj: T) = BEGIN END proc; BEGIN END AbsType. |

The compiler enters into an infinite loop while compiling AbsType.m3. Here’s one of the possible stacks traces.

|--- building in ..\NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3


* runtime error: * A runtime error occurred. *\ pc = 0xc21fe0 = Equal in ..\src\types\Brand.m3


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9303c 0xc21fe0 GenFPrint + 0x463 in ..\src\types\Brand.m3 0x93078 0xbf9cf0 IsEqual + 0x2d5 in ..\src\types\Type.m3 0x930ac 0xbf9ead IsSubtype + 0x132 in ..\src\types\Type.m3 0x93118 0xc672a3 Subtyper + 0x6e in ..\src\types\OpaqueType.m3 0x93148 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x93180 0xc5abb4 Subtyper + 0x19e in ..\src\types\ObjectType.m3 0x931b0 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x9321c 0xc6735c Subtyper + 0x127 in ..\src\types\OpaqueType.m3 0x9324c 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 ......... ......... ... more frames ... |

If the redundant revelation |AbsType.T| <: |Rep| is removed in AbsTypeRep.i3, the compiler crashes when compiling from scratch, but subsequent runs are fine.

|--- building in NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3 new exporters -> recompiling AbsTypeRep.i3


* runtime error: * A runtime error occurred. *\ pc = 0xdc9d14 = KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9300c 0xdc9d14 KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x93048 0xdc949b Get + 0x74 in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x9308c 0xb1e0bb Pass0_FindMagic + 0xbe in ..\src\Builder.m3 0x930e4 0xc5b918 FindMagic + 0x19c in ..\src\types\ObjectType.m3 0x93130 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x9317c 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x931c8 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93214 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93260 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 ......... ......... ... more frames ... |

(According to my compiler its version is d5.10.0 and it was last updated 2015-05-21. I built it this January.)

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/modula3/cm3/issues/11

ajcz commented 8 years ago

PROCEDURE proc (obj: AbsType.T); (Is this what you meant?)

(Did you mean infinite recursion?)

Yes and yes.

The compiler rule is in section 2.4.8, "Recursive Declarations".

I checked section 4.8 of “Modula-3 language definition” https://dx.doi.org/10.1145/142137.142141 but it didn’t give compiler rules ..., although it did give an example of illegal declaration REVEAL I.T = I.T BRANDED OBJECT END. But I get the point that a type cannot be a subtype of a branded copy of itself.

But here’s another issue. First consider the following illegal fragment.

TYPE T = U OBJECT END;
TYPE U <: T;  (* illegal *)
REVEAL U = T BRANDED OBJECT END

My compiler correctly reports that the second line is invalid, but then crashes. Now if I change the second line to

TYPE U <: ROOT

the new fragment will be accepted. But in this case, we have T <: U = T with a brand, which should be forbidden. In fact the semantically equivalent the fragment below is rejected.

TYPE T = U OBJECT END;
TYPE U = T BRANDED OBJECT END

— JC

darko20 commented 8 years ago

The relevant section I think is "Revelations": https://www.cs.purdue.edu/homes/hosking/m3/reference/revelations.html

The rule I was thinking of was "In any scope, the revealed supertypes of an opaque type must be linearly ordered by the subtype relation."

The question I have about the anomalous construction is: did it link? If it did then it's a bug, otherwise it's foreshadowed by " It is a static error if any type revealed in any scope as a supertype of T is not a supertype of V. Generally this error is detected at link time."

On Tue, Mar 29, 2016 at 4:11 AM, jcchu notifications@github.com wrote:

PROCEDURE proc (obj: AbsType.T); (Is this what you meant?)

(Did you mean infinite recursion?)

Yes and yes.

The compiler rule is in section 2.4.8, "Recursive Declarations".

I checked section 4.8 of “Modula-3 language definition” < https://dx.doi.org/10.1145/142137.142141> but it didn’t give compiler rules ..., although it did give an example of illegal declaration REVEAL I.T = I.T BRANDED OBJECT END. But I get the point that a type cannot be a subtype of a branded copy of itself.

But here’s another issue. First consider the following illegal fragment.

TYPE T = U OBJECT END; TYPE U <: T; (* illegal *) REVEAL U = T BRANDED OBJECT END

My compiler correctly reports that the second line is invalid, but then crashes. Now if I change the second line to

TYPE U <: ROOT

the new fragment will be accepted. But in this case, we have T <: U = T with a brand, which should be forbidden. In fact the semantically equivalent the fragment below is rejected.

TYPE T = U OBJECT END; TYPE U = T BRANDED OBJECT END

— JC

— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/modula3/cm3/issues/11#issuecomment-202668352

RodneyBates commented 8 years ago

There are enough different language and compiler issues here, I have to print posts and make notes in the margins to keep track of which is which!

On 03/28/2016 09:11 PM, jcchu wrote:

PROCEDURE proc (obj: AbsType.T); (Is this what you meant?)

(Did you mean infinite recursion?)

Yes and yes.

The compiler rule is in section 2.4.8, "Recursive Declarations".

I checked section 4.8 of “Modula-3 language definition” https://dx.doi.org/10.1145/142137.142141 but it didn’t give compiler rules ..., although it did give an example of illegal declaration REVEAL I.T = I.T BRANDED OBJECT END. But I get the point that a type cannot be a subtype of a branded copy of itself.

2.4.8 does disallow this, as follows: (Ignoring "AbsType." prefixes on T -- there is only one T in the example)

Start with REVEAL T = Rep BRANDED OBJECT END, expand one step by substituting for Rep, using Rep = T OBJECT END, giving REVEAL T = (T OBJECT END) BRANDED OBJECT END, an illegal recursive declaration, just like the example you cited.

But here’s another issue. First consider the following illegal fragment.

TYPE T = U OBJECT END; TYPE U <: T; (* illegal *) REVEAL U = T BRANDED OBJECT END

Reading 2.4.8 carefully, I see the language does not disallow this, even though the compiler does. To justify the error, section 2.4.8 need to add, to the declaration forms it gives, "an opaque type declaration N <: E" to justify the error message on this line.

The declaration of T is illegal recursive also, but there is some lack of clarity here. Section 2.2 defines type expansion to entail that: "all type names are replaced by their definitions". Of an opaque type declaration and its full revelation, I would guess that the latter would be its "definition" and not the former. Off hand, I think any problem detectable using the opaque declaration would also be detected using the revelation in the expansion. In this case, the language does not need the change I mentioned above, and the compiler's error on U <: T is not really necessary, since the problem will be reported (if the compiler were fixed) at the revelation. But this might still be a useful, earlier detection, especially when the revelation is in a different compilation unit.

The language needs to be clarified on at least the latter point and the compiler crash needs to be fixed to report this error.

My compiler correctly reports that the second line is invalid, but then crashes. Now if I change the second line to

TYPE U <: ROOT

the new fragment will be accepted. But in this case, we have T <: U = T with a brand, which should be forbidden.

And this is a compiler bug too. 2.4.8 includes a (full) revelation in the list of things that can participate in a recursive cycle, It's really the same illegal recursive declaration as before, but a different compiler behavior.

In fact the semantically equivalent the fragment below is rejected.

TYPE T = U OBJECT END; TYPE U = T BRANDED OBJECT END

— JC

— You are receiving this because you commented. Reply to this email directly or view it on GitHub https://github.com/modula3/cm3/issues/11#issuecomment-202668352

RodneyBates commented 8 years ago

On 03/28/2016 09:00 AM, jcchu wrote:

I’m trying to build a project of mine that contains something like the following.

|INTERFACE AbsType; TYPE T <: ROOT; END AbsType.

INTERFACE AbsTypeRep; IMPORT AbsType; REVEAL AbsType.T <: Rep; TYPE Rep = AbsType.T OBJECT END; PROCEDURE proc (obj: T); END AbsTypeRep.

MODULE AbsType EXPORTS AbsType, AbsTypeRep; REVEAL T = Rep BRANDED OBJECT END; PROCEDURE proc (<_UNUSED_> obj: T) = BEGIN END proc; BEGIN END AbsType. |

The compiler enters into an infinite loop while compiling AbsType.m3. Here’s one of the possible stacks traces.

|--- building in ..\NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3


* runtime error: * A runtime error occurred. *\ pc = 0xc21fe0 = Equal in ..\src\types\Brand.m3


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9303c 0xc21fe0 GenFPrint + 0x463 in ..\src\types\Brand.m3 0x93078 0xbf9cf0 IsEqual + 0x2d5 in ..\src\types\Type.m3 0x930ac 0xbf9ead IsSubtype + 0x132 in ..\src\types\Type.m3 0x93118 0xc672a3 Subtyper + 0x6e in ..\src\types\OpaqueType.m3 0x93148 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x93180 0xc5abb4 Subtyper + 0x19e in ..\src\types\ObjectType.m3 0x931b0 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 0x9321c 0xc6735c Subtyper + 0x127 in ..\src\types\OpaqueType.m3 0x9324c 0xbf9f12 IsSubtype + 0x197 in ..\src\types\Type.m3 ......... ......... ... more frames ... |

If the redundant revelation |AbsType.T| <: |Rep| is removed in AbsTypeRep.i3, the compiler crashes when compiling from scratch, but subsequent runs are fine.

Subsequent runs on mine suffer the same crash. All I did was repeat the cm3 command. Did you use some other sequence? The compiler should behave the same when repeating a failed compile, no matter what the sequence, tho' obviously not by crashing.

|--- building in NT386 ---

new source -> compiling AbsType.i3 new source -> compiling AbsTypeRep.i3 new source -> compiling AbsType.m3 new exporters -> recompiling AbsTypeRep.i3


* runtime error: * A runtime error occurred. *\ pc = 0xdc9d14 = KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg


Stack trace: FP PC Procedure


0x92fec 0xe0659b SystemError + 0x64 in ..\src\runtime\NT386\RTSignal.m3 0x9300c 0xdc9d14 KeyHash + 0xa in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x93048 0xdc949b Get + 0x74 in ..\NT386\IntRefTbl.m3 => ..\src\table\Table.mg 0x9308c 0xb1e0bb Pass0_FindMagic + 0xbe in ..\src\Builder.m3 0x930e4 0xc5b918 FindMagic + 0x19c in ..\src\types\ObjectType.m3 0x93130 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x9317c 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x931c8 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93214 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 0x93260 0xc5b944 FindMagic + 0x1c8 in ..\src\types\ObjectType.m3 ......... ......... ... more frames ... |

(According to my compiler its version is d5.10.0 and it was last updated 2015-05-21. I built it this January.)

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/modula3/cm3/issues/11

ajcz commented 8 years ago

My compiler correctly reports that the second line is invalid, but then crashes. Now if I change the second line to

TYPE U <: ROOT

the new fragment will be accepted. But in this case, we have T <: U = T with a brand, which should be forbidden.

And this is a compiler bug too. 2.4.8 includes a (full) revelation in the list of things that can participate in a recursive cycle, It's really the same illegal recursive declaration as before, but a different compiler behavior.

Yes and it seems like with the opaque type declaration T <: ROOT the compiler can be tricked to do many things with T. For example, the following fragment causes the compiler to hang.

(* fragment 1 *)

TYPE T <: ROOT; REVEAL T = T

And the next causes a crash.

(* fragment 2 *)
TYPE T <: ROOT;
REVEAL T <: T;  (* -- offending declaration *)
REVEAL T = BRANDED OBJECT END;

But here’s another question: is ROOT the same type as OBJECT END? My interpretation of §2.9 is that they are two names for the same thing, but the compiler seems to treat them differently. The following fragment, for example, is rejected.

TYPE T <: OBJECT END;  (* okay if ROOT used instead *)
REVEAL T = BRANDED OBJECT END;

But then OBJECT END can indeed replace ROOT fragments 1 and 2 when tricking the compiler.

— JC

ajcz commented 8 years ago

Subsequent runs on mine suffer the same crash. All I did was repeat the cm3 command. Did you use some other sequence? The compiler should behave the same when repeating a failed compile, no matter what the sequence, tho' obviously not by crashing.

You get that behavior when you remove “REVEAL AbsType.T <: Rep” in AbsTypeRep.i3.

— JC

[quoted message removed]