Commit Graph

74 Commits

Author SHA1 Message Date
Holly Borla
cb64d7f715 [ConstraintSystem] Fix build failures. 2020-10-15 13:30:46 -07:00
gregomni
34fa9c2786 Merge typevars of operators with shared decls after finding a solution to speed up further searching 2020-10-15 09:08:50 -07:00
gregomni
ab6d92b1cd Favor operators based on existing binds via both basename and type 2020-10-15 09:03:45 -07:00
Holly Borla
1e0038c3be [ConstraintSystem] Remove implementation of operator designated types
in the solver.
2020-10-14 16:05:54 -07:00
Pavel Yaskevich
461eafff54 [ConstraintSystem] NFC: Move ConstraintSystem.h to include/swift/Sema 2020-10-08 10:45:47 -07:00
Robert Widmann
2bca013457 Move "isDebugMode" into ConstraintSystem
This eliminates the final source of mutation of the TypeCheckerFlags on the ASTContext.
2020-05-13 09:13:44 -07:00
Hamish Knight
87577d21b3 [CS] NFC: Make failedConstraint private 2020-04-20 19:08:25 -07:00
Hamish Knight
78072de623 [CS] Assert that we don't end up with unsolved constraints
Make sure we don't end up in a situation where we
have unsolved constraints left over and consider
the system fully solved.

This requires tweaking the type matching code for
dependent members such that a concrete base is
considered a failure rather than being left
unsolved. This should only happen when not in
diagnostic mode, as otherwise we use a hole.
2020-04-10 10:16:08 -07:00
Holly Borla
c1c6a884a4 [ConstraintSystem] Respect the constraint solver performance thresholds,
including time and allocated memory, in mergePartialSolutions.
2020-03-09 14:44:12 -07:00
swift-ci
25c6002331 Merge remote-tracking branch 'origin/master' into master-rebranch 2020-01-21 16:43:52 -08:00
Pavel Yaskevich
2b8c00215f [ConstraintSystem] Delay closure body constraint generation in a couple of specific cases
* If there is a disjunction associated with closure type e.g.
  coercion to some other type `_ = { $0 } as (Int32) -> Void`

* If there is a disjunction associated with a collection which
  could provide more context to the constraint solver.
2020-01-21 12:06:32 -08:00
Erik Eckstein
1b312a85bd Merge remote-tracking branch 'origin/master' into master-rebranch 2020-01-16 10:39:20 +01:00
Pavel Yaskevich
59c749124d [CSBindings] Prefer closure type binding over disjunction
Even if contextual closure type has type variables inside
prefer it over disjunction because it provides a lot of
contextual information early which helps to solve the system
faster.
2020-01-14 00:09:32 -08:00
swift-ci
5fc1d17bf9 Merge remote-tracking branch 'origin/master' into master-next 2019-11-13 09:10:56 -08:00
Robert Widmann
d890b8ad41 Remove some save-and-restores
An awful pattern we use throughout the compiler is to save and restore global flags just for little things.  In this case, it was just to turn on some extra options in AST printing for type variables. The kicker is that the ASTDumper doesn't even respect this flag. Add this as a PrintOption and remove the offending save-and-restores.

This doesn't quite get them all: we appear to have productized this pattern in the REPL.
2019-11-13 07:37:12 -08:00
Robert Widmann
f4d333d066 Sink a bunch of semantic options into TypeCheckerOptions
Sink
- DebugConstraintSolver
- DebugConstraintSolverAttempt
- DebugConstraintSolverOnLines
- DebugGenericSignatures
- DebugForbidTypecheckPrefix
- SolverMemoryThreshold
- SolverBindingThreshold
- SolverShrinkUnsolvedThreshold
- SolverDisableShrink
- EnableOperatorDesignatedTypes
- DisableConstraintSolverPerformanceHacks
- SolverEnableOperatorDesignatedTypes
2019-11-12 22:39:49 -08:00
Ben Langmuir
ec8b255d75 [master-next] Undo temporary change to fix merge conflict
Reverts 0cf3cfabbb
2019-11-05 13:34:12 -08:00
Holly Borla
4fd1377c81 [ConstraintSystem] With the new approach for holes, hole propagation happens
automatically.

This commit also renames `ConstraintSystem::recordHole/isHole` to
`recordPotentialHole` and `isPotentialHole` to make it clear that
we don't know for sure whether a type variable is a hole until it's
bound to unresolved.
2019-11-05 09:15:13 -08:00
Holly Borla
f2fdc8c114 [ConstraintSystem] Only apply the ExplicitlySpecifyGenericArguments fix
for generic parameters that are holes.
2019-11-05 09:15:13 -08:00
Holly Borla
e97314cb5c [ConstraintSystem] Never choose the potential binding for a hole
in the constraint system over a different binding or disjunction.

In other words, we will only choose to bind a hole to `Any` if there
are no other bindings and no disjunctions.
2019-11-05 09:15:13 -08:00
Holly Borla
3bc2269f4f [ConstraintSystem] Allow generic parameters and holes to default to
`Any` in `getPotentialBindings` rather than `ComponentStep::take`.
2019-11-05 09:15:13 -08:00
Holly Borla
561e527848 [ConstraintSystem] Extend the ExplicitlySpecifyGenericArguments fix to cover
all cases of missing generic parameters.

In `ComponentStep::take` when there are no bindings or disjunctions, use hole
propagation to default remaining free type variables that aren't for generic
parameters and continue solving. Rather than using a defaultable constraint for
holes, assign a fixed type directly when we have no bindings to try.
2019-11-05 09:15:13 -08:00
Doug Gregor
17ea39accd [Constraint solver] Simplify one-way constraints to Equal, not Bind.
One-way constraint expressions, which are the only things that
introduce one-way constraints at this point, want to look through
lvalue types to produce values. Rename OneWayBind to OneWayEqual, map
it down to an Equal constraint when it is simplified (to drop
lvalue-ness), and apply that coercion during constraint application.

Part of rdar://problem/50150793.
2019-08-16 14:13:21 -07:00
Doug Gregor
da267bf7ca [Constraint system] Switch TypeVariables to a SetVector.
There were a few places where we wanted fast testing to see whether a
particular type variable is currently of interest. Instead of building
local hash tables in those places, keep type variables in a SetVector
for efficient testing.
2019-08-16 14:13:15 -07:00
Doug Gregor
3c69f6a305 [Constraint solver] Introduce one-way constraints.
Introduce the notion of "one-way" binding constraints of the form

  $T0 one-way bind to $T1

which treats the type variables $T0 and $T1 as independent up until
the point where $T1 simplifies down to a concrete type, at which point
$T0 will be bound to that concrete type. $T0 won't be bound in any
other way, so type information ends up being propagated right-to-left,
only. This allows a constraint system to be broken up in more
components that are solved independently. Specifically, the connected
components algorithm now proceeds as follows:

1. Compute connected components, excluding one-way constraints from
consideration.
2. Compute a directed graph amongst the components using only the
one-way constraints, where an edge A -> B indicates that the type
variables in component A need to be solved before those in component
B.
3. Using the directed graph, compute the set of components that need
to be solved before a given component.

To utilize this, implement a new kind of solver step that handles the
propagation of partial solutions across one-way constraints. This
introduces a new kind of "split" within a connected component, where
we collect each combination of partial solutions for the input
components and (separately) try to solve the constraints in this
component. Any correct solution from any of these attempts will then
be recorded as a (partial) solution for this component.

For example, consider:

  let _: Int8 = b ? Builtin.one_way(int8Or16(17)) :
  Builtin.one_way(int8Or16(42\
))

where int8Or16 is overloaded with types `(Int8) -> Int8` and
`(Int16) -> Int16`. There are two one-way components (`int8Or16(17)`)
and (`int8Or16(42)`), each of which can produce a value of type `Int8`
or `Int16`. Those two components will be solved independently, and the
partial solutions for each will be fed into the component that
evaluates the ternary operator. There are four ways to attempt that
evaluation:

```
  [Int8, Int8]
  [Int8, Int16]
  [Int16, Int8]
  [Int16, Int16]

To test this, introduce a new expression builtin `Builtin.one_way(x)` that
introduces a one-way expression constraint binding the result of the
expression 'x'. The builtin is meant to be used for testing purposes,
and the one-way constraint expression itself can be synthesized by the
type checker to introduce one-way constraints later on.

Of these two, there are only two (partial) solutions that can work at
all, because the types in the ternary operator need a common
supertype:

  [Int8, Int8]
  [Int16, Int16]

Therefore, these are the partial solutions that will be considered the
results of the component containing the ternary expression. Note that
only one of them meets the final constraint (convertibility to
`Int8`), so the expression is well-formed.

Part of rdar://problem/50150793.
2019-08-13 11:48:42 -07:00
Doug Gregor
dec149ce62 [Constraint graph] Move component sorting into connected components. 2019-08-11 21:49:08 -07:00
Doug Gregor
ab38be128d [Constraint graph] Handle orphaned constraints within connected components
Move the logic for creating connected components of orphaned
constraints into the connected-components algorithm code, rather than
making it a special part of SplitterStep.
2019-08-11 21:28:34 -07:00
Doug Gregor
4c04ced939 [Constraint graph] Make connected components more self-contained.
Have the constraint graph's connected-component implementation be more
self-contained, producing a vector containing each of the actual
components (where each is defined by a list of type variables and a list
of constraints). This simplifies the contract with the client
(SplitterStep) and eliminates a bunch of separate mapping steps to
interpret the results.

It also lets us enrich the Component data structure in the future.
2019-08-07 08:32:34 -07:00
Doug Gregor
805b02da37 [Constraint graph] Associate all constraints with components.
The connected components computation was not forming components when all of
the type variables in a component were already bound. Any remaining
constraints involving those type variables would then arbitrarily end up
in component 0, due to the the default-construction behavior of a map’s
operator[] with missing keys, artificially increasing the size of that
component with (typically) additional disjunctions.

Ensure that all constraints get into a component, creating one to hold
the a constraint even when all of the type variables are already bound.
Then, assert the invariant that every constraint is associated with a
component.

In time, we should probably eliminate this notion of disjunctions that
remain even when the type variable has been bound. For now, strengthen the
invariant to at least ensure that they get solved in isolation.
2019-08-06 23:15:58 -07:00
Doug Gregor
c2a9286d1d [Constraint graph] Print only those type variables that are of interest now 2019-08-05 22:21:21 -07:00
Doug Gregor
0b61f86a4a [Constraint solver] No need to associate bound type variables everywhere.
When we are associating type variables with components in a “split” step,
there is no need to record already-bound type variables with every component.
2019-08-05 17:06:52 -07:00
Pavel Yaskevich
ded44b4919 [CSStep] Attempt all disabled disjunction choices in diagnostic mode 2019-07-25 00:36:00 -07:00
Pavel Yaskevich
731ec39c24 [CSStep] Properly finalize component step without follow-up steps
Currently finalization e.g. scope reset and solution minimization
is only done if component step had follow-up e.g. type variable or
disjunction step(s), but it should be done if `take` generated any
fixes as well, or component changed score in any way, otherwise
we might miss some solutions with fixes because "best score" haven't
been reset properly.
2019-07-17 18:04:11 -07:00
Suyash Srijan
aaacd29b68 [ConstraintSystem] Adds the new overload to FailureDiagnostic as well and remove other instances of 0 summary flags 2019-06-24 22:33:38 +01:00
Pavel Yaskevich
c30845fa74 [ConstraintSystem] Detect and diagnose missing generic arguments
Introduce a fix to detect and diagnose situations when omitted
generic arguments couldn't be deduced by the solver based on
the enclosing context.

Example:

```swift
struct S<T> {
}

_ = S() // There is not enough context to deduce `T`
```

Resolves: rdar://problem/51203824
2019-05-29 16:39:41 -07:00
Gwen Mittertreiner
e51b72b3e0 Reduce the Stack Size of ConstraintSystem
The ConstraintSystem class is on the order of 1000s of bytes in size on
the stacka nd is causing issues with dispatch's 64k stack limit.

This changes most Small data types which store data on the stack to non
small heap based data types.
2019-05-13 11:40:43 -07:00
Pavel Yaskevich
8b5396bbac [CSSolver] Attempt disabled disjunction choices only if they have a fix
This draws a distinction between disabled choices with and without
fixes - former is disabled because it's unrelated, latter because
it only makes sense to attempt it during "salvage" mode while trying
to produce diagnostics.
2019-03-14 13:18:42 -07:00
Stephen Canon
6159ba810d Remove the (unused) SIMDOperators module. (#22530)
We originally planned to use this to hide some simd operators from the typechecker unless the user explicitly opted into having them but that scheme turned out to be ill-conceived, so we moved them
back into the stdlib. This change simply cleans up the empty vestigial module.
2019-02-14 16:37:41 -08:00
Doug Gregor
052d4c196c [Type checker] Pull the null check into swift::isSIMDOperator(). 2018-12-11 16:39:10 -08:00
Doug Gregor
88d34a1c7c [Constraint solver] De-priority SIMD operators.
The new SIMD proposal introduced a number of new operators, the presence of
which causes more "expression too complex" failures. Route around the
problem by de-prioritizing those operators, visiting them only if no
other operator could be chosen. This should limit the type checker
performance cost of said operators to only those expressions that need
them OR that already failed to type-check.

Fixes rdar://problem/46541800.
2018-12-11 16:34:37 -08:00
Pavel Yaskevich
7360cbcf9e [ComponentStep] NFC: Remove redundant numComponents check for debug output 2018-10-15 15:54:45 -07:00
Mark Lacey
6a3aa75932 [ConstraintSystem] Tweak -disable-constraint-solver-performance-hacks.
Allow a couple of the tests in shortCircuitDisjunctionAt() to run even
when hacks are disabled.

The first of these tests is imperfect since it assumes that "favored"
disjunction choices all come before the others (which may be the case
now but is pretty brittle).

Similarly, the second of these tests assumes that choices that are
fixes always come after ones that are not.

What we really want to do is skip these choices rather than stopping
at these points.
2018-10-04 17:09:19 -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
091a757e5d [CSStep] Allocate component scopes only if siblings didn't fail
If sibling components failed, there is no reason to establish new
scope since remaining containers are not really going to be taken
but fail fast instead.
2018-09-20 11:04:26 -07:00
Pavel Yaskevich
f9452afa4f [CSStep] NFC: Unify type binding attempt logging
Instead of printing `trying` for type variable and `assuming`
for disjunction choices, unify it so `BindingStep` logs
`attempting {type variable, disjunction choice}`.
2018-09-19 18:37:36 -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
de34d9fa6a [CSStep] Extract common type-var/disjunction functionality into BindingStep
Unify `take` implementation and API for type variable
and disjunction via `BindingStep` which accepts a producer.
2018-09-17 15:16:04 -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
c3a4434f3e [ConstraintSystem] Integrate emergency break into iterative solver loop
There are situations when solver goes exponential, before
(when solver was recursive) it would fail relatively quickly by running
out of stack space, now we really need to make sure that emergency
break is in place in main solver loop, otherwise we risk it running for
a really long time if doesn't consume too much memory since default
timeout is ~10 mins.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
f1a53c3f59 [ConstraintSystem] Remove unnecessary forward declarations of the steps
Also move `DisjunctionStep` from being a friend of `ConstraintSystem`
because it's not strictly necessary.
2018-09-15 20:56:47 -07:00