diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 19 | ||||
-rw-r--r-- | test/files/neg/t2208.check | 4 | ||||
-rw-r--r-- | test/files/neg/t2208.scala | 8 | ||||
-rw-r--r-- | test/files/pos/t2208.scala | 8 |
5 files changed, 39 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 0ebd2018fb..e115446147 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1559,6 +1559,8 @@ A type's typeSymbol should never be inspected directly. PolyType(typeParams, typeRef(pre, sym.initialize, dummyArgs)) } else if (sym.isRefinementClass) { sym.info.normalize // @MO to AM: OK? + //@M I think this is okay, but changeset 12414 (which fixed #1241) re-introduced another bug (#2208) + // see typedTypeConstructor in Typers } else { super.normalize } diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index a552c2ef7c..c3fa5555c4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3875,11 +3875,26 @@ trait Typers { self: Analyzer => /** Types a type constructor tree used in a new or supertype */ def typedTypeConstructor(tree: Tree, mode: Int): Tree = { val result = typed(tree, typeMode(mode) | FUNmode, WildcardType) - val restpe = result.tpe.normalize + + val restpe = result.tpe.normalize // normalize to get rid of type aliases for the following check (#1241) if (!phase.erasedTypes && restpe.isInstanceOf[TypeRef] && !restpe.prefix.isStable) { error(tree.pos, restpe.prefix+" is not a legal prefix for a constructor") } - result setType restpe // @M: normalization is done during erasure + + //@M fix for #2208 + // if there are no type arguments, normalization does not bypass any checks, so perform it to get rid of AnyRef + if(result.tpe.typeArgs.isEmpty) { + // minimal check: if(result.tpe.typeSymbolDirect eq AnyRefClass) { + // must expand the fake AnyRef type alias, because bootstrapping (init in Definitions) is not + // designed to deal with the cycles in the scala package (ScalaObject extends + // AnyRef, but the AnyRef type alias is entered after the scala package is + // loaded and completed, so that ScalaObject is unpickled while AnyRef is not + // yet defined ) + result setType(restpe) + } else { // must not normalize: type application must be (bounds-)checked (during RefChecks), see #2208 + // during uncurry (after refchecks), all types are normalized + result + } } def typedTypeConstructor(tree: Tree): Tree = typedTypeConstructor(tree, NOmode) diff --git a/test/files/neg/t2208.check b/test/files/neg/t2208.check new file mode 100644 index 0000000000..6f7d60d84e --- /dev/null +++ b/test/files/neg/t2208.check @@ -0,0 +1,4 @@ +ticket2208.scala:7: error: type arguments [Any] do not conform to type Alias's type parameter bounds [X <: Test.A] + class C extends Alias[Any] // not ok, normalisation should check bounds before expanding Alias + ^ +one error found
\ No newline at end of file diff --git a/test/files/neg/t2208.scala b/test/files/neg/t2208.scala new file mode 100644 index 0000000000..43bb0adec5 --- /dev/null +++ b/test/files/neg/t2208.scala @@ -0,0 +1,8 @@ +object Test { + class A + + class B[X] + type Alias[X <: A] = B[X] + + class C extends Alias[Any] // not ok, normalisation should check bounds before expanding Alias +}
\ No newline at end of file diff --git a/test/files/pos/t2208.scala b/test/files/pos/t2208.scala new file mode 100644 index 0000000000..f1a521b14c --- /dev/null +++ b/test/files/pos/t2208.scala @@ -0,0 +1,8 @@ +object Test { + class A + + class B[X] + type Alias[X <: A] = B[X] + + val foo: B[A] = new Alias[A] // check that type aliases can be instantiated +}
\ No newline at end of file |