From f91f030290ac817888a6249d91118f42b560ab87 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 17 Aug 2014 10:51:45 +0200 Subject: Disabling adapt in TreeChecker well-typed code should not need further adapations. That's why `adapt` is replaced by a subtype assertion in TreeChecker. Flushed out two instances where typechecking did not produce well-adapted trees - one in typedClosure, the other manifested itself in typedSuper. --- src/dotty/tools/dotc/transform/TreeChecker.scala | 5 ++++ src/dotty/tools/dotc/typer/TypeAssigner.scala | 2 +- src/dotty/tools/dotc/typer/Typer.scala | 29 +++++++++++++----------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index e22edf4df..473f38105 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -92,6 +92,11 @@ class TreeChecker { i"bad owner; $tree has owner ${tree.symbol.owner}, expected was ${ctx.owner}") super.index(trees) } + + override def adapt(tree: Tree, pt: Type, original: untpd.Tree = untpd.EmptyTree)(implicit ctx: Context) = { + if (ctx.mode.isExpr) assert(tree.tpe <:< pt, err.typeMismatchStr(tree.tpe, pt)) + tree + } } } diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala index ae56df82f..69334f525 100644 --- a/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -211,7 +211,7 @@ trait TypeAssigner { val owntype = if (!mix.isEmpty) findMixinSuper(cls.info) else if (inConstrCall) cls.info.firstParent - else cls.info.parents.reduceLeft((x: Type, y: Type) => AndType(x, y)) + else cls.info.parents.reduceLeft((x: Type, y: Type) => x & y) tree.withType(SuperType(cls.thisType, owntype)) } diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index cd9ddb0bd..7473e76f6 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -555,20 +555,23 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def typedClosure(tree: untpd.Closure, pt: Type)(implicit ctx: Context) = track("typedClosure") { val env1 = tree.env mapconserve (typed(_)) val meth1 = typedUnadapted(tree.meth) - val target = meth1.tpe.widen match { - case mt: MethodType => - pt match { - case SAMType(meth) if !defn.isFunctionType(pt) && mt <:< meth.info => - if (!isFullyDefined(pt, ForceDegree.all)) - ctx.error(d"result type of closure is an underspecified SAM type $pt", tree.pos) - TypeTree(pt) - case _ => - if (!mt.isDependent) EmptyTree - else throw new Error(i"internal error: cannot turn dependent method type $mt into closure, position = ${tree.pos}, raw type = ${mt.toString}") // !!! DEBUG. Eventually, convert to an error? + val target = + if (tree.tpt.isEmpty) + meth1.tpe.widen match { + case mt: MethodType => + pt match { + case SAMType(meth) if !defn.isFunctionType(pt) && mt <:< meth.info => + if (!isFullyDefined(pt, ForceDegree.all)) + ctx.error(d"result type of closure is an underspecified SAM type $pt", tree.pos) + TypeTree(pt) + case _ => + if (!mt.isDependent) EmptyTree + else throw new Error(i"internal error: cannot turn dependent method type $mt into closure, position = ${tree.pos}, raw type = ${mt.toString}") // !!! DEBUG. Eventually, convert to an error? + } + case tp => + throw new Error(i"internal error: closing over non-method $tp, pos = ${tree.pos}") } - case tp => - throw new Error(i"internal error: closing over non-method $tp, pos = ${tree.pos}") - } + else typed(tree.tpt) assignType(cpy.Closure(tree)(env1, meth1, target), meth1, target) } -- cgit v1.2.3