Scala Programming Language
  1. Scala Programming Language
  2. SI-7507

Strange error when destructuring into a val or lazy val

    Details

      Description

      class Bar
      
      abstract class Cake extends Slice {
        val bar: Bar
      }
      
      trait Slice { self: Cake =>
        import bar._
        lazy val Foo(x, y) = foo
        private case class Foo(x: Int, y: Int)
        private lazy val foo: Foo = ???
      }
      
      20:50 ~/Projects/210x/sandbox (2.10.x)$ s
      Test.scala:9: error: not found: value x$1
        lazy val Foo(x, y) = foo
                     ^
      Test.scala:9: error: not found: value x$1
        lazy val Foo(x, y) = foo
                        ^
      two errors found
      

        Activity

        Hide
        Paul Phillips added a comment - - edited

        Minimized.

        abstract class Cake extends Slice { }
        
        trait Slice { self: Cake =>
          import java.lang.String // any import will do!
          val Tuple2(x, y) = ((1, 2))
        }
        
        Show
        Paul Phillips added a comment - - edited Minimized. abstract class Cake extends Slice { } trait Slice { self: Cake => import java.lang.String // any import will do! val Tuple2(x, y) = ((1, 2)) }
        Hide
        Jason Zaugg added a comment - - edited

        After a little more whittling, it turns out to be a name lookup/access problem, unrelated to the pattern matcher.

        trait Cake extends Slice
        
        trait Slice { self: Cake =>    // must have self type that extends `Slice`
          private[this] val bippy = () // must be private[this]
          bippy
        }
        
        Show
        Jason Zaugg added a comment - - edited After a little more whittling, it turns out to be a name lookup/access problem, unrelated to the pattern matcher. trait Cake extends Slice trait Slice { self: Cake => // must have self type that extends `Slice` private[this] val bippy = () // must be private[this] bippy }
        Hide
        Jason Zaugg added a comment - - edited

        It hinges on the following condition in findMember:

        if (excl == 0L &&
              (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
            (bcs eq bcs0) ||
            (flags & PrivateLocal) != PrivateLocal ||
            (bcs0.head.hasTransOwner(bcs.head)))) {
        
            // this = Slice.this.type
            // bcs  = List(trait Cake, trait Slice, class Object, class Any)
            // bcs0 = List(trait Slice, class Object, class Any)
            // <Cake>.hasTransOwner(<Slice) == false
        
        Show
        Jason Zaugg added a comment - - edited It hinges on the following condition in findMember : if (excl == 0L && (// omit PRIVATE LOCALS unless selector class is contained in class owning the def. (bcs eq bcs0) || (flags & PrivateLocal) != PrivateLocal || (bcs0.head.hasTransOwner(bcs.head)))) { // this = Slice.this.type // bcs = List(trait Cake, trait Slice, class Object, class Any) // bcs0 = List(trait Slice, class Object, class Any) // <Cake>.hasTransOwner(<Slice) == false
        Hide
        Jason Zaugg added a comment -
        Show
        Jason Zaugg added a comment - Here's my proposed fix: https://github.com/retronym/scala/compare/scala:2.10.x...ticket/7507
        Show
        Jason Zaugg added a comment - https://github.com/scala/scala/pull/2609

          People

          • Assignee:
            Jason Zaugg
            Reporter:
            Eugene Burmako
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development