Skip to content

Compiler crash with higher kinded existential #4017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
scabug opened this issue Nov 21, 2010 · 6 comments
Closed

Compiler crash with higher kinded existential #4017

scabug opened this issue Nov 21, 2010 · 6 comments
Assignees

Comments

@scabug
Copy link

scabug commented Nov 21, 2010

The following code crashes the compiler:

def m(v: V[_] forSome { type V[_] }) = 1

What versions of the following are you using?

Scala: 2.8.1.final

Java: Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22

Operating system: Ubuntu 10.04

Trace:

Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def m(v: V[_] forSome { type V[_] }) = 1
java.lang.Error: Unknown type: ()java.lang.Object, ()java.lang.Object[class scala.tools.nsc.symtab.Types$$MethodType, class scala.tools.nsc.symtab.Types$$MethodType] TypeRef? false, false
        at scala.tools.nsc.symtab.SymbolTable.abort(SymbolTable.scala:33)
        at scala.tools.nsc.backend.icode.TypeKinds$$class.toTypeKind(TypeKinds.scala:474)
        at scala.tools.nsc.backend.icode.ICodes.toTypeKind(ICodes.scala:26)
        at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$addMethodParams$$1.apply(GenICode.scala:1476)
        at scala.tools.nsc.backend.icode.GenICode$$ICodePhase$$$$anonfun$$addMethodParams$$1.apply(GenICode.scala:1475)
        at scala.collection.LinearSeqOptimized$$class.foreach(LinearSeqOptimized.scala:61)
        at scala.collection.immutable.List.foreach(List.scala:45)
        at scala.tools.nsc.backend.icode.GenICode$$ICodePhase.addMethodParams(GenICode.scala:1475)
@scabug
Copy link
Author

scabug commented Nov 21, 2010

Imported From: https://issues.scala-lang.org/browse/SI-4017?orig=1
Reporter: Aaron Novstrup (anovstrup)

@scabug
Copy link
Author

scabug commented Nov 21, 2010

@retronym said:
See also #2308. Higher kinded existential types aren't really supported.

@scabug
Copy link
Author

scabug commented Nov 21, 2010

@adriaanm said:
thanks to Jason for pointing out what this is a duplicate of

@scabug
Copy link
Author

scabug commented Nov 21, 2010

Aaron Novstrup (anovstrup) said:
This can't really be considered a duplicate -- regardless of whether higher-kinded existentials are supported, I think we can agree that it's impolite for the compiler throw an exception, print a stack trace, and exit.

@scabug
Copy link
Author

scabug commented Jan 20, 2011

@adriaanm said:
(In r24029) introduce NullaryMethodType to disambiguate PolyType

motivation:
given def foo[T]: (T, T) and type Foo[T] = (T, T),

foo.info and TypeRef(_, Foo, Nil).normalize are both PolyType(List(T), Pair[T, T])

uncurry has been relying on an ugly hack to distinguish these cases based on ad-hoc kind inference
without this distinction, the type alias's info (a type function) would be transformed to PolyType(List(T), MethodType(Nil, Pair[T, T]))

anonymous type functions are being used more often (see #2741, #4017, #4079, #3443, #3106), which makes a proper treatment of PolyTypes more pressing

change to type representation:
PolyType(Nil, tp) -> NullaryMethodType(tp)
PolyType(tps, tp) -> PolyType(tps, NullaryMethodType(tp)) (if the polytype denoted a polymorphic nullary method)

PolyType(Nil, tp) is now invalid

the kind of a PolyType is * iff its resulttype is a NullaryMethodType or a MethodType (i.e., it's a polymorphic value)
in all other cases a PolyType now denotes a type constructor

NullaryMethodType is eliminated during uncurry

pickling:
for backwards compatibility, a NullaryMethodType(tp) is still pickled as a PolyType(Nil, tp),
unpickling rewrites pre-2.9-pickled PolyTypes according to the expected kind of the unpickled type (similar to what we used to do in uncurry)
a pickled PolyType(Nil, restpe) is unpickled to NullaryMethodType(restpe)
a pickled PolyType(tps, restpe) is unpickled to PolyType(tps, NullaryMethodType(restpe)) when the type is expected to have kind *

the rewrite probably isn't complete, but was validated by compiling against the old scalacheck jar (which has plenty of polymorphic nullary methods)
nevertheless, this commit includes a new scalacheck jar

summary of the refactoring:

  • PolyType(List(), tp) or PolyType(Nil, tp) or PolyType(parms, tp) if params.isEmpty ==> NullaryMethodType(tp)

  • whenever there was a case PolyType(tps, tp) (irrespective of tps isEmpty), now need to consider the
    case PolyType(tps, NullaryMethodType(tp)); just add a case NullaryMethodType(tp), since usually:

    • there already is a PolyType case that recurses on the result type,
    • the polytype case applied to empty and non-empty type parameter lists alike
  • tp.resultType, where tp was assumed to be a PolyType that represents a polymorphic nullary method type
    before, tp == PolyType(tps, res), now tp == PolyType(tps, NullaryMethodType(res))

  • got bitten again (last time was dependent-method types refactoring) by a TypeMap not being the identity when dropNonConstraintAnnotations is true (despite having an identity apply method). Since asSeenFrom is skipped when isTrivial, the annotations aren't dropped. The cps plugin relies on asSeenFrom dropping these annotations for trivial types though. Therefore, NullaryMethodType pretends to never be trivial. Better fix(?) in AsSeenFromMap: if(tp.isTrivial) dropNonContraintAnnotations(tp) else ...

TODO: scalap and eclipse

review by odersky, rytz

@scabug
Copy link
Author

scabug commented Jan 25, 2011

@adriaanm said:
fixed by r24029

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants