Skip to content

Commit 182c9e9

Browse files
authored
Merge pull request #61267 from xedin/rdar-100066109
[MiscDiagnostics] OpaqueChecker: Double-check validity of last expres…
2 parents f4e2d25 + 1c0e887 commit 182c9e9

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-14
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2718,20 +2718,28 @@ class OpaqueUnderlyingTypeChecker : public ASTWalker {
27182718
auto element = Body->getLastElement();
27192719
// Let's see if the last statement would make for a valid return value.
27202720
if (auto expr = element.dyn_cast<Expr *>()) {
2721-
bool conforms = llvm::all_of(OpaqueDecl->getOpaqueInterfaceGenericSignature().getRequirements(),
2722-
[&expr, this](auto requirement) {
2723-
if (requirement.getKind() == RequirementKind::Conformance) {
2724-
auto conformance =
2725-
TypeChecker::conformsToProtocol(expr->getType()->getRValueType(),
2726-
requirement.getProtocolDecl(),
2727-
Implementation->getModuleContext(),
2728-
/*allowMissing=*/ false);
2729-
return !conformance.isInvalid();
2730-
}
2731-
// If we encounter any requirements other than `Conformance`, we do
2732-
// not attempt to type check the expression.
2733-
return false;
2734-
});
2721+
auto exprType = expr->getType();
2722+
// Function body might not be valid and we cannot reply on
2723+
// \c typeCheckStmt here to propagate HadError because its
2724+
// unreliable.
2725+
if (!exprType || exprType->hasError())
2726+
return;
2727+
2728+
bool conforms = llvm::all_of(
2729+
OpaqueDecl->getOpaqueInterfaceGenericSignature()
2730+
.getRequirements(),
2731+
[&exprType, this](auto requirement) {
2732+
if (requirement.getKind() == RequirementKind::Conformance) {
2733+
auto conformance = TypeChecker::conformsToProtocol(
2734+
exprType->getRValueType(), requirement.getProtocolDecl(),
2735+
Implementation->getModuleContext(),
2736+
/*allowMissing=*/false);
2737+
return !conformance.isInvalid();
2738+
}
2739+
// If we encounter any requirements other than `Conformance`, we
2740+
// do not attempt to type check the expression.
2741+
return false;
2742+
});
27352743

27362744
// If all requirements are fulfilled, we offer to insert `return` to
27372745
// fix the issue.

test/type/opaque.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,4 +571,10 @@ do {
571571
let x = S2()
572572
x // expected-warning {{expression of type 'S2' is unused}}
573573
}
574+
575+
func test5() -> some P1 {
576+
// expected-error@-1 {{function declares an opaque return type, but has no return statements in its body from which to infer an underlying type}}
577+
let x = invalid // expected-error {{cannot find 'invalid' in scope}}
578+
x
579+
}
574580
}

0 commit comments

Comments
 (0)