diff options
author | Martin Odersky <odersky@gmail.com> | 2015-12-30 16:10:13 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-01-18 16:49:16 +0100 |
commit | 39ca54fcbe21df0fd277ab9734a032d71027fa4c (patch) | |
tree | d1ad29ce0293a05daab5e82d94dad1e881295605 /src/dotty/tools/dotc/transform/PostTyper.scala | |
parent | c0b545be494bc53f9839c8301cdca71edeb620c7 (diff) | |
download | dotty-39ca54fcbe21df0fd277ab9734a032d71027fa4c.tar.gz dotty-39ca54fcbe21df0fd277ab9734a032d71027fa4c.tar.bz2 dotty-39ca54fcbe21df0fd277ab9734a032d71027fa4c.zip |
Check bounds everywhere
Previously, bounds of a TypeDef tree were not checked. We now make
sure bounds are checked everywhere in PostTyper. The previous
partial check in Applications gets removed (it was not complete
even for TypeApplications because sometimes bounds were not yet
known when the test was performed.)
Diffstat (limited to 'src/dotty/tools/dotc/transform/PostTyper.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/PostTyper.scala | 51 |
1 files changed, 23 insertions, 28 deletions
diff --git a/src/dotty/tools/dotc/transform/PostTyper.scala b/src/dotty/tools/dotc/transform/PostTyper.scala index edf97f5b8..f9862bb95 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 and TypeApplys. + /** Check bounds of AppliedTypeTrees. * 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. @@ -97,29 +97,17 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran * Revisit this issue once we have implemented `inline`. Then we can demand * purity of the prefix unless the selection goes to an inline val. */ - private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = { - def literalize(tp: Type): Tree = tp.widenTermRefExpr match { - case ConstantType(value) if isIdempotentExpr(tree) => Literal(value) - case _ => tree - } - def norm(tree: Tree) = - if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) - else literalize(tree.tpe) - tree match { - case tree: TypeTree => - tree - case AppliedTypeTree(tycon, args) => - val tparams = tycon.tpe.typeSymbol.typeParams - val bounds = tparams.map(tparam => - 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) - } + private def normalizeTree(tree: Tree)(implicit ctx: Context): Tree = tree match { + case tree: TypeTree => tree + case _ => + if (tree.isType) { + Checking.boundsChecker.traverse(tree) + TypeTree(tree.tpe).withPos(tree.pos) + } + else tree.tpe.widenTermRefExpr match { + case ConstantType(value) if isIdempotentExpr(tree) => Literal(value) + case _ => tree + } } class PostTyperTransformer extends Transformer { @@ -161,10 +149,16 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran } case tree: Select => transformSelect(paramFwd.adaptRef(tree), Nil) - case tree @ TypeApply(sel: Select, args) => - val args1 = transform(args) - val sel1 = transformSelect(sel, args1) - if (superAcc.isProtectedAccessor(sel1)) sel1 else cpy.TypeApply(tree)(sel1, args1) + case tree @ TypeApply(fn, args) => + Checking.checkBounds(args, fn.tpe.widen.asInstanceOf[PolyType]) + fn match { + case sel: Select => + val args1 = transform(args) + val sel1 = transformSelect(sel, args1) + if (superAcc.isProtectedAccessor(sel1)) sel1 else cpy.TypeApply(tree)(sel1, args1) + case _ => + super.transform(tree) + } case tree @ Assign(sel: Select, _) => superAcc.transformAssign(super.transform(tree)) case tree: Template => @@ -186,6 +180,7 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTran val tree1 = if (sym.isClass) tree else { + Checking.boundsChecker.traverse(tree.rhs) cpy.TypeDef(tree)(rhs = TypeTree(tree.symbol.info)) } super.transform(tree1) |