diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala index d18ffcd252d5..f634defbbea2 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -397,19 +397,8 @@ object TreeChecker { promote(tree) case _ => val tree1 = super.typedUnadapted(tree, pt, locked) - def isSubType(tp1: Type, tp2: Type) = - (tp1 eq tp2) || // accept NoType / NoType - (tp1 <:< tp2) - def divergenceMsg(tp1: Type, tp2: Type) = - s"""Types differ - |Original type : ${tree.typeOpt.show} - |After checking: ${tree1.tpe.show} - |Original tree : ${tree.show} - |After checking: ${tree1.show} - |Why different : - """.stripMargin + core.TypeComparer.explained(_.isSubType(tp1, tp2)) - if (tree.hasType) // it might not be typed because Typer sometimes constructs new untyped trees and resubmits them to typedUnadapted - assert(isSubType(tree1.tpe, tree.typeOpt), divergenceMsg(tree1.tpe, tree.typeOpt)) + if tree.hasType then // it might not be typed because Typer sometimes constructs new untyped trees and resubmits them to typedUnadapted + checkType(tree1.tpe, tree.typeOpt, tree, "typedUnadapted") tree1 checkNoOrphans(res.tpe) phasesToCheck.foreach(_.checkPostCondition(res)) @@ -747,28 +736,25 @@ object TreeChecker { override def adapt(tree: Tree, pt: Type, locked: TypeVars)(using Context): Tree = { def isPrimaryConstructorReturn = ctx.owner.isPrimaryConstructor && pt.isRef(ctx.owner.owner) && tree.tpe.isRef(defn.UnitClass) - def infoStr(tp: Type) = tp match { - case tp: TypeRef => - val sym = tp.symbol - i"${sym.showLocated} with ${tp.designator}, flags = ${sym.flagsString}, underlying = ${tp.underlyingIterator.toList}%, %" - case _ => - "??" - } - if (ctx.mode.isExpr && - !tree.isEmpty && - !isPrimaryConstructorReturn && - !pt.isInstanceOf[FunOrPolyProto]) - assert(tree.tpe <:< pt, { - val mismatch = TypeMismatch(tree.tpe, pt, Some(tree)) - i"""|${mismatch.msg} - |found: ${infoStr(tree.tpe)} - |expected: ${infoStr(pt)} - |tree = $tree""".stripMargin - }) + if ctx.mode.isExpr + && !tree.isEmpty + && !isPrimaryConstructorReturn + && !pt.isInstanceOf[FunOrPolyProto] + then + checkType(tree.tpe, pt, tree, "adapt") tree } override def simplify(tree: Tree, pt: Type, locked: TypeVars)(using Context): tree.type = tree + + private def checkType(tp1: Type, tp2: Type, tree: untpd.Tree, step: String)(using Context) = + // Accept NoType <:< NoType as true + assert((tp1 eq tp2) || (tp1 <:< tp2), { + val mismatch = TypeMismatch(tp1, tp2, None) + i"""|Type Mismatch (while checking $step): + |${mismatch.message}${mismatch.explanation} + |tree = $tree ${tree.className}""".stripMargin + }) } /** Tree checker that can be applied to a local tree. */