Skip to content

Commit 45634bd

Browse files
authored
Merge pull request #17947 from xedin/rdar-42056741
[Diagnostics] Transfer previously resolved types directly from expressions
2 parents 436b861 + 939f6d4 commit 45634bd

File tree

5 files changed

+54
-48
lines changed

5 files changed

+54
-48
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,22 +2356,15 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
23562356
// telling us that it knows what it is doing, then believe it.
23572357
if (!options.contains(TCC_ForceRecheck)) {
23582358
if (CS.TC.isExprBeingDiagnosed(subExpr)) {
2359-
auto exprAndCS = CS.TC.getExprBeingDiagnosed(subExpr);
2360-
auto *savedExpr = exprAndCS.first;
2359+
auto *savedExpr = CS.TC.getExprBeingDiagnosed(subExpr);
23612360
if (subExpr == savedExpr)
23622361
return subExpr;
23632362

2364-
auto *oldCS = exprAndCS.second;
2365-
2366-
// The types on the result might have already been cached into
2367-
// another CS, but likely not this one.
2368-
if (oldCS != &CS)
2369-
CS.transferExprTypes(oldCS, savedExpr);
2370-
2363+
CS.cacheExprTypes(savedExpr);
23712364
return savedExpr;
23722365
}
23732366

2374-
CS.TC.addExprForDiagnosis(subExpr, std::make_pair(subExpr, &CS));
2367+
CS.TC.addExprForDiagnosis(subExpr, subExpr);
23752368
}
23762369

23772370
// Validate contextual type before trying to use it.
@@ -2448,7 +2441,8 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
24482441
SavedTypeData.restore();
24492442
}
24502443

2451-
CS.TC.addExprForDiagnosis(preCheckedExpr, std::make_pair(subExpr, &CS));
2444+
if (preCheckedExpr != subExpr)
2445+
CS.TC.addExprForDiagnosis(preCheckedExpr, subExpr);
24522446

24532447
return subExpr;
24542448
}

lib/Sema/ConstraintSystem.h

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,30 +1335,6 @@ class ConstraintSystem {
13351335
bool walkToDeclPre(Decl *decl) override { return false; }
13361336
};
13371337

1338-
class TransferExprTypes : public ASTWalker {
1339-
ConstraintSystem &toCS;
1340-
ConstraintSystem &fromCS;
1341-
1342-
public:
1343-
TransferExprTypes(ConstraintSystem &toCS, ConstraintSystem &fromCS)
1344-
: toCS(toCS), fromCS(fromCS) {}
1345-
1346-
Expr *walkToExprPost(Expr *expr) override {
1347-
if (fromCS.hasType(expr))
1348-
toCS.setType(expr, fromCS.getType(expr));
1349-
1350-
return expr;
1351-
}
1352-
1353-
/// \brief Ignore statements.
1354-
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
1355-
return { false, stmt };
1356-
}
1357-
1358-
/// \brief Ignore declarations.
1359-
bool walkToDeclPre(Decl *decl) override { return false; }
1360-
};
1361-
13621338
public:
13631339

13641340
void setExprTypes(Expr *expr) {
@@ -1384,10 +1360,6 @@ class ConstraintSystem {
13841360
expr->walk(CacheExprTypes(expr, *this, excludeRoot));
13851361
}
13861362

1387-
void transferExprTypes(ConstraintSystem *oldCS, Expr *expr) {
1388-
expr->walk(TransferExprTypes(*this, *oldCS));
1389-
}
1390-
13911363
/// \brief The current solver state.
13921364
///
13931365
/// This will be non-null when we're actively solving the constraint

lib/Sema/TypeChecker.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ namespace constraints {
5757
using ConformanceMap =
5858
llvm::DenseMap<SubstitutableType *, SmallVector<ProtocolConformance *, 2>>;
5959

60-
/// \brief Used for recursive lookups into an expr that is already
61-
/// being type-checked and the constraint system in which its type is
62-
/// stored.
63-
using ExprAndConstraintSystem =
64-
std::pair<Expr *, constraints::ConstraintSystem *>;
65-
6660
/// Special-case type checking semantics for certain declarations.
6761
enum class DeclTypeCheckingSemantics {
6862
/// A normal declaration.
@@ -779,7 +773,7 @@ class TypeChecker final : public LazyResolver {
779773
Optional<NominalTypeDecl *> ArrayDecl;
780774

781775
/// The set of expressions currently being analyzed for failures.
782-
llvm::DenseMap<Expr*, ExprAndConstraintSystem> DiagnosedExprs;
776+
llvm::DenseMap<Expr*, Expr*> DiagnosedExprs;
783777

784778
ModuleDecl *StdlibModule = nullptr;
785779

@@ -2311,13 +2305,13 @@ class TypeChecker final : public LazyResolver {
23112305
void checkInitializerErrorHandling(Initializer *I, Expr *E);
23122306
void checkEnumElementErrorHandling(EnumElementDecl *D);
23132307

2314-
void addExprForDiagnosis(Expr *E1, ExprAndConstraintSystem Result) {
2308+
void addExprForDiagnosis(Expr *E1, Expr *Result) {
23152309
DiagnosedExprs[E1] = Result;
23162310
}
23172311
bool isExprBeingDiagnosed(Expr *E) {
23182312
return DiagnosedExprs.count(E);
23192313
}
2320-
ExprAndConstraintSystem getExprBeingDiagnosed(Expr *E) {
2314+
Expr *getExprBeingDiagnosed(Expr *E) {
23212315
return DiagnosedExprs[E];
23222316
}
23232317

test/Constraints/rdar42056741.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
class A {
7+
static var `default` = A()
8+
9+
func foo(arg: String) -> Bool {
10+
return false
11+
}
12+
13+
func foo(arg: String, _ flag: UnsafeMutablePointer<ObjCBool>?) -> Bool {
14+
return true
15+
}
16+
}
17+
18+
class B {
19+
var bar: Bool = false
20+
func baz() {
21+
bar = A.default.foo(arg: self.) // expected-error {{expected member name following '.'}}
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-ide-test(mock-sdk: %clang-importer-sdk) -code-completion -code-completion-token=COMPLETE -source-filename=%s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
class A {
7+
static var `default` = A()
8+
9+
func foo(arg: String) -> Bool {
10+
return false
11+
}
12+
13+
func foo(arg: String, _ flag: UnsafeMutablePointer<ObjCBool>?) -> Bool {
14+
return true
15+
}
16+
}
17+
18+
class B {
19+
var bar: Bool = false
20+
func baz() {
21+
bar = A.default.foo(arg: self.#^COMPLETE^#)
22+
}
23+
}

0 commit comments

Comments
 (0)