To preserve correct behavior under substitution, the parent type
of a protocol type alias must be the 'Self' generic parameter and
not the protocol's existential type.
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.
Make getInterfaceType() call validateDecl on behalf of its clients. In effect, this makes the interface type behave like a request. It also means that its clients no longer need to perform a number of undesirable anti-patterns in order to sidestep the bizarre API contract validateDecl has at the moment
In particular, the following things are no longer necessary:
- Checking for a missing interface type then validating
- Validating the interface type then retrieving it
- Validating the interface type then retrieving a derived value
These anti-patterns will be removed in follow-up commits
Now that the generic signature is computable on demand, this predicate is doubly useless. All of the callers intended to ask "hasInterfaceType" anyways.
The general class of cycle here is when validation asks for the generic signature which triggers requirement checking which forces us to ask for the generic signature of the extension again. We should look into a more principled solution.
See rdar://55263708
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.
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
Define a request that provides the generic signature for a given generic context. This unblocks a ton of cleanup and will allow us to remove validateExtension, validateDeclForNameLookup, and a lot of the surrounding infrastructure.
Being more honest about which declarations actually have a generic signature computed has naturally introduced more cycles in requests. hasComputedGenericSignature() now acts as a recursion breaker. In the future, we should purge any uses of this accessor that specifically head-off cycles as the cycle itself is probably part of a larger structural problem.
First, remove the AvailabilityContext parameter; it was confusing because
we actually always want to use the deployment target here.
Then, split this method up into three methods:
- isAlwaysWeakImported(): simply checks for a @_weakLinked attribute, either
on the declaration itself or one of its parent contexts.
- getAvailabilityForLinkage(): returns the OS version availability when
this declaration was introduced, or if the declaration does not have
explicit availability, check it's storage (if its an accessor), or its
parent contexts.
- isWeakImported(ModuleDecl *fromModule): combines these two checks to
determine if the declaration should be weak linked when referenced from
the given module, or if it might be weak referenced from some module
(if the module parameter is null).
Do not offer a mutating fix-it if we have a mutating protocol requirement and we're assigning to it from an implicitly nonmutating setter inside a protocol extension
This eliminates the entire 'lazy generic environment' concept;
essentially, all generic environments are now lazy, and since
each signature has exactly one environment, their construction
no longer needs to be co-ordinated with deserialization.
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().
Storing NULL here on failure is brittle and was only necessary when the
typechecker was leaking type variables in expressions. Now that we're
better about this, it's best to preserve the damaged AST.
Unify a bunch of quasi-independent callsites into a single request that
builds up a generic signature from a variety of inference sources. This
draws the extension typealias workaround for SE-0229 into TypeCheckDecl
where we can better work on refactoring it. The goal is to use this as
a springboard to requests that compute generic environments for various
and sundry decls.
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.
Introduce callables: values of types that declare `func callAsFunction`
methods can be called like functions. The call syntax is shorthand for
applying `func callAsFunction` methods.
```swift
struct Adder {
var base: Int
func callAsFunction(_ x: Int) -> Int {
return x + base
}
}
var adder = Adder(base: 3)
adder(10) // desugars to `adder.callAsFunction(10)`
```
`func callAsFunction` argument labels are required at call sites.
Multiple `func callAsFunction` methods on a single type are supported.
`mutating func callAsFunction` is supported.
SR-11378 tracks improving `callAsFunction` diagnostics.