Instead of making an undo() do an infer(), let's record fine-grained
changes about what was retracted, and directly re-insert the same
elements into the data structures.
A read access asserts that the memory location is immutable for the duration
of the access, so it can be treated as a borrow rather than a mutable lvalue.
Doing this allows the borrow formal access scope fixes from #79084 to apply
to situations where a loadable type undergoes an accessor-based access with
indirect arguments (such as for public accessors when library evolution is
enabled for the type). Fixes rdar://143334632.
The return pointer may point into the materialized base value, so if the base needs
materialization, ensure that materialization covers any futher projection of the
value.
Ignore declarations that come from implicitly imported modules
when `MemberImportVisibility` feature is enabled otherwise
we might end up favoring an overload that would be diagnosed
as unavailable later.
Resolves: rdar://143582881
Fixes a regression from commit 0c128e5db7.
The old depthFirstSearch() walked all adjacencies via the constraint graph,
and thus it would visit type variables that are currently inactive because
we're solving a conjunction element.
This was inconsistent with the new union-find which only formed the
connected components from the currently active type variables; adjacencies
involving inactive type variables are no longer considered.
Fix the inconsistency by changing gatherConstraints(), which used from
addTypeVariableConstraintsToWorkList(), to also skip inactive type
variables.
Fixes rdar://problem/143340082.
We don't want to do that in general because injection should happen
only in one place but Void is special because it allows conversions
in that position.
This can happen when we're generating constraints and resolving the
type annotations written in a closure expression. Just skip the
non-copyable check in this case.
Fixes rdar://problem/143031466.
Also stop suggesting a '?' fix-it for casts, where it is not likely to
be helpful because the common intention is either to force the optional
or declare an IUO.
The non-metatype case was never supported. The same should hold for the
existential metatype case, which used to miscompile and now crashes
because the invariant reference is deemed OK but the erasure expectedly
fails to handle it:
```swift
class C<T> {}
protocol P {
associatedtype A
func f() -> any P & C<A>
func fMeta() -> any (P & C<A>).Type
}
do {
let p: any P
let _ = p.f() // error
let _ = p.fMeta() // crash
}
```
Recently I found a soundness hole here, where we would allow conversion
between `any P<T>` and `any Q<T>` even if P and Q have different primary
associated types.
However, the fix was too strict, because we still want to allow the
conversion when the associated types have the same name.
Fixes rdar://141968103.
Rather than attempting to re-implement `simplifyType`,
tweak `Solution::simplifyType` such that it can
map the resulting type out of context, and can
turn type variables into their opened generic
parameters.
Simplifying into the function expression is wrong,
like `FunctionArgument` this isn't an element that
can be simplified. This also means we don't need
to handle it in `MissingCallFailure`, since we
shouldn't be recording that fix in this case.
Re-introduce unsolved member constraint when optional object is
a type variable or member until it's bound, otherwise it's impossible
to tell whether unwrapped base would have a member or not.
If a disjunction doesn't have an application, let's prefer
it if it's passed as an argument to an operator application
or involved in a member chain, in such situations attempting
a disjunction could provide context to parent call/member chain.
If disjunction is passed as an unapplied reference to some
parameter i.e. `<base>.map(String.init(describing:))` we don't
favor it for now because optimizer cannot do enough checking
to determine whether preferring such disjunction would help
make forward progress in solving by pruning some space or
providing additional context.
Mitigation for a historic incorrect type-checker behavior
caused by one of the performance hacks that used to favor
sync constructor overload over async one in async context
if initializers take a single unlabeled argument.
```swift
struct S {
init(_: Int) {}
init(_: Int) async {}
}
func test(v: Int) async { S(v) }
```
The type-checker should use `init(_: Int) async` in `test` context
but used to select the sync overload. The hack is now gone but we
need to downgrade an error to a warning to give the developers time
to fix their code.
Let's not perform $T? -> $T for closure result types to avoid having
to re-discover solutions that differ only in location of optional
injection.
The pattern with such type variables is:
```
$T_body <conv/subtype> $T_result <conv/subtype> $T_contextual_result
```
When `$T_contextual_result` is `Optional<$U>`, the optional injection
can either happen from `$T_body` or from `$T_result` (if `return`
expression is non-optional), if we allow both the solver would
find two solutions that differ only in location of optional
injection.
Some disjunctions e.g. explicit coercions, compositions of restrictions,
and implicit CGFloat initializers have favored choices set independently
from optimization algorithm, `selectDisjunction` should account for
such situations.
`scoreCandidateMatch` needs to reflect the fact that literal can
assume any type that conforms to `ExpressibleBy{Integer, Float}Literal`
protocol but since such bindings are non-default and alway produce
a worse solution vs. default literal types if all of the arguments
are literals let's use only exact matches otherwise there is a chance
of "over-favoring" and creating more work for ranking.