본문으로 건너뛰기

Swift 6.4에서 괄호 없이 쓰는 some View?와 any 프로토콜 타입

some View? without parentheses in Swift 6.4

sarunw.com

핵심 요약

  1. Swift 6.4의 SE-0521은 타입 뒤의 ?와 !가 some 또는 any 타입 전체에 적용되도록 해, some P?를 (some P)?로 해석한다.
  2. 단일 프로토콜 existential에서는 any P?가 (any P)?와 같은 타입이며, 기존 괄호 표기도 유지돼 마이그레이션이나 ABI 변경이 필요하지 않다.
  3. 프로토콜 조합은 여전히 괄호가 필요하다. ExistentialAny를 적용할 때 단일 프로토콜의 선택적 타입에는 any P? 형태의 fix-it이 제공된다.

도입

기존 Swift 타입 파서에서는 ?가 some과 any보다 우선순위가 높았다. 그래서 some View?는 (some View)?가 아니라 some (View?)로 해석됐고, Optional이 프로토콜이 아닌 구조체이므로 컴파일 오류가 발생했다. Swift 6.4에 도입된 SE-0521은 뒤에 붙는 ?와 !를 some 또는 any 타입 전체에 적용하도록 파서 규칙을 바꾼다.

상세 요약

기존 문법에서 괄호가 필요했던 이유

Swift 6.4의 SE-0521은 some과 any 타입 뒤에 붙는 ? 또는 !가 타입 전체에 적용되도록 파서 규칙을 바꾼다. 이전에는 타입 파서에서 ?가 some과 any보다 우선순위가 높았다. 따라서 some View?는 (some View)?가 아니라 some (View?)로 해석됐다. View?는 Optional<View>이고 Optional은 프로토콜이 아닌 구조체이므로 컴파일러가 이 타입을 거부했다.

같은 문제는 existential에도 있었다. 선택적 delegate를 선언하려면 any ScannerDelegate? 대신 (any ScannerDelegate)?처럼 괄호를 써야 했다. 괄호는 타입 의미를 구별하기 위해서가 아니라 파서가 의도한 범위를 읽도록 하기 위해 필요했다.

Swift 6.4에서 달라지는 표기

파서는 이제 뒤에 오는 ?와 !를 some 또는 any 타입 전체에 적용한다. 따라서 다음 표현은 각각 괄호를 쓴 형태와 같은 의미다.

  • some View?와 (some View)?
  • any ScannerDelegate?와 (any ScannerDelegate)?
  • any ScannerDelegate!와 (any ScannerDelegate)!
  • any ~Copyable?

기존 괄호 표기는 계속 유효하다. 괄호를 쓴 형태와 쓰지 않은 형태는 mangled name까지 같은 타입이므로 코드를 마이그레이션할 필요가 없고 ABI 영향도 없다.

프로토콜 조합은 예외

any Codable & Sendable?는 여전히 사용할 수 없다. 프로토콜 조합 뒤에 붙은 ?가 조합 전체에 적용되는 것으로 파서가 읽을 수는 있지만, 조합이 길어질 때 범위를 오해하기 쉽기 때문이다. 조합 타입을 선택적으로 만들려면 any (Codable & Sendable)? 또는 (any Codable & Sendable)?처럼 괄호를 사용해야 한다. 제안은 이후 이 규칙을 완화하더라도 기존 코드와 충돌하지 않는다고 설명한다.

ExistentialAny와 fix-it

Swift는 existential 타입에 any를 명시하도록 바뀌고 있다. 현재 ScannerDelegate?처럼 any 없이 쓸 수 있는 선언도 ExistentialAny upcoming feature를 활성화하면 경고를 내며, 향후 언어 모드에서는 오류가 된다. 기존 방식으로 전환하면 optional protocol 프로퍼티마다 any뿐 아니라 괄호도 추가해야 했다.

컴파일러의 fix-it도 바뀐다. -enable-upcoming-feature ExistentialAny를 사용했을 때 let x: P?에 제안하는 수정은 기존 (any P)?에서 any P?로 변경된다. 이 동작은 단일 프로토콜의 optional 또는 implicitly unwrapped existential에 적용되며, 프로토콜 조합에는 괄호가 필요하다.

Swift 6.4의 관련 변경은 Swift 6.4 출시: Swift Build 기본 적용과 상호운용성·메모리 안전성 개선에서도 확인할 수 있다.

결론

단일 프로토콜 타입은 이제 any P?처럼 쓸 수 있고, 기존의 (any P)? 표기도 같은 타입과 mangled name을 유지하므로 코드를 당장 수정할 필요가 없다. 다만 프로토콜 조합은 읽기 쉬움을 위해 괄호를 유지해야 한다. 이 변경은 ExistentialAny에 맞춰 any를 추가할 때 단일 프로토콜의 선택적 타입을 불필요한 괄호 없이 표현하도록 fix-it도 정리한다.