Skip to content

Commit 85df97e

Browse files
authored
Merge pull request #17953 from xedin/rdar-42056741-4.2
[4.2][Diagnostics] Transfer previously resolved types directly from expressions
2 parents d5fd738 + 639a33d commit 85df97e

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
@@ -2199,22 +2199,15 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
21992199
// telling us that it knows what it is doing, then believe it.
22002200
if (!options.contains(TCC_ForceRecheck)) {
22012201
if (CS.TC.isExprBeingDiagnosed(subExpr)) {
2202-
auto exprAndCS = CS.TC.getExprBeingDiagnosed(subExpr);
2203-
auto *savedExpr = exprAndCS.first;
2202+
auto *savedExpr = CS.TC.getExprBeingDiagnosed(subExpr);
22042203
if (subExpr == savedExpr)
22052204
return subExpr;
22062205

2207-
auto *oldCS = exprAndCS.second;
2208-
2209-
// The types on the result might have already been cached into
2210-
// another CS, but likely not this one.
2211-
if (oldCS != &CS)
2212-
CS.transferExprTypes(oldCS, savedExpr);
2213-
2206+
CS.cacheExprTypes(savedExpr);
22142207
return savedExpr;
22152208
}
22162209

2217-
CS.TC.addExprForDiagnosis(subExpr, std::make_pair(subExpr, &CS));
2210+
CS.TC.addExprForDiagnosis(subExpr, subExpr);
22182211
}
22192212

22202213
// Validate contextual type before trying to use it.
@@ -2300,7 +2293,8 @@ Expr *FailureDiagnosis::typeCheckChildIndependently(
23002293
SavedTypeData.restore();
23012294
}
23022295

2303-
CS.TC.addExprForDiagnosis(preCheckedExpr, std::make_pair(subExpr, &CS));
2296+
if (preCheckedExpr != subExpr)
2297+
CS.TC.addExprForDiagnosis(preCheckedExpr, subExpr);
23042298

23052299
return subExpr;
23062300
}

lib/Sema/ConstraintSystem.h

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

1329-
class TransferExprTypes : public ASTWalker {
1330-
ConstraintSystem &toCS;
1331-
ConstraintSystem &fromCS;
1332-
1333-
public:
1334-
TransferExprTypes(ConstraintSystem &toCS, ConstraintSystem &fromCS)
1335-
: toCS(toCS), fromCS(fromCS) {}
1336-
1337-
Expr *walkToExprPost(Expr *expr) override {
1338-
if (fromCS.hasType(expr))
1339-
toCS.setType(expr, fromCS.getType(expr));
1340-
1341-
return expr;
1342-
}
1343-
1344-
/// \brief Ignore statements.
1345-
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
1346-
return { false, stmt };
1347-
}
1348-
1349-
/// \brief Ignore declarations.
1350-
bool walkToDeclPre(Decl *decl) override { return false; }
1351-
};
1352-
13531329
public:
13541330

13551331
void setExprTypes(Expr *expr) {
@@ -1375,10 +1351,6 @@ class ConstraintSystem {
13751351
expr->walk(CacheExprTypes(expr, *this, excludeRoot));
13761352
}
13771353

1378-
void transferExprTypes(ConstraintSystem *oldCS, Expr *expr) {
1379-
expr->walk(TransferExprTypes(*this, *oldCS));
1380-
}
1381-
13821354
/// \brief The current solver state.
13831355
///
13841356
/// 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.
@@ -907,7 +901,7 @@ class TypeChecker final : public LazyResolver {
907901
llvm::DenseSet<CanType> CIntegerTypes;
908902

909903
/// The set of expressions currently being analyzed for failures.
910-
llvm::DenseMap<Expr*, ExprAndConstraintSystem> DiagnosedExprs;
904+
llvm::DenseMap<Expr*, Expr*> DiagnosedExprs;
911905

912906
ModuleDecl *StdlibModule = nullptr;
913907

@@ -2497,13 +2491,13 @@ class TypeChecker final : public LazyResolver {
24972491
void checkInitializerErrorHandling(Initializer *I, Expr *E);
24982492
void checkEnumElementErrorHandling(EnumElementDecl *D);
24992493

2500-
void addExprForDiagnosis(Expr *E1, ExprAndConstraintSystem Result) {
2494+
void addExprForDiagnosis(Expr *E1, Expr *Result) {
25012495
DiagnosedExprs[E1] = Result;
25022496
}
25032497
bool isExprBeingDiagnosed(Expr *E) {
25042498
return DiagnosedExprs.count(E);
25052499
}
2506-
ExprAndConstraintSystem getExprBeingDiagnosed(Expr *E) {
2500+
Expr *getExprBeingDiagnosed(Expr *E) {
25072501
return DiagnosedExprs[E];
25082502
}
25092503

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)