Skip to content

Commit 17cd752

Browse files
committed
Propagate Failures Explicitly in Opaque Type Resolution
This code should not yield the null Type() on failure. Instead, diagnose the failure and yield an ErrorType. This matches what clients of this function expect to signal failure. Include a regression test that exercises a common failure mode if we don't do this: module interface loading crashes. rdar://62745419
1 parent a6b2750 commit 17cd752

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2658,17 +2658,21 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr,
26582658
if (auto generic = dyn_cast<GenericIdentTypeRepr>(repr)) {
26592659
for (auto argRepr : generic->getGenericArgs()) {
26602660
auto argTy = resolveType(argRepr, options);
2661-
if (!argTy)
2662-
return Type();
2661+
// If we cannot resolve the generic parameter, propagate the error out.
2662+
if (!argTy || argTy->hasError()) {
2663+
return ErrorType::get(Context);
2664+
}
26632665
TypeArgsBuf.push_back(argTy);
26642666
}
26652667
}
26662668

26672669
// Use type reconstruction to summon the opaque type decl.
26682670
Demangler demangle;
26692671
auto definingDeclNode = demangle.demangleSymbol(mangledName);
2670-
if (!definingDeclNode)
2671-
return Type();
2672+
if (!definingDeclNode) {
2673+
diagnose(repr->getLoc(), diag::no_opaque_return_type_of);
2674+
return ErrorType::get(Context);
2675+
}
26722676
if (definingDeclNode->getKind() == Node::Kind::Global)
26732677
definingDeclNode = definingDeclNode->getChild(0);
26742678
ASTBuilder builder(Context);
@@ -2678,8 +2682,9 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr,
26782682

26792683
auto TypeArgs = ArrayRef<Type>(TypeArgsBuf);
26802684
auto ty = builder.resolveOpaqueType(opaqueNode, TypeArgs, ordinal);
2681-
if (!ty) {
2685+
if (!ty || ty->hasError()) {
26822686
diagnose(repr->getLoc(), diag::no_opaque_return_type_of);
2687+
return ErrorType::get(Context);
26832688
}
26842689
return ty;
26852690
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Test that we emit a diagnostic (and don't crash) when we cannot resolve
2+
// an opaque result type reference.
3+
//
4+
// First, emit an empty module interface:
5+
//
6+
// RUN: %empty-directory(%t)
7+
// RUN: echo "" | %target-swift-frontend -typecheck -emit-module-interface-path %t/InvalidOpaqueResultType.swiftinterface -enable-library-evolution -swift-version 5 -module-name InvalidOpaqueResultType -
8+
//
9+
// Then, blit some invalid opaque result types into the interface
10+
//
11+
// Test that we reject broken type parameters
12+
// RUN: echo "public typealias SomeGenericBalderdash = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) 🦸<InvalidParameter>" >> %t/InvalidOpaqueResultType.swiftinterface
13+
// Test that we reject types we cannot demangle
14+
// RUN: echo "public typealias SomesuchNonsense = @_opaqueReturnTypeOf(\"$somesuchnonsense\", 0) 🦸" >> %t/InvalidOpaqueResultType.swiftinterface
15+
//
16+
// The stage is set:
17+
//
18+
// RUN: not %target-swift-frontend -typecheck %s -I %t 2>&1 | %FileCheck %s
19+
20+
// CHECK: cannot find type 'InvalidParameter' in scope
21+
// CHECK: unable to resolve type for _opaqueReturnTypeOf attribute
22+
// CHECK: failed to build module 'InvalidOpaqueResultType' from its module interface
23+
import InvalidOpaqueResultType

0 commit comments

Comments
 (0)