These restrictions are meant to keep placeholder types from escaping TypeCheckType. But there's really no harm in that happening as long as we diagnose it on the way out in the places it's banned. (We also need to make sure we're only diagnosing things in primaries, but that's a minor issue). The end result is that we lose information because a lot of the AST that has placeholders in it becomes filled with error types instead.
Lift the restriction on placeholders appearing in the interface type, teach the mangler to treat them as unresolved types, and teach serialization to treat them as error types.
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.
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.
Let's delay solution application to multi-statement closure bodies,
because declarations found in the body of such closures may depend
on its `ExtInfo` flags e.g. no-escape is set based on parameter if
closure is used in a call.
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 a defaulted template type parameter is not used in the function's
signature, don't create a corresponding generic argument for that
template type. This allows us to call function templates with defaulted
template type parameters. This is very common in the standard library
for things like enable_if which is used to disable various
functions/overloads with SFINAE.
The biggest part of this change is going forward not all function
templates will be imported as generic functions in Swift. This should
work OK but we may discover there was some logic which only looked for
generic function when dealing with function templates.
- Explicitly limit favoring logic to only handle
unary args, this seems to have always been the
case, but needs to be handled explicitly now that
argument lists aren't exprs
- Update the ConstraintLocator simplification to
handle argument lists
- Store a mapping of locators to argument lists
in the constraint system
- Abstract more logic into a getArgumentLocator
method which retrieves an argument-to-param locator
from an argument anchor expr
Just for convenicence.
* Replace `llvm::isa_and_nonnull` with imported `isa_and_nonnull`
* Repalce some `EXPR && isa<T>(EXPR)` with `isa_and_nonnull<T>(EXPR)`
Once coerced initializer expression has been set for
a particular pattern binding entry, let's mark it as
checked, otherwise decl checker might try to
re-typecheck it.
wrapped parameters and wrapped properties.
This fixes a bug where @autoclosure was not propagated from the wrapper's
init(wrappedValue:) to a wrapped argument.
I missed this case when previously improving the
logic here. As it turns out, using the raw anchor
as the root expression from which to derive parent
information is insufficient. This is because it
may not capture relevant parent exprs not a part
of the fix locator.
Instead, pass down a function that can be used to
derive the parent expressions from the constraint
system's own parent map. Also make sure to assign
to `expr` for the UnresolvedMemberChainResultExpr
case to make sure we correctly check for it as a
sub-expression.
Finally, now that we're looking at more parent
exprs, add logic to handle `try` and `await`
parents, as well as ClosureExprs and
CollectionExprs. I couldn't come up with a test
case for CollectionExpr, as we emit different
diagnostics in that case, but it's probably better
to tend on the side of being more future proof
there.
rdar://81512079
* [TypeResolver][TypeChecker] Add support for structural opaque result types
* [TypeResolver][TypeChecker] Clean up changes that add structural opaque result types
Such implicit tuples may be used to represent
argument lists for e.g binary expressions, and as
such shouldn't be considered as parent exprs that
satisfy the role of parentheses.
Also fix the callers to use the raw anchor as the
root expression they pass to provide an accurate
parent map. This requires sinking the
UnresolvedMemberChainResultExpr handling logic into
`getPrecedenceParentAndIndex`.
rdar://81109287
Start treating the null {Can}GenericSignature as a regular signature
with no requirements and no parameters. This not only makes for a much
safer abstraction, but allows us to simplify a lot of the clients of
GenericSignature that would previously have to check for null before
using the abstraction.
The added test case fails because the result builder inside `List2` is being type checked twice: Once for every overload of `List2`. Because of the way that result builders are being type checked right now, each overload of `List2` creates a new type variable for the key components in `foo` and the constraint system only keeps track of the key path component -> type mapping for the last solution discovered.
When we are now trying to look up the type of the first key path component for the first solution, the constraint system returns the type variable that is being used by the second solution and simplifying that type variable through the first solution fails because it doesn’t know about the type variable.
To fix the issue, make sure that the solutions keep track of the their type variables associated to key path components. That way the first solution owns its own key path component -> type variable mapping and is thus also able to simplify the type variable it has associated with the component.
Fixes rdar://80522345 [SR-14916]
To check whether the code completion node was type checked in a multi statement closure, we were assuming that we had a code completion *expression* and not considering that we could also complete in a key path component. When applicable, check if the completion key path component has a type to determine if the completion node was type checked as part of a multi-statement closure.
Resolves rdar://80271598 [SR-14891]
AutoClosureExprs created by the constraint system used to be constructed
with the decl context of the constraint system itself. This meant that
autoclosures in expressions nested in closures would initially be
parented onto any enclosing functions rather than the deepest closure
context. When we ran capture analysis and lookup from inside of the body
of these nascent values, we would fail to find declarations brought into
scope by those parent closures. This is especially relevant when
pre-typechecked code is involved since captures for those declarations
will be forced before their bodies have been recontextualized. See
issue #34230 for why we need to force things so early.
The attached test case demonstrates both bugs: The former a bogus lookup
through the parent context that would incorrectly reject this otherwise
well-formed code. The latter is a crash in SILGen when the capture
computation would fail to note $0.
Use the decl context of the solution application target, which is always
going to be the deepest user-written closure expression available to us,
and therefore the deepest scope that can introduce capturable variables.
rdar://79248469