-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix #2939: Avoid duplicating symbols in default arguments #3839
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
Conversation
5f77fd4
to
d690fb2
Compare
Something fails with the CI. |
I can reproduce the failure locally, the added run test compiles correctly but generates invalid bytecode which is detected at runtime: > run tests/run/i2939.scala
[info] Running dotty.tools.dotc.Main -classpath /home/smarter/opt/dotty/library/target/scala-2.12/dotty-library_2.12-0.7.0-bin-SNAPSHOT-nonbootstrapped.jar tests/run/i2939.scala
[success] Total time: 4 s, completed 21 janv. 2018 18:57:56
> dotr Test
Exception in thread "main" java.lang.VerifyError: Bad local variable type
Exception Details:
Location:
Test$.x$1$1()I @0: aload_1
Reason:
Type top (current frame, locals[1]) is not assignable to reference type
Current Frame:
bci: @0
flags: { }
locals: { 'Test$' }
stack: { }
Bytecode:
0x0000000: 2bbe ac
at Test.main(i2939.scala) |
Actually, compilation also fails with Ycheck: > run -Ycheck:all tests/run/i2939.scala
exception while typing def x$2: Int = args.length of class class dotty.tools.dotc.ast.Trees$DefDef # 584
...
Exception in thread "main" java.lang.AssertionError: assertion failed: wrong type, expect a method type for Test$._$x$2, but found: Int
at scala.Predef$.assert(Predef.scala:219)
at dotty.tools.dotc.transform.TreeChecker$Checker.$anonfun$typedDefDef$2(TreeChecker.scala:405)
at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:180)
at dotty.tools.dotc.transform.TreeChecker$Checker.$anonfun$typedDefDef$1(TreeChecker.scala:393)
at dotty.tools.dotc.transform.TreeChecker$Checker.withDefinedSyms(TreeChecker.scala:180)
at dotty.tools.dotc.transform.TreeChecker$Checker.typedDefDef(TreeChecker.scala:392)
at dotty.tools.dotc.typer.Typer.typedNamed$1(Typer.scala:1708)
... |
Previously a method argument could be duplicated because it was passed to the method as well as to its default argument methods. This was fatal if the argument contained local definitions or was a closure. We now unconditionally lift such arguments if the method has default parameters.
@@ -345,7 +346,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] => | |||
| Super(_, _) | |||
| Literal(_) | |||
| Closure(_, _, _) => |
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.
How come a Closure is considered a PurePath? It can contain local definitions.
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.
ah no it doesn't, nevermind.
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.
LGTM
/** Test indicating `expr` does not need lifting */ | ||
def noLift(expr: Tree)(implicit ctx: Context): Boolean | ||
|
||
/** The corresponding lifter for paam-by-name arguments */ |
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: paam -> param ?
* @return pure if expression has no side effects | ||
* idempotent if running the expression a second time has no side effects | ||
* impure otherwise | ||
* @return PurePath if expression has no side effects and cannot contain local definitions |
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.
Not sure if PurePath is the best name for this since not every PurePath expression is a valid path. Maybe NoDefPure? Or SimplePure/ComplexPure considering that later on we talk about "complex expressions" ?
Previously a method argument could be duplicated because it was passed
to the method as well as to its default argument methods. This was fatal
if the argument contained local definitions or was a closure.
We now unconditionally lift such arguments if the method has default
parameters.