Skip to content

Commit 3c2b588

Browse files
committed
[RequirementMachine] Plumb the requirement errors vector through desugarRequirement.
1 parent a74717a commit 3c2b588

File tree

4 files changed

+56
-30
lines changed

4 files changed

+56
-30
lines changed

lib/AST/RequirementMachine/ConcreteTypeWitness.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,9 @@ void PropertyMap::inferConditionalRequirements(
527527
return;
528528

529529
SmallVector<Requirement, 2> desugaredRequirements;
530+
// FIXME: Store errors in the rewrite system to be diagnosed
531+
// from the top-level generic signature requests.
532+
SmallVector<RequirementError, 2> errors;
530533

531534
// First, desugar all conditional requirements.
532535
for (auto req : conditionalRequirements) {
@@ -536,7 +539,7 @@ void PropertyMap::inferConditionalRequirements(
536539
llvm::dbgs() << "\n";
537540
}
538541

539-
desugarRequirement(req, desugaredRequirements);
542+
desugarRequirement(req, desugaredRequirements, errors);
540543
}
541544

542545
// Now, convert desugared conditional requirements to rules.

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,16 @@ using namespace rewriting;
5555
/// side into a series of same-type and concrete-type requirements where the
5656
/// left hand side is always a type parameter.
5757
static void desugarSameTypeRequirement(Type lhs, Type rhs,
58-
SmallVectorImpl<Requirement> &result) {
58+
SmallVectorImpl<Requirement> &result,
59+
SmallVectorImpl<RequirementError> &errors) {
5960
class Matcher : public TypeMatcher<Matcher> {
6061
SmallVectorImpl<Requirement> &result;
62+
SmallVectorImpl<RequirementError> &errors;
6163

6264
public:
63-
explicit Matcher(SmallVectorImpl<Requirement> &result)
64-
: result(result) {}
65+
explicit Matcher(SmallVectorImpl<Requirement> &result,
66+
SmallVectorImpl<RequirementError> &errors)
67+
: result(result), errors(errors) {}
6568

6669
bool mismatch(TypeBase *firstType, TypeBase *secondType,
6770
Type sugaredFirstType) {
@@ -86,7 +89,7 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs,
8689
// FIXME: Record concrete type conflict, diagnose upstream
8790
return true;
8891
}
89-
} matcher(result);
92+
} matcher(result, errors);
9093

9194
if (lhs->hasError() || rhs->hasError())
9295
return;
@@ -97,7 +100,8 @@ static void desugarSameTypeRequirement(Type lhs, Type rhs,
97100

98101
static void desugarSuperclassRequirement(Type subjectType,
99102
Type constraintType,
100-
SmallVectorImpl<Requirement> &result) {
103+
SmallVectorImpl<Requirement> &result,
104+
SmallVectorImpl<RequirementError> &errors) {
101105
if (!subjectType->isTypeParameter()) {
102106
// FIXME: Perform unification, diagnose redundancy or conflict upstream
103107
return;
@@ -108,7 +112,8 @@ static void desugarSuperclassRequirement(Type subjectType,
108112

109113
static void desugarLayoutRequirement(Type subjectType,
110114
LayoutConstraint layout,
111-
SmallVectorImpl<Requirement> &result) {
115+
SmallVectorImpl<Requirement> &result,
116+
SmallVectorImpl<RequirementError> &errors) {
112117
if (!subjectType->isTypeParameter()) {
113118
// FIXME: Diagnose redundancy or conflict upstream
114119
return;
@@ -133,7 +138,8 @@ static Type lookupMemberType(Type subjectType, ProtocolDecl *protoDecl,
133138
/// compositions on the right hand side into conformance and superclass
134139
/// requirements.
135140
static void desugarConformanceRequirement(Type subjectType, Type constraintType,
136-
SmallVectorImpl<Requirement> &result) {
141+
SmallVectorImpl<Requirement> &result,
142+
SmallVectorImpl<RequirementError> &errors) {
137143
// Fast path.
138144
if (constraintType->is<ProtocolType>()) {
139145
if (!subjectType->isTypeParameter()) {
@@ -152,7 +158,7 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
152158

153159
// Introduce conditional requirements if the subject type is concrete.
154160
for (auto req : concrete->getConditionalRequirements()) {
155-
desugarRequirement(req, result);
161+
desugarRequirement(req, result, errors);
156162
}
157163
return;
158164
}
@@ -166,28 +172,29 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
166172
auto *protoDecl = paramType->getBaseType()->getDecl();
167173

168174
desugarConformanceRequirement(subjectType, paramType->getBaseType(),
169-
result);
175+
result, errors);
170176

171177
auto *assocType = protoDecl->getPrimaryAssociatedType();
172178

173179
auto memberType = lookupMemberType(subjectType, protoDecl, assocType);
174180
desugarSameTypeRequirement(memberType, paramType->getArgumentType(),
175-
result);
181+
result, errors);
176182
return;
177183
}
178184

179185
auto *compositionType = constraintType->castTo<ProtocolCompositionType>();
180186
if (compositionType->hasExplicitAnyObject()) {
181187
desugarLayoutRequirement(subjectType,
182188
LayoutConstraint::getLayoutConstraint(
183-
LayoutConstraintKind::Class), result);
189+
LayoutConstraintKind::Class),
190+
result, errors);
184191
}
185192

186193
for (auto memberType : compositionType->getMembers()) {
187194
if (memberType->isExistentialType())
188-
desugarConformanceRequirement(subjectType, memberType, result);
195+
desugarConformanceRequirement(subjectType, memberType, result, errors);
189196
else
190-
desugarSuperclassRequirement(subjectType, memberType, result);
197+
desugarSuperclassRequirement(subjectType, memberType, result, errors);
191198
}
192199
}
193200

@@ -197,24 +204,29 @@ static void desugarConformanceRequirement(Type subjectType, Type constraintType,
197204
/// converted into rewrite rules by the RuleBuilder.
198205
void
199206
swift::rewriting::desugarRequirement(Requirement req,
200-
SmallVectorImpl<Requirement> &result) {
207+
SmallVectorImpl<Requirement> &result,
208+
SmallVectorImpl<RequirementError> &errors) {
201209
auto firstType = req.getFirstType();
202210

203211
switch (req.getKind()) {
204212
case RequirementKind::Conformance:
205-
desugarConformanceRequirement(firstType, req.getSecondType(), result);
213+
desugarConformanceRequirement(firstType, req.getSecondType(),
214+
result, errors);
206215
break;
207216

208217
case RequirementKind::Superclass:
209-
desugarSuperclassRequirement(firstType, req.getSecondType(), result);
218+
desugarSuperclassRequirement(firstType, req.getSecondType(),
219+
result, errors);
210220
break;
211221

212222
case RequirementKind::Layout:
213-
desugarLayoutRequirement(firstType, req.getLayoutConstraint(), result);
223+
desugarLayoutRequirement(firstType, req.getLayoutConstraint(),
224+
result, errors);
214225
break;
215226

216227
case RequirementKind::SameType:
217-
desugarSameTypeRequirement(firstType, req.getSecondType(), result);
228+
desugarSameTypeRequirement(firstType, req.getSecondType(),
229+
result, errors);
218230
break;
219231
}
220232
}
@@ -235,10 +247,10 @@ static void realizeTypeRequirement(Type subjectType, Type constraintType,
235247

236248
if (constraintType->isConstraintType()) {
237249
// Handle conformance requirements.
238-
desugarConformanceRequirement(subjectType, constraintType, reqs);
250+
desugarConformanceRequirement(subjectType, constraintType, reqs, errors);
239251
} else if (constraintType->getClassOrBoundGenericClass()) {
240252
// Handle superclass requirements.
241-
desugarSuperclassRequirement(subjectType, constraintType, reqs);
253+
desugarSuperclassRequirement(subjectType, constraintType, reqs, errors);
242254
} else {
243255
errors.push_back(
244256
RequirementError::forInvalidConformance(subjectType,
@@ -258,6 +270,7 @@ namespace {
258270
struct InferRequirementsWalker : public TypeWalker {
259271
ModuleDecl *module;
260272
SmallVector<Requirement, 2> reqs;
273+
SmallVector<RequirementError, 2> errors;
261274

262275
explicit InferRequirementsWalker(ModuleDecl *module) : module(module) {}
263276

@@ -277,7 +290,7 @@ struct InferRequirementsWalker : public TypeWalker {
277290
auto subMap = typeAlias->getSubstitutionMap();
278291
for (const auto &rawReq : decl->getGenericSignature().getRequirements()) {
279292
if (auto req = rawReq.subst(subMap))
280-
desugarRequirement(*req, reqs);
293+
desugarRequirement(*req, reqs, errors);
281294
}
282295

283296
return Action::Continue;
@@ -297,14 +310,14 @@ struct InferRequirementsWalker : public TypeWalker {
297310
auto addConformanceConstraint = [&](Type type, ProtocolDecl *protocol) {
298311
Requirement req(RequirementKind::Conformance, type,
299312
protocol->getDeclaredInterfaceType());
300-
desugarRequirement(req, reqs);
313+
desugarRequirement(req, reqs, errors);
301314
};
302315
auto addSameTypeConstraint = [&](Type firstType,
303316
AssociatedTypeDecl *assocType) {
304317
auto *protocol = assocType->getProtocol();
305318
auto secondType = lookupMemberType(firstType, protocol, assocType);
306319
Requirement req(RequirementKind::SameType, firstType, secondType);
307-
desugarRequirement(req, reqs);
320+
desugarRequirement(req, reqs, errors);
308321
};
309322
auto *tangentVectorAssocType =
310323
differentiableProtocol->getAssociatedType(ctx.Id_TangentVector);
@@ -343,7 +356,7 @@ struct InferRequirementsWalker : public TypeWalker {
343356
// FIXME: Inaccurate TypeReprs.
344357
for (const auto &rawReq : genericSig.getRequirements()) {
345358
if (auto req = rawReq.subst(subMap))
346-
desugarRequirement(*req, reqs);
359+
desugarRequirement(*req, reqs, errors);
347360
}
348361

349362
return Action::Continue;
@@ -408,7 +421,8 @@ void swift::rewriting::realizeRequirement(
408421
}
409422

410423
SmallVector<Requirement, 2> reqs;
411-
desugarLayoutRequirement(firstType, req.getLayoutConstraint(), reqs);
424+
desugarLayoutRequirement(firstType, req.getLayoutConstraint(),
425+
reqs, errors);
412426

413427
for (auto req : reqs)
414428
result.push_back({req, loc, /*wasInferred=*/false});
@@ -429,7 +443,7 @@ void swift::rewriting::realizeRequirement(
429443
}
430444

431445
SmallVector<Requirement, 2> reqs;
432-
desugarSameTypeRequirement(req.getFirstType(), secondType, reqs);
446+
desugarSameTypeRequirement(req.getFirstType(), secondType, reqs, errors);
433447

434448
for (auto req : reqs)
435449
result.push_back({req, loc, /*wasInferred=*/false});
@@ -615,6 +629,7 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
615629
assert(!proto->hasLazyRequirementSignature());
616630

617631
SmallVector<Requirement, 2> result;
632+
SmallVector<RequirementError, 2> errors;
618633

619634
auto &ctx = proto->getASTContext();
620635

@@ -656,7 +671,8 @@ TypeAliasRequirementsRequest::evaluate(Evaluator &evaluator,
656671
// within this protocol or a protocol it inherits.
657672
auto recordInheritedTypeRequirement = [&](TypeDecl *first, TypeDecl *second) {
658673
desugarSameTypeRequirement(getStructuralType(first),
659-
getStructuralType(second), result);
674+
getStructuralType(second),
675+
result, errors);
660676
};
661677

662678
// Local function to find the insertion point for the protocol's "where"

lib/AST/RequirementMachine/RequirementLowering.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ namespace rewriting {
4040
// documentation
4141
// comments.
4242

43-
void desugarRequirement(Requirement req, SmallVectorImpl<Requirement> &result);
43+
void desugarRequirement(Requirement req,
44+
SmallVectorImpl<Requirement> &result,
45+
SmallVectorImpl<RequirementError> &errors);
4446

4547
void inferRequirements(Type type, SourceLoc loc, ModuleDecl *module,
4648
SmallVectorImpl<StructuralRequirement> &result);

lib/AST/RequirementMachine/RequirementMachineRequests.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,11 @@ AbstractGenericSignatureRequestRQM::evaluate(
477477
baseSignature.getRequirements().begin(),
478478
baseSignature.getRequirements().end());
479479

480+
// We need to create this errors vector to pass to
481+
// desugarRequirement, but this request should never
482+
// diagnose errors.
483+
SmallVector<RequirementError, 4> errors;
484+
480485
// The requirements passed to this request may have been substituted,
481486
// meaning the subject type might be a concrete type and not a type
482487
// parameter.
@@ -488,7 +493,7 @@ AbstractGenericSignatureRequestRQM::evaluate(
488493
// requirements where the subject type is always a type parameter,
489494
// which is what the RuleBuilder expects.
490495
for (auto req : addedRequirements)
491-
desugarRequirement(req, requirements);
496+
desugarRequirement(req, requirements, errors);
492497

493498
// Heap-allocate the requirement machine to save stack space.
494499
std::unique_ptr<RequirementMachine> machine(new RequirementMachine(

0 commit comments

Comments
 (0)