@@ -63,44 +63,63 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs, SourceLoc loc,
63
63
SmallVectorImpl<RequirementError> &errors;
64
64
65
65
public:
66
+ bool recordedErrors = false;
67
+ bool recordedRequirements = false;
68
+
66
69
explicit Matcher(SourceLoc loc,
67
70
SmallVectorImpl<Requirement> &result,
68
71
SmallVectorImpl<RequirementError> &errors)
69
72
: loc(loc), result(result), errors(errors) {}
70
73
74
+ bool alwaysMismatchTypeParameters() const { return true; }
75
+
71
76
bool mismatch(TypeBase *firstType, TypeBase *secondType,
72
77
Type sugaredFirstType) {
73
78
if (firstType->isTypeParameter() && secondType->isTypeParameter()) {
74
79
result.emplace_back(RequirementKind::SameType,
75
80
firstType, secondType);
81
+ recordedRequirements = true;
76
82
return true;
77
83
}
78
84
79
85
if (firstType->isTypeParameter()) {
80
86
result.emplace_back(RequirementKind::SameType,
81
87
firstType, secondType);
88
+ recordedRequirements = true;
82
89
return true;
83
90
}
84
91
85
92
if (secondType->isTypeParameter()) {
86
93
result.emplace_back(RequirementKind::SameType,
87
94
secondType, firstType);
95
+ recordedRequirements = true;
88
96
return true;
89
97
}
90
98
91
99
errors.push_back(
92
100
RequirementError::forConcreteTypeMismatch(firstType,
93
101
secondType,
94
102
loc));
103
+ recordedErrors = true;
95
104
return true;
96
105
}
97
106
} matcher(loc, result, errors);
98
107
99
108
if (lhs->hasError() || rhs->hasError())
100
109
return;
101
110
102
- // FIXME: Record redundancy and diagnose upstream
103
111
(void) matcher.match(lhs, rhs);
112
+
113
+ // If neither side is directly a type parameter, the type parameter
114
+ // must be in structural position where the enclosing type is redundant.
115
+ if (!lhs->isTypeParameter() && !rhs->isTypeParameter() &&
116
+ !matcher.recordedErrors) {
117
+ // FIXME: Add a tailored error message when requirements were
118
+ // recorded, e.g. Array<Int> == Array<T>. The outer type is
119
+ // redundant, but the inner requirement T == Int is not.
120
+ errors.push_back(RequirementError::forRedundantRequirement(
121
+ {RequirementKind::SameType, lhs, rhs}, loc));
122
+ }
104
123
}
105
124
106
125
static void desugarSuperclassRequirement(Type subjectType,
@@ -109,8 +128,14 @@ static void desugarSuperclassRequirement(Type subjectType,
109
128
SmallVectorImpl<Requirement> &result,
110
129
SmallVectorImpl<RequirementError> &errors) {
111
130
if (!subjectType->isTypeParameter()) {
112
- errors.push_back(
113
- RequirementError::forNonTypeParameter(subjectType, loc));
131
+ if (constraintType->isExactSuperclassOf(subjectType)) {
132
+ errors.push_back(RequirementError::forRedundantRequirement(
133
+ {RequirementKind::Superclass, subjectType, constraintType}, loc));
134
+ } else {
135
+ errors.push_back(
136
+ RequirementError::forNonTypeParameter(subjectType, loc));
137
+ }
138
+
114
139
return;
115
140
}
116
141
@@ -123,8 +148,14 @@ static void desugarLayoutRequirement(Type subjectType,
123
148
SmallVectorImpl<Requirement> &result,
124
149
SmallVectorImpl<RequirementError> &errors) {
125
150
if (!subjectType->isTypeParameter()) {
126
- errors.push_back(
127
- RequirementError::forNonTypeParameter(subjectType, loc));
151
+ if (subjectType->isAnyClassReferenceType()) {
152
+ errors.push_back(RequirementError::forRedundantRequirement(
153
+ {RequirementKind::Layout, subjectType, layout}, loc));
154
+ } else {
155
+ errors.push_back(
156
+ RequirementError::forNonTypeParameter(subjectType, loc));
157
+ }
158
+
128
159
return;
129
160
}
130
161
@@ -163,7 +194,9 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
163
194
return;
164
195
}
165
196
166
- // FIXME: Diagnose a redundancy.
197
+ errors.push_back(RequirementError::forRedundantRequirement(
198
+ {RequirementKind::Conformance, subjectType, constraintType}, loc));
199
+
167
200
assert(conformance.isConcrete());
168
201
auto *concrete = conformance.getConcrete();
169
202
@@ -493,12 +526,13 @@ void swift::rewriting::realizeInheritedRequirements(
493
526
}
494
527
}
495
528
496
- void swift::rewriting::diagnoseRequirementErrors(
529
+ bool swift::rewriting::diagnoseRequirementErrors(
497
530
ASTContext &ctx, SmallVectorImpl<RequirementError> &errors,
498
531
bool allowConcreteGenericParams) {
532
+ bool diagnosedError = false;
499
533
if (ctx.LangOpts.RequirementMachineProtocolSignatures !=
500
534
RequirementMachineMode::Enabled)
501
- return;
535
+ return diagnosedError ;
502
536
503
537
for (auto error : errors) {
504
538
SourceLoc loc = error.loc;
@@ -520,6 +554,7 @@ void swift::rewriting::diagnoseRequirementErrors(
520
554
521
555
ctx.Diags.diagnose(loc, diag::requires_conformance_nonprotocol,
522
556
subjectType, constraintString);
557
+ diagnosedError = true;
523
558
524
559
auto getNameWithoutSelf = [&](std::string subjectTypeName) {
525
560
std::string selfSubstring = "Self.";
@@ -549,6 +584,7 @@ void swift::rewriting::diagnoseRequirementErrors(
549
584
if (!type1->hasError() && !type2->hasError()) {
550
585
ctx.Diags.diagnose(loc, diag::requires_same_concrete_type,
551
586
type1, type2);
587
+ diagnosedError = true;
552
588
}
553
589
554
590
break;
@@ -557,10 +593,41 @@ void swift::rewriting::diagnoseRequirementErrors(
557
593
case RequirementError::Kind::NonTypeParameter: {
558
594
ctx.Diags.diagnose(loc, diag::requires_not_suitable_archetype,
559
595
error.nonTypeParameter);
596
+ diagnosedError = true;
597
+ break;
598
+ }
599
+
600
+ case RequirementError::Kind::RedundantRequirement: {
601
+ auto requirement = error.redundantRequirement;
602
+ switch (requirement.getKind()) {
603
+ case RequirementKind::SameType:
604
+ ctx.Diags.diagnose(loc, diag::redundant_same_type_to_concrete,
605
+ requirement.getFirstType(),
606
+ requirement.getSecondType());
607
+ break;
608
+ case RequirementKind::Conformance:
609
+ ctx.Diags.diagnose(loc, diag::redundant_conformance_constraint,
610
+ requirement.getFirstType(),
611
+ requirement.getProtocolDecl());
612
+ break;
613
+ case RequirementKind::Superclass:
614
+ ctx.Diags.diagnose(loc, diag::redundant_superclass_constraint,
615
+ requirement.getFirstType(),
616
+ requirement.getSecondType());
617
+ break;
618
+ case RequirementKind::Layout:
619
+ ctx.Diags.diagnose(loc, diag::redundant_layout_constraint,
620
+ requirement.getFirstType(),
621
+ requirement.getLayoutConstraint());
622
+ break;
623
+ }
624
+
560
625
break;
561
626
}
562
627
}
563
628
}
629
+
630
+ return diagnosedError;
564
631
}
565
632
566
633
ArrayRef<StructuralRequirement>
0 commit comments