@@ -573,6 +573,11 @@ bool RequirementSource::isDerivedRequirement() const {
573
573
llvm_unreachable (" Unhandled RequirementSourceKind in switch." );
574
574
}
575
575
576
+ bool RequirementSource::shouldDiagnoseRedundancy (bool primary) const {
577
+ return !isInferredRequirement () && getLoc ().isValid () &&
578
+ (!primary || !isDerivedRequirement ());
579
+ }
580
+
576
581
bool RequirementSource::isSelfDerivedSource (PotentialArchetype *pa,
577
582
bool &derivedViaConcrete) const {
578
583
return getMinimalConformanceSource (pa, /* proto=*/ nullptr , derivedViaConcrete)
@@ -5090,10 +5095,9 @@ Constraint<T> GenericSignatureBuilder::checkConstraintList(
5090
5095
// If this requirement is not derived or inferred (but has a useful
5091
5096
// location) complain that it is redundant.
5092
5097
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 )) {
5097
5101
Diags.diagnose (constraint.source ->getLoc (),
5098
5102
redundancyDiag,
5099
5103
constraint.archetype ->getDependentType (genericParams),
@@ -5710,9 +5714,7 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
5710
5714
for (const auto &constraint : constraints) {
5711
5715
// If the source/destination are identical, complain.
5712
5716
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 )) {
5716
5718
Diags.diagnose (constraint.source ->getLoc (),
5717
5719
diag::redundant_same_type_constraint,
5718
5720
constraint.archetype ->getDependentType (genericParams),
@@ -5822,15 +5824,9 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
5822
5824
if (lhs.source != rhs.source || lhs.target != rhs.target )
5823
5825
return false ;
5824
5826
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 ))
5834
5830
return true ;
5835
5831
5836
5832
Diags.diagnose (lhs.constraint .source ->getLoc (),
@@ -5859,10 +5855,8 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
5859
5855
// If both the source and target are already connected, this edge is
5860
5856
// not part of the spanning tree.
5861
5857
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 )) {
5866
5860
Diags.diagnose (edge.constraint .source ->getLoc (),
5867
5861
diag::redundant_same_type_constraint,
5868
5862
edge.constraint .archetype ->getDependentType (
@@ -5975,47 +5969,47 @@ void GenericSignatureBuilder::checkSuperclassConstraints(
5975
5969
// If we have a concrete type, check it.
5976
5970
// FIXME: Substitute into the concrete type.
5977
5971
if (equivClass->concreteType ) {
5972
+ auto existing = equivClass->findAnyConcreteConstraintAsWritten (
5973
+ representativeConstraint.archetype );
5978
5974
// 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) {
5984
5978
Diags.diagnose (existing->source ->getLoc (), diag::type_does_not_inherit,
5985
5979
existing->archetype ->getDependentType (
5986
5980
genericParams),
5987
5981
existing->value , equivClass->superclass );
5988
5982
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
+ }
5990
5991
} else if (representativeConstraint.source ->getLoc ().isValid ()) {
5991
- Impl->HadAnyError = true ;
5992
-
5993
5992
Diags.diagnose (representativeConstraint.source ->getLoc (),
5994
5993
diag::type_does_not_inherit,
5995
5994
representativeConstraint.archetype ->getDependentType (
5996
5995
genericParams),
5997
5996
equivClass->concreteType , equivClass->superclass );
5998
5997
}
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 )) {
6002
6001
// It does fulfill the requirement; diagnose the redundancy.
6003
6002
Diags.diagnose (representativeConstraint.source ->getLoc (),
6004
6003
diag::redundant_superclass_constraint,
6005
6004
representativeConstraint.archetype ->getDependentType (
6006
6005
genericParams),
6007
6006
representativeConstraint.value );
6008
6007
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 );
6019
6013
}
6020
6014
}
6021
6015
}
0 commit comments