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

Unexpected behavior with by-name parameter, implicit view, and method overload. #9386

Closed
scabug opened this issue Jul 8, 2015 · 3 comments · Fixed by scala/scala#8590
Closed

Comments

@scabug
Copy link

scabug commented Jul 8, 2015

The discussion on SI-3237 seems to conclude that if an implicit view that has a by-name parameter is used on an expression of several statements then the view should apply only to the final statement of the expression. In other words the following code should print "barring", since int2Foo will only be applied to 0 and not the whole println("barring"); 0 expression:

import scala.language.implicitConversions
class Foo
object Foo { 
	implicit def int2Foo(a: => Int): Foo = new Foo //Never evaluate the argument
 	def bar(foo: Foo) = ()
}

object TestFoo extends App {
	Foo.bar { println("barring"); 0 }
}

However, if an apparently innocuous overload of the bar method is added, the behavior changes, and "barring" does not print:

import scala.language.implicitConversions
class Foo
object Foo { 
  	implicit def int2Foo(a: => Int): Foo = new Foo //Never evaluate the argument
	 def bar(foo: Foo) = ()
	 def bar(foo: Boolean) = () //unrelated overload
}

object TestFoo extends App {
	Foo.bar { println("barring"); 0 }
}

The fact that the overload affects this behavior is counterintuitive and bug prone. The specification of implicit views and by-name parameters might be ambiguous about whether or not the view should apply to the whole expression or just the last statement, but it seems to me that it should be consistent. That an overload changes the behavior here seems to be an implementation detail of method dispatch or overload resolution that should not affect this behavior.

@scabug
Copy link
Author

scabug commented Jul 8, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9386?orig=1
Reporter: Ben Reich (benreich)
Affected Versions: 2.11.4
See #3237

@scabug
Copy link
Author

scabug commented Jul 8, 2015

@som-snytt said:
It's just a bug. Args are typechecked without an expected type for overloading resolution (to see which alternatives are applicable), but the result expr must be adapted after that (which happens in the unoverloaded case because typed with an expected type).

@som-snytt
Copy link

Deeming the feature intersection of by-name implicit conversions and overload resolution a niche concern, given that both features are evil, I added a lint warning rather than muck with the trees.

As noted on the ticket, the behavior is confusing because it is the opposite of the other confusing behavior, and it is flipped by overloading. Other forms of inference are also derailed by overloading, and one could argue that this example is also simply type-driven and not a matter of plumbing or implementation detail. Also arguably, it is a bug as described in the previous comment.

@SethTisue SethTisue added this to the 2.13.2 milestone Dec 11, 2019
neo-technology-build-agent pushed a commit to neo4j/neo4j that referenced this issue Jun 15, 2023
"Implicits applied to block expressions after overload resolution may
have unexpected semantics" ???

scala/bug#9386
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants