Identifier contains a pointer to character data, and we need to ensure that this pointer has enough spare bits in it for DeclBaseName and DeclName. This currently happens to be true because the StringMap used to intern Identifier pointers happens to place a 32-bit size field in the MapTableEntry object, but it would be better to explicitly force the alignment we want and assert that it’s correct.
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!)
The recursive properties now include the type alias generic parameters
and parent type, not just the underlying type. This means that a type
alias type like Foo<T>.Bar can be dependent even if its underlying type
is not dependent.
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.
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 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().
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.
Introduce a request to form an abstract generic signature given a
base signature, additional generic parameters, and additional
requirements. It is meant to provide a caching layer in front of the
generic signature builder.
Switch one direct client of the generic signature builder over to this
mechanism, the formation of a generic signature for an existential
type.
The type alias might not have a generic signature set yet, so we have to
use the generic signature in the substitution map.
Yay for un-request-ified decl checking!
Caught by ASAN - <rdar://problem/54637931>.
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().
Note that in all cases it was either nullptr or ctx.getLazyResolver().
While passing in nullptr might appear at first glance to mean something
("don't type check anything"), in practice we would check for a nullptr
value and pull out ctx.getLazyResolver() instead. Furthermore, with
the lazy resolver going away (at least for resolveDeclSignature() calls),
it won't make sense to do that anymore anyway.