[CS] Merge VarRefCollector & UnresolvedVarCollector

These now do basically the same thing, merge their
implementations.
This commit is contained in:
Hamish Knight
2023-07-17 17:32:47 +01:00
parent 09bb346b03
commit 067583a1e3
3 changed files with 73 additions and 128 deletions

View File

@@ -239,71 +239,6 @@ private:
}
};
/// Find any references to not yet resolved outer VarDecls (including closure
/// parameters) used in the body of the inner closure. This is required because
/// isolated conjunctions, just like single-expression closures, have
/// to be connected to type variables they are going to use, otherwise
/// they'll get placed in a separate solver component and would never
/// produce a solution.
class UnresolvedVarCollector : public ASTWalker {
ConstraintSystem &CS;
llvm::SmallSetVector<TypeVariableType *, 4> Vars;
public:
UnresolvedVarCollector(ConstraintSystem &cs) : CS(cs) {}
MacroWalking getMacroWalkingBehavior() const override {
return MacroWalking::Arguments;
}
PreWalkResult<Expr *> walkToExprPre(Expr *expr) override {
if (auto *DRE = dyn_cast<DeclRefExpr>(expr)) {
auto *decl = DRE->getDecl();
if (isa<VarDecl>(decl)) {
if (auto type = CS.getTypeIfAvailable(decl)) {
if (auto *typeVar = type->getAs<TypeVariableType>()) {
Vars.insert(typeVar);
} else if (type->hasTypeVariable()) {
// Parameter or result type could be only partially
// resolved e.g. `{ (x: X) -> Void in ... }` where
// `X` is a generic type.
SmallPtrSet<TypeVariableType *, 4> typeVars;
type->getTypeVariables(typeVars);
Vars.insert(typeVars.begin(), typeVars.end());
}
}
}
}
// FIXME: We can see UnresolvedDeclRefExprs here because we don't walk into
// patterns when running preCheckExpression, since we don't resolve patterns
// until CSGen. We ought to consider moving pattern resolution into
// pre-checking, which would allow us to pre-check patterns normally.
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)) {
SmallPtrSet<TypeVariableType *, 4> typeVars;
varType->getTypeVariables(typeVars);
Vars.insert(typeVars.begin(), typeVars.end());
}
}
}
}
return Action::Continue(expr);
}
ArrayRef<TypeVariableType *> getVariables() const {
return Vars.getArrayRef();
}
};
// MARK: Constraint generation
/// Check whether it makes sense to convert this element into a constraint.
@@ -387,7 +322,7 @@ static void createConjunction(ConstraintSystem &cs,
isIsolated = true;
}
UnresolvedVarCollector paramCollector(cs);
VarRefCollector paramCollector(cs);
for (const auto &entry : elements) {
ASTNode element = std::get<0>(entry);
@@ -415,7 +350,7 @@ static void createConjunction(ConstraintSystem &cs,
if (constraints.empty())
return;
for (auto *externalVar : paramCollector.getVariables())
for (auto *externalVar : paramCollector.getTypeVars())
referencedVars.push_back(externalVar);
cs.addUnsolvedConstraint(Constraint::createConjunction(