Skip to content

Can't type String as intersection with structural type with parameterless length method  #14830

Closed
@cayhorstmann

Description

@cayhorstmann

Compiler version

3.1.1

Minimized code

val a: Comparable[String] = "Fred" // OK
val b: { def length: Int } = "Fred" // OK
val c: Comparable[String] & { def length: Int } = "Fred" // Error
val d: Comparable[String] & { def length(): Int } = "Fred" // OK

Output

-- [E007] Type Mismatch Error: -------------------------------------------------
1 |val b: Comparable[String] & { def length: Int } = "Fred"
  |                                                  ^^^^^^
  |                        Found:    ("Fred" : String)
  |                        Required: Comparable[String] & Object{length: Int}

Explanation
===========

Tree: "Fred"

I tried to show that
  ("Fred" : String)
conforms to
  Comparable[String] & Object{length: Int}
but the comparison trace ended with `false`:
          
  ==> ("Fred" : String)  <:  Comparable[String] & Object{length: Int}
    ==> ("Fred" : String)  <:  Comparable[String] & Object{length: Int} (recurring)
      ==> ("Fred" : String)  <:  Comparable[String] (recurring)
        ==> Comparable[String]  <:  Comparable[String] (left is approximated)
          ==> Comparable[String]  <:  Comparable[String] (recurring)
            ==> (java.lang : java.lang.type)  <:  java.lang.type
              ==> (java.lang : java.lang.type)  <:  java.lang.type (recurring)
              <== (java.lang : java.lang.type)  <:  java.lang.type (recurring) = true
            <== (java.lang : java.lang.type)  <:  java.lang.type = true
            ==> String  <:  String
              ==> String  <:  String (recurring)
                ==> String  <:  String (recurring)
                <== String  <:  String (recurring) = true
              <== String  <:  String (recurring) = true
            <== String  <:  String = true
            ==> String  <:  String
              ==> String  <:  String (recurring)
                ==> String  <:  String (recurring)
                <== String  <:  String (recurring) = true
              <== String  <:  String (recurring) = true
            <== String  <:  String = true
          <== Comparable[String]  <:  Comparable[String] (recurring) = true
        <== Comparable[String]  <:  Comparable[String] (left is approximated) = true
      <== ("Fred" : String)  <:  Comparable[String] (recurring) = true
      ==> ("Fred" : String)  <:  Object{length: Int} (recurring)
        ==> ("Fred" : String)  <:  Object (recurring)
          ==> Object  <:  Object (left is approximated)
            ==> Object  <:  Object (recurring)
            <== Object  <:  Object (recurring) = true
          <== Object  <:  Object (left is approximated) = true
        <== ("Fred" : String)  <:  Object (recurring) = true
        ==> hasMatchingMember(("Fred" : String) . length, => Int), member = (): Int
          ==> (): Int  <:  Int
            ==> (): Int  <:  Int (recurring)
            <== (): Int  <:  Int (recurring) = false
          <== (): Int  <:  Int = false
        <== hasMatchingMember(("Fred" : String) . length, => Int), member = (): Int = false
        ==> String  <:  Object{length: Int} (left is approximated)
          ==> String  <:  Object{length: Int} (recurring)
            ==> String  <:  Object (recurring)
              ==> Object  <:  Object (left is approximated)
                ==> Object  <:  Object (recurring)
                <== Object  <:  Object (recurring) = true
              <== Object  <:  Object (left is approximated) = true
            <== String  <:  Object (recurring) = true
            ==> hasMatchingMember(String . length, => Int), member = (): Int
              ==> (): Int  <:  Int
                ==> (): Int  <:  Int (recurring)
                <== (): Int  <:  Int (recurring) = false
              <== (): Int  <:  Int = false
            <== hasMatchingMember(String . length, => Int), member = (): Int = false
          <== String  <:  Object{length: Int} (recurring) = false
        <== String  <:  Object{length: Int} (left is approximated) = false
      <== ("Fred" : String)  <:  Object{length: Int} (recurring) = false
    <== ("Fred" : String)  <:  Comparable[String] & Object{length: Int} (recurring) = false
  <== ("Fred" : String)  <:  Comparable[String] & Object{length: Int} = false

The tests were made under the empty constraint

1 error found

Expectation

Either lines 2 and 3 should both succeed, or they should both fail.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions