They weren't always mapped out of context before building the interface type for the opaque
type decl, and we failed to substitute the base class constraint when forming an opaque archetype
with specific substitutions. Fixes rdar://problem/53318811.
Fixes rdar://problem/53407949 | SR-11138. Previously, we'd only look at the outermost property wrapper to decide whether the wrapped property's getter and setter were `mutating` (or exist at all). In reality, this requires considering the semantics of the composed accesses of each wrapper layer's
`wrappedValue` property. Fixing this systematically addresses a number of issues:
- As SR-11138 reported, composing a nonmutating-get-set wrapper ought to produce a composed wrapper
that's nonmutating.
- We would previously allow a property wrapper with a mutating getter to be nested inside one with
only a getter, even though the resulting implementation was unsound (because there's no mutable
context for the inner wrapper to execute its get on.)
- Similarly, we would construct unsound setters in cases where the setter can't exist, such as when
the nested wrapper isn't settable but the outer wrapper is.
This improves on the previous situation:
- The request ensures that the backing storage for lazy properties
and property wrappers gets synthesized first; previously it was
only somewhat guaranteed by callers.
- Instead of returning a range this just returns an ArrayRef,
which simplifies clients.
- Indexing into the ArrayRef is O(1), which addresses some FIXMEs
in the SIL optimizer.
This calculates a result directly from the function's result type
instead of checking a bit that was previously set by the type
checker. Also, always returns true for constructors to simplify
some callers.
Add `llvm_unreachable` to mark covered switches which MSVC does not
analyze correctly and believes that there exists a path through the
function without a return value.
Because opaque types are currently limited so that they only have immediate
protocol constraints, and therefore don't interact with the outer generic
parameters at all, we can get away without adding same-type constraints for
the outer generic parameters to their substitutions in the generic signature
builder when setting up the environment for an opaque archetype. This
avoids the strict assertion that opaque types not appear in other decls'
interface types. rdar://problem/50509030
Adding where clauses would break this hack.
Opaque result type archetypes can involve type variables, which
then get introduced into GenericSignatureBuilders and the
generated GenericSignatures. Allocate them in the proper arena
So we don’t end up with use-after-free errors.
Fixes rdar://problem/50309503.
This allows the conversion of the Windows `BOOL` type to be converted to
`Bool` implicitly. The implicit bridging allows for a more ergonomic
use of the native Windows APIs in Swift.
Due to the ambiguity between the Objective C `BOOL` and the Windows
`BOOL`, we must manually map the `BOOL` type to the appropriate type.
This required lifting the mapping entry for `ObjCBool` from the mapped
types XMACRO definition into the inline definition in the importer.
Take the opportunity to simplify the mapping code.
Adjust the standard library usage of the `BOOL` type which is now
eclipsed by the new `WindowsBool` type, preferring to use `Bool`
whenever possible.
Thanks to Jordan Rose for the suggestion to do this and a couple of
hints along the way.
The initialization of an instance property that has an attached
property delegate involves the initial value written on the property
declaration, the implicit memberwise initializer, and the default
arguments to the implicit memberwise initializer. Implement SILGen
support for each of these cases.
There is a small semantic change to the creation of the implicit
memberwise initializer due to SE-0242 (default arguments for the
memberwise initializer). Specifically, the memberwise initializer will
use the original property type for the parameter to memberwise
initializer when either of the following is true:
- The corresponding property has an initial value specified with the
`=` syntax, e.g., `@Lazy var i = 17`, or
- The corresponding property has no initial value, but the property
delegate type has an `init(initialValue:)`.
The specific case that changed is when a property has an initial value
specified as a direct initialization of the delegate *and* the
property delegate type has an `init(initialValue:)`, e.g.,
```swift
struct X {
@Lazy(closure: { ... })
var i: Int
}
```
Previously, this would have synthesized an initializer:
```swift
init(i: Int = ???) { ... }
```
However, there is no way for the initialization specified within the
declaration of i to be expressed via the default argument. Now, it
synthesizes an initializer:
```swift
init(i: Lazy<Int> = Lazy(closure: { ... }))
```
When a property has an attached property delegate, a backing storage
property of the corresponding delegate type will be
synthesized. Perform this synthesis, and also synthesize the
getter/setter for the original property to reference the backing
storage property.
Tear out the hacks to pre-substitute opaque types before they enter the SIL type system.
Implement UnderlyingToOpaqueExpr as bitcasting the result of the underlying expression from the
underlying type to the opaque type.
The non-generic nominal type nodes do not actually need to use LLVM's
FoldingSetNode, and on my workstation the release build of the standard
library completes about 1/3 of a second faster after switching to LLVM
DenseMap. This is perhaps not surprising, because Decl to Type mappings
are only needed during early compiler stages, but the intrusive
FoldingSetNode data decreases CPU cache efficiency during all compiler
stages. As a bonus, the resulting code is simpler.
Rather than eagerly doing a bunch of name lookups to establish the known
protocol kind, lazily match the ProtocolDecl to the list of known
protocols as-needed. This eliminates a bunch of up-front unqualified
name lookups when spinning up a type checker.