This simplifies the SILType substitution APIs and brings them in line with Doug and Slava's refactorings to improve AST-level type substitution. NFC intended.
Before this commit all code relating to handling arguments in SILBasicBlock had
somewhere in the name BB. This is redundant given that the class's name is
already SILBasicBlock. This commit drops those names.
Some examples:
getBBArg() => getArgument()
BBArgList => ArgumentList
bbarg_begin() => args_begin()
This ensures that ownership is properly propagated forward through the use-def
graph.
This was the work that was stymied by issues relating to SILBuilder performing
local ARC dataflow. I ripped out that local dataflow in 6f4e2ab and added a
cheap ARC guaranteed dataflow pass that performs the same optimization.
Also in the process of doing this work, I found that there were many SILGen
tests that were either pattern matching in the wrong functions or had wrong
CHECK lines (for instance CHECK_NEXT). I fixed all of these issues and also
expanded many of the tests so that they verify ownership. The only work I left
for a future PR is that there are certain places in tests where we are using the
projection from an original value, instead of a copy. I marked those with a
message SEMANTIC ARC TODO so that they are easy to find.
rdar://28685236
Reimplement the witness matching logic used for generic requirements
so that it properly models the expectations required of the witness,
then captures the results in the AST. The new approach has a number of
advantages over the existing hacks:
* The constraint solver no longer requires hacks to try to tangle
together the innermost archetypes from the requirement with the
outer archetypes of the context of the protocol
conformance. Instead, we create a synthetic set of archetypes that
describes the requirement as it should be matched against
witnesses. This eliminates the infamous 'SelfTypeVar' hack.
* The type checker no longer records substitutions involving a weird
mix of archetypes from different contexts (see above), so it's
actually plausible to reason about the substitutions of a witness. A
new `Witness` class contains the declaration, substitutions, and all
other information required to interpret the witness.
* SILGen now uses the substitution information for witnesses when
building witness thunks, rather than computing all of it from
scratch. ``substSelfTypeIntoProtocolRequirementType()` is now gone
(absorbed into the type checker, and improved from there), and the
witness-thunk emission code is simpler. A few other bits of SILGen
got simpler because the substitutions can now be trusted.
* Witness matching and thunk generation involving generic requirements
and nested generics now works, based on some work @slavapestov was
already doing in this area.
* The AST verifier can now verify the archetypes that occur in witness substitutions.
* Although it's not in this commit, the `Witness` structure is
suitable for complete (de-)serialization, unlike the weird mix of
archetypes previously present.
Fixes rdar://problem/24079818 and cleans up an area that's been messy
and poorly understood for a very, very long time.
Today, loads and stores are treated as having @unowned(unsafe) ownership
semantics. This leaves the user to specify ownership changes on the loaded or
stored value independently of the load/store by inserting ARC operations. With
the change to Semantic SIL, this will no longer be true. Instead loads, stores
have ownership semantics that one must reason about such as copy, take, and
trivial.
This change moves us closer to that world by eliminating the default
OwnershipQualification argument from create{Load,Store}. This means that the
compiler developer cannot ignore reasoning about the ownership semantics of the
memory operation that they are creating.
Operationally, this is a NFC change since I have just gone through the compiler
and updated all places where we create loads, stores to pass in the former
default argument ({Load,Store}OwnershipQualifier::Unqualified), to
SILBuilder::create{Load,Store}(...). For now, one can just do that in situations
where one needs to create loads/stores, but over time, I am going to tighten the
semantics up via the verifier.
rdar://28685236
The existing code assumed that the _bridgeToObjectiveC witness would never come from a protocol extension. Generating the correct set of substitutions is a bit harder than it ought to be, due to inconsistencies in how Sema represents generic witnesses. Fixes rdar://problem/28279269.
The commit was reverted because of a regression in the
Prototypes/CollectionTransformers test. I believe the root
cause was an escape analysis bug, which is fixed in my
previous commit.
id-as-Any lets you pass Optional to an ObjC API that takes `nonnull id`, and also lets you bridge containers of `Optional` to `NSArray` etc. When this occurs, we can unwrap the value and bridge it so that inhabited optionals still pass into ObjC in the expected way, but we need something to represent `none` other than the `nil` pointer. Cocoa provides `NSNull` as the canonical "null for containers" object, which is the least bad of many possible answers. If we happen to have the rare nested optional `T??`, there is no precedented analog for these in Cocoa, so just generate a unique sentinel object to preserve the `nil`-ness depth so we at least don't lose information round-tripping across the ObjC-Swift bridge.
Making Optional conform to _ObjectiveCBridgeable is more or less enough to make this all work, though there are a few additional edge case things that need to be fixed up. We don't want to accept `AnyObject??` as an @objc-compatible type, so special-case Optional in `getForeignRepresentable`.
Implements SR-0140 (rdar://problem/27905315).
If the thunk's type otherwise did not involve type parameters, we
would still pass around the generic parameters from the caller's
context, which is wasteful.
This would manifest as crashes in IRGen when bridging a block
taking another block in generic context.
- When emitting a re-abstraction thunk, make it pseudogeneric if
its parent function is pseudogeneric. This ensures we don't
try to get runtime type metadata when it doesn't exist.
- Mangle pseudogeneric-ness of a reabstraction thunk correctly.
Otherwise we could emit thunks with different signatures under
the same mangling.
- Only set the pseudogeneric attribute if the thunk has a generic
signature, since otherwise the mangling is no longer unique.
Fixes <rdar://problem/27718566>.
id-as-Any lets you pass Optional to an ObjC API that takes `nonnull id`, and also lets you bridge containers of `Optional` to `NSArray` etc. When this occurs, we can unwrap the value and bridge it so that inhabited optionals still pass into ObjC in the expected way, but we need something to represent `none` other than the `nil` pointer. Cocoa provides `NSNull` as the canonical "null for containers" object, which is the least bad of many possible answers. If we happen to have the rare nested optional `T??`, there is no precedented analog for these in Cocoa, so just generate a unique sentinel object to preserve the `nil`-ness depth so we at least don't lose information round-tripping across the ObjC-Swift bridge.
Making Optional conform to _ObjectiveCBridgeable is more or less enough to make this all work, though there are a few additional edge case things that need to be fixed up. We don't want to accept `AnyObject??` as an @objc-compatible type, so special-case Optional in `getForeignRepresentable`.
Implements SR-0140 (rdar://problem/27905315).
This patch is rather large, since it was hard to make this change
incrementally, but most of the changes are mechanical.
Now that we have a lighter-weight data structure in the AST for mapping
interface types to archetypes and vice versa, use that in SIL instead of
a GenericParamList.
This means that when serializing a SILFunction body, we no longer need to
serialize references to archetypes from other modules.
Several methods used for forming substitutions can now be moved from
GenericParamList to GenericEnvironment.
Also, GenericParamList::cloneWithOuterParameters() and
GenericParamList::getEmpty() can now go away, since they were only used
when SILGen-ing witness thunks.
Finally, when printing generic parameters with identical names, the
SIL printer used to number them from highest depth to lowest, by
walking generic parameter lists starting with the innermost one.
Now, ambiguous generic parameters are numbered from lowest depth
to highest, by walking the generic signature, which means test
output in one of the SILGen tests has changed.
When we call the DeclContext variants of these, use the
DeclContext's GenericEnvironment instead of GenericParamList.
Also, these functions would take a resolver argument, but we
always passed in nullptr, so just remove it now.
The old GenericParamList-based versions are still there
since they're called directly from SIL. They will go away
once SILFunction::ContextGenericParams is replaced with
a GenericEnvironment.
Simplify e.g., ASTContext::getBridgedToObjC(), which no longer needs
the optional return.
Eliminate the now-unused constraint kind for checking bridging to
Objective-C.
Bitcast the AnyObject result to AnyObject?, then call our new helper function, so that we can handle nils without choking. Fixes rdar://problem/27874026.
This is still a pretty bad code-generation pattern, but the layering
stuff makes it challenging to do the right thing.
Also, bridge non-optional NSErrors to Error using init_existential_ref
instead of going through the runtime function.
rdar://27810321
If a `T?` is converted to `Any?` to pass to a `_Nullable id` interface in ObjC, avoid the intermediate conversion and bridge straight to AnyObject? too.
- Previously we didn't know how to bridge address-only types. Add some
plumbing for this. Not fully general yet, but with a bit more work we
could allow resilient value types to adopt _ObjectiveCBridgable, too.
For now, this is just intended to support the id-as-Any work.
- Specifically when going from a type without any other known bridging
strategy, emit a call to the new `_bridgeAnythingToObjectiveC` entry
point from the previous commit.
Introduce bridging of NSError to ErrorProtocol, so an Objective-C API
expressed via an "NSError *" will be imported using ErrorProtocol in
the Swift. For example, the Objective-C method:
- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted;
will now be imported as:
func handleError(_ error: ErrorProtocol, userInteractionPermitted: Bool)
This is bullet (3) under the proposed solution of SE-0112. Note that
we made one semantic change here: instead of removing the conformance
of NSError to ErrorProtocol, which caused numerous problems both
theoretical and actual because the model expects that an NSError
conforms to ErrorProtocol without requiring wrapping, we instead limit
the ErrorProtocol -> NSError conversion that would be implied by
bridging. This is defensible in the short term because it also
eliminates the implicit conversion, and aligns with SE-0072, which
eliminates implicit bridging conversions altogether.
Now that ObjC types can be generic, we need to satisfy the type system by plumbing pseudogeneric parameters through func-to-block invocation thunks. Fixes rdar://problem/26524763.
We were failing to bridge Array<T> parameters in the signatures of Objective-C generics when their NSArray<T> * type in ObjC depended on generic parameters. This partially fixes rdar://problem/26371959, though IRGen still needs a fix to get us all the way through (which @rjmccall is working on).
(@DougGregor did all the work here, I'm just testing and committing.)
Bridging thunks don't yet support bridging address-only types, but
ideally they should, so that we can bridge Objective-C types to
resilient value types.
This came up while I was adding @_fixed_layout declarations in
the standard library. To make this easier to figure out in the
future, add the asserts to the bridging logic for now.
Also, to avoid hitting the asserts when we emit a reference to a
C function with an incompatible type, don't emit the foreign
function at all until we determine that the ABI conversion is safe.