Skip to content

Commit f5c3a76

Browse files
authored
Merge pull request #16234 from slavapestov/start-gutting-expr-cleaner-crap
Start gutting ExprCleaner and friends
2 parents 5fc07b8 + c89a4a5 commit f5c3a76

File tree

12 files changed

+94
-137
lines changed

12 files changed

+94
-137
lines changed

include/swift/AST/Expr.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ class alignas(8) Expr {
403403
Type getType() const { return Ty; }
404404

405405
/// setType - Sets the type of this expression.
406-
void setType(Type T) { Ty = T; }
406+
void setType(Type T);
407407

408408
/// \brief Return the source range of the expression.
409409
SourceRange getSourceRange() const;
@@ -717,13 +717,20 @@ class ErrorExpr : public Expr {
717717
/// can help us preserve the context of the code completion position.
718718
class CodeCompletionExpr : public Expr {
719719
SourceRange Range;
720+
bool Activated;
721+
720722
public:
721723
CodeCompletionExpr(SourceRange Range, Type Ty = Type()) :
722724
Expr(ExprKind::CodeCompletion, /*Implicit=*/true, Ty),
723-
Range(Range) {}
725+
Range(Range) {
726+
Activated = false;
727+
}
724728

725729
SourceRange getSourceRange() const { return Range; }
726730

731+
bool isActivated() const { return Activated; }
732+
void setActivated() { Activated = true; }
733+
727734
static bool classof(const Expr *E) {
728735
return E->getKind() == ExprKind::CodeCompletion;
729736
}

include/swift/AST/Pattern.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ class alignas(8) Pattern {
126126

127127
/// Set the type of this pattern, given that it was previously not
128128
/// type-checked.
129-
void setType(Type ty) { Ty = ty; }
129+
void setType(Type ty) {
130+
assert(!ty || !ty->hasTypeVariable());
131+
Ty = ty;
132+
}
130133

131134
/// Retrieve the delayed interface type of this pattern, if it has one.
132135
///

include/swift/AST/TypeLoc.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,7 @@ struct TypeLoc {
6565
bool isNull() const { return getType().isNull() && TyR == nullptr; }
6666

6767
void setInvalidType(ASTContext &C);
68-
void setType(Type Ty, bool validated = false) {
69-
TAndValidBit.setPointerAndInt(Ty, validated);
70-
}
68+
void setType(Type Ty, bool validated = false);
7169

7270
TypeLoc clone(ASTContext &ctx) const;
7371
};

lib/AST/Expr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ namespace {
117117
};
118118
} // end anonymous namespace
119119

120+
void Expr::setType(Type T) {
121+
assert(!T || !T->hasTypeVariable());
122+
Ty = T;
123+
}
124+
120125
template <class T> static SourceRange getSourceRangeImpl(const T *E) {
121126
static_assert(isOverriddenFromExpr(&T::getSourceRange) ||
122127
(isOverriddenFromExpr(&T::getStartLoc) &&

lib/AST/Type.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ Type QuerySubstitutionMap::operator()(SubstitutableType *type) const {
6666
return subMap.lookupSubstitution(key);
6767
}
6868

69+
void TypeLoc::setType(Type Ty, bool validated) {
70+
assert(!Ty || !Ty->hasTypeVariable());
71+
TAndValidBit.setPointerAndInt(Ty, validated);
72+
}
73+
6974
bool TypeLoc::isError() const {
7075
assert(wasValidated() && "Type not yet validated");
7176
return getType()->hasError();

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,8 @@ namespace {
19121912

19131913
Expr *visitCodeCompletionExpr(CodeCompletionExpr *expr) {
19141914
// Do nothing with code completion expressions.
1915+
auto toType = simplifyType(cs.getType(expr));
1916+
cs.setType(expr, toType);
19151917
return expr;
19161918
}
19171919

lib/Sema/CSGen.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,13 +1164,16 @@ namespace {
11641164
}
11651165

11661166
virtual Type visitCodeCompletionExpr(CodeCompletionExpr *E) {
1167-
// If the expression has already been assigned a type; just use that type.
1168-
return E->getType();
1167+
if (!E->isActivated())
1168+
return Type();
1169+
1170+
return CS.createTypeVariable(CS.getConstraintLocator(E),
1171+
TVO_CanBindToLValue);
11691172
}
11701173

11711174
Type visitLiteralExpr(LiteralExpr *expr) {
11721175
// If the expression has already been assigned a type; just use that type.
1173-
if (expr->getType() && !expr->getType()->hasTypeVariable())
1176+
if (expr->getType())
11741177
return expr->getType();
11751178

11761179
auto protocol = CS.getTypeChecker().getLiteralProtocol(expr);
@@ -1234,7 +1237,7 @@ namespace {
12341237

12351238
Type visitObjectLiteralExpr(ObjectLiteralExpr *expr) {
12361239
// If the expression has already been assigned a type; just use that type.
1237-
if (expr->getType() && !expr->getType()->hasTypeVariable())
1240+
if (expr->getType())
12381241
return expr->getType();
12391242

12401243
auto &tc = CS.getTypeChecker();
@@ -3553,7 +3556,7 @@ bool swift::typeCheckUnresolvedExpr(DeclContext &DC,
35533556
auto *TC = static_cast<TypeChecker*>(DC.getASTContext().getLazyResolver());
35543557
ConstraintSystem CS(*TC, &DC, Options);
35553558
Parent = Parent->walk(SanitizeExpr(CS));
3556-
CleanupIllFormedExpressionRAII cleanup(TC->Context, Parent);
3559+
CleanupIllFormedExpressionRAII cleanup(Parent);
35573560
InferUnresolvedMemberConstraintGenerator MCG(E, CS);
35583561
ConstraintWalker cw(MCG);
35593562
Parent->walk(cw);

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -461,13 +461,13 @@ Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
461461
}
462462

463463
// Map the generic parameters to their corresponding type variables.
464-
llvm::SmallVector<TypeLoc, 4> arguments;
464+
llvm::SmallVector<Type, 2> arguments;
465465
for (auto gp : unboundDecl->getInnermostGenericParamTypes()) {
466466
auto found = replacements.find(
467467
cast<GenericTypeParamType>(gp->getCanonicalType()));
468468
assert(found != replacements.end() &&
469469
"Missing generic parameter?");
470-
arguments.push_back(TypeLoc::withoutLoc(found->second));
470+
arguments.push_back(found->second);
471471
}
472472

473473
// FIXME: For some reason we can end up with unbound->getDecl()
@@ -477,7 +477,6 @@ Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
477477
return TC.applyUnboundGenericArguments(
478478
unbound, unboundDecl,
479479
SourceLoc(), DC, arguments,
480-
/*options*/TypeResolutionOptions(),
481480
/*resolver*/nullptr,
482481
/*unsatisfiedDependency*/nullptr);
483482
}

lib/Sema/ConstraintSystem.h

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,9 +3398,6 @@ void eraseOpenedExistentials(constraints::ConstraintSystem &CS, Expr *&expr);
33983398
/// their type variables, and we don't want pointers into the original AST to
33993399
/// dereference these now-dangling types.
34003400
class ExprCleaner {
3401-
llvm::SmallVector<Expr*,4> Exprs;
3402-
llvm::SmallVector<TypeLoc*, 4> TypeLocs;
3403-
llvm::SmallVector<Pattern*, 4> Patterns;
34043401
llvm::SmallVector<VarDecl*, 4> Vars;
34053402
public:
34063403

@@ -3409,21 +3406,6 @@ class ExprCleaner {
34093406
ExprCleaner *TS;
34103407
ExprCleanerImpl(ExprCleaner *TS) : TS(TS) {}
34113408

3412-
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
3413-
TS->Exprs.push_back(expr);
3414-
return { true, expr };
3415-
}
3416-
3417-
bool walkToTypeLocPre(TypeLoc &TL) override {
3418-
TS->TypeLocs.push_back(&TL);
3419-
return true;
3420-
}
3421-
3422-
std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
3423-
TS->Patterns.push_back(P);
3424-
return { true, P };
3425-
}
3426-
34273409
bool walkToDeclPre(Decl *D) override {
34283410
if (auto VD = dyn_cast<VarDecl>(D))
34293411
TS->Vars.push_back(VD);
@@ -3444,22 +3426,6 @@ class ExprCleaner {
34443426
~ExprCleaner() {
34453427
// Check each of the expression nodes to verify that there are no type
34463428
// variables hanging out. If so, just nuke the type.
3447-
for (auto E : Exprs) {
3448-
if (E->getType() && E->getType()->hasTypeVariable())
3449-
E->setType(Type());
3450-
}
3451-
3452-
for (auto TL : TypeLocs) {
3453-
if (TL->getTypeRepr() && TL->getType() &&
3454-
TL->getType()->hasTypeVariable())
3455-
TL->setType(Type(), false);
3456-
}
3457-
3458-
for (auto P : Patterns) {
3459-
if (P->hasType() && P->getType()->hasTypeVariable())
3460-
P->setType(Type());
3461-
}
3462-
34633429
for (auto VD : Vars) {
34643430
if (VD->hasType() && VD->getType()->hasTypeVariable()) {
34653431
VD->setType(Type());

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,31 +1649,9 @@ void PreCheckExpression::resolveKeyPathExpr(KeyPathExpr *KPE) {
16491649

16501650
/// \brief Clean up the given ill-formed expression, removing any references
16511651
/// to type variables and setting error types on erroneous expression nodes.
1652-
void CleanupIllFormedExpressionRAII::doIt(Expr *expr, ASTContext &Context) {
1652+
void CleanupIllFormedExpressionRAII::doIt(Expr *expr) {
16531653
class CleanupIllFormedExpression : public ASTWalker {
1654-
ASTContext &context;
1655-
16561654
public:
1657-
CleanupIllFormedExpression(ASTContext &context) : context(context) { }
1658-
1659-
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
1660-
// If the type of this expression has a type variable or is invalid,
1661-
// overwrite it with ErrorType.
1662-
Type type = expr->getType();
1663-
if (type && type->hasTypeVariable())
1664-
expr->setType(ErrorType::get(context));
1665-
1666-
return { true, expr };
1667-
}
1668-
1669-
// If we find a TypeLoc (e.g. in an as? expr) with a type variable, rewrite
1670-
// it.
1671-
bool walkToTypeLocPre(TypeLoc &TL) override {
1672-
if (TL.getType() && TL.getType()->hasTypeVariable())
1673-
TL.setType(Type(), /*was validated*/false);
1674-
return true;
1675-
}
1676-
16771655
bool walkToDeclPre(Decl *D) override {
16781656
// This handles parameter decls in ClosureExprs.
16791657
if (auto VD = dyn_cast<VarDecl>(D)) {
@@ -1692,13 +1670,13 @@ void CleanupIllFormedExpressionRAII::doIt(Expr *expr, ASTContext &Context) {
16921670
};
16931671

16941672
if (expr)
1695-
expr->walk(CleanupIllFormedExpression(Context));
1673+
expr->walk(CleanupIllFormedExpression());
16961674
}
16971675

16981676

16991677
CleanupIllFormedExpressionRAII::~CleanupIllFormedExpressionRAII() {
17001678
if (expr)
1701-
CleanupIllFormedExpressionRAII::doIt(*expr, Context);
1679+
CleanupIllFormedExpressionRAII::doIt(*expr);
17021680
}
17031681

17041682
/// Pre-check the expression, validating any types that occur in the
@@ -1825,7 +1803,7 @@ Type TypeChecker::typeCheckExpression(Expr *&expr, DeclContext *dc,
18251803
csOptions |= ConstraintSystemFlags::PreferForceUnwrapToOptional;
18261804
ConstraintSystem cs(*this, dc, csOptions);
18271805
cs.baseCS = baseCS;
1828-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
1806+
CleanupIllFormedExpressionRAII cleanup(expr);
18291807
ExprCleaner cleanup2(expr);
18301808

18311809
// Verify that a purpose was specified if a convertType was. Note that it is
@@ -1940,7 +1918,7 @@ getTypeOfExpressionWithoutApplying(Expr *&expr, DeclContext *dc,
19401918

19411919
// Construct a constraint system from this expression.
19421920
ConstraintSystem cs(*this, dc, ConstraintSystemFlags::AllowFixes);
1943-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
1921+
CleanupIllFormedExpressionRAII cleanup(expr);
19441922

19451923
// Attempt to solve the constraint system.
19461924
SmallVector<Solution, 4> viable;
@@ -2035,7 +2013,7 @@ void TypeChecker::getPossibleTypesOfExpressionWithoutApplying(
20352013
// If the previous checking gives the expr error type,
20362014
// clear the result and re-check.
20372015
{
2038-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
2016+
CleanupIllFormedExpressionRAII cleanup(expr);
20392017

20402018
const Type originalType = expr->getType();
20412019
if (originalType && originalType->hasError())
@@ -2058,7 +2036,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
20582036

20592037
// Construct a constraint system from this expression.
20602038
ConstraintSystem CS(*this, DC, ConstraintSystemFlags::AllowFixes);
2061-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
2039+
CleanupIllFormedExpressionRAII cleanup(expr);
20622040

20632041
auto *SE = cast<SequenceExpr>(expr);
20642042
assert(SE->getNumElements() >= 3);
@@ -2089,9 +2067,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
20892067
assert(exprAsBinOp == expr && "found wrong expr?");
20902068

20912069
// Add type variable for the code-completion expression.
2092-
auto tvRHS =
2093-
CS.createTypeVariable(CS.getConstraintLocator(CCE), TVO_CanBindToLValue);
2094-
CCE->setType(tvRHS);
2070+
CCE->setActivated();
20952071

20962072
if (auto generated = CS.generateConstraints(expr)) {
20972073
expr = generated;
@@ -2137,7 +2113,7 @@ bool TypeChecker::typeCheckExpressionShallow(Expr *&expr, DeclContext *dc) {
21372113

21382114
// Construct a constraint system from this expression.
21392115
ConstraintSystem cs(*this, dc, ConstraintSystemFlags::AllowFixes);
2140-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
2116+
CleanupIllFormedExpressionRAII cleanup(expr);
21412117
if (auto generatedExpr = cs.generateConstraintsShallow(expr))
21422118
expr = generatedExpr;
21432119
else
@@ -3003,7 +2979,7 @@ bool TypeChecker::convertToType(Expr *&expr, Type type, DeclContext *dc,
30032979
// TODO: need to add kind arg?
30042980
// Construct a constraint system from this expression.
30052981
ConstraintSystem cs(*this, dc, ConstraintSystemFlags::AllowFixes);
3006-
CleanupIllFormedExpressionRAII cleanup(Context, expr);
2982+
CleanupIllFormedExpressionRAII cleanup(expr);
30072983

30082984
// If there is a type that we're expected to convert to, add the conversion
30092985
// constraint.

0 commit comments

Comments
 (0)