@@ -550,15 +550,41 @@ object Erasure {
550
550
if (! ctx.mode.is(Mode .Type )) {
551
551
if (isErased(tree))
552
552
report.error(em " ${tree.symbol} is declared as erased, but is in fact used " , tree.srcPos)
553
- tree.symbol.getAnnotation(defn.CompileTimeOnlyAnnot ) match {
554
- case Some (annot) =>
555
- def defaultMsg =
556
- i """ Reference to ${tree.symbol.showLocated} should not have survived,
557
- |it should have been processed and eliminated during expansion of an enclosing macro or term erasure. """
558
- val message = annot.argumentConstant(0 ).fold(defaultMsg)(_.stringValue)
559
- report.error(message, tree.srcPos)
560
- case _ => // OK
561
- }
553
+
554
+ def parentSyms (tpe : Type ): LazyList [Symbol ] =
555
+ val ref = tpe.widen.finalResultType
556
+ ref.classSymbol #:: ref.parents.to(LazyList ).flatMap(parentSyms)
557
+
558
+ def checkTree (tree : Tree , pos : util.SrcPos , toCheck : LazyList [Symbol ]): Boolean =
559
+ toCheck.exists { sym =>
560
+ sym.getAnnotation(defn.CompileTimeOnlyAnnot ) match {
561
+ case Some (annot) =>
562
+ def defaultMsg =
563
+ i """ Reference to ${tree.symbol.showLocated} should not have survived,
564
+ |it should have been processed and eliminated during expansion of an enclosing macro or term erasure. """
565
+ val message = annot.argumentConstant(0 ).fold(defaultMsg)(_.stringValue)
566
+ report.error(message, pos)
567
+ true
568
+ case _ => // OK
569
+ false
570
+ }
571
+ }
572
+
573
+ tree match
574
+ case ddef : DefDef =>
575
+ for
576
+ vparams <- ddef.vparamss
577
+ vparam <- vparams
578
+ do
579
+ checkTree(vparam, vparam.tpt.srcPos, parentSyms(vparam.tpt.tpe))
580
+ checkTree(ddef, ddef.tpt.srcPos, parentSyms(ddef.tpt.tpe))
581
+
582
+ case vdef : ValDef => checkTree(vdef, vdef.tpt.srcPos, parentSyms(vdef.tpt.tpe))
583
+
584
+ case tree =>
585
+ // in the other branches we avoid checking the symbol itself
586
+ // in-case it is annotated for downstream members
587
+ checkTree(tree, tree.srcPos, tree.symbol #:: parentSyms(tree.tpe))
562
588
}
563
589
tree
564
590
}
@@ -844,8 +870,8 @@ object Erasure {
844
870
override def typedValDef (vdef : untpd.ValDef , sym : Symbol )(using Context ): Tree =
845
871
if (sym.isEffectivelyErased) erasedDef(sym)
846
872
else
847
- super .typedValDef(untpd.cpy.ValDef (vdef)(
848
- tpt = untpd.TypedSplice (TypeTree (sym.info).withSpan(vdef.tpt.span))), sym)
873
+ checkNotErased( super .typedValDef(untpd.cpy.ValDef (vdef)(
874
+ tpt = untpd.TypedSplice (TypeTree (sym.info).withSpan(vdef.tpt.span))), sym))
849
875
850
876
/** Besides normal typing, this function also compacts anonymous functions
851
877
* with more than `MaxImplementedFunctionArity` parameters to use a single
@@ -889,7 +915,7 @@ object Erasure {
889
915
vparamss = vparams :: Nil ,
890
916
tpt = untpd.TypedSplice (TypeTree (restpe).withSpan(ddef.tpt.span)),
891
917
rhs = rhs1)
892
- super .typedDefDef(ddef1, sym)
918
+ checkNotErased( super .typedDefDef(ddef1, sym) )
893
919
end typedDefDef
894
920
895
921
/** The outer parameter definition of a constructor if it needs one */
0 commit comments