Skip to content

[ConstraintSystem] Return of the new disjunction favoring/selection algorithm #79461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 42 commits into
base: main
Choose a base branch
from

Conversation

xedin
Copy link
Contributor

@xedin xedin commented Feb 18, 2025

@xedin
Copy link
Contributor Author

xedin commented Feb 18, 2025

@swift-ci please test source compatibility

@xedin
Copy link
Contributor Author

xedin commented Feb 18, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Feb 18, 2025

@swift-ci please build toolchain

@xedin xedin force-pushed the solver-perf-frankenstein branch from f785515 to 21a3705 Compare February 19, 2025 08:37
@xedin
Copy link
Contributor Author

xedin commented Feb 19, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Feb 19, 2025

@swift-ci please test source compatibility

@xedin xedin force-pushed the solver-perf-frankenstein branch 2 times, most recently from f442ec8 to 6a4b7e7 Compare February 20, 2025 22:51
@xedin
Copy link
Contributor Author

xedin commented Feb 20, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Feb 20, 2025

@swift-ci please test source compatibility

@xedin
Copy link
Contributor Author

xedin commented Feb 21, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Feb 21, 2025

@swift-ci please test source compatibility

@xedin xedin force-pushed the solver-perf-frankenstein branch from 367b059 to 37e3e32 Compare February 21, 2025 04:33
@xedin
Copy link
Contributor Author

xedin commented Feb 21, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Feb 21, 2025

@swift-ci please test source compatibility

@xedin
Copy link
Contributor Author

xedin commented Feb 21, 2025

Debug source compatibility failure is UPASS on Doggie which is expected.

@xedin xedin force-pushed the solver-perf-frankenstein branch from 37e3e32 to a7ac64a Compare March 1, 2025 02:55
@xedin xedin force-pushed the solver-perf-frankenstein branch 3 times, most recently from d593771 to d8608a3 Compare March 16, 2025 05:14
@xedin
Copy link
Contributor Author

xedin commented Mar 16, 2025

@swift-ci please test

@xedin
Copy link
Contributor Author

xedin commented Apr 21, 2025

@swift-ci please clean test

@xedin
Copy link
Contributor Author

xedin commented Apr 21, 2025

@swift-ci please test source compatibility

@xedin
Copy link
Contributor Author

xedin commented Apr 21, 2025

@swift-ci please test Windows platform

@xedin xedin force-pushed the solver-perf-frankenstein branch from d156df4 to a806a05 Compare April 29, 2025 16:42
@xedin xedin force-pushed the solver-perf-frankenstein branch from a806a05 to cc06572 Compare May 17, 2025 07:42
xedin added 2 commits June 7, 2025 23:41
… matching

Result type should only be matched if there are matches on arguments
or there are no viable candidates.
xedin added 29 commits June 7, 2025 23:41
…ures

If there are no-same type requirements and parameters use
either concrete types or generic parameter types directly,
the optimizer should be able to handle ranking. Currently
candidate arguments are considered in isolation which makes
it impossible to deal with same-type requirements and
complex generic signatures.
… `nil` while ranking `==` and `!=` operators

`==` and `!=` operators have special overloads that allow matching
`nil` literal on either side even if wrapped type on the other side
doesn't conform to `Equatable`.
…t` on `Dictionary`

Just like a subscript on `Array` if key type matches the argument
type exactly, the result of subscript operator should be a value
type wrappend in an `Optional`.
…eneric paameter types

For example passing `Int?` to `T` should be considered a match
if `T` doesn't have any requirements that block it.
…nt behavior

Thanks to `LinkedExprAnalyzer` unary argument hack was able to
infer matching based on literals and arithmetic operator chains,
let's preserve that behavior in a more principled manner.
…s based speculation

New ranking + selection algorithm suffered from over-eagerly selecting
operator disjunctions vs. unsupported non-operator ones even if the
ranking was based purely on literal candidates.

This change introduces a notion of a speculative candidate - one which
has a type inferred from a literal or an initializer call that has
failable overloads and/or implicit conversions (i.e. Double/CGFloat).

`determineBestChoicesInContext` would reset the score of an operator
disjunction which was computed based on speculative candidates alone
but would preserve favoring information. This way selection algorithm
would not be skewed towards operators and at the same time if there
is no no choice by to select one we'd still have favoring information
available which is important for operator chains that consist purely
of literals.
…s are considered

Some of the disjunctions are not supported by the optimizers but
could still be a better choice than an operator. Using a non-score
based preference mechanism first allows us to make sure that
operator disjunctions are not selected too eagerly in some situations
when i.e. a member (supported or not) could be a better choice.

`isPreferable` currently targets only operators in result builder
contexts but it could be expanded to more uses in the future.
…ameters and ternary expressions

We need to have a notion of "complete" binding set before
we can allow inference from generic parameters and ternary,
otherwise we'd make a favoring decision that might not be
correct i.e. `v ?? (<<cond>> ? nil : o)` where `o` is `Int`.
`getBindingsFor` doesn't currently infer transitive bindings
which means that for a ternary we'd only have a single
binding - `Int` which could lead to favoring overload of
`??` and has non-optional parameter on the right-hand side.
The test was slow with hacks but now it's much faster - takes about
63k scopes to solve, it could be improved by introducing new overloads
of prefix `-` to stdlib.
…plyExpr`s

The original hack never applied to subscripts.
…tors vs. non-operators

The problem this is trying to solve is eager selection of operators
over unsupported disjunctions, when matching operators let's take
speculative information into account because it helps to make better
choices in this case.
…arameter types

When matching candidate like `[Int]` against `Array<Element>`
we need to conservatively assume that if the nominals match
the argument is a viable exact match because otherwise it's
possible to skip some of the valid matches when other overload
choice have generic parameters at the same parameter position.
…ments or variadic overloads

This matches the behavior of the old hack where favoring choices
were rolled back if `mustConsider` produced `true` which happened
only for protocol requirements and variadic overload choice regardless
of their viability.
Instead of checking both protocols, check one that matches best
depending on where `String` literal candidate came from.
…ices are failable

If all of the viable initializer overloads are failable,
the only valid inference choice is an optional candidate type.
…rator chains

Most of them don't have any children but string interpolation does
and that marks whole chain as unsupported.
These choices could be better than some other non-disfavored ones
in certain situations i.e. when `async` overload is disfavored
but appears in async context it's preferrable to a non-async
overload choice.

Note that the code that mimic old hacks still needs to filter on
`@_disfavoredOverload` in few places to maintain source compatibility.
…he call instead of callee

`calleeFn` now returns the underlying declaration reference looking through
`ConstructorRefCallExpr`, which means the downgrade logic needs to check
whether the call is using initializer reference before making a decision.
@xedin xedin force-pushed the solver-perf-frankenstein branch from cc06572 to 02ab2dd Compare June 8, 2025 07:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant