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

Overridden class function with generic constraint causes unsafe behavior

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Medium
    • Resolution: Duplicate
    • Component/s: Compiler
    • Labels:
    • Environment:

      Xcode 9.3, tested in a playground.

      Description

      Class C defines a function f. Class D overrides it, but has a different generic constraint. Calling f from an instance of C using type(of:) type-checks as though C.f will be called, but at runtime D.f is called.

      class C<T> {
          
          let t: T
          
          init(t: T) {
              self.t = t
              type(of: self).f()(self)
          }
          
          class func f<U>() -> (U) -> () where U: C  {
              return { (u: U) in
                  print(u.t)
              }
          }
      }
      
      class E {
          let g = "Expected to Print"
      }
      
      class D: C<E> {
          override class func f<U>() -> (U) -> () where U: E {
              return { (u: E) in
                  print(u.g)
              }
          }
      }
      
      let d = D(t: E()) // prints random garbage
      

      Because D.f tries to access a member of E, the program reads random memory, leading to undefined behavior.

      As an aside, the ability to tighten type constraints on overrides is actually very useful in the context of the code I was working on when I discovered this. I'd like to be able to write things like var functionToRunWhenSomethingChanges: (Self, Context) -> (), which creates similar issues to this when used in the context of classes. So my solution was to make var functionToRunWhenSomethingChanges: (Any, Context) -> (), and have a setFunctionToRunWhenSomethingChanges<T>(on subject: T, _ function: (T, Context) -> ()), which ensures that things are still type safe. So It's useful to be able to add generic constraints that require that a particular class func only works for subclasses of the type that it's implemented for. Hopefully when/if this is fixed it's still possible to do that.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              Unassigned Unassigned
              Reporter:
              benpious Ben Pious
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: