Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler doesn't recognize a method in a private extension as private

Tags:

I have the following piece of code:

class C {
    private enum E {
        // ...
    }
}

private extension C {
    func f(e: E) {    // error: Method must be declared private because its parameter uses a private type
        // ...
    }
}

If I make the erroring method private, the compiler error disappears. I'm wondering whether it's a bug in Swift or I'm not getting something?

like image 289
Artem Stepanenko Avatar asked Aug 09 '18 14:08

Artem Stepanenko


1 Answers

At the top level, private is equivalent to fileprivate – as private means only accessible within the enclosing scope (and also same-file extensions), and at the top level, the file is that scope.

So what you have here is equivalent to:

class C {
    private enum E {
        // ...
    }
}

fileprivate extension C {
    // error: Method must be declared private because its parameter uses a private type.
    func f(e: E) { 
        // ...
    }
}

(and for this reason, I always write fileprivate instead of private at the top level for clarity)

which makes the issue slightly easier to understand – the extension method f is by default fileprivate and therefore accessible within the scope of the entire file, but its parameter is typed as E, which is only accessible within the scope of the class C.

As you've discovered, you could mark f as private:

class C {
  private enum E {
    // ...
  }
}

fileprivate extension C {
  private func f(e: E) {
    // ...
  }
}

or alternatively mark E as fileprivate:

class C {
  fileprivate enum E {
    // ...
  }
}

fileprivate extension C {
  func f(e: E) {
    // ...
  }
}

in order to resolve the issue such that the extension method f has the same visibility as its parameter type E.

like image 104
Hamish Avatar answered Oct 12 '22 07:10

Hamish