diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 5 | ||||
-rw-r--r-- | test/files/pos/t5777.scala | 45 |
3 files changed, 51 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index fb0616c890..5534cd179c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -499,7 +499,8 @@ trait Infer { else Some( if (targ.typeSymbol == RepeatedParamClass) targ.baseType(SeqClass) else if (targ.typeSymbol == JavaRepeatedParamClass) targ.baseType(ArrayClass) - else if ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden) targ + // this infers Foo.type instead of "object Foo" (see also widenIfNecessary) + else if (targ.typeSymbol.isModuleClass || ((opt.experimental || opt.virtPatmat) && tvar.constr.avoidWiden)) targ else targ.widen ) )) diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 6620ef7347..063db4bb88 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -765,7 +765,10 @@ trait Namers extends MethodSynthesis { val tpe1 = dropRepeatedParamType(tpe.deconst) val tpe2 = tpe1.widen - if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag) + // This infers Foo.type instead of "object Foo" + // See Infer#adjustTypeArgs for the polymorphic case. + if (tpe.typeSymbolDirect.isModuleClass) tpe1 + else if (sym.isVariable || sym.isMethod && !sym.hasAccessorFlag) if (tpe2 <:< pt) tpe2 else tpe1 else if (isHidden(tpe)) tpe2 // In an attempt to make pattern matches involving method local vals diff --git a/test/files/pos/t5777.scala b/test/files/pos/t5777.scala new file mode 100644 index 0000000000..24cea36163 --- /dev/null +++ b/test/files/pos/t5777.scala @@ -0,0 +1,45 @@ +// /scala/trac/5777/a.scala +// Wed May 9 08:44:57 PDT 2012 + +trait Ring { + trait E +} + +class Poly[C <: Ring](val ring: C) extends Ring +// This definition of Poly triggers the same failure on *both* versions +// class Poly(val ring: Ring) extends Ring + +object BigInt extends Ring + +object MyApp { + val r = new Poly(BigInt) + + implicitly[r.ring.E <:< BigInt.E] + + // fail on 2.10, works on 2.9.2 + (null.asInstanceOf[BigInt.E] : r.ring.E) + + // works on both versions + val r1 = new Poly[BigInt.type](BigInt) + (null.asInstanceOf[BigInt.E] : r1.ring.E) + + // Oddly, -Xprint:typer reports that r and r1 have the same inferred type. + // + // private[this] val r: Poly[BigInt.type] = new Poly[BigInt.type](BigInt); + // <stable> <accessor> def r: Poly[BigInt.type] = MyApp.this.r; + // (null.asInstanceOf[BigInt.E]: MyApp.r.ring.E); + // private[this] val r1: Poly[BigInt.type] = new Poly[BigInt.type](BigInt); + // <stable> <accessor> def r1: Poly[BigInt.type] = MyApp.this.r1; + // (null.asInstanceOf[BigInt.E]: MyApp.r1.ring.E) + + // diff typer-2.9.2.txt typer-2.10.txt + // ... + // --- + // > object MyApp extends scala.AnyRef { + // > def <init>(): MyApp.type = { + // > MyApp.super.<init>(); + // 30c30 + // < scala.this.Predef.implicitly[<:<[BigInt.E,MyApp.r.ring.E]](scala.this.Predef.conforms[BigInt.E]); + // --- + // > scala.this.Predef.implicitly[<:<[BigInt.E,MyApp.r.ring.E]](); +} |