@@ -167,28 +167,6 @@ class TreeChecker extends Phase with SymTransformer {
167167}
168168
169169object TreeChecker {
170- /** - Check that TypeParamRefs and MethodParams refer to an enclosing type.
171- * - Check that all type variables are instantiated.
172- */
173- def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type = new TypeMap () {
174- val definedBinders = new java.util.IdentityHashMap [Type , Any ]
175- def apply (tp : Type ): Type = {
176- tp match {
177- case tp : BindingType =>
178- definedBinders.put(tp, tp)
179- mapOver(tp)
180- definedBinders.remove(tp)
181- case tp : ParamRef =>
182- assert(definedBinders.get(tp.binder) != null , s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
183- case tp : TypeVar =>
184- assert(tp.isInstantiated, s " Uninstantiated type variable: ${tp.show}, tree = ${tree.show}" )
185- apply(tp.underlying)
186- case _ =>
187- mapOver(tp)
188- }
189- tp
190- }
191- }.apply(tp0)
192170
193171 /** Run some additional checks on the nodes of the trees. Specifically:
194172 *
@@ -723,5 +701,94 @@ object TreeChecker {
723701 }
724702
725703 override def simplify (tree : Tree , pt : Type , locked : TypeVars )(using Context ): tree.type = tree
704+
705+ /** - Check that TypeParamRefs and MethodParams refer to an enclosing type.
706+ * - Check that all type variables are instantiated.
707+ */
708+ def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type = new TypeMap () {
709+ val definedBinders = new java.util.IdentityHashMap [Type , Any ]
710+ def apply (tp : Type ): Type = {
711+ tp match {
712+ case tp : BindingType =>
713+ definedBinders.put(tp, tp)
714+ mapOver(tp)
715+ definedBinders.remove(tp)
716+ case tp : ParamRef =>
717+ assert(definedBinders.get(tp.binder) != null , s " orphan param: ${tp.show}, hash of binder = ${System .identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0" )
718+ case tp : TypeVar =>
719+ assert(tp.isInstantiated, s " Uninstantiated type variable: ${tp.show}, tree = ${tree.show}" )
720+ apply(tp.underlying)
721+ case _ =>
722+ mapOver(tp)
723+ }
724+ tp
725+ }
726+ }.apply(tp0)
726727 }
728+
729+ class LocalChecker (phasesToCheck : Seq [Phase ]) extends Checker (phasesToCheck : Seq [Phase ]) {
730+ override def assertDefined (tree : untpd.Tree )(using Context ): Unit =
731+ () // TODO check locally defined symbols
732+ // if (tree.symbol.maybeOwner.isTerm) {
733+ // val sym = tree.symbol
734+ // assert(
735+ // nowDefinedSyms.contains(sym) || patBoundSyms.contains(sym),
736+ // i"undefined symbol ${sym} at line " + tree.srcPos.line
737+ // )
738+
739+ // if (!ctx.phase.patternTranslated)
740+ // assert(
741+ // !sym.isPatternBound || patBoundSyms.contains(sym),
742+ // i"sym.isPatternBound => patBoundSyms.contains(sym) is broken, sym = $sym, line " + tree.srcPos.line
743+ // )
744+ // }
745+
746+ /** - Check that TypeParamRefs and MethodParams refer to an enclosing type.
747+ */
748+ override def checkNoOrphans (tp0 : Type , tree : untpd.Tree = untpd.EmptyTree )(using Context ): Type =
749+ tp0 // Can we check part of this?
750+ // new TypeMap() {
751+ // val definedBinders = new java.util.IdentityHashMap[Type, Any]
752+ // def apply(tp: Type): Type = {
753+ // tp match {
754+ // case tp: BindingType =>
755+ // definedBinders.put(tp, tp)
756+ // mapOver(tp)
757+ // definedBinders.remove(tp)
758+ // case tp: ParamRef =>
759+ // assert(definedBinders.get(tp.binder) != null, s"orphan param: ${tp.show}, hash of binder = ${System.identityHashCode(tp.binder)}, tree = ${tree.show}, type = $tp0")
760+ // case tp: TypeVar =>
761+ // assert(tp.isInstantiated, s"Uninstantiated type variable: ${tp.show}, tree = ${tree.show}")
762+ // apply(tp.underlying)
763+ // case _ =>
764+ // mapOver(tp)
765+ // }
766+ // tp
767+ // }
768+ // }.apply(tp0)
769+ }
770+
771+ def checkMacroGeneratedTree (tree : tpd.Tree )(using Context ): Unit =
772+ if ctx.settings.XcheckMacros .value then
773+ val checkingCtx = ctx
774+ .fresh
775+ .addMode(Mode .ImplicitsEnabled )
776+ .setReporter(new ThrowingReporter (ctx.reporter)) // TODO report as errors
777+ val treeChecker = new LocalChecker (Nil ) // TODO enable previous phase post-conditions
778+ try treeChecker.typed(tree)(using checkingCtx)
779+ catch
780+ case err : java.lang.AssertionError =>
781+ report.error(
782+ em """ Malformed tree was found while expanding macro with -Xcheck-macros.
783+ |
784+ |The tree returned by the macro was:
785+ | ${tree}
786+ |
787+ |Error:
788+ | ${err.getMessage}
789+ |
790+ | """ ,
791+ tree
792+ )
793+
727794}
0 commit comments