diff options
author | Martin Odersky <odersky@gmail.com> | 2007-10-31 17:33:02 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-10-31 17:33:02 +0000 |
commit | bff42682bc489dcdad34ec91f34e6c2c3dca7cf1 (patch) | |
tree | 9c496712c4f98e91261f15cb5b5a5a0c1b943656 | |
parent | 9e8c022640f74e963baa930dd657d920a914a43d (diff) | |
download | scala-bff42682bc489dcdad34ec91f34e6c2c3dca7cf1.tar.gz scala-bff42682bc489dcdad34ec91f34e6c2c3dca7cf1.tar.bz2 scala-bff42682bc489dcdad34ec91f34e6c2c3dca7cf1.zip |
fixed several problems with implicits.
Changed ways inner types of modules print: Module.this.Type =>
Module.type
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Flags.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 56 | ||||
-rw-r--r-- | test/files/neg/bug1275.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug452.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug515.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug545.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug630.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug696.check | 6 | ||||
-rw-r--r-- | test/files/neg/bug876.check | 2 | ||||
-rw-r--r-- | test/files/neg/bug961.check | 2 | ||||
-rw-r--r-- | test/files/neg/gadts1.check | 2 | ||||
-rw-r--r-- | test/files/neg/lubs.check | 12 | ||||
-rw-r--r-- | test/files/neg/sabin2.check | 4 |
18 files changed, 96 insertions, 53 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Flags.scala b/src/compiler/scala/tools/nsc/symtab/Flags.scala index 6a31a94444..eefc6457e4 100644 --- a/src/compiler/scala/tools/nsc/symtab/Flags.scala +++ b/src/compiler/scala/tools/nsc/symtab/Flags.scala @@ -41,7 +41,7 @@ object Flags extends Enumeration { // constructor. final val ABSOVERRIDE = 0x00040000 // combination of abstract & override final val LOCAL = 0x00080000 // symbol is local to current class. - // pre: PRIVATE is also set + // pre: PRIVATE or PROTECTED are also set final val JAVA = 0x00100000 // symbol was defined by a Java class final val SYNTHETIC = 0x00200000 // symbol is compiler-generated final val STABLE = 0x00400000 // functions that are assumed to be stable diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index cb990a0d27..0b801fca89 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -378,6 +378,12 @@ trait Symbols { def ownerChain: List[Symbol] = this :: owner.ownerChain + def hasTransOwner(sym: Symbol) = { + var o = this + while ((o ne sym) && (o ne NoSymbol)) o = o.owner + o eq sym + } + def name: Name = rawname final def name_=(name: Name) { diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 73172102a7..f1e8ca714d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -627,17 +627,21 @@ trait Types { checkMalformedSwitch = false while (continue) { continue = false - var bcs = baseClasses + val bcs0 = baseClasses + var bcs = bcs0 while (!bcs.isEmpty) { val decls = bcs.head.info.decls - bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail var entry = if (name == nme.ANYNAME) decls.elems else decls lookupEntry name while (entry ne null) { val sym = entry.sym if (sym.getFlag(requiredFlags) == requiredFlags) { val excl = sym.getFlag(excluded) - if (excl == 0) { + if (excl == 0 && + (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. + (bcs eq bcs0) || + sym.getFlag(PRIVATE | LOCAL) != (PRIVATE | LOCAL) || + (bcs0.head.hasTransOwner(bcs.head)))) { if (name.isTypeName || stableOnly) { checkMalformedSwitch = savedCheckMalformedSwitch if (util.Statistics.enabled) @@ -677,6 +681,7 @@ trait Types { entry = if (name == nme.ANYNAME) entry.next else decls lookupNextEntry entry } // while (entry ne null) // excluded = excluded | LOCAL + bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail } // while (!bcs.isEmpty) excluded = excludedFlags } // while (continue) @@ -833,7 +838,7 @@ trait Types { if (settings.debug.value) sym.nameString + ".this." else if (sym.isRoot || sym.isEmptyPackageClass || sym.isInterpreterWrapper || sym.isScalaPackageClass) "" else if (sym.isAnonymousClass || sym.isRefinementClass) "this." - else if (sym.isPackageClass) sym.fullNameString + "." + else if (sym.isModuleClass) sym.fullNameString + "." else sym.nameString + ".this." override def toString: String = if (sym.isRoot) "<root>" diff --git a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala index 52fac051bc..28d33ad2e7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala +++ b/src/compiler/scala/tools/nsc/typechecker/EtaExpansion.scala @@ -43,10 +43,17 @@ trait EtaExpansion { self: Analyzer => if (pos == util.NoPosition) { if (inIDE) newTermName( ("eta$" + symbolHash + (cnt - 1))) else newTermName(unit.fresh.newName("eta$" + symbolHash + (cnt - 1))) +/* } else if (n == 0) { - newTermName(unit.fresh.newName(pos, "eta$" + symbolHash)) + newTermName(unit.fresh.newName(pos, "etaC$" + symbolHash)) +*/ } else { - newTermName(unit.fresh.newName(pos, "eta$" + symbolHash + n + "$")) + newTermName(unit.fresh.newName(pos, "eta$" + symbolHash + (cnt - 1) + "$")) + // Martin to Sean: I removed the + // else if (n == 0) branch and changed `n' in the line above to `(cnt - 1)' + // this was necessary because otherwise curried eta-expansions would get the same + // symbol. An example which failes test/files/run/Course-2002-02.scala + // todo: review and get rid of the `n' argument (which is unused right now). } } // { cnt = cnt + 1; newTermName("eta$" + cnt) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 015c0636c8..eaa1e59b05 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -327,6 +327,8 @@ trait Infer { def isPlausiblyCompatible(tp: Type, pt: Type): Boolean = tp match { case PolyType(_, restpe) => isPlausiblyCompatible(restpe, pt) + case mt: ImplicitMethodType => + isPlausiblyCompatible(mt.resultType, pt) case MethodType(formals, _) => pt.normalize match { case TypeRef(pre, sym, args) => @@ -1081,7 +1083,11 @@ trait Infer { def inferExprAlternative(tree: Tree, pt: Type): Unit = tree.tpe match { case OverloadedType(pre, alts) => tryTwice { var alts1 = alts filter (alt => isCompatible(pre.memberType(alt), pt)) - if (alts1.isEmpty) alts1 = alts + var secondTry = false + if (alts1.isEmpty) { + alts1 = alts + secondTry = true + } def improves(sym1: Symbol, sym2: Symbol): Boolean = sym2 == NoSymbol || { val tp1 = pre.memberType(sym1) @@ -1105,11 +1111,13 @@ trait Infer { } typeErrorTree(tree, tree.symbol.tpe, pt) } else if (!competing.isEmpty) { - if (!pt.isErroneous) - context.ambiguousError(tree.pos, pre, best, competing.head, "expected type " + pt) - setError(tree) - () - + if (secondTry) { + typeErrorTree(tree, tree.symbol.tpe, pt) + } else { + if (!pt.isErroneous) + context.ambiguousError(tree.pos, pre, best, competing.head, "expected type " + pt) + setError(tree) + } } else { val applicable = alts1 filter (alt => global.typer.infer.isCompatible(pre.memberType(alt), pt)) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index df34651883..fb10d2b1b2 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -169,8 +169,7 @@ abstract class RefChecks extends InfoTransform { val mb = member.accessBoundary(member.owner) val ob = other.accessBoundary(member.owner) if (mb != RootClass && mb != NoSymbol && // todo: change - (ob == RootClass || ob == NoSymbol || - mb != ob && !(ob.ownerChain contains mb) || + (ob == RootClass || ob == NoSymbol || !ob.hasTransOwner(mb) || (other hasFlag PROTECTED) && !(member hasFlag PROTECTED))) { overrideAccessError() } else if (other hasFlag FINAL) { // (1.2) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index ecba9bb44f..ab07c52a07 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -165,12 +165,12 @@ trait Typers { self: Analyzer => case OverloadedType(_, _) => EmptyTree case PolyType(_, _) => EmptyTree case _ => - val result = inferImplicit(pos, functionType(List(from), to), true, reportAmbiguous) + val result = inferImplicit(pos, MethodType(List(from), to), reportAmbiguous) if (result != EmptyTree) result else inferImplicit( pos, - functionType(List(appliedType(ByNameParamClass.typeConstructor, List(from))), to), - true, reportAmbiguous) + MethodType(List(appliedType(ByNameParamClass.typeConstructor, List(from))), to), + reportAmbiguous) } } @@ -379,7 +379,7 @@ trait Typers { self: Analyzer => var o = owner while (o != NoSymbol && o != sym.owner && !o.isLocal && !o.hasFlag(PRIVATE) && - !o.privateWithin.ownerChain.contains(sym.owner)) + !o.privateWithin.hasTransOwner(sym.owner)) o = o.owner if (o == sym.owner) addHidden(sym) } else if (sym.owner.isTerm && !sym.isTypeParameterOrSkolem) { @@ -548,7 +548,7 @@ trait Typers { self: Analyzer => /** The member with given name of given qualifier tree */ def member(qual: Tree, name: Name) = qual.tpe match { - case ThisType(clazz) if (context.enclClass.owner.ownerChain contains clazz) => + case ThisType(clazz) if (context.enclClass.owner.hasTransOwner(clazz)) => qual.tpe.member(name) case _ => if (phase.next.erasedTypes) qual.tpe.member(name) @@ -1248,7 +1248,7 @@ trait Typers { self: Analyzer => private def checkStructuralCondition(refinement: Symbol, vparam: ValDef) { val tp = vparam.symbol.tpe - if (tp.typeSymbol.isAbstractType && !(tp.typeSymbol.ownerChain contains refinement)) + if (tp.typeSymbol.isAbstractType && !(tp.typeSymbol.hasTransOwner(refinement))) error(vparam.tpt.pos,"Parameter type in structural refinement may not refer to abstract type defined outside that same refinement") } @@ -3148,29 +3148,45 @@ trait Typers { self: Analyzer => * to <code>pt</code>, EmptyTree otherwise. * @pre <code>info.tpe</code> does not contain an error */ - private def typedImplicit(pos: Position, info: ImplicitInfo, pt: Type, isLocal: Boolean): Tree = { + private def typedImplicit(pos: Position, info: ImplicitInfo, pt0: Type, pt: Type, isLocal: Boolean): Tree = { def isStable(tp: Type): Boolean = tp match { case TypeRef(pre, sym, _) => sym.isPackageClass || sym.isModuleClass && isStable(pre) case _ => tp.isStable } + // println("typed impl for "+pt+"? "+info.name+":"+info.tpe+(isPlausiblyCompatible(info.tpe, pt))+isCompatible(depoly(info.tpe), pt)+isStable(info.pre)) if (isPlausiblyCompatible(info.tpe, pt) && isCompatible(depoly(info.tpe), pt) && isStable(info.pre)) { val tree = atPos(pos) { if (info.pre == NoPrefix/*isLocal*/) Ident(info.name) else Select(gen.mkAttributedQualifier(info.pre), info.name) } + // println("typed impl?? "+info.name+":"+info.tpe+" ==> "+tree+" with "+pt) def fail(reason: String, sym1: Symbol, sym2: Symbol): Tree = { if (settings.debug.value) - log(tree+" is not a valid implicit value because:\n"+reason + sym1+" "+sym2) + println(tree+" is not a valid implicit value because:\n"+reason + sym1+" "+sym2) EmptyTree } try { -// if (!isLocal) tree setSymbol info.sym - val tree1 = typed1(tree, EXPRmode, pt) - //if (settings.debug.value) log("typed implicit "+tree1+":"+tree1.tpe+", pt = "+pt) - val tree2 = adapt(tree1, EXPRmode, pt) - //if (settings.debug.value) log("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt) + // if (!isLocal) tree setSymbol info.sym + val isView = (pt0 ne pt) + val tree1 = + if (isView) + typed1(Apply(tree, List(Ident("<argument>") setType pt0.paramTypes.head)), EXPRmode, pt0.resultType) + else + typed1(tree, EXPRmode, pt) + //if (settings.debug.value) println("typed implicit "+tree1+":"+tree1.tpe+", pt = "+pt) + val tree2 = if (isView) (tree1: @unchecked) match { case Apply(fun, _) => fun } + else adapt(tree1, EXPRmode, pt) + //if (settings.debug.value) println("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt)("adapted implicit "+tree1.symbol+":"+tree2.tpe+" to "+pt) + def hasMatchingSymbol(tree: Tree): Boolean = (tree.symbol == info.sym) || { + tree match { + case Apply(fun, _) => hasMatchingSymbol(fun) + case TypeApply(fun, _) => hasMatchingSymbol(fun) + case Select(pre, name) => name == nme.apply && pre.symbol == info.sym + case _ => false + } + } if (tree2.tpe.isError) EmptyTree - else if (info.sym == tree1.symbol) tree2 + else if (hasMatchingSymbol(tree1)) tree2 else fail("syms differ: ", tree1.symbol, info.sym) } catch { case ex: TypeError => fail(ex.getMessage(), NoSymbol, NoSymbol) @@ -3181,7 +3197,7 @@ trait Typers { self: Analyzer => /** Infer implicit argument or view. * * @param pos position for error reporting - * @param pt the expected type of the implicit + * @param pt0 the expected type of the implicit * @param isView are we searching for a view? (this affects the error message) * @param reportAmbiguous should ambiguous errors be reported? * False iff we search for a view to find out @@ -3189,7 +3205,9 @@ trait Typers { self: Analyzer => * @return ... * @see <code>isCoercible</code> */ - private def inferImplicit(pos: Position, pt: Type, isView: Boolean, reportAmbiguous: Boolean): Tree = { + private def inferImplicit(pos: Position, pt0: Type, reportAmbiguous: Boolean): Tree = { + val pt = normalize(pt0) + val isView = pt0.isInstanceOf[MethodType] if (util.Statistics.enabled) implcnt = implcnt + 1 val startTime = if (util.Statistics.enabled) currentTime else 0l @@ -3239,7 +3257,7 @@ trait Typers { self: Analyzer => !containsError(info.tpe) && !(isLocal && shadowed.contains(info.name)) && (!isView || info.sym != Predef_identity) && - tc.typedImplicit(pos, info, pt, isLocal) != EmptyTree + tc.typedImplicit(pos, info, pt0, pt, isLocal) != EmptyTree def applicableInfos(is: List[ImplicitInfo]) = { val result = is filter isApplicable if (isLocal) @@ -3259,7 +3277,7 @@ trait Typers { self: Analyzer => "yet alternative definition ", "is defined in a subclass.\n Both definitions ") } - tc.typedImplicit(pos, best, pt, isLocal) + tc.typedImplicit(pos, best, pt0, pt, isLocal) } } @@ -3305,7 +3323,7 @@ trait Typers { self: Analyzer => def applyImplicitArgs(tree: Tree): Tree = tree.tpe match { case MethodType(formals, _) => def implicitArg(pt: Type) = { - val arg = inferImplicit(tree.pos, pt, false, true) + val arg = inferImplicit(tree.pos, pt, true) if (arg != EmptyTree) arg else errorTree(tree, "no implicit argument matching parameter type "+pt+" was found.") } diff --git a/test/files/neg/bug1275.check b/test/files/neg/bug1275.check index 6ff92a7823..9f806c0689 100644 --- a/test/files/neg/bug1275.check +++ b/test/files/neg/bug1275.check @@ -1,4 +1,4 @@ -bug1275.scala:13: error: The kind of type MyType does not conform to the expected kind of type MyType[+t] <: TestCovariance.this.Seq[t] in trait Seq. +bug1275.scala:13: error: The kind of type MyType does not conform to the expected kind of type MyType[+t] <: TestCovariance.Seq[t] in trait Seq. def span[a, s <: Seq[a] { type MyType <: s } ](xs: s): s = xs f ^ one error found diff --git a/test/files/neg/bug452.check b/test/files/neg/bug452.check index d36798ef7b..ac23ebc560 100644 --- a/test/files/neg/bug452.check +++ b/test/files/neg/bug452.check @@ -1,6 +1,6 @@ bug452.scala:3: error: type mismatch; found : Test.type (with underlying type object Test) - required: Test.this.Foo + required: Test.Foo def this() = this(this); ^ one error found diff --git a/test/files/neg/bug515.check b/test/files/neg/bug515.check index fff96a563d..a38c8b62d8 100644 --- a/test/files/neg/bug515.check +++ b/test/files/neg/bug515.check @@ -1,6 +1,6 @@ bug515.scala:7: error: type mismatch; found : java.lang.String - required: Test.this.Truc + required: Test.Truc val parent: Truc = file.getMachin ^ one error found diff --git a/test/files/neg/bug545.check b/test/files/neg/bug545.check index 892a66dfc6..d184f90e85 100644 --- a/test/files/neg/bug545.check +++ b/test/files/neg/bug545.check @@ -1,4 +1,4 @@ -bug545.scala:4: error: value blah is not a member of Test.this.Foo +bug545.scala:4: error: value blah is not a member of Test.Foo val x = foo.blah match { ^ bug545.scala:5: error: recursive value x needs type diff --git a/test/files/neg/bug630.check b/test/files/neg/bug630.check index f1ac0da57f..03113be7da 100644 --- a/test/files/neg/bug630.check +++ b/test/files/neg/bug630.check @@ -1,5 +1,5 @@ bug630.scala:20: error: error overriding value foo in trait Bar of type Req2; - object foo has incompatible type object Test.this.foo + object foo has incompatible type object Test.foo object foo extends Req1 ^ one error found diff --git a/test/files/neg/bug696.check b/test/files/neg/bug696.check index 28ce342cf1..2bc09820ed 100644 --- a/test/files/neg/bug696.check +++ b/test/files/neg/bug696.check @@ -1,9 +1,9 @@ bug696.scala:3: error: implicit method WithType is not contractive, - because the implicit parameter type TypeUtil0.this.Type[S] - is not strictly contained in the signature TypeUtil0.this.Type[S with T] + because the implicit parameter type TypeUtil0.Type[S] + is not strictly contained in the signature TypeUtil0.Type[S with T] implicit def WithType[S,T](implicit tpeS : Type[S], tpeT : Type[T]) : Type[S with T] = null ^ -bug696.scala:4: error: no implicit argument matching parameter type TypeUtil0.this.Type[Any] was found. +bug696.scala:4: error: no implicit argument matching parameter type TypeUtil0.Type[Any] was found. as[Any](null); ^ two errors found diff --git a/test/files/neg/bug876.check b/test/files/neg/bug876.check index c08d4c7de8..8ef2c031fc 100644 --- a/test/files/neg/bug876.check +++ b/test/files/neg/bug876.check @@ -1,4 +1,4 @@ -bug876.scala:25: error: wrong number of arguments for method apply: (AssertionError.this.A)manager.B in trait Map +bug876.scala:25: error: wrong number of arguments for method apply: (AssertionError.A)manager.B in trait Map assert(manager.map(A2) == List(manager.map(A2, A1))) ^ one error found diff --git a/test/files/neg/bug961.check b/test/files/neg/bug961.check index ef7e54d712..794acf5519 100644 --- a/test/files/neg/bug961.check +++ b/test/files/neg/bug961.check @@ -1,4 +1,4 @@ -bug961.scala:11: error: Temp.this.B of type object Temp.this.B does not take parameters +bug961.scala:11: error: Temp.this.B of type object Temp.B does not take parameters B() match { ^ one error found diff --git a/test/files/neg/gadts1.check b/test/files/neg/gadts1.check index b16cbaf11d..01d1412448 100644 --- a/test/files/neg/gadts1.check +++ b/test/files/neg/gadts1.check @@ -1,5 +1,5 @@ gadts1.scala:15: error: type mismatch; - found : Test.this.Double + found : Test.Double required: a case NumTerm(n) => c.x = Double(1.0) ^ diff --git a/test/files/neg/lubs.check b/test/files/neg/lubs.check index 81c280e76f..77ab20102c 100644 --- a/test/files/neg/lubs.check +++ b/test/files/neg/lubs.check @@ -1,16 +1,16 @@ lubs.scala:11: error: type mismatch; - found : test1.this.A[test1.this.A[test1.this.A[Any]]] - required: test1.this.A[test1.this.A[test1.this.A[test1.this.A[Any]]]] + found : test1.A[test1.A[test1.A[Any]]] + required: test1.A[test1.A[test1.A[test1.A[Any]]]] val x4: A[A[A[A[Any]]]] = f ^ lubs.scala:24: error: type mismatch; - found : test2.this.A{type T >: test2.this.C with test2.this.D <: test2.this.A} - required: test2.this.A{type T >: Null <: test2.this.A{type T >: Null <: test2.this.A}} + found : test2.A{type T >: test2.C with test2.D <: test2.A} + required: test2.A{type T >: Null <: test2.A{type T >: Null <: test2.A}} val x3: A { type T >: Null <: A { type T >: Null <: A } } = f ^ lubs.scala:25: error: type mismatch; - found : test2.this.A{type T >: test2.this.C with test2.this.D <: test2.this.A} - required: test2.this.A{type T >: Null <: test2.this.A{type T >: Null <: test2.this.A{type T >: Null <: test2.this.A}}} + found : test2.A{type T >: test2.C with test2.D <: test2.A} + required: test2.A{type T >: Null <: test2.A{type T >: Null <: test2.A{type T >: Null <: test2.A}}} val x4: A { type T >: Null <: A { type T >: Null <: A { type T >: Null <: A } } } = f ^ three errors found diff --git a/test/files/neg/sabin2.check b/test/files/neg/sabin2.check index cd45905df2..682c08bc62 100644 --- a/test/files/neg/sabin2.check +++ b/test/files/neg/sabin2.check @@ -1,5 +1,5 @@ -sabin2.scala:22: error: method set cannot be accessed in Test.this.Base#Inner - because its instance type (Test.this.Base#T)Unit contains a malformed type: Test.this.Base#T +sabin2.scala:22: error: method set cannot be accessed in Test.Base#Inner + because its instance type (Test.Base#T)Unit contains a malformed type: Test.Base#T a.set(b.get()) // Error ^ one error found |