Commit Graph

145 Commits

Author SHA1 Message Date
Slava Pestov
4f70388ee1 Sema: Incremental disjunction pruning 2026-02-20 19:30:35 -05:00
Slava Pestov
5f3c8a3926 Sema: Handle existential metatype conversions in scoreCandidateMatch() 2026-02-18 22:31:13 -05:00
Slava Pestov
96ab55e3b9 Sema: Remove unnecessary special case of Any in scoreCandidateMatch() 2026-02-18 22:28:21 -05:00
Slava Pestov
794a0f4eca Sema: Simplify isSubclassOf() 2026-02-18 22:28:21 -05:00
Slava Pestov
fde181df7c Sema: Remove unnecessary protocol superclass check in isSubtypeOfExistentialType()
If the candidate type conforms to the protocol, its going to satisfy
the protocol's superclass requirement on Self, too.
2026-02-18 22:28:21 -05:00
Slava Pestov
9b863df5cf Sema: Split off isSubtypeOfExistentialType() from isSubclassOf() 2026-02-18 22:28:21 -05:00
Slava Pestov
7cd06a5088 Sema: Split off TypeVariableType.h/.cpp 2026-02-05 09:19:01 -05:00
Slava Pestov
2e60d29973 Sema: Add -solver-{disable,enable}-performance-hacks flags 2026-02-03 16:34:10 -05:00
Slava Pestov
5cbdf4938e Sema: Tiny improvement to debug output in selectDisjunction() 2026-01-28 18:21:01 +00:00
Slava Pestov
fabe4b6315 Sema: Explicitly favor forced moves
If a disjunction has zero or one choices remaining, there's nothing
to lose by attempting it. This will become a more common occurrence
once disjunction pruning is enabled.
2026-01-26 21:48:59 +00:00
Slava Pestov
95a54ce82a Sema: Yet another constraint optimization pass
- Fixes https://github.com/swiftlang/swift/issues/55762
- Fixes rdar://32034560
2026-01-26 21:48:59 +00:00
Slava Pestov
c30ff009d3 Sema: Better -debug-constraints output in selectDisjunction() 2026-01-26 21:33:16 +00:00
Slava Pestov
d860523944 Merge pull request #86760 from slavapestov/solver-shuffle
Sema: Add -solver-shuffle-disjunctions= and -solver-shuffle-choices= flags for debugging
2026-01-24 12:30:43 -05:00
elsa
5e9f215f31 Merge pull request #86010 from elsakeirouz/rework-for-each-desugar
Rework ForEachStmt Desugaring
2026-01-24 13:55:51 +00:00
Slava Pestov
30f1b0187a Sema: Add -solver-shuffle-disjunctions= and -solver-shuffle-choices= flags for debugging 2026-01-23 20:02:21 -05:00
Hamish Knight
d3270fdf1e [CS] Remove ValueWitness constraint
The specialized type-checking for `for` loops was the only client of
this, it's now unused.
2026-01-23 15:17:30 +00:00
Pavel Yaskevich
411d396eb8 Merge pull request #86695 from xedin/remove-old-perf-hacks
[ConstraintSystem] Remove old performance hacks from the solver and related flags
2026-01-22 09:01:50 -08:00
Pavel Yaskevich
a33ec97216 [ConstraintSystem] Remove old performance hacks from the solver
The hacks have been disabled for a while now, so it's time to
completely remove them in favor of CSOptimizer.
2026-01-21 11:53:19 -08:00
Slava Pestov
7f7afd1629 Sema: Skip disabled constraints in computeDisjunctionInfo() 2026-01-21 13:20:40 -05:00
Slava Pestov
f762829c1a Sema: Split off computeDisjunctionInfo() from determineBestChoicesInContext()
The diff looks horrible but it's just moving a block of code out
into its own function and decreasing the indent level. Should be NFC.
2026-01-21 13:20:39 -05:00
Slava Pestov
4e39c0e694 Sema: Fix over-eager early return from determineBestChoicesInContext() 2026-01-21 11:10:44 -05:00
Slava Pestov
f74d94e4bf Sema: Extract scoreCandidateMatch() into a top-level function 2026-01-21 11:09:59 -05:00
Slava Pestov
2063c765b4 Sema: Add more logging to determineBestChoicesInContext() 2026-01-20 16:19:45 -05:00
Slava Pestov
611ceff5e0 Sema: Fix regression from floating point removal
In 7bcbe1b3f0, I forgot to scale the
value by 100 in one place. This wasn't caught by our test suite,
but it regressed the new test case I'm adding. We would select the
UnicodeScalar.init() overload taking an UInt8, and complain that
the scalar doesn't fit.
2026-01-17 23:20:29 -05:00
Slava Pestov
7bcbe1b3f0 Sema: Get rid of floating point arithmetic
I'm uncomfortable with the use of floating point arithmetic here.

Even though this is a performance heuristic, it actually impacts
solver behavior because of how choice favoring works, and because
disjunction selection order indirectly affects other broken solver
behaviors.

The constants used, like 0.01, 0.1, 0.7, etc. are not exactly
representable, so when they get added up the result might differ
from the "actual" result by a small amount.

Because of that, we don't want any "load bearing" behaviors where
someone's expression type checks quickly or in a certain way because
of pecularities of floating point arithmetic.

Instead, scale everything up by a factor of 100 and use integers.
2026-01-15 11:16:29 -05:00
Slava Pestov
302ff930e9 Sema: Remove areEqual() from determineBestChoicesInContext()
TypeBase::isEqual() canonicalizes both sides, so calling
getDesugaredType() first is not necessary.
2026-01-15 11:16:26 -05:00
Slava Pestov
3d1444353c Sema: Extract isSubclassOf() from determineBestChoicesInContext() 2026-01-15 11:16:26 -05:00
Slava Pestov
95769b59b9 Sema: Add debugging code to ConstraintSystem::selectDisjunction() 2026-01-08 09:44:42 -05:00
Slava Pestov
06f5eefcf5 Sema: Fix accidental mutation of DenseMap in ConstraintSystem::selectDisjunction()
The firstScore and secondScore bindings were references, so the
assignments to those were mutating the DenseMap unintentionally.

Refactor this code a bit, we don't want to just change the
bindings to rvalues because then we would copy the FavoredChoices
vector, so instead bind a const reference to the DisjunctionInfo
and dereference its fields instead.
2026-01-07 13:23:05 -05:00
Slava Pestov
74fa1e7f5e Sema: BindingSet::Literals can just be a vector and not a map 2025-12-13 21:16:43 -05:00
Clack Cole
a405fffebb [CSOptimizer] favor Any.Type for metatype args alongside Any fast-path
Resolves https://github.com/swiftlang/swift/issues/85020
2025-11-21 18:34:04 -07:00
Slava Pestov
23a7ca04bf Sema: Remove BindingSet::operator bool 2025-11-14 10:05:32 -05:00
Pavel Yaskevich
80e6cbf3ef Merge pull request #85460 from xedin/replace-checkconformancewithoutcontext-with-conformstoknownprotocol
[CSOptimizer] Use `conformsToKnownProtocol` to check whether paramete…
2025-11-13 07:40:36 -08:00
Pavel Yaskevich
62a917800d [CSOptimizer] Use conformsToKnownProtocol to check whether parameter conforms to ExpressibleBy{Array, Dictionary}Literal
The existing check is no-op because it would never produce a null for
`paramType` under the conditions in `else` branch. A better
API it use here is `conformsToKnownProtocol` just like in other cases.
2025-11-12 10:51:54 -08:00
Pavel Yaskevich
a01692ace1 [CSOptimizer] Skip ?? if it's involved in optional chain with unresolved result type
`??` operator is overloaded on optionality of its result. When the
first argument matches exactly, the ranking is going to be skewed
towards selecting an overload choice that returns a non-optional type.
This is not always correct i.e. when operator is involved in optional
chaining. To avoid producing an incorrect favoring, let's skip the this
disjunction when constraints associated with result type indicate
that it should be optional.

Simply adding it as a binding won't work because if the second argument
is non-optional the overload that returns `T?` would still have a lower
score.

Resolves: rdar://164201746
2025-11-11 15:21:33 -08:00
Pavel Yaskevich
c7b3b73708 Merge pull request #85391 from xedin/rdar-164247524
[CSOptimizer] Avoid favoring overloads that mismatch context on async
2025-11-10 09:52:17 -08:00
Hamish Knight
b26b0b783e [CS] Add null check for ParameterList in findFavoredChoicesBasedOnArity
rdar://164116965
2025-11-07 22:17:33 +00:00
Pavel Yaskevich
513caf2c9b [CSOptimizer] Avoid favoring overloads that mismatch context on async
This is a fix for the ported "calls with a single unlabeled argument"
hack. If overload doesn't match context on async effect, let's not favor
it because that is more important than defaulted parameters.

Resolves: rdar://164269641
2025-11-07 14:15:45 -08:00
Pavel Yaskevich
e1a6077117 [CSOptimizer] Update unary call favoring to include resolved member references
Update special favoring logic for unlabeled unary calls to support
non-overloads member references in argument positions.

The original hack missed a case where a type of a member is known
in advance (i.e. a property without overloads) because there as
another hack (shrink) for that.

This helps in situations like `Double(x)` where `x` is a property
of some type that is referenced using an implicit `self.` injected
by the compiler.

Resolves: rdar://161419917
2025-10-27 18:22:37 +09:00
Hamish Knight
3141b5a8cd [AST] NFC: Introduce PrintOptions::forDebugging 2025-09-21 23:19:06 +01:00
Pavel Yaskevich
df962a83c6 [CSOptimizer] Don't match nil to _OptionalNilComparisonType
This type is only intended for pattern matching against `nil`
and the solver shouldn't early attempt to infer this type for
`nil` for arguments of `==` and `!=` operators it should instead
be inferred from other argument or result.

Resolves: rdar://158063151
2025-09-01 20:47:56 -07:00
Pavel Yaskevich
0d33af78ca [CSOptimizer] Add support for opened existential arguments
Check whether it would be possible to match a parameter type
by opening an existential type of the candidate argument.

Resolves: rdar://158159462
2025-08-15 00:14:51 -07:00
Pavel Yaskevich
c46f9e4f45 [CSOptimizer] All the candidates should match Any parameter type
If the parameter is `Any` we assume that all candidates are
convertible to it, which makes it a perfect match. The solver
would then decide whether erasing to an existential is preferable.

Resolves: rdar://157644867
2025-08-13 14:59:54 -07:00
Pavel Yaskevich
9588d519c6 [CSOptimizer] Fix a conditional that ignores function type parameters to look through optionals
Since parameters that have function types don't participate in
ranking, function types that are wrapped in optionals should be
excluded as well, because it's possible to overload on that and
such overloads with optional types would gain an undue advantage.

For example:

```
func test(_: (() -> Void)?) {}
func test(_: () -> Void) {}

func compute(handler: () -> Void) {
  test(handler)
}
```

Without this change the second overload would be ignored and
the first one would be an exact match.

Resolves: rdar://157234317
2025-08-01 10:59:52 -07:00
Pavel Yaskevich
9445a9fca9 [CSOptimizer] Decrease an operator argument score only if requires optional injection
This makes sure that optional and non-optional types are ranked
uniformly when matched against a generic parameter type that
could accept either of them.

This is a more general fix for https://github.com/swiftlang/swift/pull/83365
2025-07-29 16:49:47 -07:00
Pavel Yaskevich
b264e27a75 [CSOptimizer] A narrow fix for nil coalescing operator optimization
`??` is overloaded on optionality of the second parameter,
prevent ranking the argument candidates for this parameter
if there are candidates that come from failable initializer
overloads because non-optional candidates are always going
to be better and that can skew the selection.

Resolves: rdar://156853018
2025-07-28 00:35:02 -07:00
Slava Pestov
30c7f4afa7 Sema: Handle ArchetypeType and DynamicSelfType in determineBestChoicesInContext()
This fixes a regression introduced in https://github.com/swiftlang/swift/pull/82574.

The test case demonstrates the issue: we would incorrectly choose the base class
overload of == if one of the parameters was an archetype or dynamic Self.

Fixes rdar://156454697.
2025-07-23 17:22:42 -04:00
Pavel Yaskevich
1f8e487e2e [CSOptimizer] Prefer logical infix operator if it has smaller overload set
Infix logical operators are usually not overloaded and don't
form disjunctions, but when they do, let's prefer them over
other operators when they have fewer choices because it helps
to split operator chains.
2025-07-08 00:10:47 -07:00
Pavel Yaskevich
979e0469e0 [CSOptimizer] Rework inferTypeOfArithmeticOperatorChain
- Expand the inference to include prefix and postfix unary operators
- Recognize previously resolved declaration and member references
  in argument positions and record their types.
- Expand reconciliation logic from Double<->Int to include other
  floating-point types and `CGFloat`.
2025-06-27 23:43:12 -07:00
Pavel Yaskevich
ef2be0d3f5 [CSOptimizer] Rank operators with the same score based on speculative status
If the scores are the same and both disjunctions are operators
they could be ranked purely based on whether the candidates
were speculative or not. The one with more context always wins.

Consider the following situation:

```swift
func test(_: Int) { ... }
func test(_: String) { ... }

test("a" + "b" + "c")
```

In this case we should always prefer ... + "c" over "a" + "b"
because it would fail and prune the other overload if parameter
type (aka contextual type) is `Int`.
2025-06-27 23:43:12 -07:00