Skip to content

Commit 9767782

Browse files
committed
Check bounds of inferred typevars in PostTyper.
1 parent 5cce9b4 commit 9767782

File tree

5 files changed

+21
-10
lines changed

5 files changed

+21
-10
lines changed

src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
6868
// TODO fill in
6969
}
7070

71-
/** Check bounds of AppliedTypeTrees.
71+
/** Check bounds of AppliedTypeTrees and TypeApplys.
7272
* Replace type trees with TypeTree nodes.
7373
* Replace constant expressions with Literal nodes.
7474
* Note: Demanding idempotency instead of purity in literalize is strictly speaking too loose.
@@ -114,6 +114,9 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran
114114
tparam.info.asSeenFrom(tycon.tpe.normalizedPrefix, tparam.owner.owner).bounds)
115115
Checking.checkBounds(args, bounds, _.substDealias(tparams, _))
116116
norm(tree)
117+
case TypeApply(fn, args) =>
118+
Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType])
119+
norm(tree)
117120
case _ =>
118121
norm(tree)
119122
}

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ trait Applications extends Compatibility { self: Typer =>
607607
case pt: PolyType =>
608608
if (typedArgs.length <= pt.paramBounds.length)
609609
typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
610-
checkBounds(typedArgs, pt)
610+
Checking.checkBounds(typedArgs, pt)
611611
case _ =>
612612
}
613613
assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)

src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ object Checking {
4141
d"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
4242
arg.pos)
4343

44+
/** Check that type arguments `args` conform to corresponding bounds in `poly`
45+
* Note: This does not check the bounds of AppliedTypeTrees. These
46+
* are handled by method checkBounds in FirstTransform
47+
*/
48+
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
49+
checkBounds(args, poly.paramBounds, _.substParams(poly, _))
50+
4451
/** Check that `tp` refers to a nonAbstract class
4552
* and that the instance conforms to the self type of the created class.
4653
*/
@@ -295,13 +302,6 @@ trait Checking {
295302
tree
296303
}
297304

298-
/** Check that type arguments `args` conform to corresponding bounds in `poly`
299-
* Note: This does not check the bounds of AppliedTypeTrees. These
300-
* are handled by method checkBounds in FirstTransform
301-
*/
302-
def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit =
303-
Checking.checkBounds(args, poly.paramBounds, _.substParams(poly, _))
304-
305305
/** Check that type `tp` is stable. */
306306
def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit =
307307
if (!tp.isStable && !tp.isErroneous)
@@ -407,7 +407,6 @@ trait NoChecking extends Checking {
407407
import tpd._
408408
override def checkNonCyclic(sym: Symbol, info: TypeBounds, reportErrors: Boolean)(implicit ctx: Context): Type = info
409409
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
410-
override def checkBounds(args: List[tpd.Tree], poly: PolyType)(implicit ctx: Context): Unit = ()
411410
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
412411
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
413412
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class tests extends CompilerTest {
107107

108108
@Test def neg_abstractOverride() = compileFile(negDir, "abstract-override", xerrors = 2)
109109
@Test def neg_blockescapes() = compileFile(negDir, "blockescapesNeg", xerrors = 1)
110+
@Test def neg_bounds() = compileFile(negDir, "bounds", xerrors = 2)
110111
@Test def neg_typedapply() = compileFile(negDir, "typedapply", xerrors = 4)
111112
@Test def neg_typedIdents() = compileDir(negDir, "typedIdents", xerrors = 2)
112113
@Test def neg_assignments() = compileFile(negDir, "assignments", xerrors = 3)

tests/neg/bounds.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
object Test {
2+
class C[B >: String <: Int](x: B)
3+
def g[B >: String <: Int](x: B): Int = x
4+
def main(args: Array[String]): Unit = {
5+
g("foo")
6+
new C("bar")
7+
}
8+
}

0 commit comments

Comments
 (0)