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

Compiler does not compile a function with a default argument initialized using an expression with the same name field #9413

Open
scabug opened this issue Jul 22, 2015 · 2 comments
Assignees
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) minimized named/default args typer
Milestone

Comments

@scabug
Copy link

scabug commented Jul 22, 2015

The following trivial example produces a compiler error:

class A {
  val b = ""
  def f(b: Option[String] = Some(b))
}

The error is

Error:(3, 34) type mismatch;
 found   : Option[String]
 required: String
  def f(b: Option[String] = Some(b))
                                 ^

The error seems to suggest the compiler is trying to initialize b argument with itself, not with the b field, when the b field should be the only possible valid interpretation in this context, as b argument is not visible in the parameter list itself.

@scabug
Copy link
Author

scabug commented Jul 22, 2015

Imported From: https://issues.scala-lang.org/browse/SI-9413?orig=1
Reporter: Ondřej Španěl (OSpanel)
Affected Versions: 2.11.7

@scabug
Copy link
Author

scabug commented Jul 23, 2015

@lrytz said (edited on Jul 23, 2015 7:19:46 PM UTC):
Hah. In fact, default argument expressions are always type-checked in a context where the parameter is in scope - this is a bug.
The reason: normal value definitions are allowed to be recursive, so we need a special case for parameters.

Now, unfortunately we cannot just use the outer context, because parameters of a previous parameter list are visible: def f(x: Int)(y: Int = x) is valid.
The type checker doesn't have a scope per parameter list, only one per method, so there's no easy fix.

Here's another bug that has the same underlying reason:

class A {
  type T
}

class C {
  val a: A
  def f(a: String, b: a.T) = 0
}

By the spec (http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#default-arguments):
{quote}The scope of a formal value parameter name x comprises all subsequent parameter clauses, as well as the method return type and the function body.
{quote}

So the parameter a should not be in scope in the type definition of b. However, in reality, the type checker will resolve a in a.T to the parameter instead of the field and yield an error:

error: type T is not a member of String
         def f(a: String, b: a.T) = 0
                               ^

@scabug scabug added this to the Backlog milestone Apr 7, 2017
@som-snytt som-snytt added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Nov 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) minimized named/default args typer
Projects
None yet
Development

No branches or pull requests

4 participants