Enable solver to transitively infer bindings through argument conversion
constraints. That helps to infer bindings for (generic) parameters
from their arguments e.g.
```swift
func foo<T: ExpressibleByStringLiteral>(_: String, _: T) -> T {
fatalError()
}
func bar(_: Any?) {}
func test() {
bar(foo("", ""))
}
```
In this case `T` can currently only be inferred as `Any?`
(based on parameter type of `bar`) although a complete
set of bindings for that type variable includes `String`
as well, which comes from use of `T` in argument position.
Resolves: rdar://problem/56212087
Consider following example:
```swift
struct MyType<TyA, TyB> {
var a : TyA, b : TyB
}
typealias B<T1> = MyType<T1, T1>
_ = B(a: "foo", b: 42)
```
Here `T1` is equal to `TyA` and `TyB` so diagnostic about
conflicting arguments ('String' vs. 'Int') should only be
produced for "representative" `T1`.
Semantically, an `inout` parameter is both a parameter and a result.
`@differentiable` and `@derivative` attributes now support original functions
with one "semantic result": either a formal result or an `inout` parameter.
Derivative typing rules for functions with `inout` parameters are now defined.
The differential/pullback type of a function with `inout` differentiability
parameters also has `inout` parameters. This is ideal for performance.
Differential typing rules:
- Case 1: original function has no `inout` parameters.
- Original: `(T0, T1, ...) -> R`
- Differential: `(T0.Tan, T1.Tan, ...) -> R.Tan`
- Case 2: original function has a non-wrt `inout` parameter.
- Original: `(T0, inout T1, ...) -> Void`
- Differential: `(T0.Tan, ...) -> T1.Tan`
- Case 3: original function has a wrt `inout` parameter.
- Original: `(T0, inout T1, ...) -> Void`
- Differential: `(T0.Tan, inout T1.Tan, ...) -> Void`
Pullback typing rules:
- Case 1: original function has no `inout` parameters.
- Original: `(T0, T1, ...) -> R`
- Pullback: `R.Tan -> (T0.Tan, T1.Tan, ...)`
- Case 2: original function has a non-wrt `inout` parameter.
- Original: `(T0, inout T1, ...) -> Void`
- Pullback: `(T1.Tan) -> (T0.Tan, ...)`
- Case 3: original function has a wrt `inout` parameter.
- Original: `(T0, inout T1, ...) -> Void`
- Pullback: `(inout T1.Tan) -> (T0.Tan, ...)`
Resolves TF-1164.
Remove meaningless `assert(false)` assertion from
`hasOverridingDifferentiableAttribute` in `TypeCheckDeclOverride.cpp`.
The assertion served no purpose and can safely be removed.
Resolves TF-1167. Add test.
Detect that disjunction is going to be applied to arguments which
don't provide any additional contextual information and allow only
a single choice to be attempted in such case to avoid triggering
exponential behavior in the solver.
The problem is most visible with operators e.g.
```swift
.foo == .bar || 1 == .baz
```
If neither member could be contextually determined and solver was
allowed to attempt all of the overloads for `==` and `||` that
would lead to exponential behavior (because each has 30+ overloads)
and generation of hundreds of partial solutions.
Resolves: rdar://problem/56400265
- Support `@differentiable` and `@derivative` attributes for original
initializers in final classes. Reject original initializers in non-final
classes.
- Synchronize tests.
Revert the property wrappers part of dd51251014.
Every part of the qualified lookup stack needs to synthesize property
wrapper members, otherwise we'll be subject to the relativistic effects
of semantic lookups in different files. Besides, Codable was the main
source of cycles and circularity under the old scheme.
Resolves rdar://59531889
If constraint system is underconstrained e.g. because there are
editor placeholders, it's possible to end up with multiple solutions
where each ambiguous declaration is going to have its own overload kind:
```swift
func foo(_: Int) -> [Int] { ... }
func foo(_: Double) -> (result: String, count: Int) { ... }
_ = foo(<#arg#>).count
```
In this case solver would produce 2 solutions: one where `count`
is a property reference on `[Int]` and another one is tuple access
for a `count:` element.
Resolves: rdar://problem/49712598
Currently constraint solver is only capable of detecting universally unavailable
overloads but that's insufficient because it's still possible to pick a contextually
unavailable overload choice which could be better than e.g. generic overload, or
one with defaulted arguments, marked as disfavored etc.
Let's introduce `ConstraintSystem::isDeclUnavailable` which supports both universal
and contextual unavailability and allow constraint solver to rank all unavailable
overload choices lower than any other possible choice(s).
Resolves: rdar://problem/59056638
Attempt to look up original function before checking whether the `value:` result
conforms to `Differentiable`.
This improves diagnostics: "original function not found" should be diagnosed as
early as possible.
Do a bit of cleanup here. Also expand the storage check to query the
backing variable for any attached property wrappers. If these are not
default-initialized or default initializable then the generated
initializer will contain unfixable DI errors.
Resolves rdar://58495602
Don't attempt to figure out what exactly is ambiguous, let
`diagnoseAmbiguity` take care of that. Simplify make sure
that only some of the solutions have fixes and these fixes
are all related to use of ephemeral pointers.
It turns out that, if you pull in any nontrivial module, there are thousands of submodules and none of them could possibly have a cross-import overlay. Avoid evaluating them.
These are mostly harmless, except that they make the two module names synonymous in qualified lookup. A hard error seems too aggressive for something that could easily be caused by uncoordinated changes to two modules, so warn instead.
This commit refactors NameBinding.cpp virtually to the point of a rewrite. The goal is to make the import handling code process a struct containing information extracted from an ImportDecl, rather than the ImportDecl itself, so that a future commit can perform the same processing on imports that are not directly represented by an ImportDecl. The result takes more code, but it disentangles a knot of complicated logic into separate threads.
One semi-functional change is that validation of scoped imports (i.e. checking that the declaration actually exists) is now deferred until all of the file’s imports have been processed. Once cross-imports are supported, this will be necessary because scoped imports can select declarations from cross-import overlays, and the full set of cross-import overlays can’t be known until all imports have been seen.
Some comments refer to things that won’t exist until the next commit, like the visibleModules property. I’ll let you in on a litlte secret: I didn’t really do this all in one go.