@@ -588,9 +588,13 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
588588 case New (_) | Closure (_, _, _) =>
589589 Pure
590590 case TypeApply (fn, _) =>
591+ val sym = fn.symbol
591592 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
594598 else Impure
595599 case Apply (fn, args) =>
596600 val factorPurity = minOf(exprPurity(fn), args.map(exprPurity))
@@ -634,6 +638,15 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
634638
635639 def isPureBinding (tree : Tree )(using Context ): Boolean = statPurity(tree) >= Pure
636640
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+
637650 /** Is the application `tree` with function part `fn` known to be pure?
638651 * Function value and arguments can still be impure.
639652 */
@@ -645,6 +658,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
645658
646659 tree.tpe.isInstanceOf [ConstantType ] && tree.symbol != NoSymbol && isKnownPureOp(tree.symbol) // A constant expression with pure arguments is pure.
647660 || fn.symbol.isStableMember && fn.symbol.isConstructor // constructors of no-inits classes are stable
661+ || isPureSyntheticCaseApply(fn.symbol)
648662
649663 /** The purity level of this reference.
650664 * @return
0 commit comments