Uploaded image for project: 'Swift'
  1. Swift
  2. SR-435

Less specific method recorded in the protocol witness table

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Medium
    • Resolution: Unresolved
    • Component/s: Compiler
    • Labels:
      None

      Description

      When there are default protocol implementation, constrained protocol extension implementation, type implementation, constrained type extension implementation, of an API, which one is actually called is very confusing and some current behaviors are quite odd.

      I think:
      1. The definite dispatching rules should specified and documented.
      2. Some of current behaviors are bugs — though I'm not sure which because I'm not sure about the dispatching rules — and should fixed.

      Commented code with execution results should explain the issues more clearly:

      protocol P {
          typealias T
          
          func f()
          func g()
      }
      
      extension P {
          func f() {
              print("P.f")
          }
          
          func g() {
              print("P.g")
              f() // Should call P.Equatable.f if T is Equatable, shouldn't it?
          }
      }
      
      extension P where T: Equatable {
          func f() {
              print("P.Equatable.f") // Inaccessible to P.g? Not even to P.Equatable.g but accessible to to Foo.Equatable.g — odd.
          }
          
      //    func g() {
      //        print("P.Equatable.g")
      //        f() // Should call P.Equatable.f if T is Equatable, shouldn't it?
      //    }
      }
      
      struct Foo<U>: P {
          typealias T = U
          
      //    func g() {
      //        print("Foo.g")
      //        f()
      //    }
      }
      
      extension Foo where U: Equatable {
      //    func f() {
      //        print("Foo.Equatable.f") // Inaccessible to P.g or Foo.g? At least accessible to Foo.Equatable.g.
      //    }
          
      //    func g() {
      //        print("Foo.Equatable.g")
      //        f()
      //    }
      }
      
      let foo = Foo<Int>()
      foo.f()
      print("")
      foo.g()
      
      // Uncomment P.Equatable.g, Foo.g, Foo.Equatable.g, Foo.Equatable.f to see other behaviors.
      

      The actual output:

      P.Equatable.f
      
      P.g
      P.f
      

      The expected output:

      P.Equatable.f
      
      P.g
      P.Equatable.f
      

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              an0 Ling Wang
            • Votes:
              1 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated: