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

Bogus type mismatch reported against default implicit argument

    Details

      Description

      With trunk as of 2.10.0.r26093-b20111130020250 compiling the following,

      class A[T]
      class B {
        def m(a: A[this.type] = new A[this.type]) { }
      }
      
      object DefaultArgBogusTypeMismatch {
        def newB = new B
      
        newB.m()
      
        // this compiles
        // val stableB = new B
        // stableB.m()
      }
      

      Results in the error report below,

      t5259.scala:9: error: type mismatch;
       found   : A[_2.type] where val _2: B
       required: A[_1.type] where val _1: B
        newB.m()
             ^
      

      Adriaan's comment is that it shouldn't be necessary to existentially abstract over the "this" reference, which is what's causing the problem here.

        Activity

        Hide
        Lukas Rytz added a comment -

        same behavior since at least 2.8.1

        Show
        Lukas Rytz added a comment - same behavior since at least 2.8.1
        Hide
        Lukas Rytz added a comment -

        This is not so easy to fix. The invocation

        newB.m()
        

        is first transformed by named/default args to

        { val qual$1 = newB
          qual$1.m(qual$1.m$default$1)
        }
        

        In the method call qual$1.m, the qualifier tree Ident(qual$1) is created in blockWithQualifier using gen.mkAttributedRef which doesn't assign a SingleType.

        That's why the qualifier has type B instead of SingleType(qual$1). Selecting the m method therefore has an existential type

        qual$1.m: (a: A[_1.type])Unit

        Note that I applied a small change which runs the type-checker on the Select node, instead of assigning the type directly:

        -          val f = Select(gen.mkAttributedRef(sym), selected)
        -                   .setType(baseFun1.tpe).setSymbol(baseFun1.symbol)
        +          val sel = Select(gen.mkAttributedRef(sym), selected)
        +          val f = blockTyper.typedOperator(sel)
        

        Then there's the question why qual$1.m$default$1 also has an existential types, but I guess it's something along the same lines.

        Anyway, I'll stop working on this for now, it seems a very cornery case, and there's no deep underlying bad bug, it's due to the singleton this.type.

        Show
        Lukas Rytz added a comment - This is not so easy to fix. The invocation newB.m() is first transformed by named/default args to { val qual$1 = newB qual$1.m(qual$1.m$default$1) } In the method call qual$1.m , the qualifier tree Ident(qual$1) is created in blockWithQualifier using gen.mkAttributedRef which doesn't assign a SingleType . That's why the qualifier has type B instead of SingleType(qual$1) . Selecting the m method therefore has an existential type qual$1.m: (a: A[_1.type])Unit Note that I applied a small change which runs the type-checker on the Select node, instead of assigning the type directly: - val f = Select(gen.mkAttributedRef(sym), selected) - .setType(baseFun1.tpe).setSymbol(baseFun1.symbol) + val sel = Select(gen.mkAttributedRef(sym), selected) + val f = blockTyper.typedOperator(sel) Then there's the question why qual$1.m$default$1 also has an existential types, but I guess it's something along the same lines. Anyway, I'll stop working on this for now, it seems a very cornery case, and there's no deep underlying bad bug, it's due to the singleton this.type .
        Hide
        Lukas Rytz added a comment -

        Oh, I just realized that we can create an Ident tree and type-check it instead of using gen.mkAttributedRef, that should be fine in this case (it's always an Ident to a the local value). So now the question is only about qual$1.m$default$1

        Show
        Lukas Rytz added a comment - Oh, I just realized that we can create an Ident tree and type-check it instead of using gen.mkAttributedRef , that should be fine in this case (it's always an Ident to a the local value). So now the question is only about qual$1.m$default$1
        Show
        Lukas Rytz added a comment - fixed in https://github.com/scala/scala/commit/7d79c4460814c9f8997de0fa1d756a734fb8a3d3

          People

          • Assignee:
            Lukas Rytz
            Reporter:
            Miles Sabin
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development