Commit Graph

104 Commits

Author SHA1 Message Date
Pavel Yaskevich
f462521078 [ConstraintSystem] Refactor arg/param matching to handle autoclosures
Make sure that presence of `@autoclosure` attribute handled
in one place - `matchCallArguments`, which makes it possible
to remove the rest of (now redundant) autoclosure related
logic scattered throughout solver.
2018-11-10 11:59:28 -08:00
Pavel Yaskevich
fa1e2d33aa [CSBindings] Detect situations when type variable bindings could be incomplete
When `bind param` constraint is associated with a given
type variable a set of bindings collected for it is
potentially incomplete, because binding gathering doesn't
look through related type variables. Which means that
such type variable has to be de-prioritized until
`bind param` constraint is resolved or there is just
nothing else to try, otherwise there is a risk that
solver would skip some of the valid solutions.

This only affects type variable that appears one the
right-hand side of the `bind param` constraint and
represents result type of the closure body, because
left-hand side gets types from overload choices.

Resolves: rdar://problem/45659733
2018-11-09 15:27:27 -08:00
Pavel Yaskevich
c4c9cc32fb Revert "[CSBindings] Detect situations when type variable bindings could be incomplete"
This reverts commit 4f708890c1.
2018-11-09 11:50:19 -08:00
Dan Zheng
2a4e1b83fd Implement @dynamicCallable. (#20305)
* Implement dynamically callable types (`@dynamicCallable`).

- Implement dynamically callable types as proposed in SE-0216.
  - Dynamic calls are resolved based on call-site syntax.
  - Use the `withArguments:` method if it's defined and there are no
    keyword arguments.
  - Otherwise, use the `withKeywordArguments:` method.
- Support multiple `dynamicallyCall` methods.
  - This enables two scenarios:
    - Overloaded `dynamicallyCall` methods on a single
      `@dynamicCallable` type.
    - Multiple `dynamicallyCall` methods from a `@dynamicCallable`
      superclass or from `@dynamicCallable` protocols.
  - Add `DynamicCallableApplicableFunction` constraint. This, used with
    an overload set, is necessary to support multiple `dynamicallyCall`
    methods.
2018-11-09 09:49:14 -08:00
Pavel Yaskevich
4f708890c1 [CSBindings] Detect situations when type variable bindings could be incomplete
When `bind param` constraint is associated with a given type
variable a set of bindings collected for it is potentially
incomplete, because binding gathering doesn't look through related
type variables. Which means that such type variable has to be
de-prioritized until `bind param` constraint is resolved
or there is just nothing else to try, otherwise there is a
risk that solver would skip some of the valid solutions.

Resolves: rdar://problem/45659733
2018-10-31 17:58:54 -07:00
Mark Lacey
85237aa071 [ConstraintSystem] Allow getPotentialBindings to find supertypes of optionals.
Improve enumerateDirectSupertypes so that for T? it will return U? if
U is a supertype of T. This is another form of direct supertype.

This is making up for a deficiency in the completeness of our Type
join implementation, which should be able to directly compute a join
of disparate types that share some common supertype, but sometimes
fails to in cases involving protocol compositions.

Fixes rdar://problem/45490737
2018-10-23 21:56:38 -07:00
Slava Pestov
2d4b25960d Sema: Type variables for opened generic parameters store the generic parameter type and not an archetype
There's no need to instantiate archetypes in the generic environment
of the declaration being opened.

A couple of diagnostics changed. They were already misleading, and the
new diagnostics, while different, are not any more misleading than
before.
2018-09-27 20:49:23 -07:00
gregomni
c73048e4ee Fixes from review 2018-09-24 09:43:43 -07:00
gregomni
6deb401cc6 Previously we were sharing a single type variable for a param of a closure's function type and it's paramDecl's type inside the closure itself. With inout parameters this caused vardecls of inout type and some hacks to deal with them.
Instead, create two TVs and constrain them appropriately.
2018-09-23 17:41:18 -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
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
308bdd6b57 [CSBindings] NFC: refactoring of enumerateDirectSupertypes 2018-08-31 11:21:24 -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
a69c6e2964 [CSBindings] Don't record duplicate bindings for opened nominal types
Otherwise it would result in checking the same type multiple times
and results in worse pontential binding picks.
2018-08-30 18:15:55 -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
Slava Pestov
2975f145a1 Sema: Remove ArgumentTupleConversion constraint now that its no longer used 2018-08-28 14:40:56 -07:00
Slava Pestov
65edce7591 Sema: Add FunctionInput and FunctionResult constraints
These are temporary.

FunctionInput is conditional on fixing some ranking behavior to not
depend on type variables having argument tuples bound to them.
Hopefully we can replace TVO_PreferSubtypeBinding with a better
mechanism that compares overload types instead.

FunctionResult is used in CSDiag's contextual type diagnostics.
This is also on the chopping block.
2018-08-28 14:37:57 -07:00
Rintaro Ishizaki
9481e01845 [ConstraintSystem] Defensive guard not to join unresolved type
in PotentialBindings::addPotentialBinding()
2018-08-15 20:40:05 +09:00
Slava Pestov
3ef0991826 AST: Remove TypeBase::getWithoutImmediateLabel()
Again, it appears that looking through one-element tuples is
no longer a thing we need to do.
2018-08-08 10:18:52 -07:00
Pavel Yaskevich
624c183fe0 [ConstraintGraph] Change gatherConstraints to take SetVector
For stable iteration order, let's switch from `SmallPtrSet`
to `SetVector` which ensures insertion order iteration.
2018-07-27 15:34:15 -07:00
Pavel Yaskevich
dd798accd8 [ConstraintGraph] Use set to gather constraints for type variables
Since it's possible to find the same constraint through two different
but equivalent type variables, let's use a set to store constraints
instead of a vector to avoid processing the same constraint multiple
times.
2018-07-26 22:41:07 -07:00
Mark Lacey
48544fb5c1 Tweak formatting to match surrounding code. 2018-06-18 21:53:01 -07:00
Mark Lacey
54b2504699 [ConstraintSystem] Fix a logic error in computing potential bindings.
A change was made to attempt to use constraints that we have between
type variables to inform potential bindings, such that if we have:
   $T1 <: $T2
we would use $T1's bindings to add to the bindings of $T2. This is
only valid if we're adding bindings where $T1 is the supertype,
though, otherwise we could have the constraints:
  $T1 <: $T2
  $T1 <: X
imply that $T2 is a supertype of X, which doesn't make sense.

Fixes rdar://problem/40810000 (aka https://bugs.swift.org/browse/SR-7875).
2018-06-18 18:33:30 -07:00
Pavel Yaskevich
a014842696 [CSBindings] Look through non-value types earlier to avoid producing incorrect bindings
Before checking any requirements of the binding type, let's look
through @autoclosure and/or non-variable types if source constraint
requires that, otherwise we'd end up creating bindings for types
which later on might end up causing infinite recursion like dependent
member types in result position of @autoclosure parameter.

Resolves: rdar://problem/38272904
2018-04-05 00:11:15 -07:00
Pavel Yaskevich
298bf2aed4 [CSBindings] Cleanup literal binding inference
Don't attempt to store literal bindings directly to `PotentialBindings`
since they might get superseded by non-literal bindings deduced from
other constraints, also don't attempt to check literal protocol conformance
on type variables or member types since such types would always end-up
returning trivial conformance which results in removal of viable literal types.

Resolves: rdar://problem/38535743
2018-03-27 22:51:37 -07:00
Pavel Yaskevich
79b14c8916 [Sema] Improve diagnostics for non-escaping function types
Allow certain bindings and conversions involving non-escaping
function types to succeed in "diagnostic" mode to gather fixes
and diagnose such problems better, expecially related to
conversions to 'Any' and generic parameters.

Resolves: rdar://problem/38648760
2018-03-20 17:57:03 -07:00
Mark Lacey
cb674efaa4 Fixes for uses of noescape functions.
Disallow noescape functions from being inferred as escaping functions,
or passed as Any.

Fixes rdar://problem/24097075.
2018-03-18 22:01:55 -07:00
Pavel Yaskevich
b95635ca13 [SILGen] NFC: Add test-cases for rdar://problem/37790062
Port multiple test-cases from `test/Constraints/closures.swift`
to SILGen to verify that closures are inferred as having `Void`
result type, and there is no function conversion thunk emitted
to convert from `() -> T` to `() -> Void` for literal closures.
2018-03-12 14:20:00 -07:00
Pavel Yaskevich
18d2c1d8b4 [CSBindings] Try Void as a binding for closure result type variable
If we could find a binding for type variable representing closure result
let's also add implicit `Void` type as another pontential binding to attempt
because there is an implicit conversion from `() -> T` to `() -> Void`
so finding `Void` early is going to help avoid function conversions down
the line.

Resolves: rdar://problem/37790062
2018-03-10 23:59:11 -08:00
Mark Lacey
962c25f467 Begin refactoring type variable binding code.
Move all the code specific to dealing with relational constraints out
into a separate function.

I expect to do more refactoring here so this is likely not the final
form for this code - just one step in the direction of breaking things
down into smaller logical pieces.
2018-03-09 14:48:55 -08:00
Pavel Yaskevich
380ea4a671 [CSBindings] Try to infer bindings from related type variables
Attempt to use potential bindings inferred for related types variables
discoverable through 'subtype' constraints, this helps to build a
more precise bindings domain for each type variable.

Resolves: rdar://problem/38159133
2018-03-05 18:53:40 -08:00
Mark Lacey
758570982a Start stubbing out more parts of Type::join().
Improve support for Optional among other things.

Return Any when it is really the best answer given the types involved,
or nullptr if we cannot yet produce an accurate result.

This implementation returns Any? when joining Any with an
Optional<T>. In our type system both Any and Any? are effectively
subtypes of one another since each can hold all the values that the
other can hold. So this choice is somewhat arbitrary, but does line up
nicely with the notion that T is always a subtype of T?.
2018-02-28 23:13:59 -08:00
Pavel Yaskevich
5208049ff8 [CSBindings] Form bindings correctly when they come from 'OptionalObject' constraint
Fixes a bug in `getPotentialBindings` when the source of the bindings
is 'OptionalObject' constraint and type variable is on the left-hand
side of that constraint, that makes such type variable always have an
optional type since right-hand side of 'OptionalObject' is its 'object'
type.

Resolves: rdar://problem/37508855
2018-02-13 14:25:00 -08:00
Pavel Yaskevich
c6ff7b40cc [CSBindings] Look through optional types when trying to validate l-valueness of the new bindings
When bindings are picked for particular type variable, right-hand
side of the binding might be another type variable wrapped into optional
type, when trying to determine if both sides of the binding have the
same l-valueness it's imperative to look throught optional type of the
right-hand side. Otherwise new binding might be effectively unsolvable.

Resolves: rdar://problem/37291371
2018-02-08 01:55:39 -08:00
Mark Lacey
b4b66bc8e8 Replace getAnyOptionalObjectType with getOptionalObjectType. 2018-02-05 23:59:00 -08:00
Mark Lacey
3f9689e477 Remove lookThroughImplicitlyUnwrappedOptionalType. 2018-02-03 10:57:10 -08:00
Pavel Yaskevich
5d5872bb83 [CSBindings] Avoid binding type variables to collection types directly
Instead of binding collection types directly let's try to
bind using temporary type variables substituted for element
types, that's going to ensure that subtype relationship is
always preserved.

Resolves: rdar://problem/35541153
2017-12-01 23:04:19 -08:00
Doug Gregor
e3a5318b97 [Type checker] Teach conformsToProtocol() to check conditional requirements.
conformsToProtocol() is the main way in which we check whether a given type
conforms to a given protocol. Extend it to check conditional requirements by
default, so that an unmodified caller will get the "does not conform" result
(with diagnostics when a location is present) rather than simply ignoring
the conditional requirements.

Some callers take responsibility for conditional requirements, e.g., to
push them into the constraint system. Allow those callers to opt out of
this checking, and do so wherever appropriate.

Fixes rdar://problem/35518088, where we were ignoring the conditional
requirements needed to verify that Equatable synthesis could be performed.
2017-11-21 21:02:00 -08:00
Pavel Yaskevich
4317074a9a [ConstraintSolver] Prioritize certain type variables while looking for bindings
Presence of some constraints (Subtype at least) requires a certain
contextual ranking of the type variables associated with them when
it comes to picking bindings, otherwise it might lead to no or
invalid solutions, because only a set of the bindings for the best
type variable is attempted.

Resolves: rdar://problem/22898292
2017-10-03 10:41:35 -07:00
Pavel Yaskevich
695baccc3e Revert "[ConstraintSolver] Prioritize certain type variables while looking for bindings"
This reverts commit 001b09747a.
2017-10-02 17:30:18 -07:00
Pavel Yaskevich
001b09747a [ConstraintSolver] Prioritize certain type variables while looking for bindings
Presence of some constraints (Subtype at least) requires a certain
contextual ranking of the type variables associated with them when
it comes to picking bindings, otherwise it might lead to no or
invalid solutions, because only a set of the bindings for the best
type variable is attempted.

Resolves: rdar://problem/22898292
2017-09-30 14:36:16 -07:00
Pavel Yaskevich
3b06f2e897 Merge pull request #12072 from xedin/rdar-33429010
[ConstraintGraph] Don't try to contract edge of parameter bindings with `inout` attribute
2017-09-26 11:51:09 -07:00
Mark Lacey
e46d2a7216 [Constraint system] Move addPotentialBinding implementation back to CSBdinings.cpp.
The method is logically part of PotentialBindings, but the
implementation doesn't need to live in the header.
2017-09-25 16:52:41 -07:00
Pavel Yaskevich
80e4a2226b [ConstraintGraph] Don't try to contract edge of parameter bindings with inout attribute
Currently edge related to the parameter bindings is contracted
without properly checking if newly created equivalence class has
the same inout & l-value requirements. This patch improves the
situation by disallowing contraction of the edges related to parameter
binding constraint where left-hand side has `inout` attribute set.

Such guarantees that parameter can get `inout` type assigned when
argument gets `l-value` type.

Resolves: rdar://problem/33429010
2017-09-22 17:23:12 -07:00
Pavel Yaskevich
c8fad863c4 [ConstraintSolver] NFC: Refactor PontentialBindings to reference type variable they belong to 2017-09-16 23:35:44 -07:00
Pavel Yaskevich
8c2fa12ac9 [ConstraintSolver] NFC: Move addPotentialBinding into PotentialBindings 2017-09-15 13:31:15 -07:00
Mark Lacey
54f2844acd Merge pull request #11629 from rudkx/bind-param-constraints
Try to ensure we try to bind the elements of BindParam constraints le…
2017-08-25 22:13:52 -07:00
Mark Lacey
a41fa9482f Try to ensure we try to bind the elements of BindParam constraints left-to-right.
If we allow the right-hand type to be bound first, it can artificially
limit the options for the left-hand side, so attempt to delay binding of
the right-hand side types until after we've chosen something for the
left-hand side.

The test here will not fail without this change, but will fail without
this change if the ConstraintGraph.cpp changes from @xedin's edge
contraction patch (https://github.com/apple/swift/pull/11118) are
applied.
2017-08-25 18:00:30 -07:00
Pavel Yaskevich
829ac700a8 [ConstraintSolver] Fix validation of DynamicTypeOf to use left-hand side's representative
When search for potential bindings for the given type variable
encounters `DynamicTypeOf` constraint, its validation should use
representative type variable of the left-hand side instead of
direct comparison.
2017-08-24 18:43:49 -07:00
Pavel Yaskevich
7c9840c204 [ConstraintSolver] When searching for viable bindings treat DynamicTypeOf constraint specially
When trying to find bindings let's avoid type variables which
represent left-hand side of the `DynamicTypeOf` constraint,
 because such type variables might be (implicitly) convertible to
[existential] metatype, but at the same time bound to something else
(e.g. Any), which fails when solver tries to simplify `DynamicTypeOf`
constraint itself.
2017-08-23 18:03:27 -07:00