aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Checking.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-21 18:09:10 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-24 14:57:49 +0100
commita468a864dcdb89091985c194737968a979e874fb (patch)
tree4fc942a70e2a3a2c9a9f84acf1f57a696e587233 /src/dotty/tools/dotc/typer/Checking.scala
parentf6ebe1ec66220db511d0080f3807c3a0512fc01c (diff)
downloaddotty-a468a864dcdb89091985c194737968a979e874fb.tar.gz
dotty-a468a864dcdb89091985c194737968a979e874fb.tar.bz2
dotty-a468a864dcdb89091985c194737968a979e874fb.zip
checkBounds refactoring
Move core logic to TypeOps, only leave error reporting in Checking. That way, we have the option of re-using the code as a simple test elsewhere.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Checking.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala29
1 files changed, 6 insertions, 23 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index fdc70e207..2ff2e9e3b 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -33,27 +33,11 @@ object Checking {
/** A general checkBounds method that can be used for TypeApply nodes as
* well as for AppliedTypeTree nodes.
*/
- def checkBounds(args: List[tpd.Tree], boundss: List[TypeBounds], instantiate: (Type, List[Type]) => Type)(implicit ctx: Context) = {
- val argTypes = args.tpes
- for ((arg, bounds) <- args zip boundss) {
- def notConforms(which: String, bound: Type) = {
- ctx.error(
+ def checkBounds(args: List[tpd.Tree], boundss: List[TypeBounds], instantiate: (Type, List[Type]) => Type)(implicit ctx: Context) =
+ for ((arg, which, bound) <- ctx.boundsViolations(args, boundss, instantiate))
+ ctx.error(
d"Type argument ${arg.tpe} does not conform to $which bound $bound ${err.whyNoMatchStr(arg.tpe, bound)}",
arg.pos)
- }
- def checkOverlapsBounds(lo: Type, hi: Type): Unit = {
- //println(i"instantiating ${bounds.hi} with $argTypes")
- //println(i" = ${instantiate(bounds.hi, argTypes)}")
- val hiBound = instantiate(bounds.hi, argTypes)
- if (!(lo <:< hiBound)) notConforms("upper", hiBound)
- if (!(bounds.lo <:< hi)) notConforms("lower", bounds.lo)
- }
- arg.tpe match {
- case TypeBounds(lo, hi) => checkOverlapsBounds(lo, hi)
- case tp => checkOverlapsBounds(tp, tp)
- }
- }
- }
/** A type map which checks that the only cycles in a type are F-bounds
* and that protects all F-bounded references by LazyRefs.
@@ -192,10 +176,9 @@ trait Checking {
/** 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
- * TODO: remove pos parameter
*/
- def checkBounds(args: List[tpd.Tree], poly: PolyType, pos: Position)(implicit ctx: Context): Unit = Checking.checkBounds(
- args, poly.paramBounds, (tp, argTypes) => tp.substParams(poly, argTypes))
+ 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 =
@@ -292,7 +275,7 @@ 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, pos: Position)(implicit ctx: Context): Unit = ()
+ 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 checkLegalPrefix(tp: Type, selector: Name, pos: Position)(implicit ctx: Context): Unit = ()
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp