Creation of the "bound" generic signature isn't possible with interface
types or type variables, so open up the opaque interface signature
instead and separately bind the outer type parameters as appropriate.
Address small gaps in several places to make named opaque result types
partially work:
* Augment name lookup to look into the generic parameters when inside the
result type, which is used both to create structure and add requirements
via a `where` clause.
* Resolve opaque generic type parameter references to
OpaqueTypeArchetypeType instances, as we do for the "some" types
* Customize some opaque-type-specific diagnostics and type printing to
refer to the opaque generic parameter names specifically
* Fix some minor issues with the constraint system not finding
already-opened opaque generic type parameters and with the handling of
the opaque result type candidate set.
The major limitation on opaque types, where we cannot add requirements
that aren't strictly protocol or superclass requirements on the
generic parameters, remains. Until then, named opaque result types are
no more expressive than structural opaque result types.
Opaque opaque types and record them within the "opened types" of the
constraint system, then use that information to compute the set of
substitutions needed for the opaque type declaration using the normal
mechanism of the constraint solver. Record these substitutions within
the underlying-to-opaque conversion.
Use the recorded substitutions in the underlying-to-opaque conversion
to set the underlying substitutions for the opaque type declaration
itself, rather than reconstructing the substitutions in an ad hoc manner
that does not account for structural opaque result types.
Multi-statement closure inference doesn't play well with result builders
at the moment because it expects all of the information from the parent
statements to be inferred before solver starts working on the body of a
nested closure. Let's prevent inference for nested multi-statement closures
until result builders are ported to use conjunctions and solve the body
incrementally top-down instead of in one shot.
Insert an implicit conversion from pack types to tuples with equivalent parallel structure. That means
1) The tuple must have the same arity
2) The tuple may not have any argument labels
3) The tuple may not have any variadic or inout components
4) The tuple must have the same element types as the pack
When evaluating whether code is within a closure that uses concurrency
features, use the type of the closure as it's known during type checking,
so that contextual information (e.g., it's passed to a `@Sendable` or
`async` parameter of function type) can affect the result. This
corrects the definition for doing strict checking within a minimal
context for the end result of the type-check, rather than it's initial
state, catching more issues.
Fixes SR-15131 / rdar://problem/82535088.
Use this to enable better detection of async contexts when determining
whether to diagnose problems with concurrency.
Part of SR-15131 / rdar://problem/82535088.
`init` calls to redeclared types would end up diagnosed as ambiguity,
so locator simplification needs to account for the fact that "base"
of constructor might be overloaded type reference.
Resolves: rdar://84879566
Caching the result here feels a little overkill as
it's only useful for one protocol, and the
`TypeChecker::getDefaultType` computation is
cached by the request evaluator.
if the expression is an argument to `#selector`.
For `#selector` arguments, functions and properties are syntactically distinct
with the getter/setter label, so the solver should not unconditionally prefer
properties to unapplied functions. A better fix for this is to port over the
`#selector` diagnostics from CSApply, and not attempt invalid disjunction choices
based on the selector kind on the valid code path.
When referencing a function that contains parameters with the hidden
`@_unsafeSendable` or `@_unsafeMainActor` attributes, adjust the
function type to make the types of those parameters `@Sendable` or
`@MainActor`, respectively, based on both the context the expression:
* `@Sendable` will be applied when we are in a context with strict
concurrency checking.
* `@MainActor` will be applied when we are in a context with strict
concurrency checking *or* the function is being directly applied so
that an argument is provided in the immediate expression.
The second part of the rule of `@MainActor` reflects the fact that
making the parameter `@MainActor` doesn't break existing code (because
there is a conversion to add a global actor to a function value), but
it does enable such code to synchronously use a `@MainActor`-qualified
API.
The main effect of this change is that, in a strict concurrency
context, the type of referencing an unapplied function involving
`@_unsafeSendable` or `@_unsafeMainActor` in a strict context will
make those parameters `@Sendable` or `@MainActor`, which ensures that
these constraints properly work with non-closure arguments. The former
solution only applied to closure literals, which left some holes in
Sendable checking.
Fixes rdar://77753021.
Simplification of member locator would produce a base expression,
this is what we want for diagnostics but not for comparisons in
`diagnoseAmbiguity` because base expression is located at a different
depth which would lead to incorrect results if both reference and base
expression are ambiguous e.g. `test[x].count` if both `[x]` and `count`
are ambiguous than simplification of `count` would produce `[x]` which
is incorrect.
This is the test-case (already in the suite) that exibits this behavior:
```
func test_ambiguity_with_placeholders(pairs: [(rank: Int, count: Int)]) -> Bool {
return pairs[<#^ARG^#>].count == 2
}
```
Here subscript would either return a tuple or `ArraySlice` and
`count` is ambiguous because both have it.
The current IUO design always forms a disjunction
at the overload reference, for both:
- An IUO property `T!`, forming `$T := T? or T`
- An IUO-returning function `() -> T!`, forming `$T := () -> T? or () -> T`
This is simple in concept, however it's suboptimal
for the latter case of IUO-returning functions for
a couple of reasons:
- The arguments cannot be matched independently of
the disjunction
- There's some awkwardness when it comes e.g wrapping
the overload type in an outer layer of optionality
such as `(() -> T!)?`:
- The binding logic has to "adjust" the correct
reference type after forming the disjunction.
- The applicable fn solving logic needs a special
case to handle such functions.
- The CSApply logic needs various hacks such as
ImplicitlyUnwrappedFunctionConversionExpr to
make up for the fact that there's no function
conversion for IUO functions, we can only force
unwrap the function result.
- This lead to various crashes in cases where
we we'd fail to detect the expr and peephole
the force unwrap.
- This also lead to crashes where the solver
would have a different view of the world than
CSApply, as the former would consider an
unwrapped IUO function to be of type `() -> T`
whereas CSApply would correctly see the overload
as being of type `() -> T?`.
To remedy these issues, IUO-returning functions no
longer have their disjunction formed at the overload
reference. Instead, a disjunction is formed when
matching result types for the applicable fn
constraint, using the callee locator to determine
if there's an IUO return to consider. CSApply then
consults the callee locator when finishing up
applies, and inserts the force unwraps as needed,
eliminating ImplicitlyUnwrappedFunctionConversionExpr.
This means that now all IUO disjunctions are of the
form `$T := T? or T`. This will hopefully allow a
further refactoring away from using disjunctions
and instead using type variable binding logic to
apply the correct unwrapping.
Fixes SR-10492.
In order to fit with the new IUO model where
functions with IUO results have the disjunction
formed when matching result types, we need to
update this logic to form applicable fn
constraints for the implicit `x[dynamicMember:]`
subscript call.
This is done using a new ImplicitDynamicMemberSubscript
locator path element to allow easy identification of
what the right callee and argument list should be.
A contextual purpose for a sequence expression associated with
`for-in` statement, that decays into a `ConformsTo` constraint
to a `Sequence` or `AsyncSequence` protocol.
Note that CTP_ForEachSequence is almost identical to CTP_ForEachStmt
but the meaning of latter is overloaded, so to avoid breaking solution
targets I have decided to add a new purpose for now.
If we encounter a placeholder type here, propagate
it to the type variable, as we don't know whether
it should be optional or non-optional, and we
would have already recorded a fix for it.
SR-15219
rdar://83352038
for unapplied references when the choice is a function declaration.
This will allow the solver to prune those overload choices when it
has already found a solultion with a property (all else equal in the
score). This is already done as an ambiguity tie-breaker in solution
ranking, but adding this bit to the score will prune a lot of search
space within the solver.