diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp index f7489412dc0f2..01f7095abbcb4 100644 --- a/lib/Sema/CSSolver.cpp +++ b/lib/Sema/CSSolver.cpp @@ -1449,53 +1449,77 @@ ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables) { } bool ConstraintSystem::Candidate::solve() { - // Cleanup after constraint system generation/solving, - // because it would assign types to expressions, which - // might interfere with solving higher-level expressions. - ExprCleaner cleaner(E); + // For cleanup to work correctly e.g. `CleanupIllFormedExpressionRAII` + // `E` has to be 'reference to pointer' but, in this situation, it can't + // because we don't want to accidently modify AST while trying to reduce + // type domains of sub-expressions. Because constraint generation _might_ + // produce completely different expression let's use a locally scoped + // 'reference to pointer' variable instead of `E` which enables both + // proper constraint generation/solving and cleanup. + auto *&expr = E; + { + // Cleanup after constraint system generation/solving, + // because it would assign types to expressions, which + // might interfere with solving higher-level expressions. + ExprCleaner cleaner(expr); + CleanupIllFormedExpressionRAII cleanup(TC.Context, expr); + + // Allocate new constraint system for sub-expression. + ConstraintSystem cs(TC, DC, None); + + // Generate constraints for the new system. + if (auto generatedExpr = cs.generateConstraints(expr)) { + expr = generatedExpr; + } else { + // Failure to generate constraint system for sub-expression + // means we can't continue solving sub-expressions. + return true; + } - // Allocate new constraint system for sub-expression. - ConstraintSystem cs(TC, DC, None); + // If there is contextual type present, add an explicit "conversion" + // constraint to the system. + if (!CT.isNull()) { + auto constraintKind = ConstraintKind::Conversion; + if (CTP == CTP_CallArgument) + constraintKind = ConstraintKind::ArgumentConversion; - // Generate constraints for the new system. - if (auto generatedExpr = cs.generateConstraints(E)) { - E = generatedExpr; - } else { - // Failure to generate constraint system for sub-expression means we can't - // continue solving sub-expressions. - return true; - } - - // If there is contextual type present, add an explicit "conversion" - // constraint to the system. - if (!CT.isNull()) { - auto constraintKind = ConstraintKind::Conversion; - if (CTP == CTP_CallArgument) - constraintKind = ConstraintKind::ArgumentConversion; + cs.addConstraint(constraintKind, cs.getType(expr), CT, + cs.getConstraintLocator(expr), /*isFavored=*/true); + } - cs.addConstraint(constraintKind, cs.getType(E), CT, - cs.getConstraintLocator(E), /*isFavored=*/true); - } + // Try to solve the system and record all available solutions. + llvm::SmallVector solutions; + { + SolverState state(cs); - // Try to solve the system and record all available solutions. - llvm::SmallVector solutions; - { - SolverState state(cs); + // Use solveRec() instead of solve() in here, because solve() + // would try to deduce the best solution, which we don't + // really want. Instead, we want the reduced set of domain choices. + cs.solveRec(solutions, FreeTypeVariableBinding::Allow); + } - // Use solveRec() instead of solve() in here, because solve() - // would try to deduce the best solution, which we don't - // really want. Instead, we want the reduced set of domain choices. - cs.solveRec(solutions, FreeTypeVariableBinding::Allow); - } + // No solutions for the sub-expression means that either main expression + // needs salvaging or it's inconsistent (read: doesn't have solutions). + if (solutions.empty()) + return true; - // No solutions for the sub-expression means that either main expression - // needs salvaging or it's inconsistent (read: doesn't have solutions). - if (solutions.empty()) - return true; + // Record found solutions as suggestions. + this->applySolutions(solutions); + + // Solution application is going to modify types of sub-expresssions, + // so we need to avoid clean-up afterwords, but let's double-check + // if we have any implicit expressions with type variables and + // nullify their types. + cleanup.disable(); + expr->forEachChildExpr([&](Expr *childExpr) -> Expr * { + Type type = childExpr->getType(); + if (childExpr->isImplicit() && type && type->hasTypeVariable()) + childExpr->setType(Type()); + return childExpr; + }); - // Record found solutions as suggestions. - this->applySolutions(solutions); - return false; + return false; + } } void ConstraintSystem::Candidate::applySolutions( diff --git a/validation-test/compiler_crashers/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift b/validation-test/compiler_crashers_fixed/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift similarity index 80% rename from validation-test/compiler_crashers/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift rename to validation-test/compiler_crashers_fixed/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift index 2d7b5b3a5765d..06a785dc0b637 100644 --- a/validation-test/compiler_crashers/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift +++ b/validation-test/compiler_crashers_fixed/28593-unreachable-executed-at-swift-lib-ast-type-cpp-3771.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir [{_=#keyPath(t>w diff --git a/validation-test/compiler_crashers/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift b/validation-test/compiler_crashers_fixed/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift similarity index 81% rename from validation-test/compiler_crashers/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift rename to validation-test/compiler_crashers_fixed/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift index e3ec7a3ebaa14..2c333c7a2d636 100644 --- a/validation-test/compiler_crashers/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift +++ b/validation-test/compiler_crashers_fixed/28623-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir f#keyPath(n&_==a>c{{{{{{{{{{{{{{{{{_=b:{{{{c{{{{{{d diff --git a/validation-test/compiler_crashers/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift b/validation-test/compiler_crashers_fixed/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift similarity index 80% rename from validation-test/compiler_crashers/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift rename to validation-test/compiler_crashers_fixed/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift index ae32b2f9ea681..ec248a45d86b9 100644 --- a/validation-test/compiler_crashers/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift +++ b/validation-test/compiler_crashers_fixed/28631-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir [{{{{{{{{{{{{{{0=#keyPath(n&_=d diff --git a/validation-test/compiler_crashers/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift b/validation-test/compiler_crashers_fixed/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift similarity index 83% rename from validation-test/compiler_crashers/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift rename to validation-test/compiler_crashers_fixed/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift index c22489c5ad611..7cf03a0912d30 100644 --- a/validation-test/compiler_crashers/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift +++ b/validation-test/compiler_crashers_fixed/28632-unreachable-executed-at-swift-lib-ast-type-cpp-1130.swift @@ -5,9 +5,8 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior // REQUIRES: asserts -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir {func a> print(a==#keyPath(a{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{ diff --git a/validation-test/compiler_crashers/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift b/validation-test/compiler_crashers_fixed/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift similarity index 74% rename from validation-test/compiler_crashers/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift rename to validation-test/compiler_crashers_fixed/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift index 82f3bc015f01a..e0aaea40dbae9 100644 --- a/validation-test/compiler_crashers/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift +++ b/validation-test/compiler_crashers_fixed/28635-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift @@ -5,7 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir func a|Set(#keyPath(t>a>a{ diff --git a/validation-test/compiler_crashers/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift b/validation-test/compiler_crashers_fixed/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift similarity index 80% rename from validation-test/compiler_crashers/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift rename to validation-test/compiler_crashers_fixed/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift index 70b9a429a48cb..849688ae16ba6 100644 --- a/validation-test/compiler_crashers/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift +++ b/validation-test/compiler_crashers_fixed/28639-unreachable-executed-at-swift-lib-ast-type-cpp-1337.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir print([{#keyPath(a}(t>A diff --git a/validation-test/compiler_crashers/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift b/validation-test/compiler_crashers_fixed/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift similarity index 80% rename from validation-test/compiler_crashers/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift rename to validation-test/compiler_crashers_fixed/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift index 40f87f57fa236..acaf2bc933c75 100644 --- a/validation-test/compiler_crashers/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift +++ b/validation-test/compiler_crashers_fixed/28640-swift-tupletype-get-llvm-arrayref-swift-tupletypeelt-swift-astcontext-const.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir protocol a func a|Set(#keyPath(t>a{ diff --git a/validation-test/compiler_crashers/28641-result-case-not-implemented.swift b/validation-test/compiler_crashers_fixed/28641-result-case-not-implemented.swift similarity index 82% rename from validation-test/compiler_crashers/28641-result-case-not-implemented.swift rename to validation-test/compiler_crashers_fixed/28641-result-case-not-implemented.swift index ef6976bfe3c51..d3370b0ab9172 100644 --- a/validation-test/compiler_crashers/28641-result-case-not-implemented.swift +++ b/validation-test/compiler_crashers_fixed/28641-result-case-not-implemented.swift @@ -5,7 +5,6 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior // REQUIRES: asserts -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir {let β=b&[{{{#keyPath(n&[{{{{{{{{{{{{{{{{{{{{{{{{{{a{{{{s diff --git a/validation-test/compiler_crashers/28642-swift-optionaltype-get-swift-type.swift b/validation-test/compiler_crashers_fixed/28642-swift-optionaltype-get-swift-type.swift similarity index 80% rename from validation-test/compiler_crashers/28642-swift-optionaltype-get-swift-type.swift rename to validation-test/compiler_crashers_fixed/28642-swift-optionaltype-get-swift-type.swift index 9fe9ea6a92851..c2e862abfb3e4 100644 --- a/validation-test/compiler_crashers/28642-swift-optionaltype-get-swift-type.swift +++ b/validation-test/compiler_crashers_fixed/28642-swift-optionaltype-get-swift-type.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir Array(_==#keyPath(t>Void! diff --git a/validation-test/compiler_crashers/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift b/validation-test/compiler_crashers_fixed/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift similarity index 80% rename from validation-test/compiler_crashers/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift rename to validation-test/compiler_crashers_fixed/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift index f797ed802dbb5..26986fc8bd929 100644 --- a/validation-test/compiler_crashers/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift +++ b/validation-test/compiler_crashers_fixed/28645-swift-type-transform-llvm-function-ref-swift-type-swift-type-const.swift @@ -5,6 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir (.n).h.n&[(#keyPath(t>A diff --git a/validation-test/compiler_crashers/28646-swift-lvaluetype-get-swift-type.swift b/validation-test/compiler_crashers_fixed/28646-swift-lvaluetype-get-swift-type.swift similarity index 81% rename from validation-test/compiler_crashers/28646-swift-lvaluetype-get-swift-type.swift rename to validation-test/compiler_crashers_fixed/28646-swift-lvaluetype-get-swift-type.swift index 569bfa8082f85..772fd2340a16a 100644 --- a/validation-test/compiler_crashers/28646-swift-lvaluetype-get-swift-type.swift +++ b/validation-test/compiler_crashers_fixed/28646-swift-lvaluetype-get-swift-type.swift @@ -5,8 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// REQUIRES: deterministic-behavior -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir #keyPath(a print(Int print(_=#keyPath(a