[Sema] Produce better diagnostics when using inout on parameter types that cannot be 'inout'. Resolves #68417

This commit is contained in:
Minhyuk Kim
2023-09-12 23:32:17 +09:00
parent 7eac199984
commit d9a03dda17
3 changed files with 20 additions and 3 deletions

View File

@@ -3685,6 +3685,9 @@ ERROR(attr_not_on_variadic_parameters,none,
"'%0' must not be used on variadic parameters", (StringRef))
ERROR(attr_not_on_subscript_parameters,none,
"'%0' must not be used on subscript parameters", (StringRef))
ERROR(attr_not_on_enum_case_parameters,none,
"'%0' must not be used on enum case parameters", (StringRef))
ERROR(attr_not_on_stored_properties,none,
"'%0' must not be used on stored properties", (DeclAttribute))

View File

@@ -4294,19 +4294,26 @@ TypeResolver::resolveOwnershipTypeRepr(OwnershipTypeRepr *repr,
options.hasBase(TypeResolverContext::SubscriptDecl) ||
options.hasBase(TypeResolverContext::EnumElementDecl)) {
decltype(diag::attr_only_on_parameters) diagID;
if (options.getBaseContext() == TypeResolverContext::SubscriptDecl) {
auto diagID = diag::attr_only_on_parameters;
bool removeRepr = true;
if (options.hasBase(TypeResolverContext::SubscriptDecl)) {
diagID = diag::attr_not_on_subscript_parameters;
} else if (options.is(TypeResolverContext::VariadicFunctionInput)) {
diagID = diag::attr_not_on_variadic_parameters;
} else if (options.hasBase(TypeResolverContext::EnumElementDecl)) {
diagID = diag::attr_not_on_enum_case_parameters;
} else {
diagID = diag::attr_only_on_parameters;
removeRepr = false;
}
StringRef name;
if (ownershipRepr) {
name = ownershipRepr->getSpecifierSpelling();
}
diagnoseInvalid(repr, repr->getSpecifierLoc(), diagID, name);
auto diag = diagnoseInvalid(repr, repr->getSpecifierLoc(), diagID, name);
if (removeRepr)
diag.fixItRemove(repr->getLoc());
return ErrorType::get(getASTContext());
}

View File

@@ -205,3 +205,10 @@ func rdar94888357() {
let _ = S<String, String>("") // expected-error {{generic type 'S' specialized with too many type parameters (got 2, but expected 1)}}
}
// https://github.com/apple/swift/issues/68417
enum E {
subscript(x: inout Int) -> Bool { true } // expected-error {{'inout' must not be used on subscript parameters}} {{16-22=}}
case c(x: inout Int) // expected-error {{'inout' must not be used on enum case parameters}} {{13-19=}}
func d(x: inout Int ...) // expected-error {{'inout' must not be used on variadic parameters}} {{13-19=}}
}