Skip to content

Commit 122020e

Browse files
committed
[Sema] Ban opaque types in parameter position.
1 parent 9196c9a commit 122020e

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

Diff for: include/swift/AST/DiagnosticsSema.def

+4
Original file line numberDiff line numberDiff line change
@@ -4865,6 +4865,10 @@ ERROR(opaque_type_unsupported_pattern,none,
48654865
ERROR(opaque_type_in_protocol_requirement,none,
48664866
"'some' type cannot be the return type of a protocol requirement; did you mean to add an associated type?",
48674867
())
4868+
ERROR(opaque_type_in_parameter,none,
4869+
"'some' cannot appear in parameter position in result "
4870+
"type %0",
4871+
(Type))
48684872

48694873
// Function differentiability
48704874
ERROR(attr_only_on_parameters_of_differentiable,none,

Diff for: lib/Sema/TypeCheckGeneric.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,28 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
277277
/*unboundTyOpener*/ nullptr,
278278
/*placeholderHandler*/ nullptr)
279279
.resolveType(repr);
280+
281+
// Opaque types cannot be used in parameter position.
282+
Type desugared = interfaceType->getDesugaredType();
283+
bool hasError = desugared.findIf([&](Type type) -> bool {
284+
if (auto *fnType = type->getAs<FunctionType>()) {
285+
for (auto param : fnType->getParams()) {
286+
if (!param.getPlainType()->hasOpaqueArchetype())
287+
continue;
288+
289+
ctx.Diags.diagnose(repr->getLoc(),
290+
diag::opaque_type_in_parameter,
291+
interfaceType);
292+
return true;
293+
}
294+
}
295+
296+
return false;
297+
});
298+
299+
if (hasError)
300+
return nullptr;
301+
280302
auto metatype = MetatypeType::get(interfaceType);
281303
opaqueDecl->setInterfaceType(metatype);
282304
return opaqueDecl;

Diff for: test/type/opaque_return_structural.swift

+11
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,14 @@ func structuralMemberLookupBad() {
8585
tup.0.paul();
8686
tup.0.d(); // expected-error{{value of type 'some P' has no member 'd'}}
8787
}
88+
89+
// expected-error@+1 {{'some' cannot appear in parameter position in result type '(some P) -> Void'}}
90+
func opaqueParameter() -> (some P) -> Void {}
91+
92+
// expected-error@+1 {{'some' cannot appear in parameter position in result type '((some P) -> Void) -> Void'}}
93+
func opaqueParameter() -> ((some P) -> Void) -> Void {}
94+
95+
typealias Takes<T> = (T) -> Void
96+
97+
// expected-error@+1 {{'some' cannot appear in parameter position in result type 'Takes<some P>' (aka '(some P) -> ()')}}
98+
func indirectOpaqueParameter() -> Takes<some P> {}

0 commit comments

Comments
 (0)