-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #2772: Special case Devalify for java.lang.System.* #2781
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
be8bcee
f4c19d9
faa8864
cd035b2
f824164
cf54051
09d4a8c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -166,10 +166,12 @@ class Devalify extends Optimisation { | |
|
||
def readingOnlyVals(t: Tree)(implicit ctx: Context): Boolean = dropCasts(t) match { | ||
case Typed(exp, _) => readingOnlyVals(exp) | ||
|
||
case TypeApply(fun @ Select(rec, _), List(tp)) => | ||
if ((fun.symbol eq defn.Any_asInstanceOf) && rec.tpe.derivesFrom(tp.tpe.classSymbol)) | ||
readingOnlyVals(rec) | ||
else false | ||
|
||
case Apply(Select(rec, _), Nil) => | ||
def isGetterOfAImmutableField = t.symbol.isGetter && !t.symbol.is(Mutable) | ||
def isCaseClassWithVar = t.symbol.info.decls.exists(_.is(Mutable)) | ||
|
@@ -182,8 +184,10 @@ class Devalify extends Optimisation { | |
if (isGetterOfAImmutableField || isAccessingProductField || isImmutableCaseAccessor) | ||
readingOnlyVals(rec) | ||
else false | ||
|
||
case Select(rec, _) if t.symbol.is(Method) => | ||
if (t.symbol.isGetter && !t.symbol.is(Mutable)) readingOnlyVals(rec) // getter of a immutable field | ||
if (t.symbol.isGetter && !t.symbol.is(Mutable)) | ||
readingOnlyVals(rec) // getter of a immutable field | ||
else if (t.symbol.owner.derivesFrom(defn.ProductClass) && t.symbol.owner.is(CaseClass) && t.symbol.name.isSelectorName) { | ||
def isImmutableField = { | ||
val fieldId = t.symbol.name.toString.drop(1).toInt - 1 | ||
|
@@ -194,13 +198,22 @@ class Devalify extends Optimisation { | |
} else if (t.symbol.is(CaseAccessor) && !t.symbol.is(Mutable)) | ||
readingOnlyVals(rec) | ||
else false | ||
|
||
case Select(qual, _) if !t.symbol.is(Mutable) => | ||
readingOnlyVals(qual) | ||
if (t.symbol == defn.SystemModule) { | ||
// System.in is static final fields that, for legacy reasons, must be | ||
// allowed to be changed by the methods System.setIn... | ||
// https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5.4 | ||
false | ||
} else | ||
readingOnlyVals(qual) | ||
|
||
case t: Ident if !t.symbol.is(Mutable) && !t.symbol.is(Method) && !t.symbol.info.dealias.isInstanceOf[ExprType] => | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing says that there might not be an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The implementation of this case calls @DarkDimius Could you explain why we even need this |
||
desugarIdent(t) match { | ||
case Some(t) => readingOnlyVals(t) | ||
case None => true | ||
} | ||
|
||
case t: This => true | ||
// null => false, or the following fails devalify: | ||
// trait I { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import java.io.OutputStream | ||
|
||
object Test { | ||
def main(args: Array[String]): Unit = { | ||
val oldErr = System.err | ||
System.setErr(null) // setOut(null) confuses the testing framework... | ||
val a = () => foo(oldErr) | ||
a() | ||
} | ||
|
||
def foo(err: OutputStream): Unit = { | ||
err.write(0) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: a -> an