Details

      Description

      [minimized from the original report]

      abstract class Template[T <: AnyRef](private val t: T) {
      
        type Repr[T]<:Template[T]
      
        def withTimeout(timeout:Long): Repr[T] = this.asInstanceOf[Repr[T]]
        def withReadModifiers(readModifiers:Int): Repr[T] = this.asInstanceOf[Repr[T]]
      }
      
      class Curve
      
      class CurveTemplate [T <: Curve](t: T) extends Template(t) {
        type Repr = CurveTemplate[T]
      }
      
      
      object Example {
       new CurveTemplate(new Curve).withTimeout(2000L).withReadModifiers(0)
      }
      
      1. ReadModifiers.java
        0.6 kB
        Edmondo Porcu
      2. Template.scala
        1.0 kB
        Edmondo Porcu

        Activity

        Hide
        Edmondo Porcu added a comment -

        Curiously, the problem seems to be introduced by the cast to the abstract type.

        If the abstract type is replaced by an extra generic parameter, everything works fine and compile

        Show
        Edmondo Porcu added a comment - Curiously, the problem seems to be introduced by the cast to the abstract type. If the abstract type is replaced by an extra generic parameter, everything works fine and compile
        Hide
        A. P. Marki added a comment -

        The useful error messages can be elicited by speaking very slowly to scalac (or by commenting the expression entirely):

            /*
        porcu.scala:5: error: type arguments [T] do not conform to class Template's type parameter bounds [T <: Object]
          type Repr[T]<:Template[T]
                        ^
        porcu.scala:42: error: overriding type Repr in class Template with bounds[T] <: gist2427426.Template[T];
         type Repr has incompatible type
          type Repr = CurveTemplate[T]
               ^
        two errors found
            */
        
        // in the attached code
        object Example {
          def main(args:Array[String]) ={
            /*
            val template = new CurveTemplate(new Curve).withTimeout(2000L).withReadModifiers(ReadModifiers.DIRTY_READ).resolve
            println(template)
            */
            /*
            val a = new CurveTemplate(new Curve)
            val b = a.withTimeout(2000L)
        // This is not yet germane
            //error: value withReadModifiers is not a member of a.Repr[gist2427426.Curve]
            val c = b.withReadModifiers(ReadModifiers.DIRTY_READ)
            val d = c.resolve
            println(d)
            */
            val a: CurveTemplate[Curve] = new CurveTemplate(new Curve)
            val b: CurveTemplate[Curve] = a.withTimeout(2000L)
            val c: CurveTemplate[Curve] = b.withReadModifiers(ReadModifiers.DIRTY_READ)
            val d = c.resolve
            println(d)
          }
        }
        
        Show
        A. P. Marki added a comment - The useful error messages can be elicited by speaking very slowly to scalac (or by commenting the expression entirely): /* porcu.scala:5: error: type arguments [T] do not conform to class Template's type parameter bounds [T <: Object] type Repr[T]<:Template[T] ^ porcu.scala:42: error: overriding type Repr in class Template with bounds[T] <: gist2427426.Template[T]; type Repr has incompatible type type Repr = CurveTemplate[T] ^ two errors found */ // in the attached code object Example { def main(args:Array[String]) ={ /* val template = new CurveTemplate(new Curve).withTimeout(2000L).withReadModifiers(ReadModifiers.DIRTY_READ).resolve println(template) */ /* val a = new CurveTemplate(new Curve) val b = a.withTimeout(2000L) // This is not yet germane //error: value withReadModifiers is not a member of a.Repr[gist2427426.Curve] val c = b.withReadModifiers(ReadModifiers.DIRTY_READ) val d = c.resolve println(d) */ val a: CurveTemplate[Curve] = new CurveTemplate(new Curve) val b: CurveTemplate[Curve] = a.withTimeout(2000L) val c: CurveTemplate[Curve] = b.withReadModifiers(ReadModifiers.DIRTY_READ) val d = c.resolve println(d) } }
        Hide
        Edmondo Porcu added a comment -

        I am bit able to get the compiler error with 2.9.1 because the compiler crashes. What did you do to get the error message?

        Show
        Edmondo Porcu added a comment - I am bit able to get the compiler error with 2.9.1 because the compiler crashes. What did you do to get the error message?
        Hide
        Hubert Plociniczak added a comment -

        Note that you will get the correct error message if you comment out everything apart from Template class.
        This is because checking the bounds is done during refchecks.

        new CurveTemplate(new Curve).withTimeout(2000L)
        

        will need to perform dealiasing in order to get the type of withTimeout (again before Refchecks) and that will simply have ErrorType as a result type, which already gives you pretty uninformative error message.
        Now, if you additionally call on the result

        ... .withReadModifiers(...)
        

        it is just getting lost and crashes after typers. So either we will be checking the bounds earlier or basically we defer this check until refchecks.
        I have a solution for that, but it needs a bit more testing.

        Show
        Hubert Plociniczak added a comment - Note that you will get the correct error message if you comment out everything apart from Template class. This is because checking the bounds is done during refchecks. new CurveTemplate(new Curve).withTimeout(2000L) will need to perform dealiasing in order to get the type of withTimeout (again before Refchecks) and that will simply have ErrorType as a result type, which already gives you pretty uninformative error message. Now, if you additionally call on the result ... .withReadModifiers(...) it is just getting lost and crashes after typers. So either we will be checking the bounds earlier or basically we defer this check until refchecks. I have a solution for that, but it needs a bit more testing.
        Hide
        Hubert Plociniczak added a comment -

        Bumping to critical, I want to fix this for 2.10. #811 contains a fix but it needs a bit more work.

        Show
        Hubert Plociniczak added a comment - Bumping to critical, I want to fix this for 2.10. #811 contains a fix but it needs a bit more work.
        Show
        Adriaan Moors added a comment - https://github.com/scala/scala/pull/1087

          People

          • Assignee:
            Hubert Plociniczak
            Reporter:
            Edmondo Porcu
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development