summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-05-09 09:18:11 -0700
committerPaul Phillips <paulp@improving.org>2012-05-09 10:08:55 -0700
commite8e88f785d0020f215098450d16157e973673ba3 (patch)
treeb8047970e45d6a2aaf574a71aeb4ca647d7a43fc
parentd89ba7ff172e2f4ee12130d8caf8b9b74f581897 (diff)
downloadscala-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.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala5
-rw-r--r--test/files/pos/t5777.scala45
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]]();
+}