Cannot override a type with non-volatile upper bound

后端 未结 3 1799
一个人的身影
一个人的身影 2020-12-31 13:30


I have a compiler error in scala and I don\'t know what does it refer to:
Assume these declarations:

trait Abstract {
  type MyType
}
trait AInner
trait         


        
3条回答
  •  梦谈多话
    2020-12-31 14:20

    Removing this check in the compiler lets us shine a light on the potential for unsoundness.

    diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
    index 37a7e3c..78a8959 100644
    --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
    +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
    @@ -5128,8 +5128,7 @@ trait Typers extends Adaptations with Tags {
    
           def typedSelectFromTypeTree(tree: SelectFromTypeTree) = {
             val qual1 = typedType(tree.qualifier, mode)
    -        if (qual1.tpe.isVolatile) TypeSelectionFromVolatileTypeError(tree, qual1)
    -        else typedSelect(tree, qual1, tree.name)
    +        typedSelect(tree, qual1, tree.name)
           }
    
           def typedTypeBoundsTree(tree: TypeBoundsTree) = {
    

    Then, running the code from a compiler test case for illegal type selection for volatile types:

    scala> class A; class B extends A
    defined class A
    defined class B
    
    scala> trait C {
         |   type U
         |   trait D { type T >: B <: A }
         |   val y: (D with U)#T = new B
         | }
    defined trait C
    
    scala> class D extends C {
         |   trait E
         |   trait F { type T = E }
         |   type U = F
         |   def frob(arg : E) : E = arg
         |   frob(y)
         | }
    defined class D
    
    scala> new D
    java.lang.ClassCastException: B cannot be cast to D$E
    

    As I understand it, the issue stems from the fact that Scala doesn't have true intersection types.

    scala> type A = { type T = Int }
    defined type alias A
    
    scala> type B = { type T = String }
    defined type alias B
    
    scala> "": (A with B)#T
    res16: String = ""
    
    scala> 0: (A with B)#T
    :37: error: type mismatch;
     found   : Int(0)
     required: String
                  0: (A with B)#T
                  ^
    

    This might change in the future, if the research into Dependent Object Types (DOT) bears fruit.

提交回复
热议问题