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.
VarDecls inherit their TypeRepr from their enclosing pattern, if any.
To retrieve the TypeRepr attached to a VarDecl or a ParamDecl in
a uniform way, the getTypeReprOrParentPatternTypeRepr API has been
provided.
TypeCheckPattern used to splat the interface type into this, and
different parts of the compiler would check one or the other. There is
now one source of truth: The interface type. The type repr is now just
a signal that the user has written an explicit type annotation on
a parameter. For variables, we will eventually be able to just grab
this information from the parent pattern.
Make getRawValueExpr() return a checked value.
This entails a strange kind of request that effectively acts like
a cache warmer. In order to properly check the raw value expression for
a single case, we actually need all the other cases for the
autoincrementing synthesis logic. The strategy is therefore to have the
request act at the level of the parent EnumDecl and check all the values
at once. We also cache at the level of the EnumDecl so the cache
"warms" for all enum elements simultaneously.
The request also abuses TypeResolutionStage to act as an indicator for
how much information to compute. In the minimal case, we will return
a complete accounting of (auto-incremented) raw values. In the maximal
case we will also check and record types and emit diagnostics. The
minimal case is uncached to support repeated evaluation.
Note that computing the interface type of an @objc enum decl *must*
force this request. The enum's raw values are part of the ABI, and we
should not get all the way to IRGen before discovering that we cannot
possibly lay out the enum. In the future, we might want to consider
moving this check earlier or have IRGen tolerate broken cases but for
now we will maintain the status quo and not have IRGen emit
diagnostics.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
This removes it from the AST and largely replaces it with AnyObject
at the SIL and IRGen layers. Some notes:
- Reflection still uses the notion of "unknown object" to mean an
object with unknown refcounting. There's no real reason to make
this different from AnyObject (an existential containing a
single object with unknown refcounting), but this way nothing
changes for clients of Reflection, and it's consistent with how
native objects are represented.
- The value witness table and reflection descriptor for AnyObject
use the mangling "BO" instead of "yXl".
- The demangler and remangler continue to support "BO" because it's
still in use as a type encoding, even if it's not an AST-level
Type anymore.
- Type-based alias analysis for Builtin.UnknownObject was incorrect,
so it's a good thing we weren't using it.
- Same with enum layout. (This one assumed UnknownObject never
referred to an Objective-C tagged pointer. That certainly wasn't how
we were using it!)
Most of AST, Parse, and Sema deal with FileUnits regularly, but SIL
and IRGen certainly don't. Split FileUnit out into its own header to
cut down on recompilation times when something changes.
No functionality change.
This avoids making the structural type dependent on whether the interface type has been computed and neatly avoids special-casing non-parsed declarations which set their underlying type up front.
Computing the interface type of a typealias used to push validation forward and recompute the interface type on the fly. This was fragile and inconsistent with the way interface types are computed in the rest of the decls. Separate these two notions, and plumb through explicit interface type computations with the same "computeType" idiom. This will better allow us to identify the places where we have to force an interface type computation.
Also remove access to the underlying type loc. It's now just a cache location the underlying type request will use. Push a type repr accessor to the places that need it, and push the underlying type accessor for everywhere else. Getting the structural type is still preferred for pre-validated computations.
This required the resetting of a number of places where we were - in many cases tacitly - asking the question "does the interface type exist". This enables the removal of validateDeclForNameLookup
If we see `MyModule.Type`, the parser thinks this is a metatype type.
Escape the name `Type` so the parser can recognize it's a type name.
Fixes [SR-11422](https://bugs.swift.org/browse/SR-11422) rdar://55094784
Rework the lazy function body parsing mechanism to use the
request-evaluator, so that asking for the body of a function will
initiate parsing. Clean up a number of callers to
AbstractFunctionDecl::getBody() that don't actually need the body, so
we don't perform unnecessary parsing.
This change does not delay parsing of function bodies in the general
case; rather, it sets up the infrastructure to always delay parsing of
function bodies.
Rework the lazy function body parsing mechanism to use the
request-evaluator, so that asking for the body of a function will
initiate parsing. Clean up a number of callers to
AbstractFunctionDecl::getBody() that don't actually need the body, so
we don't perform unnecessary parsing.
This change does not delay parsing of function bodies in the general
case; rather, it sets up the infrastructure to always delay parsing of
function bodies.
We've fixed a number of bugs recently where callers did not expect
to get a null Type out of subst(). This occurs particularly often
in SourceKit, where the input AST is often invalid and the types
resulting from substitution are mostly used for display.
Let's fix all these potential problems in one fell swoop by changing
subst() to always return a Type, possibly one containing ErrorTypes.
Only a couple of places depended on the old behavior, and they were
easy enough to change from checking for a null Type to checking if
the result responds with true to hasError().
Also while we're at it, simplify a few call sites of subst().
The only place this was used in Decl.h was the failability kind of a
constructor.
I decided to replace this with a boolean isFailable() bit. Now that
we have isImplicitlyUnwrappedOptional(), it seems to make more sense
to not have ConstructorDecl represent redundant information which
might not be internally consistent.
Most callers of getFailability() actually only care if the result is
failable or not; the few callers that care about it being IUO can
check isImplicitlyUnwrappedOptional() as well.
We incorrectly assumed that a requirement 'rooted' in an outer parameter
must be necessarily defined as part of the outer context's signature,
and thus we were skipping it when printing the 'where' clause of a
nested declaration or an extension of a nested type.
Instead, actually get the outer generic signature and filter requirements
that the outer signature satisfies.
Fixes <rdar://problem/53769896>, <https://bugs.swift.org/browse/SR-11221>.
Since the return value of getAccessor() depends on mutable state, it
does not make sense in the request evaluator world. Let's begin by
removing some utility methods derived from getAccessor(), replacing
calls to them with calls to getAccessor().
Previously they were just skipped if enum elements weren't exploded
into their own individual lines, since the ASTPrinter assumed they'd
be present on the EnumCaseDecl. This led to miscompiles when using
a module interface for an enum with indirect cases, since they'd be
printed as non-indirect cases.
rdar://problem/53329452
The backing property for 'foo' is now '_foo', and the projected value '$foo'.
This updates Indexing to report occurrences of foo within both $foo and
_foo occurrences (rather than just $foo - the old _foo).
FindRelatedIdents was similarlar updated, so it reports 'foo' ranges in both
_foo and $foo.
CursorInfo now reports the USR, documentation, and location of foo when invoked
occurrences of $foo or _foo, but now leaves the name, type, and annotated
declaration of _foo/$foo as is. Having the same USR ensures rename invoked on
any of them will still rename via foo. Reporting foo's documentation comment
instead is just to present something more useful to the user.
That is, if they appear inside a larger type, they may need to be
parenthesized. ASTPrinter is careful about this already, so this
doesn't actually change any existing behavior, but it makes the
default more conservative when no PrintOptions are in play.
When an @_implementationOnly import includes Objective-C categories
for existing types, it's useful to be able to override the members
provided in those categories without exposing them to clients of the
framework being built. Allow this as long as the overriding
declaration is marked as @_implementationOnly itself, with an
additional check that the type of the declaration does not change.
(Normally overrides are allowed to change in covariant ways.)
Part of rdar://50827914
There are still cases (a module with a type that's the same name as the
module) where we cannot fully qualify all types. In those cases, allow
them to remain unqualified with a flag, `-Xfrontend
-preserve-types-as-written-in-module-interface`.
We should not be making assumptions about module lookup when we're
compiling a module interface, so instead print the types fully
qualified.
rdar://48445154