Skip to content

Commit e9266c2

Browse files
committed
Sema: Fix accepts-invalid with throwing function types
We can't unconditionally skip the conformance check if the type contains type parameters; instead, we only want to skip it in the structural resolution stage. In interface resolution stage, we proceed by mapping the type into the generic environment first.
1 parent 8400b43 commit e9266c2

File tree

3 files changed

+15
-7
lines changed

3 files changed

+15
-7
lines changed

lib/Sema/TypeCheckType.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -4233,12 +4233,15 @@ NeverNullType TypeResolver::resolveASTFunctionType(
42334233
thrownTy = resolveType(thrownTypeRepr, thrownTypeOptions);
42344234
if (thrownTy->hasError()) {
42354235
thrownTy = Type();
4236-
} else if (!options.contains(TypeResolutionFlags::SilenceErrors) &&
4237-
!thrownTy->hasTypeParameter() &&
4238-
!checkConformance(thrownTy, ctx.getErrorDecl())) {
4239-
diagnoseInvalid(
4240-
thrownTypeRepr, thrownTypeRepr->getLoc(), diag::thrown_type_not_error,
4241-
thrownTy);
4236+
} else if (inStage(TypeResolutionStage::Interface) &&
4237+
!options.contains(TypeResolutionFlags::SilenceErrors)) {
4238+
auto thrownTyInContext = GenericEnvironment::mapTypeIntoContext(
4239+
resolution.getGenericSignature().getGenericEnvironment(), thrownTy);
4240+
if (!checkConformance(thrownTyInContext, ctx.getErrorDecl())) {
4241+
diagnoseInvalid(
4242+
thrownTypeRepr, thrownTypeRepr->getLoc(), diag::thrown_type_not_error,
4243+
thrownTy);
4244+
}
42424245
}
42434246
}
42444247

test/Generics/typed_throws.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ func f2<T: P1>(_: T) where () throws(T.A) -> () == () throws -> () {}
1414

1515
protocol P2 {
1616
associatedtype A where A == () throws(E) -> ()
17-
associatedtype E
17+
associatedtype E: Error
1818
}
1919

2020
// CHECK-LABEL: typed_throws.(file).f3@

test/decl/func/typed_throws.swift

+5
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,8 @@ extension Result {
211211
}
212212
}
213213
}
214+
215+
struct NotAnError<T> {}
216+
217+
func badThrowingFunctionType<T>(_: () throws(NotAnError<T>) -> ()) {}
218+
// expected-error@-1 {{thrown type 'NotAnError<T>' does not conform to the 'Error' protocol}}

0 commit comments

Comments
 (0)