A static member CAN be used on an instance

Given the following code:

class Parent {
  class func classFunc() {}
  func p() { classFunc() } // ⛔️ error: static member 'classFunc' cannot be used on instance of type 'Parent'


  class Child: Parent {
    func c() { classFunc() } // ⛔️ error: static member 'classFunc' cannot be used on instance of type 'Parent.Child'
  }

  class Inner {
    func i() { classFunc() } // ✅ No error?!
  }
}

The last one doesn't cause any errors.
Is this behavior expected, or some kind of bug about name lookup?

Expected behaviour. In the last example you are not calling classFunc from the instance of Parent (or a subclass of Parent) but from an instance of another class; if you try to put there self.classFunc() you'll get an error obviously, ditto if you put Self.classFunc(). It's only because the Inner class is contextually within Parent you don't need to put the explicit prefix Parent.classFunc().

2 Likes

The post explains the behavior.

Same happens in this example, hopefully slightly easier to see what's going on:

enum Color {
    case red, green, blue
}

extension Color {
    func foo() { // instance method
        let x: Color = .red // ✅ ok
        let y: Color = red  // 🛑 error
    }
}

extension Color {
    struct UnrelatedJustTextuallyInside {
        func foo() { // instance method of another type
            let x: Color = red // ✅ ok
        }
    }
}

struct UnrelatedAndTextuallyOutside {
    func foo() { // instance method of another type
        let x: Color = red // 🛑 error
    }
}

@tera @rayx
Thank you all.
I didn't notice that this is well-known behavior, and I'm sorry for creating a duplicate topic as a result. :bowing_man:

1 Like

It's fine. It's not necessarily a well known behavior. I knew it just because I happened to read that post :slight_smile: