@@ -166,10 +166,12 @@ class Devalify extends Optimisation {
166
166
167
167
def readingOnlyVals (t : Tree )(implicit ctx : Context ): Boolean = dropCasts(t) match {
168
168
case Typed (exp, _) => readingOnlyVals(exp)
169
+
169
170
case TypeApply (fun @ Select (rec, _), List (tp)) =>
170
171
if ((fun.symbol eq defn.Any_asInstanceOf ) && rec.tpe.derivesFrom(tp.tpe.classSymbol))
171
172
readingOnlyVals(rec)
172
173
else false
174
+
173
175
case Apply (Select (rec, _), Nil ) =>
174
176
def isGetterOfAImmutableField = t.symbol.isGetter && ! t.symbol.is(Mutable )
175
177
def isCaseClassWithVar = t.symbol.info.decls.exists(_.is(Mutable ))
@@ -182,8 +184,10 @@ class Devalify extends Optimisation {
182
184
if (isGetterOfAImmutableField || isAccessingProductField || isImmutableCaseAccessor)
183
185
readingOnlyVals(rec)
184
186
else false
187
+
185
188
case Select (rec, _) if t.symbol.is(Method ) =>
186
- if (t.symbol.isGetter && ! t.symbol.is(Mutable )) readingOnlyVals(rec) // getter of a immutable field
189
+ if (t.symbol.isGetter && ! t.symbol.is(Mutable ))
190
+ readingOnlyVals(rec) // getter of a immutable field
187
191
else if (t.symbol.owner.derivesFrom(defn.ProductClass ) && t.symbol.owner.is(CaseClass ) && t.symbol.name.isSelectorName) {
188
192
def isImmutableField = {
189
193
val fieldId = t.symbol.name.toString.drop(1 ).toInt - 1
@@ -194,13 +198,22 @@ class Devalify extends Optimisation {
194
198
} else if (t.symbol.is(CaseAccessor ) && ! t.symbol.is(Mutable ))
195
199
readingOnlyVals(rec)
196
200
else false
201
+
197
202
case Select (qual, _) if ! t.symbol.is(Mutable ) =>
198
- readingOnlyVals(qual)
203
+ if (t.symbol == defn.SystemModule ) {
204
+ // System.in is static final fields that, for legacy reasons, must be
205
+ // allowed to be changed by the methods System.setIn...
206
+ // https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5.4
207
+ false
208
+ } else
209
+ readingOnlyVals(qual)
210
+
199
211
case t : Ident if ! t.symbol.is(Mutable ) && ! t.symbol.is(Method ) && ! t.symbol.info.dealias.isInstanceOf [ExprType ] =>
200
212
desugarIdent(t) match {
201
213
case Some (t) => readingOnlyVals(t)
202
214
case None => true
203
215
}
216
+
204
217
case t : This => true
205
218
// null => false, or the following fails devalify:
206
219
// trait I {
0 commit comments