Skip to content

Commit a9106ca

Browse files
committed
[ConstraintSystem] Account for missing unwrap(s) in call to optional Objective-C members
1 parent 448a14e commit a9106ca

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7427,6 +7427,26 @@ ConstraintSystem::simplifyApplicableFnConstraint(
74277427
// Track how many times we do this so that we can record a fix for each.
74287428
++unwrapCount;
74297429
}
7430+
7431+
// Let's account for optional members concept from Objective-C
7432+
// which forms a disjunction for member type to check whether
7433+
// it would be possible to use optional type directly or it has
7434+
// to be force unwrapped (because such types are imported as IUO).
7435+
if (unwrapCount > 0 && desugar2->is<TypeVariableType>()) {
7436+
auto *typeVar = desugar2->castTo<TypeVariableType>();
7437+
auto *locator = typeVar->getImpl().getLocator();
7438+
if (locator->isLastElement<LocatorPathElt::Member>()) {
7439+
auto *fix = ForceOptional::create(*this, origType2, desugar2,
7440+
getConstraintLocator(locator));
7441+
if (recordFix(fix, /*impact=*/unwrapCount))
7442+
return SolutionKind::Error;
7443+
7444+
// Since the right-hand side of the constraint has been changed
7445+
// we have to re-generate this constraint to use new type.
7446+
flags |= TMF_GenerateConstraints;
7447+
return formUnsolved();
7448+
}
7449+
}
74307450
}
74317451

74327452
// For a function, bind the output and convert the argument to the input.

test/Constraints/iuo_objc.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,29 @@ func iuo_error(prop: IUOProperty) {
99
// expected-note@-2{{coalesce}}
1010
// expected-note@-3{{force-unwrap}}
1111
let _: Coat? = prop.iuo.optional()!
12-
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
12+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
13+
// expected-note@-2{{coalesce}}
14+
// expected-note@-3{{force-unwrap}}
1315
let _: Coat? = prop.iuo.optional!()
1416
let _: Coat? = prop.iuo.optional!()!
1517
let _: Coat? = prop.iuo!.optional()
1618
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped}}
1719
// expected-note@-2{{coalesce}}
1820
// expected-note@-3{{force-unwrap}}
1921
let _: Coat? = prop.iuo!.optional()!
20-
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
22+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
23+
// expected-note@-2{{coalesce}}
24+
// expected-note@-3{{force-unwrap}}
2125
let _: Coat? = prop.iuo!.optional!()
2226
let _: Coat? = prop.iuo!.optional!()!
2327
let _: Coat = prop.iuo.optional()
2428
// expected-error@-1 {{value of optional type '(() -> Coat)?' must be unwrapped}}
2529
// expected-note@-2{{coalesce}}
2630
// expected-note@-3{{force-unwrap}}
2731
let _: Coat = prop.iuo.optional()!
28-
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
32+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
33+
// expected-note@-2{{coalesce}}
34+
// expected-note@-3{{force-unwrap}}
2935
let _: Coat = prop.iuo.optional!()
3036
let _: Coat = prop.iuo.optional!()!
3137
let _: Coat = prop.iuo!.optional()
@@ -34,7 +40,9 @@ func iuo_error(prop: IUOProperty) {
3440
// expected-note@-3{{force-unwrap}}
3541

3642
let _: Coat = prop.iuo!.optional()!
37-
// expected-error@-1 {{cannot invoke 'optional' with no arguments}}
43+
// expected-error@-1 {{value of optional type '(() -> Coat?)?' must be unwrapped to a value of type '() -> Coat?'}}
44+
// expected-note@-2{{coalesce}}
45+
// expected-note@-3{{force-unwrap}}
3846
let _: Coat = prop.iuo!.optional!()
3947
let _: Coat = prop.iuo!.optional!()!
4048

0 commit comments

Comments
 (0)