Skip to content

Commit cd93126

Browse files
committed
[GSB] Teach requirement inference to use SubstitutionMaps.
The ad hoc substitution functions here were really odd; use SubstitutionMap directly, and pass it through to GenericSignatureBuilder::addRequirement().
1 parent 908123a commit cd93126

File tree

4 files changed

+31
-33
lines changed

4 files changed

+31
-33
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ class GenericSignatureBuilder {
373373
/// where \c Dictionary requires that its key type be \c Hashable,
374374
/// the requirement \c K : Hashable is inferred from the parameter type,
375375
/// because the type \c Dictionary<K,V> cannot be formed without it.
376-
void inferRequirements(TypeLoc type);
376+
void inferRequirements(ModuleDecl &module, TypeLoc type);
377377

378378
/// Infer requirements from the given pattern, recursively.
379379
///
@@ -387,7 +387,8 @@ class GenericSignatureBuilder {
387387
/// where \c Dictionary requires that its key type be \c Hashable,
388388
/// the requirement \c K : Hashable is inferred from the parameter type,
389389
/// because the type \c Dictionary<K,V> cannot be formed without it.
390-
void inferRequirements(ParameterList *params,GenericParamList *genericParams);
390+
void inferRequirements(ModuleDecl &module, ParameterList *params,
391+
GenericParamList *genericParams);
391392

392393
/// Finalize the set of requirements, performing any remaining checking
393394
/// required before generating archetypes.

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,13 +2586,15 @@ bool GenericSignatureBuilder::addRequirement(
25862586

25872587
/// AST walker that infers requirements from type representations.
25882588
class GenericSignatureBuilder::InferRequirementsWalker : public TypeWalker {
2589+
ModuleDecl &module;
25892590
GenericSignatureBuilder &Builder;
25902591
TypeRepr *typeRepr;
25912592

25922593
public:
2593-
InferRequirementsWalker(GenericSignatureBuilder &builder,
2594+
InferRequirementsWalker(ModuleDecl &module,
2595+
GenericSignatureBuilder &builder,
25942596
TypeRepr *typeRepr)
2595-
: Builder(builder), typeRepr(typeRepr) { }
2597+
: module(module), Builder(builder), typeRepr(typeRepr) { }
25962598

25972599
Action walkToTypePost(Type ty) override {
25982600
auto boundGeneric = ty->getAs<BoundGenericType>();
@@ -2603,49 +2605,39 @@ class GenericSignatureBuilder::InferRequirementsWalker : public TypeWalker {
26032605
if (!genericSig)
26042606
return Action::Stop;
26052607

2606-
/// Retrieves the type substitution.
2607-
auto args = boundGeneric->getGenericArgs();
2608-
auto genericSigDepth =
2609-
genericSig->getInnermostGenericParams().front()->getDepth();
2610-
auto getTypeSubstitution = [&](SubstitutableType *dependentType) -> Type {
2611-
if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
2612-
if (gp->getDepth() == genericSigDepth)
2613-
return args[gp->getIndex()];
2614-
2615-
return gp;
2616-
}
2617-
2618-
return dependentType;
2619-
};
2608+
/// Retrieve the substitution.
2609+
auto allSubs = boundGeneric->gatherAllSubstitutions(&module, nullptr);
2610+
auto subMap = genericSig->getSubstitutionMap(allSubs);
26202611

26212612
// Handle the requirements.
26222613
// FIXME: Inaccurate TypeReprs.
26232614
auto source = FloatingRequirementSource::forInferred(typeRepr);
2624-
for (const auto &rawReq : genericSig->getRequirements()) {
2625-
if (auto req = rawReq.subst(getTypeSubstitution,
2626-
Builder.getLookupConformanceFn()))
2627-
Builder.addRequirement(*req, source);
2615+
for (const auto &req : genericSig->getRequirements()) {
2616+
Builder.addRequirement(req, source, &subMap);
26282617
}
26292618

26302619
return Action::Continue;
26312620
}
26322621
};
26332622

2634-
void GenericSignatureBuilder::inferRequirements(TypeLoc type) {
2623+
void GenericSignatureBuilder::inferRequirements(ModuleDecl &module,
2624+
TypeLoc type) {
26352625
if (!type.getType())
26362626
return;
26372627
// FIXME: Crummy source-location information.
2638-
InferRequirementsWalker walker(*this, type.getTypeRepr());
2628+
InferRequirementsWalker walker(module, *this, type.getTypeRepr());
26392629
type.getType().walk(walker);
26402630
}
26412631

2642-
void GenericSignatureBuilder::inferRequirements(ParameterList *params,
2643-
GenericParamList *genericParams) {
2632+
void GenericSignatureBuilder::inferRequirements(
2633+
ModuleDecl &module,
2634+
ParameterList *params,
2635+
GenericParamList *genericParams) {
26442636
if (genericParams == nullptr)
26452637
return;
26462638

26472639
for (auto P : *params)
2648-
inferRequirements(P->getTypeLoc());
2640+
inferRequirements(module, P->getTypeLoc());
26492641
}
26502642

26512643
/// Perform typo correction on the given nested type, producing the

lib/Sema/TypeCheckDecl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7464,7 +7464,8 @@ checkExtensionGenericParams(TypeChecker &tc, ExtensionDecl *ext, Type type,
74647464

74657465
// Local function used to infer requirements from the extended type.
74667466
auto inferExtendedTypeReqs = [&](GenericSignatureBuilder &builder) {
7467-
builder.inferRequirements(TypeLoc::withoutLoc(extInterfaceType));
7467+
builder.inferRequirements(*ext->getModuleContext(),
7468+
TypeLoc::withoutLoc(extInterfaceType));
74687469
};
74697470

74707471
// Validate the generic type signature.

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ void TypeChecker::checkGenericParamList(GenericSignatureBuilder *builder,
323323

324324
// Infer requirements from the inherited types.
325325
for (const auto &inherited : param->getInherited()) {
326-
builder->inferRequirements(inherited);
326+
builder->inferRequirements(*lookupDC->getParentModule(), inherited);
327327
}
328328
}
329329
}
@@ -508,7 +508,8 @@ static bool checkGenericFuncSignature(TypeChecker &tc,
508508

509509
// Infer requirements from the pattern.
510510
if (builder) {
511-
builder->inferRequirements(params, genericParams);
511+
builder->inferRequirements(*func->getParentModule(), params,
512+
genericParams);
512513
}
513514
}
514515

@@ -527,7 +528,8 @@ static bool checkGenericFuncSignature(TypeChecker &tc,
527528
// Infer requirements from it.
528529
if (builder && genericParams &&
529530
fn->getBodyResultTypeLoc().getTypeRepr()) {
530-
builder->inferRequirements(fn->getBodyResultTypeLoc());
531+
builder->inferRequirements(*func->getParentModule(),
532+
fn->getBodyResultTypeLoc());
531533
}
532534
}
533535
}
@@ -863,7 +865,8 @@ static bool checkGenericSubscriptSignature(TypeChecker &tc,
863865
// Infer requirements from it.
864866
if (genericParams && builder &&
865867
subscript->getElementTypeLoc().getTypeRepr()) {
866-
builder->inferRequirements(subscript->getElementTypeLoc());
868+
builder->inferRequirements(*subscript->getParentModule(),
869+
subscript->getElementTypeLoc());
867870
}
868871

869872
// Check the indices.
@@ -875,7 +878,8 @@ static bool checkGenericSubscriptSignature(TypeChecker &tc,
875878

876879
// Infer requirements from the pattern.
877880
if (builder)
878-
builder->inferRequirements(params, genericParams);
881+
builder->inferRequirements(*subscript->getParentModule(), params,
882+
genericParams);
879883

880884
return badType;
881885
}

0 commit comments

Comments
 (0)