Commit Graph

731 Commits

Author SHA1 Message Date
Mark Lacey
703341239b Add support for multiple designated types for an operator declaration.
Add parsing, type checking, serialization, and deserialization support
for specifying multiple types as "designated" for operator lookup for
a given operator declaration.

The constraint solver still considers only the first type when
deciding the order to attempt the elements of a disjunction, so this
doesn't really change behavior yet.
2018-10-09 23:54:01 -07:00
Mark Lacey
36284ba377 Extend operator decls to allow any designated nominal type for lookup.
Rather than limiting this to protocols, allow any nominal type.

Rename -enable-operator-designated-protocols to
-enable-operator-designated-types to reflect the change.
2018-10-06 17:02:31 -07:00
Mark Lacey
b08060b4f1 [ConstraintSystem] Fix mistake involving comparison to extension.
We need to compare the Decl for the nominal we're extending, not the
extension decl itself.
2018-10-06 01:27:40 -07:00
Mark Lacey
985bcba9c3 [ConstraintSystem] Address review feedback. 2018-10-03 23:27:19 -07:00
Mark Lacey
1f517d328d [ConstraintSystem] Distinguish between overloads from a type vs. an extension.
For operators with default implementations in an extension, we don't
want to typecheck it both with overloads from the protocol type and
the ones from the extension.
2018-10-03 18:51:43 -07:00
Mark Lacey
0955aa4677 [ConstraintSystem] Replace argument walk with a more robust utility.
For now this is only used for the same purpose as the previous type
constraint walking utility function.

Eventually we can incorporate this into our selection of overload
choices.
2018-10-03 18:08:00 -07:00
Mark Lacey
aad2295d9c [ConstraintSystem] Only look for overloads in the designated type if
one was designated.
2018-10-03 17:19:59 -07:00
Mark Lacey
86a6dc0e0e Fix small formatting problem. 2018-10-03 17:04:37 -07:00
Mark Lacey
93b553cf4d [ConstraintSystem] Use operator designated protocols to speed type checking.
Use the type designated in the operator declaration as a mechanism to
limit the exploration we do in constraint solving. If we can find a
solution with an overload defined within that type or an extension of
that type, we do not look at any of the other options in the
disjunction.

This is disabled by default, and enabled with
> `-swift-version 5 -Xfrontend -solver-enable-operator-designated-protocols`
2018-10-03 14:41:59 -07:00
Mark Lacey
9cc817db1b Merge branch 'master' into fix-ordering 2018-09-26 17:43:35 -07:00
Mark Lacey
61b96d039c Merge pull request #19469 from rudkx/disjunction-partitioning
[ConstraintSystem] Add the notion of disjunction partitioning.
2018-09-26 17:26:42 -07:00
Mark Lacey
1d227731c1 [ConstraintSystem] Only use the new disjunction ordering under -swift-version 5.
This will minimize the chance of breaking code. Currently SwiftLint
has one "too complex" expression with this change. Further changes to
the solver may improve that situation, and potentially allow us to
move this out from -swift-version 5 if we're willing to take the risk
of breaking some code as a result.
2018-09-26 14:55:07 -07:00
Mark Lacey
7e0c7040c0 [ConstraintSystem] Use shouldStopAt to limit disjunction choices.
Rather than using shouldStopAfter, use shouldStopAt, and check if
we're at the beginning of a disjunction (with an already successful
solution).
2018-09-26 13:42:40 -07:00
Pavel Yaskevich
bd527c114e [CSBindings] Don't consider dependent member types even if they are wrapped in optionals
Because binding producer is going to attempt to unwrap optionals
and try the type, which would lead to infinite recursion because
dependent member types aren't bindable.

Resolves: rdar://problem/44770297
2018-09-25 20:59:58 -07:00
Mark Lacey
d7cf84ab51 [ConstraintSystem] Use Param::getPlainType() rather than Param::getType(). 2018-09-20 15:26:13 -07:00
Mark Lacey
732b98fb05 [ConstraintSystem] Fold some logic into the gatherConstraints predicate. 2018-09-20 15:25:20 -07:00
Mark Lacey
dd6f57759b [ConstraintSystem] Use llvm::all_of. 2018-09-20 15:25:01 -07:00
Mark Lacey
948ee3c9bf [ConstraintSystem] Remove lambda that returns true since this argument
is defualted in the same way.
2018-09-20 14:24:34 -07:00
Mark Lacey
c6c66f6873 [ConstraintSystem] Change the order in which we visit disjunctions.
Attempt to visit disjunctions that are associated with applies where
we have at least some useful information about the types of all of the
arguments before visiting other disjunctions.

Two tests here got faster, and one slightly slower. One of the
faster tests is actually moving from test/ to the slow/ directory in
validation-test because despite going from 16s to less than 1s, it was
still borderline for what we consider the slow threshold, so I made
the test more complex. The one that got a little slower is
rdar22022980, which I also made more complex so that it is clearly
"slow" by the way we are testing it.

slower:
  rdar22022980.swift

faster:
  rdar33688063.swift
  expression_too_complex_4.swift
2018-09-20 13:15:59 -07:00
Pavel Yaskevich
ed9c219492 [CSStep] Add state transition verification
Instead of asserting in the solver loop, let's move all of that
logic into `SolverStep::transitionTo(StepState)` and verify state
transition validity there.
2018-09-19 16:08:01 -07:00
Pavel Yaskevich
8daaf905d6 [CSStep] Switch to use std::unique_ptr for work list
Instead of manually managing lifetime of the steps, let's just
use `std::unique_ptr` instead.
2018-09-19 11:19:15 -07:00
Pavel Yaskevich
82d07ad88d [ConstraintSystem] NFC: TypeBinding abstraction is no longer necessary 2018-09-17 15:28:37 -07:00
Pavel Yaskevich
bec3d28407 [CSStep] Add isDebugMode and getDebugLogger methods and refactor logging
Instead of using `TypeChecker` and related APIs directly every time,
let's just abstract it all away to easily check if solver is running
in debug mode and to produce indented logger.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
2eb0e824e4 [ConstraintSystem] Remove recursive solver algorithm and related logic
`solveRec` is now gone as well as all related logic,
such as attempting type variable and disjunction choices recursively.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
baceb68f85 [ConstraintSystem] Rename solveIteratively to solve and start using it
Remove solution filtering from new iterative `solve` method, and
replace all usages of `solveRec` with it.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
f9fcd271e7 [CSStep] Rework how splitter handles component steps
First of all, let the splitter transfer constraints from inactive
work-list to associated components. Also start tracking components
to reinstate constraints back to constraint system when everything
is done, this allows to execute component steps in any desirable order.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
cdc9810f00 [CSStep] Split SolverStep::take(bool) into setup, take and resume
Introduce a notion of `StepState` with some valid transitions,
and split monolithic `take(bool)` into three phases - `setup`, `take`, and
`resume`.

* `setup` - is preliminary state before the step has been taken
            for the first time.

* `take` - represents actual logic of the step, results in either
           step being done or suspended.

* `resume` - `take` might split steps into smaller ones to make
             incremental progress towards the target, which means
             that the main step has to be suspended. `resume` is
             triggered when all of the "follow-up" steps have been
             executed and are "done".
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
c9bf47cb39 [CSStep] Add Disjunction step
`DisjunctionStep` attempts all of the viable choices,
at least one of the choices has to succeed for disjunction
to be considered a success.

`DisjunctionStep` attempts each choice and generates followup
`SplitterStep` to see if applying choice to constraint system
resulted in any simplification.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
64415c81ff [CSStep] Rename advance to take(bool) and propagate failures
Failure propagation is crucial for splitter and component steps
because that's the only signal for them to figure out if they
could be completely solved or have to fail.

For example, if one of the component steps created by "split"
fails it would cascade to the rest of the pending component steps
receiving "fail" signal and ultimately result in failure of the
"split" when it's re-taken.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
7723487b18 [CSStep] Add StepResult container 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
60581da15e [ConstraintSystem] Add Splitter, Component and binding steps
* `SplitterStep` is responsible for running connected components
  algorithm to determine how many independent sub-systems there are.
  Once that's done it would create one `ComponentStep` per such
  sub-system, and move to try to solve each and then merge partial
  solutions produced by components into complete solution(s).

* `ComponentStep` represents a set of type variables and related
  constraints which could be solved independently. It's further
  simplified into "binding" steps which attempt type variable and
  disjunction choices.

* "Binding" steps such as `TypeVariableStep` and `DisjunctionStep`
  are responsible for trying type binding choices in attempt to
  simplify the system and produce a solution. After attempting each
  choice they introduce a new "split" step to compute more work.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
0dda1af94d [CSStep] Implement computeFollowupSteps 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
daf4c2f3b5 [CSSolver] Add skeleton of iterative solve
The idea so to split solving into non-recursive steps,
represented by `SolverStep`, each of the steps is resposible
for a unit of work e.g. attempting type variable or
disjunction bindings/choices.

Each step could produce more work via "follow-up" steps,
complete "partial" solution when it's done, or error which
terminates solver loop.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
e4252a5fc7 [ConstraintSystem] Add flags to TypeBinding 2018-09-05 12:32:40 -07:00
Pavel Yaskevich
2acfff0deb [ConstraintSystem] Unify type var and disjunction choice producers
Introduce a base `BindingProducer` type which can produce bindings
for both type variables and disjunctions.
2018-09-05 00:12:55 -07:00
Pavel Yaskevich
2d5d2d1bea [ConstraintSystem] NFC: Lambda no longer needed in tryTypeVariableBindings 2018-09-04 22:28:15 -07:00
Pavel Yaskevich
edfabc6715 [ConstraintSystem] NFC: Refactor solveForDisjunction to use TypeBinding
* Extract logic for attempting individual choices into `solveForDisjunctionChoice`
* Remove all of the unnecessary information from `DisjunctionChoice`
* Convert auxiliary logic to operate on `TypeBinding` instead of `DisjunctionChoice`
2018-09-04 22:27:54 -07:00
Pavel Yaskevich
a9bb68cea7 [ConstraintSystem] Extend TypeBinding to look more like a base class
Add all of the important information to the `TypeBinding` which covers
both type variable and disjunction choices.
2018-09-04 22:27:46 -07:00
Pavel Yaskevich
e5b63fa16c [ConstraintSystem] NFC: Unify type variable and disjunction choice representation
Introduce `TypeBinding` interface with a single `attempt` method
which is useful to encapsulate specific binding logic used for
attempting disjunction choices and type variable bindings under
a single interface. This makes it easier to unify top-level logic
responsible for binding enumeration.

It should also make it possible to introduce unified binding producer
interface in the future.
2018-09-03 23:27:41 -07:00
Pavel Yaskevich
d560b36c5c [ConstraintSystem] NFC: Move allowFreeTypeVariableBindings into SolverState
Currently `allowFreeTypeVariableBindings` flag has to be passed all
the way down from top-level `solve` call to `finalize` that forms
(partial and complete) solutions. Instead of doing that, let's just
make it a part of the solver state, which is already present
throughout whole solver run.
2018-08-31 19:51:11 -07:00
Pavel Yaskevich
f5aaa15df7 [CSSolver] NFC: Refactor tryTypeVariableBindings to use generator
Encapsulate most of the logic related to new binding generation
and iteration into `TypeVarBindingGenerator`. `tryTypeVariableBindings`
is only responsible for attempting bindings and recording results.

One more step towards iterative solver.
2018-08-31 00:53:03 -07:00
Pavel Yaskevich
f110942097 Merge pull request #19066 from xedin/try-typevar-bindings-cleanup
[CSBindings] Cleanup `tryTypeVariableBindings`
2018-08-30 16:12:51 -07:00
Pavel Yaskevich
2ae8e8d0cb [CSBindings] Cleanup tryTypeVariableBindings
* Move logic to ensure that r-value type var would get r-value type to `PotentialBindings`;
* Strip uncessary parens directly when creating `PotentialBinding`;
* Check if the binding is viable before inclusion in the set, instead of filtering it later;
* Assert that bindings don't have types with errors included in the set.
2018-08-30 00:08:26 -07:00
Mark Lacey
1d9d2049e4 Merge pull request #19063 from rudkx/a-few-less-scopes
[ConstraintSystem] Minor refactor to avoid creating scopes we don't n…
2018-08-29 20:09:18 -07:00
Mark Lacey
026d41556d [ConstraintSystem] Minor refactor to avoid creating scopes we don't need.
This probably won't hit much, and shouldn't change behavior in any way
outside of statistics we generate about the number of scopes that get
opened.
2018-08-29 18:32:48 -07:00
Pavel Yaskevich
012315fcaf [ConstraintSystem] NFC: Refactor solveForDisjunctionChoices to use iterator
Instead of passing a set of choices, locator and other flags to
`solveForDisjunctionChoices` directly, let's wrap all that information
into "disjunction" iterator which returns `DisjunctionChoice`s
directly.
2018-08-29 13:34:24 -07:00
Pavel Yaskevich
3be5c203e3 [ConstraintSystem] NFC: Move isExplicitConversion to Constraint
Since this logic is tightly coupled to constraint, it makes sense
to move just there, also it's easier to re-use it elsewhere since
it doesn't have to be `private` anymore.
2018-08-29 00:01:36 -07:00
Slava Pestov
2975f145a1 Sema: Remove ArgumentTupleConversion constraint now that its no longer used 2018-08-28 14:40:56 -07:00
Doug Gregor
8dc20dfcac [Type checker] Move TypeChecker::resolveType() into TypeResolution.
Now that type resolution is (almost completely) separated from the type
checker instance, move resolveType() out to TypeResolution where it
belongs.
2018-08-20 22:31:59 -07:00
Doug Gregor
7fa4f1df54 Merge pull request #18859 from DougGregor/type-resolution-stage
[Type Checker] Add TypeResolution(Stage) to describe type computations.
2018-08-20 18:44:31 -07:00