@@ -167,28 +167,6 @@ class TreeChecker extends Phase with SymTransformer {
167
167
}
168
168
169
169
object 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)
192
170
193
171
/** Run some additional checks on the nodes of the trees. Specifically:
194
172
*
@@ -723,5 +701,97 @@ object TreeChecker {
723
701
}
724
702
725
703
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)
726
727
}
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 // TODO: 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 (original : tpd.Tree , expansion : 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(expansion)(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
+ |Macro was:
785
+ | ${original}
786
+ |
787
+ |The macro returned:
788
+ | ${expansion}
789
+ |
790
+ |Error:
791
+ | ${err.getMessage}
792
+ |
793
+ | """ ,
794
+ original
795
+ )
796
+
727
797
}
0 commit comments