summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala13
-rw-r--r--test/files/pos/t8046.scala20
-rw-r--r--test/files/pos/t8046b.scala16
-rw-r--r--test/files/pos/t8046c.scala19
-rw-r--r--test/files/run/t8046.check2
-rw-r--r--test/files/run/t8046/Test.scala18
-rw-r--r--test/files/run/t8046/t8046c.scala13
-rw-r--r--test/pending/pos/t6161.scala22
9 files changed, 124 insertions, 4 deletions
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 19c67879f5..0ca8611719 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -166,9 +166,10 @@ trait BaseTypeSeqs {
val index = new Array[Int](nparents)
var i = 0
for (p <- parents) {
+ val parentBts = p.dealias.baseTypeSeq // dealias need for SI-8046.
pbtss(i) =
- if (p.baseTypeSeq eq undetBaseTypeSeq) AnyClass.info.baseTypeSeq
- else p.baseTypeSeq
+ if (parentBts eq undetBaseTypeSeq) AnyClass.info.baseTypeSeq
+ else parentBts
index(i) = 0
i += 1
}
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index d8bbd981b9..e9230aceee 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1998,7 +1998,9 @@ trait Types
if (sym.typeParams.size != args.size)
devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args")
- asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args)
+ val GenPolyType(tparams, result) = asSeenFromOwner(tp)
+ assert((tparams eq Nil) || tparams == sym.typeParams, (tparams, sym.typeParams))
+ result.instantiateTypeParams(sym.typeParams, args)
}
// note: does not go through typeRef. There's no need to because
@@ -2308,7 +2310,14 @@ trait Types
}
thisInfo.decls
}
- protected[Types] def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform
+ protected[Types] def baseTypeSeqImpl: BaseTypeSeq =
+ if (sym.info.baseTypeSeq exists (_.typeSymbolDirect.isAbstractType))
+ // SI-8046 base type sequence might have more elements in a subclass, we can't map it element wise.
+ transform(sym.info).baseTypeSeq
+ else
+ // Optimization: no abstract types, we can compute the BTS of this TypeRef as an element-wise map
+ // of the BTS of the referenced symbol.
+ sym.info.baseTypeSeq map transform
override def baseTypeSeq: BaseTypeSeq = {
val cache = baseTypeSeqCache
diff --git a/test/files/pos/t8046.scala b/test/files/pos/t8046.scala
new file mode 100644
index 0000000000..304d70b6b8
--- /dev/null
+++ b/test/files/pos/t8046.scala
@@ -0,0 +1,20 @@
+trait One {
+ type Op[A]
+ type Alias[A] = Op[A]
+}
+
+trait Two extends One {
+ trait Op[A] extends (A => A)
+
+ // This compiles
+ class View1 extends Op[Int] { def apply(xs: Int) = xs }
+
+ // ??? base class View2 not found in basetypes of class View2
+ // ./a.scala:9: error: class View2 needs to be abstract, since \
+ // method apply in trait Function1 of type (v1: T1)R is not defined
+ // (Note that T1 does not match Int)
+ // class View2 extends Alias[Int] { def apply(xs: Int) = xs }
+ // ^
+ // one error found
+ class View2 extends Alias[Int] { def apply(xs: Int) = xs }
+}
diff --git a/test/files/pos/t8046b.scala b/test/files/pos/t8046b.scala
new file mode 100644
index 0000000000..45b99fd7e0
--- /dev/null
+++ b/test/files/pos/t8046b.scala
@@ -0,0 +1,16 @@
+trait One {
+ type Op[A]
+ type Alias = Op[Int]
+}
+
+trait Two extends One {
+ trait Op[A] extends M[A]
+ //(a: Alias) => a.value.toChar // okay
+ // (=> A).asSeenFrom(a.type, trait M): => Int
+ class View2 extends Alias { value.toChar } // toChar is not a member of type parameter A
+ // (=> A).asSeenFrom(View2.this.type, trait M): => A
+
+ // override type Alias = Op[Int] // works with this
+}
+
+trait M[A] { def value: A = sys.error("") }
diff --git a/test/files/pos/t8046c.scala b/test/files/pos/t8046c.scala
new file mode 100644
index 0000000000..f05b4c15b5
--- /dev/null
+++ b/test/files/pos/t8046c.scala
@@ -0,0 +1,19 @@
+trait One {
+ type Op[A]
+ type Alias[A] = Op[A]
+}
+
+trait Three extends One {
+ trait Op[A] extends (A => A)
+
+ def f1(f: Op[Int]) = f(5)
+ def f2(f: Alias[Int]) = f(5)
+ def f3[T <: Op[Int]](f: T) = f(5)
+ def f4[T <: Alias[Int]](f: T) = f(5)
+ // ./a.scala:12: error: type mismatch;
+ // found : Int(5)
+ // required: T1
+ // def f4[T <: Alias[Int]](f: T) = f(5)
+ // ^
+}
+
diff --git a/test/files/run/t8046.check b/test/files/run/t8046.check
new file mode 100644
index 0000000000..905b0b35ca
--- /dev/null
+++ b/test/files/run/t8046.check
@@ -0,0 +1,2 @@
+List(trait Op, trait Function1, class Object, class Any)
+BTS(T,Three.this.Op[Int],Int => Int,Object,Any)
diff --git a/test/files/run/t8046/Test.scala b/test/files/run/t8046/Test.scala
new file mode 100644
index 0000000000..f6b525d1b5
--- /dev/null
+++ b/test/files/run/t8046/Test.scala
@@ -0,0 +1,18 @@
+import scala.tools.partest._
+
+object Test extends DirectTest {
+ override def code = ""
+ override def extraSettings: String = "-usejavacp"
+
+ override def show() {
+ val c = newCompiler()
+ new c.Run
+ import c._
+
+ val f4 = typeOf[Three].member(newTermName("f4"))
+ val f4ParamInfo = f4.paramss.head.head.info
+ println(f4ParamInfo.baseClasses)
+ println(f4ParamInfo.baseTypeSeq)
+ }
+}
+
diff --git a/test/files/run/t8046/t8046c.scala b/test/files/run/t8046/t8046c.scala
new file mode 100644
index 0000000000..0b484da530
--- /dev/null
+++ b/test/files/run/t8046/t8046c.scala
@@ -0,0 +1,13 @@
+import language._
+
+trait One {
+ type Op[A]
+ type Alias[A] = Op[A]
+}
+
+trait Three extends One {
+ trait Op[A] extends (A => A)
+
+ def f4[T <: Alias[Int]](f: T) = 0
+}
+
diff --git a/test/pending/pos/t6161.scala b/test/pending/pos/t6161.scala
new file mode 100644
index 0000000000..5783cc85f2
--- /dev/null
+++ b/test/pending/pos/t6161.scala
@@ -0,0 +1,22 @@
+object t6161 {
+ trait N {
+ type Name
+ }
+
+ trait N1 extends N {
+ class Name {
+ type ThisNameType <: Name
+ def encode: ThisNameType = ???
+ }
+ }
+
+ trait S {
+ self: N => // change to N1 and it compiles
+ type NameType <: Name
+ }
+
+ object g extends S with N1
+
+ val n1: g.NameType = ???
+ val n2: g.Name = n1.encode
+}