diff options
author | Martin Odersky <odersky@gmail.com> | 2006-08-22 16:20:09 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2006-08-22 16:20:09 +0000 |
commit | 9050da710809b5d9fafa577264b0e1aa61fc6ef7 (patch) | |
tree | 49f92667370f2dc78e03612ca1c925b583ff1144 | |
parent | dd535c3645330025d366f82f1032184b51886274 (diff) | |
download | scala-9050da710809b5d9fafa577264b0e1aa61fc6ef7.tar.gz scala-9050da710809b5d9fafa577264b0e1aa61fc6ef7.tar.bz2 scala-9050da710809b5d9fafa577264b0e1aa61fc6ef7.zip |
Fixed bugs. Generalized implicit lookup.
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Mixin.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 31 | ||||
-rw-r--r-- | test/files/neg/bug691.check | 4 | ||||
-rwxr-xr-x | test/files/neg/bug691.scala | 29 | ||||
-rw-r--r-- | test/files/neg/bug712.check | 4 | ||||
-rw-r--r-- | test/files/neg/bug712.scala | 19 | ||||
-rw-r--r-- | test/files/pos/bug661.scala | 17 | ||||
-rwxr-xr-x | test/files/pos/bug690.scala | 14 | ||||
-rwxr-xr-x | test/files/pos/bug694.scala | 10 |
10 files changed, 122 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index b304b8c68a..8e1a9cc7a4 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -299,8 +299,6 @@ abstract class Mixin extends InfoTransform { val sym = stat.symbol stat match { case _: DefDef if (sym.isModule && sym.owner.isClass && sym.hasFlag(PRIVATE)) => - if (settings.debug.value) - log("implementing " + sym + sym.locationString)//debug val vdef = attributedDef(position(sym), gen.mkModuleVarDef(sym)) val adef = attributedDef( position(sym), diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 27f3310c11..cac726f51e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -300,6 +300,7 @@ trait Contexts requires Analyzer { def implicitss: List[List[ImplicitInfo]] = { if (implicitsRunId != currentRunId) { implicitsRunId = currentRunId + implicitsCache = List() val newImplicits: List[ImplicitInfo] = if (owner != outer.owner && owner.isClass && !owner.isPackageClass) { if (!owner.isInitialized) return outer.implicitss diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c01cbdb689..67b667e819 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -8,7 +8,7 @@ package scala.tools.nsc.typechecker import symtab.Flags._ import util.HashSet -import scala.tools.nsc.util.Position +import scala.tools.nsc.util.{Position, Set, HashSet} import scala.collection.mutable.{HashMap, ListBuffer} /** Methods to create symbols and to enter them into scopes. */ @@ -1666,12 +1666,17 @@ trait Typers requires Analyzer { if ((mode & SUPERCONSTRmode) != 0) clazz.info.parents.head else intersectionType(clazz.info.parents) else { - val ps = clazz.info.parents dropWhile (p => p.symbol.name != mix) + val ps = clazz.info.parents filter (p => p.symbol.name == mix) if (ps.isEmpty) { if (settings.debug.value) System.out.println(clazz.info.parents map (.symbol.name));//debug - error(tree.pos, ""+mix+" does not name a base class of "+clazz) + error(tree.pos, ""+mix+" does not name a parent class of "+clazz) ErrorType - } else ps.head + } else if (ps.tail.isEmpty) { + ps.head + } else { + error(tree.pos, "ambiguous parent class qualifier") + ErrorType + } } tree setSymbol clazz setType SuperType(selftype, owntype) } @@ -1957,8 +1962,21 @@ trait Typers requires Analyzer { } def implicitsOfType(tp: Type): List[List[ImplicitInfo]] = { - val tp1 = if (isFunctionType(tp)) intersectionType(tp.typeArgs.reverse) else tp - tp1.baseClasses map implicitsOfClass + def getParts(tp: Type, s: Set[Symbol]): unit = tp match { + case TypeRef(pre, sym, args) if (!sym.isPackageClass) => + for (val bc <- sym.info.baseClasses) + if (sym.isClass) s.addEntry(sym) + getParts(pre, s) + for (val arg <- args) getParts(arg, s) + case SingleType(pre, _) => + getParts(pre, s) + case RefinedType(ps, _) => + for (val p <- ps) getParts(p, s) + case _ => + } + val classes = new HashSet[Symbol] + getParts(tp, classes) + classes.elements.map(implicitsOfClass).toList } def implicitsOfClass(clazz: Symbol): List[ImplicitInfo] = ( @@ -1985,4 +2003,3 @@ trait Typers requires Analyzer { } } } - diff --git a/test/files/neg/bug691.check b/test/files/neg/bug691.check new file mode 100644 index 0000000000..252ce6b5d3 --- /dev/null +++ b/test/files/neg/bug691.check @@ -0,0 +1,4 @@ +bug691.scala:27 error: ambiguous parent class qualifier + trait TiC extends super[Arrow].Ti2 with super[AssignArrow].Ti1;
+ ^ +one error found diff --git a/test/files/neg/bug691.scala b/test/files/neg/bug691.scala new file mode 100755 index 0000000000..233476f658 --- /dev/null +++ b/test/files/neg/bug691.scala @@ -0,0 +1,29 @@ +trait Base { + trait AssignArrow { + type T <: Ti0; + trait Ti0; + } + abstract class Arrow extends AssignArrow; + val arrow : Arrow; +} + +trait Ext0 extends Base { + trait AssignArrow extends super.AssignArrow { + type T <: Ti1; + trait Ti1 extends super.Ti0; + } +} +trait Ext1 extends Base { + trait Arrow extends super.Arrow { + type T <: Ti2; + trait Ti2 extends super.Ti0; + trait TiXX extends Ti2; + } + val arrow : Arrow; +} +trait Composition extends Ext0 with Ext1 { + object arrow0 extends Arrow with AssignArrow { + type T = TiC + trait TiC extends super[Arrow].Ti2 with super[AssignArrow].Ti1; + } +} diff --git a/test/files/neg/bug712.check b/test/files/neg/bug712.check new file mode 100644 index 0000000000..277aaf6be5 --- /dev/null +++ b/test/files/neg/bug712.check @@ -0,0 +1,4 @@ +bug712.scala:10 error: value self is not a member of B.this.ParentImpl + implicit def coerce(p : ParentImpl) = p.self; + ^ +one error found diff --git a/test/files/neg/bug712.scala b/test/files/neg/bug712.scala new file mode 100644 index 0000000000..0887810c85 --- /dev/null +++ b/test/files/neg/bug712.scala @@ -0,0 +1,19 @@ +trait A { + type Node <: NodeImpl; + implicit def coerce(n : NodeImpl) = n.self; + trait NodeImpl { + def self : Node; + } +} +trait B extends A { + type Parent <: ParentImpl; + implicit def coerce(p : ParentImpl) = p.self; + trait ParentImpl; + type Symbol; + trait SymbolImpl { + def scope : Int; + } + implicit def coerceSym(sym : Symbol) : SymbolImpl; + var s : Symbol = null; + val s_scope = s.scope; +} diff --git a/test/files/pos/bug661.scala b/test/files/pos/bug661.scala new file mode 100644 index 0000000000..3a447241fe --- /dev/null +++ b/test/files/pos/bug661.scala @@ -0,0 +1,17 @@ +package test; + +object test { + abstract class A { + abstract class C { + type M; + def foo(n : M) : Unit = {} + } + } + trait B extends A { + type N; + trait C extends super.C { + type M = N; + override def foo(n : M) : Unit = super.foo(n); + } + } +} diff --git a/test/files/pos/bug690.scala b/test/files/pos/bug690.scala new file mode 100755 index 0000000000..a93c54f007 --- /dev/null +++ b/test/files/pos/bug690.scala @@ -0,0 +1,14 @@ +package test; +trait test { + type T; + trait Manager { + type T <: test.this.T; + def foo(t : T) = {}; + } + object M0 extends Manager { + override type T = test.this.T; + override def foo(t : T) = super.foo(t); + } + def t : T; + M0.foo(t); +} diff --git a/test/files/pos/bug694.scala b/test/files/pos/bug694.scala new file mode 100755 index 0000000000..96eb55f5c0 --- /dev/null +++ b/test/files/pos/bug694.scala @@ -0,0 +1,10 @@ +object test3 { + trait Type[T]; + case object IntType extends Type[Int]; + case object StringType extends Type[String]; + + def f[T](t : Type[T]) : T = t match { + case IntType => 10; + case StringType => "hello"; + } +}
\ No newline at end of file |