summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-27 17:16:01 +0000
committerPaul Phillips <paulp@improving.org>2011-06-27 17:16:01 +0000
commit77c01a9baca66c1a5a099318d403dbedbe4feeeb (patch)
tree6ee2cd41fae1d25794fd16256d686dcfe30c846b
parent94a00c31680623cd2793b0db87c2bcfac10c9563 (diff)
downloadscala-77c01a9baca66c1a5a099318d403dbedbe4feeeb.tar.gz
scala-77c01a9baca66c1a5a099318d403dbedbe4feeeb.tar.bz2
scala-77c01a9baca66c1a5a099318d403dbedbe4feeeb.zip
Don't infer anonymous classes.
possible, just far enough to avoid all kinds of undesirable consequences which accompany the preservation of too much type information. (The problems are akin to inferring the singleton type too freely.) // Example of code which did not compile, but now does class A class B[T <: A](cons: T) object C extends B(new A {}) Closes #4110, #3048. I already ran this by moors, so review by odersky.
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala4
-rw-r--r--test/files/jvm/manifests.check2
-rw-r--r--test/files/pos/bug3048.scala8
-rw-r--r--test/files/run/bug4110.check2
-rw-r--r--test/files/run/bug4110.scala11
6 files changed, 30 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index 6152cd70f5..bc9eda760c 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -5134,6 +5134,12 @@ A type's typeSymbol should never be inspected directly.
val rest = elimSuper(ts1 filter (t1 => !(t <:< t1)))
if (rest exists (t1 => t1 <:< t)) rest else t :: rest
}
+ def elimAnonymousClass(t: Type) = t match {
+ case TypeRef(pre, clazz, Nil) if clazz.isAnonymousClass =>
+ clazz.classBound.asSeenFrom(pre, clazz.owner)
+ case _ =>
+ t
+ }
/** A collector that tests for existential types appearing at given variance in a type */
class ContainsVariantExistentialCollector(v: Int) extends TypeCollector(false) {
@@ -5153,12 +5159,6 @@ A type's typeSymbol should never be inspected directly.
/** Eliminate from list of types all elements which are a subtype
* of some other element of the list. */
private def elimSub(ts: List[Type], depth: Int): List[Type] = {
- def elimAnonymousClass(t: Type) = t match {
- case TypeRef(pre, clazz, List()) if clazz.isAnonymousClass =>
- clazz.classBound.asSeenFrom(pre, clazz.owner)
- case _ =>
- t
- }
def elimSub0(ts: List[Type]): List[Type] = ts match {
case List() => List()
case t :: ts1 =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index b8dcadc090..2bf1d0035d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1214,7 +1214,7 @@ trait Infer {
*
* @param fn fn: the function that needs to be instantiated.
* @param undetparams the parameters that need to be determined
- * @param args the actional argumments in the call.
+ * @param args the actual arguments supplied in the call.
* @param pt the expected type of the function application
* @return The type parameters that remain uninstantiated,
* and that thus have not been substituted.
@@ -1234,7 +1234,7 @@ trait Infer {
try {
val pt = if (pt0.typeSymbol == UnitClass) WildcardType else pt0
val formals = formalTypes(params0 map (_.tpe), args.length)
- val argtpes = actualTypes(args map (_.tpe.deconst), formals.length)
+ val argtpes = actualTypes(args map (x => elimAnonymousClass(x.tpe.deconst)), formals.length)
val restpe = fn.tpe.resultType(argtpes)
val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) =
diff --git a/test/files/jvm/manifests.check b/test/files/jvm/manifests.check
index 3b8ca5b5b1..54f504b929 100644
--- a/test/files/jvm/manifests.check
+++ b/test/files/jvm/manifests.check
@@ -29,7 +29,7 @@ x=Foo, m=Foo[scala.collection.immutable.List[Int]]
x=Foo, m=Foo[Foo[Int]]
x=Foo, m=Foo[scala.collection.immutable.List[Foo[Int]]]
-x=Test1$$anon$1, m=Test1$$anon$1
+x=Test1$$anon$1, m=Object with Bar[java.lang.String]
()=()
true=true
diff --git a/test/files/pos/bug3048.scala b/test/files/pos/bug3048.scala
new file mode 100644
index 0000000000..dc056ecba2
--- /dev/null
+++ b/test/files/pos/bug3048.scala
@@ -0,0 +1,8 @@
+class B
+object C extends B
+
+class F[T <: B](cons: => T)
+class F2[T <: B](cons: => T) extends F(cons)
+
+object D extends F2(C) // works
+object E extends F2(new B {})
diff --git a/test/files/run/bug4110.check b/test/files/run/bug4110.check
new file mode 100644
index 0000000000..8b005989de
--- /dev/null
+++ b/test/files/run/bug4110.check
@@ -0,0 +1,2 @@
+Object with Test$A with Test$B
+Object with Test$A with Test$B
diff --git a/test/files/run/bug4110.scala b/test/files/run/bug4110.scala
new file mode 100644
index 0000000000..a42646ce52
--- /dev/null
+++ b/test/files/run/bug4110.scala
@@ -0,0 +1,11 @@
+object Test extends App {
+ def inferredType[T : Manifest](v : T) = println(manifest[T])
+
+ trait A
+ trait B
+
+ inferredType(new A with B)
+
+ val name = new A with B
+ inferredType(name)
+} \ No newline at end of file