Find more looping implicits - #15481
Conversation
1. Also check apply methods of companions of implicit or given classes.
Specifically apply methods of implicit Conversions.
2. Look inside Inlined nodes to detect loops.
Fixes scala#15474
Fixes scala#10947
|
|
||
| if sym.isOneOf(GivenOrImplicit | Lazy | ExtensionMethod) then | ||
| if sym.isOneOf(GivenOrImplicit | Lazy | ExtensionMethod) | ||
| || sym.name == nme.apply && sym.owner.is(Module) && sym.owner.sourceModule.isOneOf(GivenOrImplicit) |
There was a problem hiding this comment.
Could you please add a comment to explain the intent behind the condition on the right side of the ||? I wonder if this condition is too strong, but I am not sure. Do we have existing “pos” tests (the PR only contains two “neg” tests)?
|
This will help folks who need help and also save time on tickets! |
|
I tried the main branch for the following code (compiler build from commit: de3a82c, Find more looping implicits): // scalaVersion := "3.2.1-RC1-bin-SNAPSHOT" object Demo2:
given Conversion[String, Int] with
def apply(s: String): Int = s.toInt
def main(args: Array[String]): Unit =
val s = "123"
val i: Int = s
println(s"s=$s i=$i }")
It report "Infinite loop in function body" now. |
|
@wangzaixiang Your example is now a test. Note that |
Sure. I got it. It's not a BUG. thanks. |
|
My eyes went briefly out of focus when I looked at the example. It's like an optical illusion. To clarify further, the conversion to Rubbing my eyes. |
|
@odersky Isn't needed change to check file of test i13044 a sign of regression? Since introducing this change Caliban is not able to build in the community build (it's using -Xfatal-warnings) The mentioned test file is used 2 times:
PS. |
|
The code that fails to compile is deriving an instance for a recursive ADT (simplified): sealed trait InputValue
object InputValue {
case class ListValue(values: List[InputValue]) extends InputValue
case class ObjectValue(fields: Map[String, InputValue]) extends InputValue
case class SimpleValue(name: String) extends InputValue
}And it was called like this: implicit lazy val inputValueSchema: Schema[Any, InputValue] = Schema.derivedDuring the derivation, it will need an instance of itself because it's recursive, but it was finding itself thanks to |
|
@ghostdogpr Can we minimize this to a self-contained example? That would be important to see whether the code is actually safe and, if that's the case, to refine the checking analysis. |
Here's a minimized example: https://gist.github.com/ghostdogpr/b525ee4062427fa06861b96e3544fae2 |
|
@ghostdogpr Thanks for the minimization! It seems the change in this PR uncovered another bug in the loop checking. Fix forthcoming. |
Also check apply methods of companions of implicit or given classes.
Specifically apply methods of implicit Conversions.
Look inside Inlined nodes to detect loops.
Fixes #15474
Fixes #10947