Skip to content

Commit 6fb5c30

Browse files
committed
[CSDiagnostics] Contextual failure could result in optional chain having non-optional type
Fixes a crash during diagnostics by not assuming that optional chain would always produce an optional type, which is not true because in error scenarios it could get assigned an invalid type from context. Resolves: rdar://85516390
1 parent b6047e2 commit 6fb5c30

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2351,7 +2351,9 @@ bool ContextualFailure::diagnoseAsError() {
23512351
if (isExpr<OptionalTryExpr>(anchor) ||
23522352
isExpr<OptionalEvaluationExpr>(anchor)) {
23532353
auto objectType = fromType->getOptionalObjectType();
2354-
if (objectType->isEqual(toType)) {
2354+
// Cannot assume that `fromType` is always optional here since
2355+
// it could assume a type from context.
2356+
if (objectType && objectType->isEqual(toType)) {
23552357
MissingOptionalUnwrapFailure failure(getSolution(), getType(anchor),
23562358
toType,
23572359
getConstraintLocator(anchor));
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
protocol P {
4+
}
5+
6+
struct MyThing : P {
7+
var myVar: String? { "" }
8+
}
9+
10+
struct Test {
11+
func test(thing: MyThing?) -> P {
12+
return thing?.myVar
13+
// expected-error@-1 {{return expression of type 'String' does not conform to 'P'}}
14+
// expected-error@-2 {{value of optional type 'String?' must be unwrapped to a value of type 'String'}}
15+
// expected-note@-3 {{coalesce using '??' to provide a default when the optional value contains 'nil'}}
16+
// expected-note@-4 {{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
17+
}
18+
}

0 commit comments

Comments
 (0)