Skip to content

Commit b312615

Browse files
authored
Merge pull request swiftlang#31484 from CodaFi/opaque-results-may-vary
Propagate Failures Explicitly in Opaque Type Resolution
2 parents b196ee9 + fb8e23e commit b312615

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
@@ -2657,17 +2657,21 @@ Type TypeResolver::resolveOpaqueReturnType(TypeRepr *repr,
26572657
if (auto generic = dyn_cast<GenericIdentTypeRepr>(repr)) {
26582658
for (auto argRepr : generic->getGenericArgs()) {
26592659
auto argTy = resolveType(argRepr, options);
2660-
if (!argTy)
2661-
return Type();
2660+
// If we cannot resolve the generic parameter, propagate the error out.
2661+
if (!argTy || argTy->hasError()) {
2662+
return ErrorType::get(Context);
2663+
}
26622664
TypeArgsBuf.push_back(argTy);
26632665
}
26642666
}
26652667

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

26782682
auto TypeArgs = ArrayRef<Type>(TypeArgsBuf);
26792683
auto ty = builder.resolveOpaqueType(opaqueNode, TypeArgs, ordinal);
2680-
if (!ty) {
2684+
if (!ty || ty->hasError()) {
26812685
diagnose(repr->getLoc(), diag::no_opaque_return_type_of);
2686+
return ErrorType::get(Context);
26822687
}
26832688
return ty;
26842689
}
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)