Skip to content

[ConstraintSystem] Remove LinkedExprAnalyzer #40786

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

Closed
wants to merge 13 commits into from

Conversation

xedin
Copy link
Contributor

@xedin xedin commented Jan 10, 2022

Based on #40748.

  • Split generic operators into separate partitions upfront (might be wasted work so could be improved);
  • Introduce a new partition for a "partially specialized" overloads such as <T>(Array<T>, Array<T>) -> Array<T> which could be checked right after "concrete" overloads because they are quick to rule out and are more specialized than other generic overloads;
  • Remove old logic that looked at other disjunction choices while partitioning current one;
  • Prevent solver from stopping before attempting generic overloads of unary operators when CGFloat<->Double conversion in involved.

xedin added 13 commits December 28, 2021 21:38
… one that has none

If one of the sides has no favored overloads, it's a strong enough
indication that we know more about the other side.
Prelude.

The core idea behind `shrink` is simple - reduce overload sets via
a bottom-up walk'n'solve that would utilize previously discovered
solutions along the way. This helps in some circumstances but requires
rollbacks and AST modification (if choices produced by previous steps
fail to produce solutions higher up). For some expressions, especially
ones with multiple generic overload sets, `shrink` is actively harmful
because it would never be able to produce useful results.

The Algorithm.

These changes integrate core idea of local information propagation
from `shrink` into the disjunction selection algorithm itself.

The algorithm itself is as follows - at the beginning use existing
selection algorithm (based on favoring, active choices, etc.) to
select the first disjunction to attempt, and push it to the stack
of "selected" disjunctions; next time solver requests a disjunction,
use the last selected one to pick the closest disjunction to it in
the AST order preferring parents over children.

For example:

```
         +
       /   \
     *     Float(<some variable e.g. `r` = 10))
   /  \
 exp   Float(1.0)
  |
 2.0
```

If solver starts by picking `Float(r)` first, it would then
attempt `+`, `exp` in that order. If it did pick `Float(1.0)`
then, the sequence is `*`, `+` and finally `exp`.

Since the main idea here to is keep everything as local as possible
along a given path, that means special handling for closures and tuples:

- Closures: if last disjunction is a call with a trailing closure argument,
  and such argument is resolved (constraint are generate for the body) -
  use selection algorithm to peek next disjunction from the body of the
  closure, and solve everything inside before moving to the next member
  in the chain (if any). This helps with linked member expressions e.g.
  `.map { ... }.filter { ... }.reduce { ... }`;

- Tuples: The idea here is to keep solving local to a current element
  until it runs out of disjunction, and then use selection algorithm to
  peek from the pool of disjunctions associated with other elements of
  the tuple.

Resolves: SR-10130
Resolves: rdar://48992848
Resolves: rdar://23682605
Resolves: rdar://46713933
…rom common result compulation

This is the situation where a property has the same name as a method e.g.

```swift
protocol P {
  var test: String { get }
}

extension P {
  var test: String { get { return "" } }
}

struct S : P {
  func test() -> Int { 42 }
}

var s = S()
s.test() // disjunction would have two choices here, one
         // for the property from `P` and one for the method of `S`.
```
In cases like this, let's exclude property overload from common
result determination because it cannot be applied.

Note that such overloads cannot be disabled, because they still
have to be checked in diagnostic mode and there is (currently)
no way to re-enable them for diagnostics.
@xedin
Copy link
Contributor Author

xedin commented Jan 10, 2022

@swift-ci please test source compatibility

@xedin
Copy link
Contributor Author

xedin commented Jan 10, 2022

@swift-ci please smoke test compiler performance

@swift-ci
Copy link
Contributor

Compilation-performance test failed

@xedin
Copy link
Contributor Author

xedin commented Jan 11, 2022

Looks like partitioning might be too aggressive now...

@xedin
Copy link
Contributor Author

xedin commented Dec 19, 2024

Superseded by #63585

@xedin xedin closed this Dec 19, 2024
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.

2 participants