Skip to content

Commit 7991c66

Browse files
committed
[SE-0341]: Disable use of opaque parameters in consuming positions.
Based on the review discussion of this proposal, prohibit the use of opaque parameters in "consuming" positions of function types, as we did with opaque result types in SE-0328.
1 parent 5cda4f4 commit 7991c66

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4997,9 +4997,9 @@ ERROR(opaque_type_in_protocol_requirement,none,
49974997
"'some' type cannot be the return type of a protocol requirement; did you mean to add an associated type?",
49984998
())
49994999
ERROR(opaque_type_in_parameter,none,
5000-
"'some' cannot appear in parameter position in result "
5001-
"type %0",
5002-
(Type))
5000+
"'some' cannot appear in parameter position in %select{result|parameter}0"
5001+
" type %1",
5002+
(bool, Type))
50035003

50045004
// Function differentiability
50055005
ERROR(attr_only_on_parameters_of_differentiable,none,

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3251,6 +3251,44 @@ void TypeChecker::checkParameterList(ParameterList *params,
32513251
}
32523252
}
32533253

3254+
// Opaque types cannot occur in parameter position.
3255+
Type interfaceType = param->getInterfaceType();
3256+
if (interfaceType->hasTypeParameter()) {
3257+
interfaceType.findIf([&](Type type) {
3258+
if (auto fnType = type->getAs<FunctionType>()) {
3259+
for (auto innerParam : fnType->getParams()) {
3260+
auto paramType = innerParam.getPlainType();
3261+
if (!paramType->hasTypeParameter())
3262+
continue;
3263+
3264+
bool hadError = paramType.findIf([&](Type innerType) {
3265+
auto genericParam = innerType->getAs<GenericTypeParamType>();
3266+
if (!genericParam)
3267+
return false;
3268+
3269+
auto genericParamDecl = genericParam->getDecl();
3270+
if (!genericParamDecl)
3271+
return false;
3272+
3273+
if (!genericParamDecl->isOpaqueType())
3274+
return false;
3275+
3276+
param->diagnose(
3277+
diag::opaque_type_in_parameter, true, interfaceType);
3278+
return true;
3279+
});
3280+
3281+
if (hadError)
3282+
return true;
3283+
}
3284+
3285+
return false;
3286+
}
3287+
3288+
return false;
3289+
});
3290+
}
3291+
32543292
if (param->hasAttachedPropertyWrapper())
32553293
(void) param->getPropertyWrapperInitializerInfo();
32563294

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ OpaqueResultTypeRequest::evaluate(Evaluator &evaluator,
274274

275275
ctx.Diags.diagnose(repr->getLoc(),
276276
diag::opaque_type_in_parameter,
277-
interfaceType);
277+
false, interfaceType);
278278
return true;
279279
}
280280
}

test/type/opaque_parameters.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,10 @@ func testPrimaries(
102102
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfInts)
103103
_ = takeMatchedPrimaryCollections(arrayOfInts, setOfStrings) // expected-error{{type of expression is ambiguous without more context}}
104104
}
105+
106+
107+
// Prohibit use of opaque parameters in consuming positions.
108+
typealias FnType<T> = (T) -> Void
109+
110+
func consumingA(fn: (some P) -> Void) { } // expected-error{{'some' cannot appear in parameter position in parameter type '(some P) -> Void'}}
111+
func consumingB(fn: FnType<some P>) { } // expected-error{{'some' cannot appear in parameter position in parameter type '(some P) -> Void'}}

0 commit comments

Comments
 (0)