Skip to content

Pattern given on the LHS of a val definition should enter corresponding scope #11897

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

Closed
LPTK opened this issue Mar 26, 2021 · 8 comments · Fixed by #12631
Closed

Pattern given on the LHS of a val definition should enter corresponding scope #11897

LPTK opened this issue Mar 26, 2021 · 8 comments · Fixed by #12631
Assignees
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala itype:enhancement
Milestone

Comments

@LPTK
Copy link
Contributor

LPTK commented Mar 26, 2021

Compiler version

3.0.0-RC1

Minimized code

scala> given Int = 0
lazy val given_Int: Int

scala> def test = {
     |   val (x, given Int) = (1, 1)
     |   summon[Int]
     | }
def test: Int

scala> test                                                                                                             
val res0: Int = 0

Expectation

This is quite surprising/unexpected.

I would expect it to work in the same way as the following:

scala> def test = {
     |   given Int = 1
     |   summon[Int]
     | }
def test: Int

scala> test
val res1: Int = 1
@LPTK LPTK added the itype:bug label Mar 26, 2021
@bishabosha
Copy link
Member

bishabosha commented Mar 26, 2021

def test = {
  val (x, given Int) = (1, 1)
  summon[Int]
}

desugars to the following:

def test: <error no implicit values were found that match type Int> = 
  {
    val x: Int =
      Tuple2.apply[Int, Int](1, 1):(Int, Int) @unchecked match 
        {
          case Tuple2.unapply[Int, Int](x @ _, given given_Int @ _:Int) =>
            x:Int
        }
    summon[Int](/* missing */summon[Int])
  }

@LPTK
Copy link
Contributor Author

LPTK commented Mar 26, 2021

Yes, but that's totally unexpected from a user point of view.

I always thought the desugaring of local val bindings with patterns was unnecessarily convoluted and allocation-heavy.

The correct approach would be to desugar them as:

def test = {
  (1, 1) match
  case (x, given Int) =>
    summon[Int]
    ... // rest of the block
}

Though this does not really generalize to member vals, which I am not convinced should be allowed to bind patterns anyway.

@bishabosha
Copy link
Member

sorry I should clarify, I agree that alongside x there should be introduced a definition for the given if the current design continues

@bishabosha bishabosha added the area:desugar Desugaring happens after parsing but before typing, see desugar.scala label Mar 26, 2021
@odersky
Copy link
Contributor

odersky commented Mar 26, 2021

Though this does not really generalize to member vals, which I am not convinced should be allowed to bind patterns anyway.

Note: this would also mean that toplevel vals and object vals cannot be allowed to bind patterns. So a rather drastic change.

@LPTK
Copy link
Contributor Author

LPTK commented Mar 26, 2021

Yes, it would definitely be too drastic to disallow them now. So at least member vals have to be supported with the current scheme (which still needs to be improved to handle given patterns).
But that doesn't prevent using a more efficient scheme for local vals.

BTW, the problem in this issue is reminiscent of the limitations of type binding in val definitions. For instance:

val (ls: List[t]) = List(1, 2, 3)  // Not found: type t

List(1, 2, 3) match { case ls: List[t] => ... } // works as expected

@bishabosha
Copy link
Member

bishabosha commented May 27, 2021

for reference, this behaviour was intentional from when given patterns were first added
https://github.com/lampepfl/dotty/blob/d09981141ea16a98c654b98ca582b9626bf0ff0b/tests/neg/given-pattern.scala#L7

@bishabosha
Copy link
Member

In the discussion at the dotty meeting we decided to resolve this with an error for given patterns in val definitions

@som-snytt
Copy link
Contributor

I tried to exploit the desugaring as shown, for example an extractor in the pattern takes the given, but it's not in scope.

If nothing else, closing off this avenue will save folks many hours trying to pursue it.

smarter added a commit that referenced this issue Jun 3, 2021
fix #11897: error on given pattern in val def
@Kordyjan Kordyjan added this to the 3.0.2 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:desugar Desugaring happens after parsing but before typing, see desugar.scala itype:enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants