Files
swift-mirror/test/Constraints/iuo_objc.swift
Hamish Knight 287fa8e8de [CS] Refactor IUO handling
The current IUO design always forms a disjunction
at the overload reference, for both:

- An IUO property `T!`, forming `$T := T? or T`
- An IUO-returning function `() -> T!`, forming `$T := () -> T? or () -> T`

This is simple in concept, however it's suboptimal
for the latter case of IUO-returning functions for
a couple of reasons:

- The arguments cannot be matched independently of
  the disjunction
- There's some awkwardness when it comes e.g wrapping
  the overload type in an outer layer of optionality
  such as `(() -> T!)?`:
  - The binding logic has to "adjust" the correct
    reference type after forming the disjunction.
  - The applicable fn solving logic needs a special
    case to handle such functions.
- The CSApply logic needs various hacks such as
  ImplicitlyUnwrappedFunctionConversionExpr to
  make up for the fact that there's no function
  conversion for IUO functions, we can only force
  unwrap the function result.
  - This lead to various crashes in cases where
    we we'd fail to detect the expr and peephole
    the force unwrap.
  - This also lead to crashes where the solver
    would have a different view of the world than
    CSApply, as the former would consider an
    unwrapped IUO function to be of type `() -> T`
    whereas CSApply would correctly see the overload
    as being of type `() -> T?`.

To remedy these issues, IUO-returning functions no
longer have their disjunction formed at the overload
reference. Instead, a disjunction is formed when
matching result types for the applicable fn
constraint, using the callee locator to determine
if there's an IUO return to consider. CSApply then
consults the callee locator when finishing up
applies, and inserts the force unwraps as needed,
eliminating ImplicitlyUnwrappedFunctionConversionExpr.

This means that now all IUO disjunctions are of the
form `$T := T? or T`. This will hopefully allow a
further refactoring away from using disjunctions
and instead using type variable binding logic to
apply the correct unwrapping.

Fixes SR-10492.
2021-10-12 14:14:33 +01:00

66 lines
2.4 KiB
Swift

// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
// REQUIRES: objc_interop
import Foundation
func iuo_error(prop: IUOProperty) {
let _: Coat? = prop.iuo.optional()
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat? = prop.iuo.optional()!
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat? = prop.iuo.optional!()
let _: Coat? = prop.iuo.optional!()!
let _: Coat? = prop.iuo!.optional()
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat? = prop.iuo!.optional()!
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat? = prop.iuo!.optional!()
let _: Coat? = prop.iuo!.optional!()!
let _: Coat = prop.iuo.optional()
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat = prop.iuo.optional()!
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat = prop.iuo.optional!()
let _: Coat = prop.iuo.optional!()!
let _: Coat = prop.iuo!.optional()
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat = prop.iuo!.optional()!
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
// expected-note@-2{{coalesce}}
// expected-note@-3{{force-unwrap}}
let _: Coat = prop.iuo!.optional!()
let _: Coat = prop.iuo!.optional!()!
let _ = prop.iuo.name
}
protocol X {}
extension X where Self : OptionalRequirements {
func test() {
let _ = self.name
}
}
func rdar61337704() {
func setColor(v: ColorDescriptor) { }
let descriptor = PaletteDescriptor()
setColor(v: descriptor.colors[0]) // Ok
}