Creating a @_dynamicReplacement function requires the creation of a
reference to the original function. We need to call SILGenModule's
getFunction to satisfy all the assertions in place.
rdar://59774606
A keypath component for a stored property can take one of several forms:
- The property offset is known to be constant at compile-time.
This is used in the simplest cases for classes and structs.
- The property offset is not constant, but can be loaded from a global.
This is used for classes that require runtime resilient layout, but where
the offsets do not depend on the generic context.
- The property offset is not constant, and must be loaded from metadata.
This is the case where the offset depends on the generic context. Here,
we were only set up to load it from a fixed offset in the metadata.
This works for generic structs, or generic classes where the superclass
chain does not cross a resilience boundary.
However, if a resilience boundary is crossed, the offset of the field
offset in the metadata must itself be obtained at runtime by adding a
constant to a value loaded from a global. This case is not supported by
the current keypath ABI due to an oversight.
I filed <rdar://problem/59777983> to track extending the ABI to handle
this more elegantly in the future.
Fixes <rdar://problem/59617119>.
emitKeyPathComponentForDecl was only checking if the setter was
accessible from the current module, not the current function.
This failed when accessing an internal setter from a module
imported for testing.
emitKeyPathComponentForDecl was only checking if the setter was
accessible from the current module, not the current function.
This failed when accessing an internal setter from a module
imported for testing.
Name binding can trigger swiftinterface compilation, which creates
a new ASTContext and runs a compilation job. If the compiler was
run with -stats-output-dir, this could trigger an assertion because
SharedTimer is not re-entrant.
Fix this by replacing all direct uses of SharedTimer in the frontend
with FrontendStatsTracer. SharedTimer is still used to _implement_
FrontendStatsTracer, however we can collapse some of the layers in
the implementation later. Many of the usages should also become
redundant over time once more code is converted over to requests.
This commit introduces a request to type-check a
default argument expression and splits
`getDefaultValue` into 2 accessors:
- `getStructuralDefaultExpr` which retrieves the
potentially un-type-checked default argument
expression.
- `getTypeCheckedDefaultExpr` which retrieves a
fully type-checked default argument expression.
In addition, this commit adds `hasDefaultExpr`,
which allows checking for a default expr without
kicking off a request.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
https://forums.swift.org/t/improving-the-representation-of-polymorphic-interfaces-in-sil-with-substituted-function-types/29711
This prepares SIL to be able to more accurately preserve the calling convention of
polymorphic generic interfaces by letting the type system represent "substituted function types".
We add a couple of fields to SILFunctionType to support this:
- A substitution map, accessed by `getSubstitutions()`, which maps the generic signature
of the function to its concrete implementation. This will allow, for instance, a protocol
witness for a requirement of type `<Self: P> (Self, ...) -> ...` for a concrete conforming
type `Foo` to express its type as `<Self: P> (Self, ...) -> ... for <Foo>`, preserving the relation
to the protocol interface without relying on the pile of hacks that is the `witness_method`
protocol.
- A bool for whether the generic signature of the function is "implied" by the substitutions.
If true, the generic signature isn't really part of the calling convention of the function.
This will allow closure types to distinguish a closure being passed to a generic function, like
`<T, U> in (*T, *U) -> T for <Int, String>`, from the concrete type `(*Int, *String) -> Int`,
which will make it easier for us to differentiate the representation of those as types, for
instance by giving them different pointer authentication discriminators to harden arm64e
code.
This patch is currently NFC, it just introduces the new APIs and takes a first pass at updating
code to use them. Much more work will need to be done once we start exercising these new
fields.
This does bifurcate some existing APIs:
- SILFunctionType now has two accessors to get its generic signature.
`getSubstGenericSignature` gets the generic signature that is used to apply its
substitution map, if any. `getInvocationGenericSignature` gets the generic signature
used to invoke the function at apply sites. These differ if the generic signature is
implied.
- SILParameterInfo and SILResultInfo values carry the unsubstituted types of the parameters
and results of the function. They now have two APIs to get that type. `getInterfaceType`
returns the unsubstituted type of the generic interface, and
`getArgumentType`/`getReturnValueType` produce the substituted type that is used at
apply sites.
Switch most callers to explicit indices. The exceptions lie in things that needs to manipulate the parsed output directly including the Parser and components of the ASTScope. These are included as friend class exceptions.
This flag, currently staged in as `-experimental-skip-non-inlinable-function-bodies`, will cause the typechecker to skip typechecking bodies of functions that will not be serialized in the resulting `.swiftmodule`. This patch also includes a SIL verifier that ensures that we don’t accidentally include a body that we should have skipped.
There is still some work left to make sure the emitted .swiftmodule is exactly the same as what’s emitted without the flag, which is what’s causing the benchmark noise above. I’ll be committing follow-up patches to address those, but for now I’m going to land the implementation behind a flag.
Teach SILGen to emit a separate SIL function to capture the
initialization of the backing storage type for a wrapped property
based on the wrapped value. This eliminates manual code expansion at
every use site.
Like the last commit, SourceFile is used a lot by Parse and Sema, but
less so by the ClangImporter and (de)Serialization. Split it out to
cut down on recompilation times when something changes.
This commit does /not/ split the implementation of SourceFile out of
Module.cpp, which is where most of it lives. That might also be a
reasonable change, but the reason I was reluctant to is because a
number of SourceFile members correspond to the entry points in
ModuleDecl. Someone else can pick this up later if they decide it's a
good idea.
No functionality change.
Removes duplicated logic from the implementations of
FileUnit::lookupValue, and simplifies the interface to
ModuleDecl::lookupValue, where everyone was passing an empty
(non-filtering) access path anyway /except/ during actual lookup from
source code. No functionality change.
This memoizes the result, which is fine for all callers; the only
exception is open existential types where each new open existential
now explicitly gets a unique generic environment, allocated by
calling GenericEnvironment::getIncomplete().