@@ -588,9 +588,13 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
588
588
case New (_) | Closure (_, _, _) =>
589
589
Pure
590
590
case TypeApply (fn, _) =>
591
+ val sym = fn.symbol
591
592
if tree.tpe.isInstanceOf [MethodOrPoly ] then exprPurity(fn)
592
- else if fn.symbol == defn.QuotedTypeModule_of || fn.symbol == defn.Predef_classOf then Pure
593
- else if fn.symbol == defn.Compiletime_erasedValue && tree.tpe.dealias.isInstanceOf [ConstantType ] then Pure
593
+ else if sym == defn.QuotedTypeModule_of
594
+ || sym == defn.Predef_classOf
595
+ || sym == defn.Compiletime_erasedValue && tree.tpe.dealias.isInstanceOf [ConstantType ]
596
+ || defn.capsErasedValueMethods.contains(sym)
597
+ then Pure
594
598
else Impure
595
599
case Apply (fn, args) =>
596
600
val factorPurity = minOf(exprPurity(fn), args.map(exprPurity))
@@ -634,6 +638,15 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
634
638
635
639
def isPureBinding (tree : Tree )(using Context ): Boolean = statPurity(tree) >= Pure
636
640
641
+ def isPureSyntheticCaseApply (sym : Symbol )(using Context ): Boolean =
642
+ sym.isAllOf(SyntheticMethod )
643
+ && sym.name == nme.apply
644
+ && sym.owner.is(Module )
645
+ && {
646
+ val cls = sym.owner.companionClass
647
+ cls.is(Case ) && cls.isNoInitsRealClass
648
+ }
649
+
637
650
/** Is the application `tree` with function part `fn` known to be pure?
638
651
* Function value and arguments can still be impure.
639
652
*/
@@ -645,6 +658,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
645
658
646
659
tree.tpe.isInstanceOf [ConstantType ] && tree.symbol != NoSymbol && isKnownPureOp(tree.symbol) // A constant expression with pure arguments is pure.
647
660
|| fn.symbol.isStableMember && fn.symbol.isConstructor // constructors of no-inits classes are stable
661
+ || isPureSyntheticCaseApply(fn.symbol)
648
662
649
663
/** The purity level of this reference.
650
664
* @return
0 commit comments