Skip to content
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

Implicit resolution of parameters is different depending on whether return types of implicits are inferred. #5618

Open
scabug opened this issue Mar 27, 2012 · 6 comments

Comments

@scabug
Copy link

scabug commented Mar 27, 2012

This session from my REPL is probably more explanatory than I can be:

scala> case class Class1()
defined class Class1

scala> case class Class2(implicit class1: Class1) {
     |   def printClass1() = println(class1)
     | }
defined class Class2

scala> object Test {
     |   val class2 = new Class2
     |   implicit val class1 = new Class1()
     | }
<console>:12: error: could not find implicit value for parameter class1: Class1
         val class2 = new Class2
                      ^

scala> object Test {
     |   val class2 = new Class2
     |   implicit val class1: Class1 = new Class1()
     | }
defined module Test

scala> Test.class2.printClass1()
null

scala> object Test {
     |   implicit val class1 = new Class1()
     |   val class2 = new Class2
     | }
defined module Test

scala> Test.class2.printClass1()
Class1()

This is an example of using implicit parameters as a basic inversion of control in the first definition of the module Test the compiler is correctly failing as there is no definition at that point. However, in the second definition of Test, the compiler appears to allow this through, but passes the reference to class1 before it is initialized (confirmed using -Xprint:typer). The final definition is the fully valid case.

It would appear that specifying the type of class1 somehow causes that code to be valid.

@scabug
Copy link
Author

scabug commented Mar 27, 2012

Imported From: https://issues.scala-lang.org/browse/SI-5618?orig=1
Reporter: Sean Parsons (seanparsons)
Affected Versions: 2.9.1, 2.10.0, 2.11.0-RC1

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@paulp said:
I wanted to say "as specified", but I can't find it in the spec. If it's not in there it's way overdue to be in there. Anyway, this is "as intended." See comments in #801.

@scabug
Copy link
Author

scabug commented Mar 27, 2012

Sean Parsons (seanparsons) said:
The comments in that bug are for implicit conversions aren't they? In either case I'd say this is pretty confusing in its current state.

@scabug
Copy link
Author

scabug commented Mar 27, 2012

@paulp said:
It is about implicit eligibility.

@scabug
Copy link
Author

scabug commented May 2, 2012

@axel22 said:
Test case added in pending/neg.

@diesalbla
Copy link

Here is a simplified example that I have tried in Scala 2.13.x.

case class A()
object Test {
  def f(implicit a: A) = 42
  implicit val a /* :A */ = A()
}

Like the original example, if the type annotation of a is commented, then the compiler rejects this program. If the type annotation is uncommented, then the compiler accepts the program but warns that a is uninitialised. This shows two issues:

  1. In the first case, the implicit search for resolving f does not account for the implicit declaration of a, because the type is not annotated and it has not been inferred yet. If the specification states that the parameter to f should be resolved before inferring the type of a, then we are getting the expected behaviour.
  2. In the second case, in which it is using a non-initialised value, that is the same problem as if we were not using implicit values.

All in all, I am not sure if this should be regarded as expected behaviour, and is therefore not a bug.

@scala scala deleted a comment from scabug Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants