diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-08-09 11:51:37 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2010-08-09 11:51:37 +0000 |
commit | 3ac03c3d3f0e21f279ba8c405351e445af623ceb (patch) | |
tree | ea405a577a99904525cc9b3042d7c5ac207ae20c | |
parent | 40aafbdf1a9a52c1236f07e06d48fb24b5fa2169 (diff) | |
download | scala-3ac03c3d3f0e21f279ba8c405351e445af623ceb.tar.gz scala-3ac03c3d3f0e21f279ba8c405351e445af623ceb.tar.bz2 scala-3ac03c3d3f0e21f279ba8c405351e445af623ceb.zip |
closes #3582: typedTypeDef needs to run in a ne...
closes #3582: typedTypeDef needs to run in a new typer for TypeDefs with
type parameters
this was honored when typedTypeDef was called by typed1, but other
callers did not this would cause higher-order type parameters to be
re-entered in the scope of a method or a class
(by the way, should we recycle scopes for higher-order type params? now
new scopes are created, symbols entered, and tree's symbols updated)
changed some spurious vars to vals
review by odersky
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/TypingTransformers.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 16 | ||||
-rw-r--r-- | test/files/pos/t3582.scala | 12 | ||||
-rw-r--r-- | test/files/pos/t3582b.scala | 5 |
6 files changed, 33 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 9e10d3a408..acf4f6d43d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -137,7 +137,7 @@ trait Types extends reflect.generic.Types { self: SymbolTable => * It makes use of the fact that these two operations depend only on the parents, * not on the refinement. */ - var intersectionWitness = new WeakHashMap[List[Type], Type] + val intersectionWitness = new WeakHashMap[List[Type], Type] private object gen extends { val global : Types.this.type = Types.this diff --git a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala index 6656b79d26..de5355de61 100644 --- a/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala +++ b/src/compiler/scala/tools/nsc/transform/TypingTransformers.scala @@ -26,7 +26,7 @@ trait TypingTransformers { protected def typedPos(pos: Position)(tree: Tree) = localTyper typed { atPos(pos)(tree) } /** a typer for each enclosing class */ - var typers: Map[Symbol, analyzer.Typer] = new HashMap + val typers: Map[Symbol, analyzer.Typer] = new HashMap override def atOwner[A](owner: Symbol)(trans: => A): A = atOwner(curTree, owner)(trans) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 5687917e46..22a1bee9b2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -297,7 +297,7 @@ trait Namers { self: Analyzer => val sym = tree.symbol if (settings.debug.value) log("entered " + sym + " in " + context.owner + ", scope-id = " + context.scope.## ) var ltype = namerOf(sym).typeCompleter(tree) - if (!tparams.isEmpty) { + if (tparams nonEmpty) { //@M! TypeDef's type params are handled differently //@M e.g., in [A[x <: B], B], A and B are entered first as both are in scope in the definition of x //@M x is only in scope in `A[x <: B]' diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index cbdbadc4bf..381b1ceed3 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1788,8 +1788,18 @@ trait Typers { self: Analyzer => } def typedTypeDef(tdef: TypeDef): TypeDef = { - reenterTypeParams(tdef.tparams) // @M! - val tparams1 = tdef.tparams mapConserve (typedTypeDef) // @M! + def typeDefTyper = { + if(tdef.tparams isEmpty) Typer.this + else newTyper(context.makeNewScope(tdef, tdef.symbol)) + } + typeDefTyper.typedTypeDef0(tdef) + } + + // call typedTypeDef instead + // a TypeDef with type parameters must always be type checked in a new scope + private def typedTypeDef0(tdef: TypeDef): TypeDef = { + reenterTypeParams(tdef.tparams) + val tparams1 = tdef.tparams mapConserve {typedTypeDef(_)} val typedMods = removeAnnotations(tdef.mods) // complete lazy annotations val annots = tdef.symbol.annotations @@ -3803,7 +3813,7 @@ trait Typers { self: Analyzer => newTyper(context.makeNewScope(tree, sym)).typedDefDef(ddef) case tdef @ TypeDef(_, _, _, _) => - newTyper(context.makeNewScope(tree, sym)).typedTypeDef(tdef) + typedTypeDef(tdef) case ldef @ LabelDef(_, _, _) => labelTyper(ldef).typedLabelDef(ldef) diff --git a/test/files/pos/t3582.scala b/test/files/pos/t3582.scala new file mode 100644 index 0000000000..0ac112efbf --- /dev/null +++ b/test/files/pos/t3582.scala @@ -0,0 +1,12 @@ +trait C[A] +object Test { + def ImplicitParamCA[CC[A], A](implicit ev: C[A]) {implicitly[C[A]]} // must use this exact syntax... + // error: could not find implicit value for parameter e: C[A] +} +// [[syntax trees at end of typer]] +// abstract trait C#5[A#9116 >: Nothing#5832 <: Any#52] extends scala#33.AnyRef#2780; +// final object Test#15 extends java.lang.Object#2485 with ScalaObject#1913 { +// def ImplicitParamCA#9123[CC#9124[A#10858 >: Nothing#5832 <: Any#52] >: [A#10858]Nothing#5832 <: [A#10858]Any#52, +// A#9125 >: Nothing#5832 <: Any#52](implicit ev#10856: C#5[A#9127]): Unit#3818 +// = scala#34.this.Predef#1683.implicitly#8816[C#5[A#10858]]() +// } diff --git a/test/files/pos/t3582b.scala b/test/files/pos/t3582b.scala new file mode 100644 index 0000000000..8f0bfb9b2a --- /dev/null +++ b/test/files/pos/t3582b.scala @@ -0,0 +1,5 @@ +object ParamScoping { + // scoping worked fine in the result type, but was wrong in body + // reason: typedTypeDef needs new context, which was set up by typed1 but not by typedDefDef and typedClassDef + def noOverlapFOwithHO[T, G[T]]: G[T] = null.asInstanceOf[G[T]] +}
\ No newline at end of file |