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:
            8 Start watching this issue

              Dates

              Created:
              Updated: