Skip to content

Commit ac6ea62

Browse files
xedinahoppen
authored andcommitted
[CSGen] NFC: Extract var reference collector to be used in more places
1 parent d55f737 commit ac6ea62

File tree

1 file changed

+59
-58
lines changed

1 file changed

+59
-58
lines changed

lib/Sema/CSGen.cpp

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,61 @@ namespace {
848848

849849
namespace {
850850

851+
// Collect any variable references whose types involve type variables,
852+
// because there will be a dependency on those type variables once we have
853+
// generated constraints for the closure/tap body. This includes references
854+
// to other closure params such as in `{ x in { x }}` where the inner
855+
// closure is dependent on the outer closure's param type, as well as
856+
// cases like `for i in x where bar({ i })` where there's a dependency on
857+
// the type variable for the pattern `i`.
858+
struct VarRefCollector : public ASTWalker {
859+
ConstraintSystem &cs;
860+
llvm::SmallPtrSet<TypeVariableType *, 4> varRefs;
861+
862+
VarRefCollector(ConstraintSystem &cs) : cs(cs) {}
863+
864+
bool shouldWalkCaptureInitializerExpressions() override { return true; }
865+
866+
MacroWalking getMacroWalkingBehavior() const override {
867+
return MacroWalking::Arguments;
868+
}
869+
870+
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
871+
// Retrieve type variables from references to var decls.
872+
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
873+
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
874+
if (auto varType = cs.getTypeIfAvailable(varDecl)) {
875+
varType->getTypeVariables(varRefs);
876+
}
877+
}
878+
}
879+
880+
// FIXME: We can see UnresolvedDeclRefExprs here because we have
881+
// not yet run preCheckExpression() on the entire closure body
882+
// yet.
883+
//
884+
// We could consider pre-checking more eagerly.
885+
if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
886+
auto name = declRef->getName();
887+
auto loc = declRef->getLoc();
888+
if (name.isSimpleName() && loc.isValid()) {
889+
auto *varDecl =
890+
dyn_cast_or_null<VarDecl>(ASTScope::lookupSingleLocalDecl(
891+
cs.DC->getParentSourceFile(), name.getFullName(), loc));
892+
if (varDecl)
893+
if (auto varType = cs.getTypeIfAvailable(varDecl))
894+
varType->getTypeVariables(varRefs);
895+
}
896+
}
897+
898+
return Action::Continue(expr);
899+
}
900+
901+
PreWalkAction walkToDeclPre(Decl *D) override {
902+
return Action::VisitChildrenIf(isa<PatternBindingDecl>(D));
903+
}
904+
};
905+
851906
class ConstraintGenerator : public ExprVisitor<ConstraintGenerator, Type> {
852907
ConstraintSystem &CS;
853908
DeclContext *CurDC;
@@ -2902,76 +2957,22 @@ namespace {
29022957
auto *locator = CS.getConstraintLocator(closure);
29032958
auto closureType = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
29042959

2905-
// Collect any variable references whose types involve type variables,
2906-
// because there will be a dependency on those type variables once we have
2907-
// generated constraints for the closure body. This includes references
2908-
// to other closure params such as in `{ x in { x }}` where the inner
2909-
// closure is dependent on the outer closure's param type, as well as
2910-
// cases like `for i in x where bar({ i })` where there's a dependency on
2911-
// the type variable for the pattern `i`.
2912-
struct CollectVarRefs : public ASTWalker {
2913-
ConstraintSystem &cs;
2914-
llvm::SmallPtrSet<TypeVariableType *, 4> varRefs;
2915-
2916-
CollectVarRefs(ConstraintSystem &cs) : cs(cs) { }
2917-
2918-
bool shouldWalkCaptureInitializerExpressions() override { return true; }
2919-
2920-
MacroWalking getMacroWalkingBehavior() const override {
2921-
return MacroWalking::Arguments;
2922-
}
2923-
2924-
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
2925-
// Retrieve type variables from references to var decls.
2926-
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
2927-
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
2928-
if (auto varType = cs.getTypeIfAvailable(varDecl)) {
2929-
varType->getTypeVariables(varRefs);
2930-
}
2931-
}
2932-
}
2933-
2934-
// FIXME: We can see UnresolvedDeclRefExprs here because we have
2935-
// not yet run preCheckExpression() on the entire closure body
2936-
// yet.
2937-
//
2938-
// We could consider pre-checking more eagerly.
2939-
if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
2940-
auto name = declRef->getName();
2941-
auto loc = declRef->getLoc();
2942-
if (name.isSimpleName() && loc.isValid()) {
2943-
auto *varDecl = dyn_cast_or_null<VarDecl>(
2944-
ASTScope::lookupSingleLocalDecl(cs.DC->getParentSourceFile(),
2945-
name.getFullName(), loc));
2946-
if (varDecl)
2947-
if (auto varType = cs.getTypeIfAvailable(varDecl))
2948-
varType->getTypeVariables(varRefs);
2949-
}
2950-
}
2951-
2952-
return Action::Continue(expr);
2953-
}
2954-
2955-
PreWalkAction walkToDeclPre(Decl *D) override {
2956-
return Action::VisitChildrenIf(isa<PatternBindingDecl>(D));
2957-
}
2958-
} collectVarRefs(CS);
2959-
2960+
VarRefCollector refCollector(CS);
29602961
// Walk the capture list if this closure has one, because it could
29612962
// reference declarations from the outer closure.
29622963
if (auto *captureList =
29632964
getAsExpr<CaptureListExpr>(CS.getParentExpr(closure))) {
2964-
captureList->walk(collectVarRefs);
2965+
captureList->walk(refCollector);
29652966
} else {
2966-
closure->walk(collectVarRefs);
2967+
closure->walk(refCollector);
29672968
}
29682969

29692970
auto inferredType = inferClosureType(closure);
29702971
if (!inferredType || inferredType->hasError())
29712972
return Type();
29722973

29732974
SmallVector<TypeVariableType *, 4> referencedVars{
2974-
collectVarRefs.varRefs.begin(), collectVarRefs.varRefs.end()};
2975+
refCollector.varRefs.begin(), refCollector.varRefs.end()};
29752976

29762977
CS.addUnsolvedConstraint(
29772978
Constraint::create(CS, ConstraintKind::FallbackType, closureType,

0 commit comments

Comments
 (0)