diff options
author | Paul Phillips <paulp@improving.org> | 2012-05-09 09:18:11 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-05-09 10:08:55 -0700 |
commit | e8e88f785d0020f215098450d16157e973673ba3 (patch) | |
tree | b8047970e45d6a2aaf574a71aeb4ca647d7a43fc | |
parent | d89ba7ff172e2f4ee12130d8caf8b9b74f581897 (diff) | |
download | scala-e8e88f785d0020f215098450d16157e973673ba3.tar.gz scala-e8e88f785d0020f215098450d16157e973673ba3.tar.bz2 scala-e8e88f785d0020f215098450d16157e973673ba3.zip |
Restored portion of code removed in a7f68ce32c .
A hole in the net discovered by retronym makes me put back the
former special casing of module class type inference; there's no
reason to get it wrong. It appears that
TypeRef(pre1, sym1, Nil)
SingleType(pre2, sym2)
are not seen as equivalent if they have different prefixes even
if the prefixes should be equivalent. For now I'm leaving it; in
principle this patch should eventually be reverted after subtyping
and/or the representation of singleton types advances to the point
that it isn't necessary. Closes SI-5777.
-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]](); +} |