Skip to content

Commit 299ff02

Browse files
committed
GSB: Diagnose redundant layout requirements using the redundant requirement graph
1 parent 1617727 commit 299ff02

File tree

5 files changed

+61
-37
lines changed

5 files changed

+61
-37
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2425,15 +2425,17 @@ NOTE(superclass_redundancy_here,none,
24252425
(unsigned, Type, Type))
24262426

24272427
ERROR(conflicting_layout_constraints,none,
2428-
"%select{generic parameter |protocol |}0%1 has conflicting "
2429-
"constraints %2 and %3",
2430-
(unsigned, Type, LayoutConstraint, LayoutConstraint))
2428+
"type %0 has conflicting constraints %1 and %2",
2429+
(Type, LayoutConstraint, LayoutConstraint))
2430+
NOTE(conflicting_layout_constraint, none,
2431+
"constraint conflicts with %0 : %1",
2432+
(Type, LayoutConstraint))
24312433
WARNING(redundant_layout_constraint,none,
2432-
"redundant constraint %0 : %1", (Type, LayoutConstraint))
2434+
"redundant constraint %0 : %1",
2435+
(Type, LayoutConstraint))
24332436
NOTE(previous_layout_constraint, none,
2434-
"constraint %1 : %2 %select{written here|implied here|"
2435-
"inferred from type here}0",
2436-
(unsigned, Type, LayoutConstraint))
2437+
"constraint %0 : %1 implied here",
2438+
(Type, LayoutConstraint))
24372439

24382440
WARNING(redundant_same_type_constraint,none,
24392441
"redundant same-type constraint %0 == %1", (Type, Type))

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7113,8 +7113,45 @@ void GenericSignatureBuilder::diagnoseRedundantRequirements() const {
71137113
break;
71147114
}
71157115

7116+
case RequirementKind::Layout: {
7117+
auto layout = req.getRHS().get<LayoutConstraint>();
7118+
7119+
auto conflict = Impl->ConflictingRequirements.find(req);
7120+
if (conflict != Impl->ConflictingRequirements.end()) {
7121+
Impl->HadAnyError = true;
7122+
7123+
auto otherLayout = conflict->second.get<LayoutConstraint>();
7124+
Context.Diags.diagnose(loc, diag::conflicting_layout_constraints,
7125+
subjectType, layout, otherLayout);
7126+
7127+
for (auto otherReq : found->second) {
7128+
auto *otherSource = otherReq.getSource();
7129+
auto otherLoc = otherSource->getLoc();
7130+
if (otherLoc.isInvalid())
7131+
continue;
7132+
7133+
Context.Diags.diagnose(otherLoc, diag::conflicting_layout_constraint,
7134+
subjectType, otherLayout);
7135+
}
7136+
} else {
7137+
Context.Diags.diagnose(loc, diag::redundant_layout_constraint,
7138+
subjectType, layout);
7139+
7140+
for (auto otherReq : found->second) {
7141+
auto *otherSource = otherReq.getSource();
7142+
auto otherLoc = otherSource->getLoc();
7143+
if (otherLoc.isInvalid())
7144+
continue;
7145+
7146+
Context.Diags.diagnose(otherLoc, diag::previous_layout_constraint,
7147+
subjectType, layout);
7148+
}
7149+
}
7150+
7151+
break;
7152+
}
7153+
71167154
case RequirementKind::Superclass:
7117-
case RequirementKind::Layout:
71187155
case RequirementKind::SameType:
71197156
// TODO
71207157
break;
@@ -8023,24 +8060,7 @@ void GenericSignatureBuilder::checkLayoutConstraints(
80238060
EquivalenceClass *equivClass) {
80248061
if (!equivClass->layout) return;
80258062

8026-
checkConstraintList<LayoutConstraint>(
8027-
genericParams, equivClass->layoutConstraints, RequirementKind::Layout,
8028-
[&](const Constraint<LayoutConstraint> &constraint) {
8029-
return constraint.value == equivClass->layout;
8030-
},
8031-
[&](const Constraint<LayoutConstraint> &constraint) {
8032-
auto layout = constraint.value;
8033-
8034-
// If the layout constraints are mergable, i.e. compatible,
8035-
// it is a redundancy.
8036-
if (layout.merge(equivClass->layout)->isKnownLayout())
8037-
return ConstraintRelation::Redundant;
8038-
8039-
return ConstraintRelation::Conflicting;
8040-
},
8041-
diag::conflicting_layout_constraints,
8042-
diag::redundant_layout_constraint,
8043-
diag::previous_layout_constraint);
8063+
removeSelfDerived(*this, equivClass->layoutConstraints, /*proto=*/nullptr);
80448064
}
80458065

80468066
bool GenericSignatureBuilder::isRedundantExplicitRequirement(

test/Compatibility/anyobject_class.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
protocol P : class, AnyObject { } // expected-warning{{redundant inheritance from 'AnyObject' and Swift 3 'class' keyword}}{{14-21=}}
55
// expected-warning@-1{{redundant constraint 'Self' : 'AnyObject'}}
6-
// expected-note@-2{{constraint 'Self' : 'AnyObject' written here}}
6+
// expected-note@-2{{constraint 'Self' : 'AnyObject' implied here}}

test/attr/attr_specialize.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,16 +171,17 @@ func funcWithForbiddenSpecializeRequirement<T>(_ t: T) {
171171
}
172172

173173
@_specialize(where T: _Trivial(32), T: _Trivial(64), T: _Trivial, T: _RefCountedObject)
174-
// expected-error@-1{{generic parameter 'T' has conflicting constraints '_Trivial(64)' and '_Trivial(32)'}}
175-
// expected-error@-2{{generic parameter 'T' has conflicting constraints '_RefCountedObject' and '_Trivial(32)'}}
174+
// expected-error@-1{{type 'T' has conflicting constraints '_Trivial(64)' and '_Trivial(32)'}}
175+
// expected-error@-2{{type 'T' has conflicting constraints '_RefCountedObject' and '_Trivial(32)'}}
176176
// expected-warning@-3{{redundant constraint 'T' : '_Trivial'}}
177-
// expected-note@-4 3{{constraint 'T' : '_Trivial(32)' written here}}
177+
// expected-note@-4 {{constraint 'T' : '_Trivial' implied here}}
178+
// expected-note@-5 2{{constraint conflicts with 'T' : '_Trivial(32)'}}
178179
@_specialize(where T: _Trivial, T: _Trivial(64))
179180
// expected-warning@-1{{redundant constraint 'T' : '_Trivial'}}
180-
// expected-note@-2 1{{constraint 'T' : '_Trivial(64)' written here}}
181+
// expected-note@-2 1{{constraint 'T' : '_Trivial' implied here}}
181182
@_specialize(where T: _RefCountedObject, T: _NativeRefCountedObject)
182183
// expected-warning@-1{{redundant constraint 'T' : '_RefCountedObject'}}
183-
// expected-note@-2 1{{constraint 'T' : '_NativeRefCountedObject' written here}}
184+
// expected-note@-2 1{{constraint 'T' : '_RefCountedObject' implied here}}
184185
@_specialize(where Array<T> == Int) // expected-error{{generic signature requires types 'Array<T>' and 'Int' to be the same}}
185186
// expected-error@-1 {{too few generic parameters are specified in '_specialize' attribute (got 0, but expected 1)}}
186187
// expected-note@-2 {{missing constraint for 'T' in '_specialize' attribute}}
@@ -193,14 +194,15 @@ public protocol Proto: class {
193194
}
194195

195196
@_specialize(where T: _RefCountedObject)
196-
// expected-error@-1 {{too few generic parameters are specified in '_specialize' attribute (got 0, but expected 1)}}
197-
// expected-note@-2 {{missing constraint for 'T' in '_specialize' attribute}}
197+
// expected-warning@-1 {{redundant constraint 'T' : '_RefCountedObject'}}
198+
// expected-error@-2 {{too few generic parameters are specified in '_specialize' attribute (got 0, but expected 1)}}
199+
// expected-note@-3 {{missing constraint for 'T' in '_specialize' attribute}}
198200
@_specialize(where T: _Trivial)
199-
// expected-error@-1{{generic parameter 'T' has conflicting constraints '_Trivial' and '_NativeClass'}}
201+
// expected-error@-1{{type 'T' has conflicting constraints '_Trivial' and '_NativeClass'}}
200202
// expected-error@-2 {{too few generic parameters are specified in '_specialize' attribute (got 0, but expected 1)}}
201203
// expected-note@-3 {{missing constraint for 'T' in '_specialize' attribute}}
202204
@_specialize(where T: _Trivial(64))
203-
// expected-error@-1{{generic parameter 'T' has conflicting constraints '_Trivial(64)' and '_NativeClass'}}
205+
// expected-error@-1{{type 'T' has conflicting constraints '_Trivial(64)' and '_NativeClass'}}
204206
// expected-error@-2 {{too few generic parameters are specified in '_specialize' attribute (got 0, but expected 1)}}
205207
// expected-note@-3 {{missing constraint for 'T' in '_specialize' attribute}}
206208
public func funcWithABaseClassRequirement<T>(t: T) -> Int where T: C1 {

test/decl/ext/extensions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class JustAClass2: ImposeClassReq1 {
259259
var someProperty = 0
260260
}
261261

262-
extension ImposeClassReq1 where Self: AnyObject {
262+
extension ImposeClassReq1 where Self: AnyObject { // expected-warning {{redundant constraint 'Self' : 'AnyObject'}}
263263
var wrappingProperty1: Int {
264264
get { return someProperty }
265265
set { someProperty = newValue }

0 commit comments

Comments
 (0)