Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: Scala 2.10.0
    • Component/s: Misc Compiler
    • Labels:
    • Environment:

      type checker, singleton type, widening, dependent method types

      Description

      I expected the following code to compile:

      trait Foo {
        type Arg
        type Prod
        def makeProd(a : Arg): Prod
      }
      
      // simulate dependent method types
      case class buildProd(foo: Foo) {
        def apply(a: foo.Arg): foo.Prod = foo.makeProd(a)
      }
      
      object main {
        val myFoo = new Foo{type Arg=Int; type Prod=(Int, Int); def makeProd(i: Int) = (i, i)}
        
        buildProd(myFoo)(1)
      }
      

      Instead, the compiler complains:

      15: error: method apply cannot be accessed in buildProd
       because its instance type (Foo#Arg)Foo#Prod contains a malformed type: Foo#Arg
        buildProd(myFoo)(1)
                 ^
      one error found
      

      It seems foo.type gets approximated to Foo too early..

        Activity

        Hide
        Martin Odersky added a comment -

        This would require dependent method types. They are not currently in Scala. I'll keep the ticket open as a request for enhancement.

        Show
        Martin Odersky added a comment - This would require dependent method types. They are not currently in Scala. I'll keep the ticket open as a request for enhancement.
        Hide
        Adriaan Moors added a comment -

        I fiddled with this some more, and adding a type parameter `TFoo` to buildProd is enough to get the program to type check. This makes me think the original problem is not directly related to dependent method types (in fact, it encodes them, but I don't think it uses them).

        case class buildProd[TFoo <: Foo](foo: TFoo) {  // now it works
          def apply(a: foo.Arg): foo.Prod = foo.makeProd(a)
        }
        
        Show
        Adriaan Moors added a comment - I fiddled with this some more, and adding a type parameter `TFoo` to buildProd is enough to get the program to type check. This makes me think the original problem is not directly related to dependent method types (in fact, it encodes them, but I don't think it uses them). case class buildProd[TFoo <: Foo](foo: TFoo) { // now it works def apply(a: foo.Arg): foo.Prod = foo.makeProd(a) }
        Hide
        Martin Odersky added a comment -

        But don't you need to parameterize the call also, as in:

           buildProd[myFoo.tpe](myFoo)
        

        ?

        Show
        Martin Odersky added a comment - But don't you need to parameterize the call also, as in: buildProd[myFoo.tpe](myFoo) ?
        Hide
        Adriaan Moors added a comment -

        Replying to [comment:3 odersky]:
        > But don't you need to parameterize the call also, as in:

            buildProd[myFoo.tpe](myFoo)
         }}
        > ?
        In a more complicated example, yes -- here, the following is inferred (-Xprint:typer):
        

        buildProd[java.lang.Object with Foo

        {type Arg = Int; type Prod = (Int, Int)}

        ](main.this.myFoo).apply(1)

        Show
        Adriaan Moors added a comment - Replying to [comment:3 odersky] : > But don't you need to parameterize the call also, as in: buildProd[myFoo.tpe](myFoo) }} > ? In a more complicated example, yes -- here, the following is inferred (-Xprint:typer): buildProd[java.lang.Object with Foo {type Arg = Int; type Prod = (Int, Int)} ](main.this.myFoo).apply(1)
        Hide
        Martin Odersky added a comment -

        Milestone postponed deleted

        Show
        Martin Odersky added a comment - Milestone postponed deleted
        Hide
        Simon Ochsenreither added a comment -

        In 2.10.0.r24516-b20110320020044 it has changed to just a type mismatch:

        scala>   buildProd(myFoo)(1)
        <console>:12: error: type mismatch;
         found   : Int(1)
         required: _4.foo.Arg where val _4: buildProd
                 buildProd(myFoo)(1)
                                  ^
        
        Show
        Simon Ochsenreither added a comment - In 2.10.0.r24516-b20110320020044 it has changed to just a type mismatch: scala> buildProd(myFoo)(1) <console>:12: error: type mismatch; found : Int(1) required: _4.foo.Arg where val _4: buildProd buildProd(myFoo)(1) ^
        Hide
        Paul Phillips added a comment -

        I'm adding a test and closing this; if someone thinks there is an interesting space between what the test accomplishes and what we should be accomplishing, go ahead and reopen it.

        Show
        Paul Phillips added a comment - I'm adding a test and closing this; if someone thinks there is an interesting space between what the test accomplishes and what we should be accomplishing, go ahead and reopen it.
        Hide
        Commit Message Bot added a comment -

        (extempore in r25907) Test case closes SI-102.

        No review.

        Show
        Commit Message Bot added a comment - (extempore in r25907 ) Test case closes SI-102 . No review.

          People

          • Assignee:
            Martin Odersky
            Reporter:
            Adriaan Moors
            TracCC:
            Simon Ochsenreither
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development