Skip to content

Commit 285a1ff

Browse files
committed
---
yaml --- r: 345950 b: refs/heads/master c: 71c178b h: refs/heads/master
1 parent 9de2f72 commit 285a1ff

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: abe703a4fd50a909198ed13d7c8c3ce8a8f605f5
2+
refs/heads/master: 71c178b4d223548570b4ae6262deaa9ecda602d3
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/DiagnosticsCommon.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ NOTE(profile_read_error,none,
9595
ERROR(generic_signature_not_minimal,none,
9696
"generic requirement '%0' is redundant in %1", (StringRef, StringRef))
9797

98+
WARNING(protocol_extension_redundant_requirement,none,
99+
"requirement of '%1' to '%2' is redundant in an extension of '%0'",
100+
(StringRef, StringRef, StringRef))
101+
98102
ERROR(attr_only_on_parameters, none,
99103
"'%0' may only be used on parameters", (StringRef))
100104

trunk/lib/Sema/TypeCheckGeneric.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,32 @@ void checkGenericParamList(TypeChecker &tc,
7878
RequirementRequest::visitRequirements(owner, resolution.getStage(),
7979
[&](const Requirement &req, RequirementRepr *reqRepr) {
8080
auto source = FloatingRequirementSource::forExplicit(reqRepr);
81+
82+
// If we're extending a protocol and adding a redundant requirement,
83+
// for example, `extension Foo where Self: Foo`, then emit a
84+
// diagnostic.
85+
86+
if (auto decl = owner.dc->getAsDecl()) {
87+
if (auto extDecl = dyn_cast<ExtensionDecl>(decl)) {
88+
auto extType = extDecl->getExtendedType();
89+
auto extSelfType = extDecl->getSelfInterfaceType();
90+
auto reqLHSType = req.getFirstType();
91+
auto reqRHSType = req.getSecondType();
92+
93+
if (extType->isExistentialType() &&
94+
reqLHSType->isEqual(extSelfType) &&
95+
reqRHSType->isEqual(extType)) {
96+
97+
auto &ctx = extDecl->getASTContext();
98+
ctx.Diags.diagnose(extDecl->getLoc(),
99+
diag::protocol_extension_redundant_requirement,
100+
extType->getString(),
101+
extSelfType->getString(),
102+
reqRHSType->getString());
103+
}
104+
}
105+
}
106+
81107
builder->addRequirement(req, reqRepr, source, nullptr,
82108
lookupDC->getParentModule());
83109
return false;

trunk/test/decl/ext/protocol.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,23 @@ extension S1 {
176176
}
177177
}
178178

179+
// ----------------------------------------------------------------------------
180+
// Protocol extensions with redundant requirements
181+
// ----------------------------------------------------------------------------
182+
183+
protocol FooProtocol {}
184+
extension FooProtocol where Self: FooProtocol {} // expected-warning {{requirement of 'Self' to 'FooProtocol' is redundant in an extension of 'FooProtocol'}}
185+
186+
protocol AnotherFooProtocol {}
187+
protocol BazProtocol {}
188+
extension AnotherFooProtocol where Self: BazProtocol, Self: AnotherFooProtocol {} // expected-warning {{requirement of 'Self' to 'AnotherFooProtocol' is redundant in an extension of 'AnotherFooProtocol'}}
189+
190+
protocol AnotherBazProtocol {
191+
associatedtype BazValue
192+
}
193+
194+
extension AnotherBazProtocol where BazValue: AnotherBazProtocol {} // ok, does not warn because BazValue is not Self
195+
179196
// ----------------------------------------------------------------------------
180197
// Protocol extensions with additional requirements
181198
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)