diff options
author | odersky <odersky@gmail.com> | 2015-11-09 09:53:27 +0100 |
---|---|---|
committer | odersky <odersky@gmail.com> | 2015-11-09 09:53:27 +0100 |
commit | b3a1626d81385624f1db894a360288b85e8b3585 (patch) | |
tree | d796e885f95ba60b2367b619639d9cfd248b025d | |
parent | 3d5a2e2987066a1575db2874cf2c4721a1a66de1 (diff) | |
parent | 9767782a4766826ef903836609cb34c9bad2df61 (diff) | |
download | dotty-b3a1626d81385624f1db894a360288b85e8b3585.tar.gz dotty-b3a1626d81385624f1db894a360288b85e8b3585.tar.bz2 dotty-b3a1626d81385624f1db894a360288b85e8b3585.zip |
Merge pull request #927 from dotty-staging/stdlib-bounds
Drop checking that lower bound is a subtype of upper bound.
-rw-r--r-- | src/dotty/tools/dotc/core/unpickleScala2/Scala2Unpickler.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PostTyper.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Checking.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 | ||||
-rw-r--r-- | test/dotc/scala-collections.whitelist | 3 | ||||
-rw-r--r-- | test/dotc/tests.scala | 1 | ||||
-rw-r--r-- | tests/neg/bounds.scala | 8 | ||||
-rw-r--r-- | tests/pos/bounds.scala | 7 | ||||
-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 |