diff --git a/lib/Sema/CSBindings.cpp b/lib/Sema/CSBindings.cpp index 45033e1bd7f2a..2074b0e39d191 100644 --- a/lib/Sema/CSBindings.cpp +++ b/lib/Sema/CSBindings.cpp @@ -1232,6 +1232,36 @@ bool BindingSet::isViable(PotentialBinding &binding, bool isTransitive) { return true; } +static bool hasConversions(Type type) { + if (type->isAnyHashable() || type->isDouble() || type->isCGFloat()) + return true; + + if (type->getAnyPointerElementType()) + return true; + + if (auto *structTy = type->getAs()) { + if (auto eltTy = structTy->isArrayType()) { + return hasConversions(eltTy); + } else if (auto pair = ConstraintSystem::isDictionaryType(structTy)) { + return hasConversions(pair->second); + } else if (auto eltTy = ConstraintSystem::isSetType(structTy)) { + return hasConversions(*eltTy); + } + + return false; + } + + if (auto *enumTy = type->getAs()) { + if (enumTy->getOptionalObjectType()) + return true; + + return false; + } + + return !(type->is() || type->is() || + type->is() || type->is()); +} + bool BindingSet::favoredOverDisjunction(Constraint *disjunction) const { if (isHole()) return false; @@ -1240,30 +1270,10 @@ bool BindingSet::favoredOverDisjunction(Constraint *disjunction) const { if (binding.Kind == AllowedBindingKind::Supertypes) return false; - auto type = binding.BindingType; - if (CS.shouldAttemptFixes()) return false; - if (type->isAnyHashable() || type->isDouble() || type->isCGFloat()) - return false; - - { - PointerTypeKind pointerKind; - if (type->getAnyPointerElementType(pointerKind)) { - switch (pointerKind) { - case PTK_UnsafeRawPointer: - case PTK_UnsafeMutableRawPointer: - return false; - - default: - break; - } - } - } - - return type->is() || type->is() || - type->is(); + return !hasConversions(binding.BindingType); })) { // Result type of subscript could be l-value so we can't bind it early. if (!TypeVar->getImpl().isSubscriptResultType() && diff --git a/validation-test/Sema/type_checker_perf/fast/array_concatenation.swift b/validation-test/Sema/type_checker_perf/fast/array_concatenation.swift new file mode 100644 index 0000000000000..1ce9d4293dc49 --- /dev/null +++ b/validation-test/Sema/type_checker_perf/fast/array_concatenation.swift @@ -0,0 +1,30 @@ +// RUN: %target-typecheck-verify-swift -solver-disable-shrink + +// Self-contained test case +protocol P1 {}; func f(_: T, _: T) -> T { fatalError() } +protocol P2 {}; func f(_: T, _: T) -> T { fatalError() } +protocol P3 {}; func f(_: T, _: T) -> T { fatalError() } +protocol P4 {}; func f(_: T, _: T) -> T { fatalError() } + +func f(_: Array, _: Array) -> Array { fatalError() } + +let fn1: (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> Array = { + f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f($0, $1), $2), $3), $4), $5), $6), $7), $8), $9), $10), $11), $12), $13), $14), $15), $16), $17), $18), $19) +} + +let fn2: (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> Array = { + f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f([$0], [$1]), [$2]), [$3]), [$4]), [$5]), [$6]), [$7]), [$8]), [$9]), [$10]), [$11]), [$12]), [$13]), [$14]), [$15]), [$16]), [$17]), [$18]), [$19]) +} + +let x1: Array = f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f([0], [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]), [0]) + +// Same setup with standard library operator +let fn3: (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> Array = { + $0 + $1 + $2 + $3 + $4 + $5 + $6 + $7 + $8 + $9 + $10 + $11 + $12 + $13 + $14 + $15 + $16 + $17 + $18 + $19 +} + +let fn4: (_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) -> Array = { + [$0] + [$1] + [$2] + [$3] + [$4] + [$5] + [$6] + [$7] + [$8] + [$9] + [$10] + [$11] + [$12] + [$13] + [$14] + [$15] + [$16] + [$17] + [$18] + [$19] +} + +let x2: Array = [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] + [0] diff --git a/validation-test/Sema/type_checker_perf/slow/mixed_string_array_addition.swift b/validation-test/Sema/type_checker_perf/fast/mixed_string_array_addition.swift similarity index 76% rename from validation-test/Sema/type_checker_perf/slow/mixed_string_array_addition.swift rename to validation-test/Sema/type_checker_perf/fast/mixed_string_array_addition.swift index aa0c3979b5ef2..75c7d1050eb4d 100644 --- a/validation-test/Sema/type_checker_perf/slow/mixed_string_array_addition.swift +++ b/validation-test/Sema/type_checker_perf/fast/mixed_string_array_addition.swift @@ -3,7 +3,6 @@ func method(_ arg: String, body: () -> [String]) {} func test(str: String, properties: [String]) { - // expected-error@+1 {{the compiler is unable to type-check this expression in reasonable time}} method(str + "" + str + "") { properties.map { param in "" + param + "" + param + "" + param + ""