Skip to content

Commit 5f4e024

Browse files
committed
[GSB] Clean up decision-making logic for redundant-constraint warnings.
Lots of DRY violations to refactor.
1 parent fb2b070 commit 5f4e024

File tree

2 files changed

+43
-41
lines changed

2 files changed

+43
-41
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,14 @@ class GenericSignatureBuilder::RequirementSource final
11981198
/// path.
11991199
bool isDerivedRequirement() const;
12001200

1201+
/// Whether we should diagnose a redundant constraint based on this
1202+
/// requirement source.
1203+
///
1204+
/// \param primary Whether this is the "primary" requirement source, on which
1205+
/// a "redundant constraint" warning would be emitted vs. the requirement
1206+
/// source that would be used for the accompanying note.
1207+
bool shouldDiagnoseRedundancy(bool primary) const;
1208+
12011209
/// Determine whether the given derived requirement \c source, when rooted at
12021210
/// the potential archetype \c pa, is actually derived from the same
12031211
/// requirement. Such "self-derived" requirements do not make the original

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,11 @@ bool RequirementSource::isDerivedRequirement() const {
573573
llvm_unreachable("Unhandled RequirementSourceKind in switch.");
574574
}
575575

576+
bool RequirementSource::shouldDiagnoseRedundancy(bool primary) const {
577+
return !isInferredRequirement() && getLoc().isValid() &&
578+
(!primary || !isDerivedRequirement());
579+
}
580+
576581
bool RequirementSource::isSelfDerivedSource(PotentialArchetype *pa,
577582
bool &derivedViaConcrete) const {
578583
return getMinimalConformanceSource(pa, /*proto=*/nullptr, derivedViaConcrete)
@@ -5090,10 +5095,9 @@ Constraint<T> GenericSignatureBuilder::checkConstraintList(
50905095
// If this requirement is not derived or inferred (but has a useful
50915096
// location) complain that it is redundant.
50925097
Impl->HadAnyRedundantConstraints = true;
5093-
if (!constraint.source->isDerivedRequirement() &&
5094-
!constraint.source->isInferredRequirement() &&
5095-
constraint.source->getLoc().isValid() &&
5096-
!representativeConstraint->source->isInferredRequirement()) {
5098+
if (constraint.source->shouldDiagnoseRedundancy(true) &&
5099+
representativeConstraint &&
5100+
representativeConstraint->source->shouldDiagnoseRedundancy(false)) {
50975101
Diags.diagnose(constraint.source->getLoc(),
50985102
redundancyDiag,
50995103
constraint.archetype->getDependentType(genericParams),
@@ -5710,9 +5714,7 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
57105714
for (const auto &constraint : constraints) {
57115715
// If the source/destination are identical, complain.
57125716
if (constraint.archetype == constraint.value) {
5713-
if (!constraint.source->isDerivedRequirement() &&
5714-
!constraint.source->isInferredRequirement() &&
5715-
constraint.source->getLoc().isValid()) {
5717+
if (constraint.source->shouldDiagnoseRedundancy(true)) {
57165718
Diags.diagnose(constraint.source->getLoc(),
57175719
diag::redundant_same_type_constraint,
57185720
constraint.archetype->getDependentType(genericParams),
@@ -5822,15 +5824,9 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
58225824
if (lhs.source != rhs.source || lhs.target != rhs.target)
58235825
return false;
58245826

5825-
// We have two edges connected the same components. If both
5826-
// have locations, diagnose them.
5827-
if (lhs.constraint.source->getLoc().isInvalid() ||
5828-
rhs.constraint.source->getLoc().isInvalid())
5829-
return true;
5830-
5831-
// If the constraint source is inferred, don't diagnose it.
5832-
if (lhs.constraint.source->isInferredRequirement() ||
5833-
rhs.constraint.source->isInferredRequirement())
5827+
// Check whethe we should diagnose redundancy for both constraints.
5828+
if (!lhs.constraint.source->shouldDiagnoseRedundancy(true) ||
5829+
!rhs.constraint.source->shouldDiagnoseRedundancy(false))
58345830
return true;
58355831

58365832
Diags.diagnose(lhs.constraint.source->getLoc(),
@@ -5859,10 +5855,8 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
58595855
// If both the source and target are already connected, this edge is
58605856
// not part of the spanning tree.
58615857
if (connected[edge.source] && connected[edge.target]) {
5862-
if (edge.constraint.source->getLoc().isValid() &&
5863-
!edge.constraint.source->isInferredRequirement() &&
5864-
firstEdge.constraint.source->getLoc().isValid() &&
5865-
!firstEdge.constraint.source->isInferredRequirement()) {
5858+
if (edge.constraint.source->shouldDiagnoseRedundancy(true) &&
5859+
firstEdge.constraint.source->shouldDiagnoseRedundancy(false)) {
58665860
Diags.diagnose(edge.constraint.source->getLoc(),
58675861
diag::redundant_same_type_constraint,
58685862
edge.constraint.archetype->getDependentType(
@@ -5975,47 +5969,47 @@ void GenericSignatureBuilder::checkSuperclassConstraints(
59755969
// If we have a concrete type, check it.
59765970
// FIXME: Substitute into the concrete type.
59775971
if (equivClass->concreteType) {
5972+
auto existing = equivClass->findAnyConcreteConstraintAsWritten(
5973+
representativeConstraint.archetype);
59785974
// Make sure the concrete type fulfills the superclass requirement.
5979-
if (!equivClass->superclass->isExactSuperclassOf(equivClass->concreteType)) {
5980-
if (auto existing = equivClass->findAnyConcreteConstraintAsWritten(
5981-
representativeConstraint.archetype)) {
5982-
Impl->HadAnyError = true;
5983-
5975+
if (!equivClass->superclass->isExactSuperclassOf(equivClass->concreteType)){
5976+
Impl->HadAnyError = true;
5977+
if (existing) {
59845978
Diags.diagnose(existing->source->getLoc(), diag::type_does_not_inherit,
59855979
existing->archetype->getDependentType(
59865980
genericParams),
59875981
existing->value, equivClass->superclass);
59885982

5989-
// FIXME: Note the representative constraint.
5983+
if (representativeConstraint.source->getLoc().isValid()) {
5984+
Diags.diagnose(representativeConstraint.source->getLoc(),
5985+
diag::superclass_redundancy_here,
5986+
representativeConstraint.source->classifyDiagKind(),
5987+
representativeConstraint.archetype->getDependentType(
5988+
genericParams),
5989+
equivClass->superclass);
5990+
}
59905991
} else if (representativeConstraint.source->getLoc().isValid()) {
5991-
Impl->HadAnyError = true;
5992-
59935992
Diags.diagnose(representativeConstraint.source->getLoc(),
59945993
diag::type_does_not_inherit,
59955994
representativeConstraint.archetype->getDependentType(
59965995
genericParams),
59975996
equivClass->concreteType, equivClass->superclass);
59985997
}
5999-
} else if (representativeConstraint.source->getLoc().isValid() &&
6000-
!representativeConstraint.source->isDerivedRequirement() &&
6001-
!representativeConstraint.source->isInferredRequirement()) {
5998+
} else if (representativeConstraint.source->shouldDiagnoseRedundancy(true)
5999+
&& existing &&
6000+
existing->source->shouldDiagnoseRedundancy(false)) {
60026001
// It does fulfill the requirement; diagnose the redundancy.
60036002
Diags.diagnose(representativeConstraint.source->getLoc(),
60046003
diag::redundant_superclass_constraint,
60056004
representativeConstraint.archetype->getDependentType(
60066005
genericParams),
60076006
representativeConstraint.value);
60086007

6009-
if (auto existing = equivClass->findAnyConcreteConstraintAsWritten(
6010-
representativeConstraint.archetype)) {
6011-
if (!existing->source->isInferredRequirement()) {
6012-
Diags.diagnose(existing->source->getLoc(),
6013-
diag::same_type_redundancy_here,
6014-
existing->source->classifyDiagKind(),
6015-
existing->archetype->getDependentType(genericParams),
6016-
existing->value);
6017-
}
6018-
}
6008+
Diags.diagnose(existing->source->getLoc(),
6009+
diag::same_type_redundancy_here,
6010+
existing->source->classifyDiagKind(),
6011+
existing->archetype->getDependentType(genericParams),
6012+
existing->value);
60196013
}
60206014
}
60216015
}

0 commit comments

Comments
 (0)