Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Sema] Emit a diagnostic when extending a protocol with a redundant requirement #20503

Merged
merged 12 commits into from
Nov 16, 2018
Merged
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsCommon.def
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ NOTE(profile_read_error,none,
ERROR(generic_signature_not_minimal,none,
"generic requirement '%0' is redundant in %1", (StringRef, StringRef))

WARNING(extension_redundant_requirement,none,
"redundant requirement in extension", ())
theblixguy marked this conversation as resolved.
Show resolved Hide resolved

ERROR(attr_only_on_parameters, none,
"'%0' may only be used on parameters", (StringRef))

Expand Down
16 changes: 16 additions & 0 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,22 @@ bool RequirementRequest::visitRequirements(
// Resolve to a requirement.
auto req = evaluator(RequirementRequest{owner, index, stage});
if (req) {

// If we're in an extension declaration and if we are adding a
// redundant requirement (for example, `extension Foo where Self: Foo`)
// then emit a diagnostic.

// FIXME: Leads to duplicate diagnostic emissions
if (auto extDecl = dyn_cast<ExtensionDecl>(owner.dc->getAsDecl())) {
theblixguy marked this conversation as resolved.
Show resolved Hide resolved
auto ownerType = extDecl->getExtendedType();
auto reqType = req->getSecondType();

if (reqType->isEqual(ownerType)) {
auto &ctx = extDecl->getASTContext();
ctx.Diags.diagnose(extDecl->getLoc(), diag::extension_redundant_requirement);
}
}

// Invoke the callback. If it returns true, we're done.
if (callback(*req, &requirements[index]))
return true;
Expand Down
12 changes: 12 additions & 0 deletions test/decl/ext/protocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ extension S1 {
}
}

// ----------------------------------------------------------------------------
// Protocol extensions with redundant requirements
// ----------------------------------------------------------------------------

protocol Foo {}
extension Foo where Self: Foo {} // expected-warning {{redundant requirement in extension}}

protocol Bar {}
protocol Baz {}
extension Bar where Self: Baz {} // ok
extension Bar where Self: Bar, Self: Baz {} // expected-warning {{redundant requirement in extension}}

// ----------------------------------------------------------------------------
// Protocol extensions with additional requirements
// ----------------------------------------------------------------------------
Expand Down