Commit Graph

116 Commits

Author SHA1 Message Date
Joe Groff
6b605f41cb Type substitution eliminates dependencies with Escapable targets.
When a generic function has potentially Escapable outputs, those outputs
declare lifetime dependencies, which have no effect when substitution
leads to those types becoming `Escapable` in a concrete context.
This means that type substitution should canonically eliminate lifetime
dependencies targeting Escapable parameters or returns, and that
type checking should allow a function value with potentially-Escapable
lifetime dependencies to bind to a function type without those dependencies
when the target of the dependencies is Escapable.

Fixes rdar://147533059.
2025-04-02 08:54:45 -07:00
Joe Groff
5c4406b5e8 Add an @_addressableForDependencies type attribute.
This attribute makes it so that a parameter of the annotated type, as well as
any type structurally containing that type as a field, becomes passed as
if `@_addressable` if the return value of the function has a dependency on
the parameter. This allows nonescapable values to take interior pointers into
such types.
2025-01-02 21:33:51 -08:00
Slava Pestov
5147adcca5 SIL: Handle ProtocolCompositionType in SubstFunctionTypePatternVisitor
Fixes https://github.com/swiftlang/swift/issues/62061.
2024-09-16 21:20:55 -04:00
Andrew Trick
a90b515df9 Fix type lowering of ~Escapable generics.
Factor AbstractionPattern::conformsToKnownProtocol and lower ~Escapable using the same logic as ~Copyable.

Adds support for conditionally Escapable enums.

Correctly sets the SILType::isTrivial flags for conditionally escapable structs and enums in environments (extensions)
that provide an Escapable conformance, such as:

    struct NE<E: ~Escapable> : ~Escapable {}

    extension NE: Escapable {
      func foo() -> Self {
        // Self is both Escapable and trivial here.
        self
      }
    }

Fixes rdar://125950218 ([nonescapable] support conditionally escapable enums)
2024-04-07 22:58:28 -07:00
Doug Gregor
f54782eab5 [SILGen] Correctly determine the thrown error type for closures
When a closure throws a generic error type, we were retrieving the
substituted error type (involving archetypes) when we needed to be
working with the interface type.

Fixes rdar://124484012.
2024-03-13 12:51:48 -07:00
Joe Groff
fe7049ed13 SIL: More accurate for type lowering whether a type is trivial based on conditional Copyable requirements.
We want a conditionally-copyable type to still be classified as trivial in cases
where it's bitwise-copyable, has a trivial deinit, and is Copyable. The previous
implementation here only checked at the declaration level whether a type was
Copyable or not; get a more accurate answer by consulting the combination
of information in the substituted type and abstraction pattern we have
available during type lowering so that we classify definitely-copyable substitutions
of a conditionally-copyable type as trivial. Should fix rdar://123654553 and
rdar://123658878.
2024-02-27 15:01:20 -08:00
Ben Barham
ef8825bfe6 Migrate llvm::Optional to std::optional
LLVM has removed llvm::Optional, move over to std::optional. Also
clang-format to fix up all the renamed #includes.
2024-02-21 11:20:06 -08:00
John McCall
868fc6ad46 Basic SILGen for @isolated(any).
The main piece that's still missing here is support for closures;
they actually mostly work, but they infer the wrong isolation for
actor-isolated closures (it's not expressed in the type, so obviously
they're non-isolated), so it's not really functional.  We also have
a significant problem where reabstraction thunks collide incorrectly
because we don't mangle (or represent!) formal isolation into
SILFunctionType; that's another follow-up.  Otherwise, I think SILGen
is working.
2024-02-19 21:21:03 -05:00
Slava Pestov
1d05c356c4 SIL: AbstractionPattern support for typed throws 2023-10-27 17:37:43 -04:00
Slava Pestov
04fe8f4bc6 SIL: Add forEachExpandedPackElement() and use it in type lowering
Probably there's no way to hit this right now, but there will be if
concrete formal PackTypes start showing up in AST.
2023-07-19 16:24:38 -04:00
Slava Pestov
8a07466938 SIL: Fix SubstFunctionTypePatternVisitor handling of pack types
The included test case also covers the previous commit.
2023-07-19 16:24:27 -04:00
Slava Pestov
76c90f6024 Merge pull request #67362 from slavapestov/sil-pattern-count-abstraction
SIL: Fix substituted function type visitor for PackExpansionType with concrete pattern type
2023-07-19 07:49:27 -04:00
John McCall
1a7d44a11d Diagnose attempts to reabstract variadic function types in unimplementable ways. 2023-07-18 13:22:35 -04:00
Slava Pestov
e0a1a11a6b SIL: Fix substituted function type visitor for PackExpansionType with concrete pattern type
If the pattern doesn't have any pack parameters in it anymore,
we need to recover the substituted count type from the original
count type.

Fixes rdar://problem/112065340.
2023-07-18 12:19:22 -04:00
John McCall
e14f2bc0c7 [NFC] Add a method to just ask if a tuple AP vanishes under substitution 2023-06-29 19:39:51 -04:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Slava Pestov
ec3aa5c9d7 SIL: Preliminary AbstractionPattern support for PackElementType 2023-06-06 14:18:37 -04:00
John McCall
9bf4e8c4a3 Remove a couple of over-eager assertions.
The best substitutions we can easily find in nested functions for
captured local variables are the forwarding substitutions of the
current environment.  These should be fine for type-substitution
purposes but do not necessarily match the generic signature of the
original variable's environment, which can trip these assertions.
Unfortunately, I can't think of an easy way to weaken these
assertions sufficiently to cover this case.

This should fix the source-compat suite regression reported in
rdar://107642925.
2023-04-14 02:04:47 -04:00
John McCall
30817b11dd Support vanishing tuples in the the general abstraction pattern routines. 2023-04-03 23:14:47 -04:00
John McCall
debc8d9ebd [NFC] Move forEachTupleElement to use a generator 2023-03-22 22:04:36 -04:00
John McCall
f99efc2f94 Fix unsafeGetSubstFieldType to propagate a substitution map in
whichever case it happens to be in.

This is a basic fix so that parallel walks on tuples and function
types in the substituted type will work .  Separately, though, I
do not think the places that use this really need to be passed an
orig type; this is used for computing type properties, and I am
not aware of any reason we should need an orig type to compute
type properties.  Additionally, the orig types computed by this
function are not really correct because of the substitution being
done in some cases, so it'd be very nice to rip this all out.
I'm not good to look into that right now, though.
2023-03-22 15:40:02 -04:00
John McCall
5f1a669f2f [NFC] Change the existing client of forEachFunctionParam
Yeah, this is much cleaner.
2023-03-20 16:01:54 -04:00
John McCall
3342d67161 Fix the creation of substituted abstraction patterns for expansions 2023-03-17 22:07:10 -04:00
John McCall
72cc8dcb1e [NFC] Rewrite the subst-type extracttor to be a CanTypeVisitor 2023-03-16 15:56:46 -04:00
John McCall
f3e7daf478 [NFC] Remove the now-dead PackExpanded accessors from AbstractionPattern 2023-03-16 01:38:46 -04:00
John McCall
4499e3d055 [NFC] Introduce new APIs for traversing orig/subst parameters in parallel 2023-03-16 01:38:46 -04:00
John McCall
9ab4dc494c [NFC] Add better APIs for parallel destructuring of orig+subst types
As I've been iterating on this work, I've been gradually mulling these
over, and I think this is the way to go for now.  These should make it
a lot less cumbersome to write these kinds of traversals correctly.

The intent is to the sunset the existing expanded-components stuff
after I do a similar pass for function parameters.
2023-03-16 00:19:30 -04:00
John McCall
a15a2e86fe Add a helper function for checking if a tuple AP contains expansions 2023-03-09 02:16:09 -05:00
John McCall
81d9e6865a Add a couple convenience APIs for working with abstraction patterns 2023-03-07 03:15:31 -05:00
John McCall
bd53f5d5df Allow AbstractionPattern to optionally carry substitutions
This allows the AP to answer questions like how many
elements/parameters in the substituted type correspond to
this pack expansion.

I've threaded this through a lot of cases for foreign patterns
that probably won't ever need it.
2023-02-24 15:02:09 -05:00
John McCall
d25a8aec8b Add explicit lowering for value packs and pack expansions.
- SILPackType carries whether the elements are stored directly
  in the pack, which we're not currently using in the lowering,
  but it's probably something we'll want in the final ABI.
  Having this also makes it clear that we're doing the right
  thing with substitution and element lowering.  I also toyed
  with making this a scalar type, which made it necessary in
  various places, although eventually I pulled back to the
  design where we always use packs as addresses.

- Pack boundaries are a core ABI concept, so the lowering has
  to wrap parameter pack expansions up as packs.  There are huge
  unimplemented holes here where the abstraction pattern will
  need to tell us how many elements to gather into the pack,
  but a naive approach is good enough to get things off the
  ground.

- Pack conventions are related to the existing parameter and
  result conventions, but they're different on enough grounds
  that they deserve to be separated.
2023-01-29 03:29:06 -05:00
Slava Pestov
f9141e1aa1 SIL: Stub out type lowering of function types containing pack expansions 2022-12-06 14:15:07 -05:00
Slava Pestov
09b061bd0d SIL: Preliminary type lowering for PackType and PackExpansionType 2022-11-08 19:09:07 -05:00
Slava Pestov
9d96ed940f AST: Rename 'canonical wrt. generic signature' to 'reduced'
We had two notions of canonical types, one is the structural property
where it doesn't contain sugared types, the other one where it does
not contain reducible type parameters with respect to a generic
signature.

Rename the second one to a 'reduced type'.
2022-08-09 12:46:31 -04:00
Robert Widmann
ce4afc7e4d Recurse Into Existential Types With Generic Structure
Before the introduction of parameterized existential types, there
was no generic structure under these types. Now that there is, we'll
need to recurse into them to pick up any latent generic types
and lower them appropriately.

rdar://94320481
2022-06-18 12:36:50 -06:00
Michael Gottesman
8216a2a816 [move-only] Rename AbstractionPattern move only wrapper add/remove methods to match SILType's
Just forgot to change these when I changed the name of the SILType methods. In
summary:

1. withoutMoveOnly -> removingMoveOnlyWrapper
2. withMoveOnly -> addingMoveOnlyWrapper
2022-06-15 14:15:21 -07:00
zoecarver
9c32aace6c [nfc] Remove dead operator code pt. 1 2022-06-10 13:33:29 -07:00
Michael Gottesman
02759d150b [move-only] Add methods to AbstractionPattern to add/remove the move only bit.
The names are AbstractionPattern::with{,out}MoveOnly().
2022-06-03 11:27:16 -07:00
Josh Soref
d767912be2 Spelling sil (#42471)
* spelling: accessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accessories

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: allocated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: amortizes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: are

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: arguments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: cacheable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: check

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compatible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compilation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completely

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: construct

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: derivation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deserialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: destroyed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: determined

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: different

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: doesn't

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equality

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equivalent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: formation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: forwards

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: global

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: guaranteed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: have

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identify

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inaccessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indeterminate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inefficient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inheritance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantaneous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instruction

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intentionally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interior

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intrinsic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introducing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: irrelevant

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: message

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: multi

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessarily

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: object

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: one

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherwise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pattern

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pipeline

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: possibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: postdominance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: providing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reached

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: refrigerator

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: remaining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resilient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scavenge

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scheduled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: separately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: serializable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplicity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specifically

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substituted

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: subtypes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: supplement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: syntax

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: there

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: these

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: this

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: though

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: through

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transpose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: trivial

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: value

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: verification

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: visibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: weird

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whole

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-22 15:11:09 -07:00
Doug Gregor
209167ae30 Eliminate spurious uses of ArchetypeType::getRoot(). 2022-01-19 09:54:34 -08:00
Joe Groff
5c404acbde SIL: More robust substituted function type lowering.
This change separates out the formation of the generic signature and
substitutions for a SIL substituted function type as a pre-pass
before doing the actual function type lowering. The only input we
really need to form this signature is the original abstraction pattern
that a type is being lowered against, and pre-computing it should make
the code less side-effecty and confusing. It also allows us to handle
generic nominal types in a more robust way; we transfer over all of
the nominal type requirements to the generalized generic signature,
then when recursively visiting the bindings, we same-type-constrain
the generic parameters used in those requirements to the newly-generalized
generic arguments. This ensures that the minimized signature preserves
any non-trivial requirements imposed by the nominal type, such as
conditional conformances on its type arguments, same-type constraints
among associated types, etc.

This approach does lead to less-than-optimal generalized generic
signatures getting generated, since nominal type generic arguments
get same-type-bound either to other generic arguments or fixed to
concrete types almost always. It would be useful to do a minimization
pass on the final generic signature to eliminate these unnecessary
generic arguments, but that can be done in a follow-up PR.
2021-11-10 12:45:34 -08:00
Robert Widmann
e545d7f760 Lift getCanonicalTypeInContext up to GenericSignature 2021-09-20 15:43:07 -07:00
Joe Groff
fdc0e08d60 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-09 13:42:02 -07:00
Joe Groff
3abe16f40f Revert "SILGen: Emit literal closures at the abstraction level of their context. [take 2]" (#39228) 2021-09-09 11:53:43 -05:00
Joe Groff
43506a29a2 SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-09-07 11:55:29 -07:00
Holly Borla
86e1014399 Revert " SILGen: Emit literal closures at the abstraction level of their context." 2021-08-18 09:03:23 -07:00
Joe Groff
309500d4bf SILGen: Emit literal closures at the abstraction level of their context.
Literal closures are only ever directly referenced in the context of the expression they're written in,
so it's wasteful to emit them at their fully-substituted calling convention and then reabstract them if
they're passed directly to a generic function. Avoid this by saving the abstraction pattern of the context
before emitting the closure, and then lowering its main entry point's calling convention at that
level of abstraction. Generalize some of the prolog/epilog code to handle converting arguments and returns
to the correct representation for a different abstraction level.
2021-08-16 09:39:19 -07:00
nate-chandler
8345174bae Merge pull request #38370 from nate-chandler/rdar79383990
[SILGen] Used formal type when bridging completion handler arguments.
2021-07-26 10:57:49 -07:00
Nate Chandler
4cb8453d6a [SILGen] Used formal type when bridging continuation arguments.
Address a FIXME where lowered types rather than formal types were used
when converting from objc to native types which resulted in a failure to
convert block types.
2021-07-24 14:25:26 -07:00