aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala2
-rw-r--r--src/dotty/tools/dotc/transform/PostTyper.scala5
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
-rw-r--r--test/dotc/scala-collections.whitelist3
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/neg/bounds.scala8
-rw-r--r--tests/pos/bounds.scala7
-rw-r--r--tests/pos/t1279a.scala (renamed from tests/neg/t1279a.scala)0
10 files changed, 31 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
index 05d4a70fc..9269109ad 100644
--- a/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
+++ b/src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala
@@ -415,6 +415,8 @@ class Scala2Unpickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClas
// println(owner.info.decls.toList.map(_.debugString).mkString("\n ")) // !!! DEBUG
// }
// (5) Create a stub symbol to defer hard failure a little longer.
+ println(i"***** missing reference, looking for $name in $owner")
+ println(i"decls = ${owner.info.decls}")
new Exception().printStackTrace()
ctx.newStubSymbol(owner, name, source)
}
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala
index fc4427277..221d097f9 100644
--- a/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -68,7 +68,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
// TODO fill in
}
- /** Check bounds of AppliedTypeTrees.
+ /** Check bounds of AppliedTypeTrees and TypeApplys.
* Replace type trees with TypeTree nodes.
* Replace constant expressions with Literal nodes.
* Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose.
@@ -114,6 +114,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds)
Checking.checkBounds(args, bounds, _.substDealias(tparams, _))
norm(tree)
+ case TypeApply(fn, args) =>
+ Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType])
+ norm(tree)
case _ =>
norm(tree)
}
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 0fee17bcd..87bed8895 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -607,7 +607,7 @@ trait Applications extends Compatibility { self: Typer =>
case pt: PolyType =>
if (typedArgs.length <= pt.paramBounds.length)
typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
- checkBounds(typedArgs, pt)
+ Checking.checkBounds(typedArgs, pt)
case _ =>
}
assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index b8b4c89b4..3dc7b67df 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -41,6 +41,13 @@ object Checking {
d"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
arg.pos)
+ /** Check that type arguments `args` conform to corresponding bounds in `poly`
+ * Note: This does not check the bounds of AppliedTypeTrees. These
+ * are handled by method checkBounds in FirstTransform
+ */
+ def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
+ checkBounds(args, poly.paramBounds, _.substParams(poly, _))
+
/** Check that `tp` refers to a nonAbstract class
* and that the instance conforms to the self type of the created class.
*/
@@ -295,13 +302,6 @@ trait Checking {
tree
}
- /** Check that type arguments `args` conform to corresponding bounds in `poly`
- * Note: This does not check the bounds of AppliedTypeTrees. These
- * are handled by method checkBounds in FirstTransform
- */
- def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
- Checking.checkBounds(args, poly.paramBounds, _.substParams(poly, _))
-
/** Check that type `tp` is stable. */
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit =
if (!tp.isStable && !tp.isErroneous)
@@ -407,7 +407,6 @@ trait NoChecking extends Checking {
import tpd._
override def checkNonCyclic(sym: Symbol, info: TypeBounds, reportErrors: Boolean)(implicit ctx: Context): Type = info
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
- override def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit = ()
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index e2b9bb569..c621d96c4 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -866,8 +866,6 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val TypeBoundsTree(lo, hi) = desugar.typeBoundsTree(tree)
val lo1 = typed(lo)
val hi1 = typed(hi)
- if (!(lo1.tpe <:< hi1.tpe))
- ctx.error(d"lower bound ${lo1.tpe} does not conform to upper bound ${hi1.tpe}", tree.pos)
assignType(cpy.TypeBoundsTree(tree)(lo1, hi1), lo1, hi1)
}
diff --git a/test/dotc/scala-collections.whitelist b/test/dotc/scala-collections.whitelist
index ede1a14dc..76fa64c8e 100644
--- a/test/dotc/scala-collections.whitelist
+++ b/test/dotc/scala-collections.whitelist
@@ -110,8 +110,7 @@
./scala-scala/src/library/scala/collection/immutable/Iterable.scala
./scala-scala/src/library/scala/collection/immutable/LinearSeq.scala
-# https://github.com/lampepfl/dotty/issues/915
-# ./scala-scala/src/library/scala/collection/immutable/List.scala
+./scala-scala/src/library/scala/collection/immutable/List.scala
./scala-scala/src/library/scala/collection/immutable/MapProxy.scala
./scala-scala/src/library/scala/collection/immutable/PagedSeq.scala
./scala-scala/src/library/scala/collection/immutable/Queue.scala
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index c8cbeec94..1bd37125f 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -108,6 +108,7 @@ class tests extends CompilerTest {
@Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2)
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1)
+ @Test def neg_bounds() = compileFile(negDir, "bounds", xerrors = 2)
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
@Test def neg_typedIdents() = compileDir(negDir, "typedIdents", xerrors = 2)
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)
diff --git a/tests/neg/bounds.scala b/tests/neg/bounds.scala
new file mode 100644
index 000000000..8d2cd8259
--- /dev/null
+++ b/tests/neg/bounds.scala
@@ -0,0 +1,8 @@
+object Test {
+ class C[B >: String <: Int](x: B)
+ def g[B >: String <: Int](x: B): Int = x
+ def main(args: Array[String]): Unit = {
+ g("foo")
+ new C("bar")
+ }
+}
diff --git a/tests/pos/bounds.scala b/tests/pos/bounds.scala
index 26bc84a1b..625359f74 100644
--- a/tests/pos/bounds.scala
+++ b/tests/pos/bounds.scala
@@ -9,3 +9,10 @@ object ListMap {
def empty[X, Y] = new ListMap[X, Y]
def apply[A1, B2](elems: Tuple2[A1, B2]*): Map[A1, B2] = empty[A1,B2].++(elems.iterator)
}
+
+class Test[A] {
+
+ def f[B >: A <: AnyRef](x: A): AnyRef = (x: B)
+ def g[B >: String <: Int](x: B): Int = x
+
+}
diff --git a/tests/neg/t1279a.scala b/tests/pos/t1279a.scala
index 6d768d435..6d768d435 100644
--- a/tests/neg/t1279a.scala
+++ b/tests/pos/t1279a.scala