Implements SE-0460 -- the non-underscored version of @specialized.
It allows to specify "internal" (not abi affecting) specializations.
rdar://150033316
Plus tweak `DefaultDefinitionTypeRequest` caching to support querying the
cached type when dumping. This fixes a crash where type computation is
triggered in the dumper before import resolution in `-dump-parse` mode.
Clang importer diagnostics that are produced as a result of a reference
in Swift code are attached to as notes to the Sema produced diagnostic
that indicates the declaration is unavailable.
Ex: Notes about why a C function import failed are attached to
the error explaining that the symbol could not be found in scope.
This patch introduces new diagnostics to the ClangImporter to help
explain why certain C, Objective-C or C++ declarations fail to import
into Swift. This patch includes new diagnostics for the following entities:
- C functions
- C struct fields
- Macros
- Objective-C properties
- Objective-C methods
In particular, notes are attached to indicate when any of the above
entities fail to import as a result of refering an incomplete (only
forward declared) type.
The new diangostics are hidden behind two new flags, -enable-experimental-clang-importer-diagnostics
and -enable-experimental-eager-clang-module-diagnostics. The first flag emits diagnostics lazily,
while the second eagerly imports all declarations visible from loaded Clang modules. The first
flag is intended for day to day swiftc use, the second for module linting or debugging the importer.
This attribute allows to define a pre-specialized entry point of a
generic function in a library.
The following definition provides a pre-specialized entry point for
`genericFunc(_:)` for the parameter type `Int` that clients of the
library can call.
```
@_specialize(exported: true, where T == Int)
public func genericFunc<T>(_ t: T) { ... }
```
Pre-specializations of internal `@inlinable` functions are allowed.
```
@usableFromInline
internal struct GenericThing<T> {
@_specialize(exported: true, where T == Int)
@inlinable
internal func genericMethod(_ t: T) {
}
}
```
There is syntax to pre-specialize a method from a different module.
```
import ModuleDefiningGenericFunc
@_specialize(exported: true, target: genericFunc(_:), where T == Double)
func prespecialize_genericFunc(_ t: T) { fatalError("dont call") }
```
Specially marked extensions allow for pre-specialization of internal
methods accross module boundries (respecting `@inlinable` and
`@usableFromInline`).
```
import ModuleDefiningGenericThing
public struct Something {}
@_specializeExtension
extension GenericThing {
@_specialize(exported: true, target: genericMethod(_:), where T == Something)
func prespecialize_genericMethod(_ t: T) { fatalError("dont call") }
}
```
rdar://64993425
Start fixing SR-12526: `@derivative` attribute cross-module deserialization
crash. Remove original `AbstractFunctionDecl *` from `DerivativeAttr` and store
`DeclID` instead, mimicking `DynamicReplacementAttr`.
Type erasure requires a circular construction by its very nature:
@_typeEraser(AnyProto)
protocol Proto { /**/ }
public struct AnyProto : Proto {}
If we eagerly resolve AnyProto, the chain of resolution steps that
deserialization must make goes a little something like this:
Lookup(Proto)
-> Deserialize(@_typeEraser(AnyProto))
-> Lookup(AnyProto)
-> DeserializeInheritedStuff(AnyProto)
-> Lookup(Proto)
This cycle could be broken if the order of incremental inputs was
such that we had already cached the lookup of Proto.
Resolve this cycle in any case by suspending the deserialization of the
type eraser until the point it's demanded by adding
ResolveTypeEraserTypeRequest.
rdar://61270195
To support lazy resolution of the cross-referenced function in a serialized @_dynamicReplacement(for: ...) attribute, add a utility to the LazyMemberLoader and plumb it through. This is a more general utility than the current resolver, which relies on the type checker to strip the attribute off of VarDecls and fan it back out onto accessors, which means serialization has only ever seen AbstractFunctionDecls.
Witness matching is a source of a lot of ad-hoc cycles, and mixes the
logic that performs resolution, caching, validation, and cycle detection into one
place. To make matters worse, some checkers kick off other checks in
order to cache work for further declarations, and access an internal
cache on their subject conformance for many requirements at once, or
sometimes just one requirement.
None of this fits into the request evaluator's central view of the
caching. This is further evidenced by the fact that if you attempt to
move the caching step into the evaluator, it overcaches the same
witness and trips asserts.
As a start, define requests for the resolution steps, and flush some
hacks around forcing witness resolution. The caching logic is mostly
untouched (the requests don't actually cache anything), but some cycle
breaking is now handled in the evaluator itself. Once witness matching
has been refactored to cache with the evaluator, all of these hacks can
go away.
My urge to destroy the LazyResolver outweighs the compromises here.
Codable's deep magic currently forces conformance checks in the middle
of name lookup in order to inject CodingKeys into lookup results. This
is compounded by the fact that this lookup fixup is occuring
incrementally, meaning depending on order of requirements being looked
up, Decl::getMembers() will give you a different answer.
Compounding this, NameLookup relied on the LazyResolver to formalize
this layering violation, and relied on implicit laziness to guard
against re-entrancy.
The approach is multi-pronged:
1) Shift the layering violation into the request evaluator
2) Spell out the kinds of resolution we support explicitly (make them
easier to find and kill)
3) Remove the LazyResolver entrypoint this was relying on
4) Split off the property wrappers part into its own utility
The moment you've all been waiting for...
Define InterfaceTypeRequest and use it to, well, compute the interface
type. This naturally widens the few cycles that we pick up with the
request evaluator.
There is still a lot of work to get done here, mostly around scaling
back all of the ad-hoc circularity checks around the interface type
computation. It would also be great to improve the circularity
diagnostics.
Push the relevant work this was doing down into the callers. Most of them didn't want to validate the entire extension and force its generic parameters, they just wanted to validate the nominal type.
We must eagerly validate the generic signature of extensions, though. This avoids a class of cycles where non-generic members of an extension with a generic signaure will call through to getGenericSignatureOfContext and force the generic signature anyways. When this calls through to protocol witness matching, the signature can be recursively computed.
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.
Lazy parsing for the members of nominal types and extensions depends
only on information already present in
`IterableDeclContext`. Eliminate the use of PersistentParserState as
an intermediary and have the member-parsing request construct a new
`Parser` instance itself to handle parsing. Make this possible even
for ill-formed nominal types/extensions to simplify the code path.
Eliminate `LazyMemberParser` and all of its uses, because it was only
present for lazy member parsing, which no longer needs it.
Ensure that lazy parsing of the members of nominal type definitions
and extensions is handled through a request. Most of the effort here
is in establishing a new request zone for parser requests.
ConformanceChecker::ensureRequirementsAreSatisfied() modifies the
conformance as it resolves each one of its associated conformances,
so a re-entrant call can end up corrupting state by adding too
many elements to the buffer, or adding elements at the wrong
offsets.
If TypeChecker::checkConformanceRequirements() was called before
ConformanceChecker::resolveTypeWitnesses(), we could re-entrantly call
ConformanceChecker::ensureRequirementsAreSatisfied():
TypeChecker::checkConformanceRequirements()
=> ConformanceChecker::ensureRequirementsAreSatisfied()
=> Type::subst(), etc
=> ConformanceChecker::resolveTypeWitnesses()
=> ConformanceChecker::ensureRequirementsAreSatisfied()
The code in SubstitutionMap::lookupConformance() worked around
this by checking the failure condition and calling
resolveTypeWitness() first, before calling getAssociatedConformance().
Instead, remove this and call resolveTypeWitness() from inside
NormalProtocolConformance::getAssociatedConformance().
If the type checker doesn't prepopulate signature conformances, fill
them in when we first need them. This is a stopgap solution until we
can move these queries over to the request-evaluator.
Fixes rdar://problem/34584596, as well as a regression introduced by
the use of mangled names for associated conformances in witness tables.
Introduce a new request kind to capture the computation of the set of
overridden declarations of a given declaration, eliminating the
stateful “setOverriddenDecls()” calls from the type checker.
Rather than call through the LazyResolver (when available) to satisfy
queries that may require type checking, call into the evaluator
directly: it will make use of the type checker (via the lazy resolver)
when necessary. This change should allow us to use the
request-evaluator’s cache for state rather than mutable AST state,
as well as the ability to see requests that were evaluated after
type checking.
Implement TypeChecker::resolveInheritedProtocols() in terms of
"getInheritedType()" queries, instead.
[Sema] Put back resolveInheritedProtocols().
We're still depending on it to update state in some cases.
Wire up the request-evaluator with an instance in ASTContext, and
introduce two request kinds: one to retrieve the superclass of a class
declaration, and one to compute the type of an entry in the
inheritance clause.
Teach ClassDecl::getSuperclass() to go through the request-evaluator,
centralizing the logic to compute and extract the superclass
type.
Fixes the crasher from rdar://problem/26498438.
Introduced during the bring-up of the generics system in July, 2012,
Substitution (and SubstitutionList) has been completely superseded by
SubstitutionMap. R.I.P.
We need to be able to find which conformances need to be
declared/constructed without forcing extensions to be completely
validated. This is important for both SR-6569 and
rdar://problem/36499373. The former due to the source-level recursion,
and the latter because implied conformances weren't always
constructed (but are needed for good diagnostics).
They weren't always constructed because:
1. ConformanceLookupTable's updateLookupTable on an early stage (before
implied conformances are found) triggers extension
validation *before* constructing any conformances, but *after*
updating the stage state
2. extension validation validates the conditional requirements
3. validating the conditional requirements requires setting up generic
signatures
4. setting up generic signatures forces the types conformances and so
ends up in updateLookupTable on the same nominal again, skipping over
the earlier stages that are complete/in progress
5. we expand the conformances that are implied by all the conformances we
know about... But we don't know any, because we haven't finished the
first updateLookupTable.
This breaks the loop at step 2: we instead do the minimal work needed to
know what conformances an extension (might) declare, which is connect
the extension to a type, and then resolve the inherited TypeReprs to
Types.
With the previous changes, validating a property while
type checking its initializer is no longer a fatal error.
This means we don't have to do anything special when
validating typo correction candidates, so we can get rid
of the TypoCorrectionResolver. This means there is now
only one subclass of LazyResolver, the TypeChecker itself.
When loading the named members for a given name, we want to load all
of the members with that base name... not only the ones that match the
full name, because the lookup table is indexed by base name and
filtering too early drops candidates.
Fixes rdar://problem/36085994.