Skip to content

Commit e3df69a

Browse files
committed
Add Solution::resolveConcreteDeclRef
This is a convenience member for computing the contextual substitutions for a decl reference at a given locator.
1 parent 049d56a commit e3df69a

File tree

2 files changed

+29
-37
lines changed

2 files changed

+29
-37
lines changed

lib/Sema/CSApply.cpp

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,17 @@ SubstitutionMap Solution::computeSubstitutions(
9696
lookupConformanceFn);
9797
}
9898

99+
ConcreteDeclRef
100+
Solution::resolveConcreteDeclRef(ValueDecl *decl,
101+
ConstraintLocatorBuilder locator) const {
102+
if (!decl)
103+
return ConcreteDeclRef();
104+
105+
// Get the generic signatue of the decl and compute the substitutions.
106+
auto sig = decl->getInnermostDeclContext()->getGenericSignatureOfContext();
107+
return ConcreteDeclRef(decl, computeSubstitutions(sig, locator));
108+
}
109+
99110
static bool shouldAccessStorageDirectly(Expr *base, VarDecl *member,
100111
DeclContext *DC) {
101112
// This only matters for stored properties.
@@ -490,13 +501,9 @@ namespace {
490501
return typeExpr;
491502
}
492503

493-
auto substitutions =
494-
solution.computeSubstitutions(
495-
decl->getInnermostDeclContext()->getGenericSignatureOfContext(),
496-
locator);
504+
auto ref = solution.resolveConcreteDeclRef(decl, locator);
497505
auto declRefExpr =
498-
new (ctx) DeclRefExpr(ConcreteDeclRef(decl, substitutions),
499-
loc, implicit, semantics, type);
506+
new (ctx) DeclRefExpr(ref, loc, implicit, semantics, type);
500507
cs.cacheType(declRefExpr);
501508
declRefExpr->setFunctionRefKind(functionRefKind);
502509
return forceUnwrapIfExpected(declRefExpr, choice, locator);
@@ -751,12 +758,7 @@ namespace {
751758
}
752759

753760
// Build a member reference.
754-
SubstitutionMap substitutions =
755-
solution.computeSubstitutions(
756-
member->getInnermostDeclContext()->getGenericSignatureOfContext(),
757-
memberLocator);
758-
auto memberRef = ConcreteDeclRef(member, substitutions);
759-
761+
auto memberRef = solution.resolveConcreteDeclRef(member, memberLocator);
760762
auto refTy = solution.simplifyType(openedFullType);
761763

762764
// If we're referring to the member of a module, it's just a simple
@@ -1400,12 +1402,9 @@ namespace {
14001402

14011403
// Form the subscript expression.
14021404

1403-
// Compute the substitutions used to reference the subscript.
1404-
SubstitutionMap substitutions =
1405-
solution.computeSubstitutions(
1406-
subscript->getInnermostDeclContext()->getGenericSignatureOfContext(),
1407-
locator.withPathElement(locatorKind));
1408-
ConcreteDeclRef subscriptRef(subscript, substitutions);
1405+
// Compute the concrete reference to the subscript.
1406+
auto subscriptRef = solution.resolveConcreteDeclRef(
1407+
subscript, locator.withPathElement(locatorKind));
14091408

14101409
// Handle dynamic lookup.
14111410
if (choice.getKind() == OverloadChoiceKind::DeclViaDynamic ||
@@ -1480,10 +1479,7 @@ namespace {
14801479
auto &ctx = tc.Context;
14811480

14821481
// Compute the concrete reference.
1483-
SubstitutionMap substitutions =
1484-
solution.computeSubstitutions(ctor->getGenericSignature(), locator);
1485-
1486-
auto ref = ConcreteDeclRef(ctor, substitutions);
1482+
auto ref = solution.resolveConcreteDeclRef(ctor, locator);
14871483

14881484
// The constructor was opened with the allocating type, not the
14891485
// initializer type. Map the former into the latter.
@@ -4525,17 +4521,11 @@ namespace {
45254521
// There is a fix which diagnoses such situation already.
45264522
assert(!varDecl->isStatic());
45274523

4528-
auto dc = property->getInnermostDeclContext();
4529-
4530-
// Compute substitutions to refer to the member.
4531-
SubstitutionMap subs = solution.computeSubstitutions(
4532-
dc->getGenericSignatureOfContext(), locator);
4533-
45344524
auto resolvedTy = overload.openedType;
45354525
resolvedTy = simplifyType(resolvedTy);
45364526

4537-
auto ref = ConcreteDeclRef(property, subs);
4538-
4527+
// Compute the concrete reference to the member.
4528+
auto ref = solution.resolveConcreteDeclRef(property, locator);
45394529
return KeyPathExpr::Component::forProperty(ref, resolvedTy,
45404530
componentLoc);
45414531
}
@@ -4561,12 +4551,9 @@ namespace {
45614551
subscript->getInterfaceType()->castTo<AnyFunctionType>()->getParams(),
45624552
/*canonicalVararg=*/false);
45634553

4564-
SubstitutionMap subs;
4565-
if (auto sig = dc->getGenericSignatureOfContext()) {
4566-
// Compute substitutions to refer to the member.
4567-
subs = solution.computeSubstitutions(sig, locator);
4568-
indexType = indexType.subst(subs);
4569-
}
4554+
// Compute substitutions to refer to the member.
4555+
auto ref = solution.resolveConcreteDeclRef(subscript, locator);
4556+
indexType = indexType.subst(ref.getSubstitutions());
45704557

45714558
// If this is a @dynamicMemberLookup reference to resolve a property
45724559
// through the subscript(dynamicMember:) member, restore the
@@ -4599,7 +4586,6 @@ namespace {
45994586
auto subscriptType =
46004587
simplifyType(overload.openedType)->castTo<AnyFunctionType>();
46014588
auto resolvedTy = subscriptType->getResult();
4602-
auto ref = ConcreteDeclRef(subscript, subs);
46034589

46044590
// Coerce the indices to the type the subscript expects.
46054591
auto *newIndexExpr =

lib/Sema/ConstraintSystem.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,12 @@ class Solution {
699699
SubstitutionMap computeSubstitutions(GenericSignature sig,
700700
ConstraintLocatorBuilder locator) const;
701701

702+
/// Resolves the contextual substitutions for a reference to a declaration
703+
/// at a given locator.
704+
ConcreteDeclRef
705+
resolveConcreteDeclRef(ValueDecl *decl,
706+
ConstraintLocatorBuilder locator) const;
707+
702708
/// Return the disjunction choice for the given constraint location.
703709
unsigned getDisjunctionChoice(ConstraintLocator *locator) const {
704710
assert(DisjunctionChoices.count(locator));

0 commit comments

Comments
 (0)