-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Wrong rewrite of implicit arguments passed as { } #22731
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
Comments
This issue was picked for the Scala Issue Spree of Monday, April 7th. @mbovel, @mrdziuban and @ajafri2001 will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here. |
Reproduced with class Input(x: String)
trait Decoder[T]
object Decoder {
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
}
object Input {
given Decoder[Input] = Decoder { () =>
Input("")
}
} to ( class Input(x: String)
trait Decoder[T]
object Decoder {
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
}
object Input {
given Decoder[Input] = Decoder using { () =>
Input("")
}
} while we'd probably want the following (curly braces changed to parentheses, and class Input(x: String)
trait Decoder[T]
object Decoder {
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
}
object Input {
given Decoder[Input] = Decoder(using () =>
Input("")
)
} |
This may be valid sometimes, but often you may need to keep curly braces, and just add parentheses around the block, as the function body may contain constructs not available without braces, like variable declarations. |
Ah right, so should we aim to rewrite to the following? object Input {
given Decoder[Input] = Decoder (using {() =>
Input("")
})
} |
As a primary form, yes, this. Removing the inner braces may be sometimes possible, but I find this secondary - I do not expect rewrites to create a code which is always nice, but it should be compilable. |
Here is such an example: trait Decoder[T]
object Decoder {
inline def apply[T](implicit f: () => Unit): Decoder[T] = ???
}
object Input {
given Decoder[Int] = Decoder(using {() => val x = 42; println("blip")})
}
@main def main = () We should add it as a test case. |
Does this compile? I would expect |
Yes, the type parameter of This can actually further be minimized to: trait Decoder
def Decoder(implicit f: () => Unit): Decoder = ???
@main def main =
Decoder { () => val x = 42; println("blip") } or even def foo(implicit bar: () => Unit): Unit = ???
@main def main =
foo { () => val x = 42; println("blip") } |
The error message and patch are generated here: scala3/compiler/src/dotty/tools/dotc/typer/Migrations.scala Lines 130 to 142 in 0cd43fe
|
So, from what we observed, the parentheses should be added if and only if the function was applied with the trailing lambda syntax (curly braces): def foo(implicit bar: () => Unit): Unit = ???
@main def main =
foo { () => val x = 42; println("blip") } // should add parentheses
foo({ () => val x = 42; println("blip") }) // should not add parentheses However we are missing this information. Could we add it to the |
Probably I'm the only one who was hoping for "infix |
I think adding an |
Okay, I tried an alternative implementation based on @som-snytt's suggestion: #22937. The changeset is indeed much smaller. |
Compiler version
3.7.0-RC1-bin-20250303-91985db-NIGHTLY
Minimized code
Compile this with "-rewrite", "-source", "3.7-migration".
Output
The code cannot be compiled, the
using
word is placed at a location where it makes no sense.Note:
Expectation
The rewrite should not produce invalid code.
The text was updated successfully, but these errors were encountered: