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

Typealias in constrained extension misinterprets the where clause

    XMLWordPrintable

    Details

      Description

      The following seemingly invalid program compiles ( ! ), and the result is the same as if the where-clauses had been removed, so it seems like typealiases added in constrained extensions ignores the constraint:

      struct S<T> {
          var v: (A, B, C)
      }
      extension S where T == Int {
          typealias A = Int
      }
      extension S where T == Bool {
          typealias B = Bool
      }
      extension S where T == Float {
          typealias C = Float
      }
      print(S<String>.A.self) // Int
      print(S<String>.B.self) // Bool
      print(S<String>.C.self) // Float
      print(S<Double>.A.self) // Int
      print(S<Double>.B.self) // Bool
      print(S<Double>.C.self) // Float
      

      The same is true when using a protocol instead of a struct:

      protocol P {
          associatedtype Q
          var v: (D, E, F) { get }
      }
      extension P where Q == Int {
          typealias D = Int
      }
      extension P where Q == Bool {
          typealias E = Bool
      }
      extension P where Q == Float {
          typealias F = Float
      }
      struct R<T> : P {
          typealias Q = T
          var v: (D, E, F)
      }
      print(R<String>.D.self) // Int
      print(R<String>.E.self) // Bool
      print(R<String>.F.self) // Float
      print(R<Double>.D.self) // Int
      print(R<Double>.E.self) // Bool
      print(R<Double>.F.self) // Float
      

      UPDATE:
      As the following program shows, it seems like the where-clause is actually misinterpreted rather than ignored:

      // typealias misinterprets where clause of extension
      
      struct S<A> {
          var hmm: (A, B, C)
      }
      extension S where A == Bool {
          typealias B = A
          static func printB() { print(B.self) }
      }
      extension S where A == Float {
          typealias C = A
          static func printC() { print(C.self) }
      }
      let a = S(hmm: ("strange", true, Float(42.1)))
      dump(a)
      // Will print:
      ▿ TestXc9b3.S<Swift.String>
        ▿ hmm: (3 elements)
          - .0: "strange"
          - .1: true
          - .2: 42.0999985
      

      Note: I have only used (a single) same-type constraint (eg A == Float) in the where-clause here, but there are similar problems when constraining to protocol types (eg A: FloatingPoint).

      Tested in Xcode 9 beta 3, same behavior in default toolchain and dev snapshot 2017-07-12.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              slavapestov Slava Pestov
              Reporter:
              jens Jens Persson
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: