mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSGen] NFC: Extract var reference collector to be used in more places
This commit is contained in:
committed by
Alex Hoppen
parent
d55f737cc5
commit
ac6ea62cec
@@ -848,6 +848,61 @@ namespace {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Collect any variable references whose types involve type variables,
|
||||||
|
// because there will be a dependency on those type variables once we have
|
||||||
|
// generated constraints for the closure/tap body. This includes references
|
||||||
|
// to other closure params such as in `{ x in { x }}` where the inner
|
||||||
|
// closure is dependent on the outer closure's param type, as well as
|
||||||
|
// cases like `for i in x where bar({ i })` where there's a dependency on
|
||||||
|
// the type variable for the pattern `i`.
|
||||||
|
struct VarRefCollector : public ASTWalker {
|
||||||
|
ConstraintSystem &cs;
|
||||||
|
llvm::SmallPtrSet<TypeVariableType *, 4> varRefs;
|
||||||
|
|
||||||
|
VarRefCollector(ConstraintSystem &cs) : cs(cs) {}
|
||||||
|
|
||||||
|
bool shouldWalkCaptureInitializerExpressions() override { return true; }
|
||||||
|
|
||||||
|
MacroWalking getMacroWalkingBehavior() const override {
|
||||||
|
return MacroWalking::Arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
|
||||||
|
// Retrieve type variables from references to var decls.
|
||||||
|
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
|
||||||
|
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
|
||||||
|
if (auto varType = cs.getTypeIfAvailable(varDecl)) {
|
||||||
|
varType->getTypeVariables(varRefs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: We can see UnresolvedDeclRefExprs here because we have
|
||||||
|
// not yet run preCheckExpression() on the entire closure body
|
||||||
|
// yet.
|
||||||
|
//
|
||||||
|
// We could consider pre-checking more eagerly.
|
||||||
|
if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
|
||||||
|
auto name = declRef->getName();
|
||||||
|
auto loc = declRef->getLoc();
|
||||||
|
if (name.isSimpleName() && loc.isValid()) {
|
||||||
|
auto *varDecl =
|
||||||
|
dyn_cast_or_null<VarDecl>(ASTScope::lookupSingleLocalDecl(
|
||||||
|
cs.DC->getParentSourceFile(), name.getFullName(), loc));
|
||||||
|
if (varDecl)
|
||||||
|
if (auto varType = cs.getTypeIfAvailable(varDecl))
|
||||||
|
varType->getTypeVariables(varRefs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Action::Continue(expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
PreWalkAction walkToDeclPre(Decl *D) override {
|
||||||
|
return Action::VisitChildrenIf(isa<PatternBindingDecl>(D));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class ConstraintGenerator : public ExprVisitor<ConstraintGenerator, Type> {
|
class ConstraintGenerator : public ExprVisitor<ConstraintGenerator, Type> {
|
||||||
ConstraintSystem &CS;
|
ConstraintSystem &CS;
|
||||||
DeclContext *CurDC;
|
DeclContext *CurDC;
|
||||||
@@ -2902,68 +2957,14 @@ namespace {
|
|||||||
auto *locator = CS.getConstraintLocator(closure);
|
auto *locator = CS.getConstraintLocator(closure);
|
||||||
auto closureType = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
|
auto closureType = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
|
||||||
|
|
||||||
// Collect any variable references whose types involve type variables,
|
VarRefCollector refCollector(CS);
|
||||||
// because there will be a dependency on those type variables once we have
|
|
||||||
// generated constraints for the closure body. This includes references
|
|
||||||
// to other closure params such as in `{ x in { x }}` where the inner
|
|
||||||
// closure is dependent on the outer closure's param type, as well as
|
|
||||||
// cases like `for i in x where bar({ i })` where there's a dependency on
|
|
||||||
// the type variable for the pattern `i`.
|
|
||||||
struct CollectVarRefs : public ASTWalker {
|
|
||||||
ConstraintSystem &cs;
|
|
||||||
llvm::SmallPtrSet<TypeVariableType *, 4> varRefs;
|
|
||||||
|
|
||||||
CollectVarRefs(ConstraintSystem &cs) : cs(cs) { }
|
|
||||||
|
|
||||||
bool shouldWalkCaptureInitializerExpressions() override { return true; }
|
|
||||||
|
|
||||||
MacroWalking getMacroWalkingBehavior() const override {
|
|
||||||
return MacroWalking::Arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
|
|
||||||
// Retrieve type variables from references to var decls.
|
|
||||||
if (auto *declRef = dyn_cast<DeclRefExpr>(expr)) {
|
|
||||||
if (auto *varDecl = dyn_cast<VarDecl>(declRef->getDecl())) {
|
|
||||||
if (auto varType = cs.getTypeIfAvailable(varDecl)) {
|
|
||||||
varType->getTypeVariables(varRefs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: We can see UnresolvedDeclRefExprs here because we have
|
|
||||||
// not yet run preCheckExpression() on the entire closure body
|
|
||||||
// yet.
|
|
||||||
//
|
|
||||||
// We could consider pre-checking more eagerly.
|
|
||||||
if (auto *declRef = dyn_cast<UnresolvedDeclRefExpr>(expr)) {
|
|
||||||
auto name = declRef->getName();
|
|
||||||
auto loc = declRef->getLoc();
|
|
||||||
if (name.isSimpleName() && loc.isValid()) {
|
|
||||||
auto *varDecl = dyn_cast_or_null<VarDecl>(
|
|
||||||
ASTScope::lookupSingleLocalDecl(cs.DC->getParentSourceFile(),
|
|
||||||
name.getFullName(), loc));
|
|
||||||
if (varDecl)
|
|
||||||
if (auto varType = cs.getTypeIfAvailable(varDecl))
|
|
||||||
varType->getTypeVariables(varRefs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Action::Continue(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
PreWalkAction walkToDeclPre(Decl *D) override {
|
|
||||||
return Action::VisitChildrenIf(isa<PatternBindingDecl>(D));
|
|
||||||
}
|
|
||||||
} collectVarRefs(CS);
|
|
||||||
|
|
||||||
// Walk the capture list if this closure has one, because it could
|
// Walk the capture list if this closure has one, because it could
|
||||||
// reference declarations from the outer closure.
|
// reference declarations from the outer closure.
|
||||||
if (auto *captureList =
|
if (auto *captureList =
|
||||||
getAsExpr<CaptureListExpr>(CS.getParentExpr(closure))) {
|
getAsExpr<CaptureListExpr>(CS.getParentExpr(closure))) {
|
||||||
captureList->walk(collectVarRefs);
|
captureList->walk(refCollector);
|
||||||
} else {
|
} else {
|
||||||
closure->walk(collectVarRefs);
|
closure->walk(refCollector);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto inferredType = inferClosureType(closure);
|
auto inferredType = inferClosureType(closure);
|
||||||
@@ -2971,7 +2972,7 @@ namespace {
|
|||||||
return Type();
|
return Type();
|
||||||
|
|
||||||
SmallVector<TypeVariableType *, 4> referencedVars{
|
SmallVector<TypeVariableType *, 4> referencedVars{
|
||||||
collectVarRefs.varRefs.begin(), collectVarRefs.varRefs.end()};
|
refCollector.varRefs.begin(), refCollector.varRefs.end()};
|
||||||
|
|
||||||
CS.addUnsolvedConstraint(
|
CS.addUnsolvedConstraint(
|
||||||
Constraint::create(CS, ConstraintKind::FallbackType, closureType,
|
Constraint::create(CS, ConstraintKind::FallbackType, closureType,
|
||||||
|
|||||||
Reference in New Issue
Block a user