Skip to content

Commit f1a94fe

Browse files
committed
[Diagnostics] Transfer previously resolved types directly from expressions
While trying to diagnose the problem with previously type-checked sub-expression, use its type-checked variant as a source of type information, instead of transferring from its original constraint system, because if expression was type-checked successfully it would have all of the required information in AST, and that doesn't rely on associated constraint system being present. Resolves: rdar://problem/42056741 (cherry picked from commit d324969)
1 parent d5fd738 commit f1a94fe

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
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/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

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

0 commit comments

Comments
 (0)