Rather than directly using the ArchetypeBuilder associated with a
canonical generic signature, use a canonical GenericEnvironment
associated with that canonical generic signature. This has a few
benefits:
* It's cleaner to not have IRGen working with archetype builders;
GenericEnvironment is the right abstraction for mapping between
dependent types and archetypes for a specific context.
* It helps us separate the archetype builder from a *specific*
set of archetypes. This is an ongoing refactor that is intended to
allow us to re-use archetype builders across different generic
environments.
As part of this, ArchetypeBuilder::substDependentType() has gone away
in favor of GenericEnvironment::mapTypeIntoContext().
Store leading a trailing "trivia" around a token, such as whitespace,
comments, doc comments, and escaping backticks. These are syntactically
important for preserving formatting when printing ASTs but don't
semantically affect the program.
Tokens take all trailing trivia up to, but not including, the next
newline. This is important to maintain checks that statements without
semicolon separators start on a new line, among other things.
Trivia are now data attached to the ends of tokens, not tokens
themselves.
Create a new Syntax sublibrary for upcoming immutable, persistent,
thread-safe ASTs, which will contain only the syntactic information
about source structure, as well as for generating new source code, and
structural editing. Proactively move swift::Token into there.
Since this patch is getting a bit large, a token fuzzer which checks
for round-trip equivlence with the workflow:
fuzzer => token stream => file1
=> Lexer => token stream => file 2 => diff(file1, file2)
Will arrive in a subsequent commit.
This patch does not change the grammar.
This function had a weird, pre-ProtocolConformanceRef interface that
returned true when the type conformed to the protocol, then had a
separate indirect return value for the concrete conformance (if there
is one). Refactor this API, and the similar
TypeChecker::containsProtocol(), to produce an optional
ProtocolConformanceRef, which is far more idiomatic and easier to
use. Push ProtocolConformanceRef into a few more places. Should be NFC
An environment is always associated with a location with a signature, so
having them separate is pointless duplication. This patch also updates
the serialization to round-trip the signature data.
The ASTContext had a wacky "get member type" callback that actually
called back into the constraint system (!) to build member types. This
callback was obsoleted by the change that started representing nested
types as DependentMemberTypes.
In the constraint solver, we've traditionally modeled nested type via
a "type member" constraint of the form
$T1 = $T0.NameOfTypeMember
and treated $T1 as a type variable. While the solver did generally try
to avoid attempting bindings for $T1 (it would wait until $T0 was
bound, which solves the constraint), on occasion we would get weird
behavior because the solver did try to bind the type
variable.
With this commit, model nested types via DependentMemberType, the same
way we handle (e.g.) the nested type of a generic type parameter. This
solution maintains more information (e.g., we know specifically which
associated type we're referring to), fits in better with the type
system (we know how to deal with dependent members throughout the type
checker, AST, and so on), and is easier to reason able.
This change is a performance optimization for the type checker for a
few reasons. First, it reduces the number of type variables we need to
deal with significantly (we create half as many type variables while
type checking the standard library), and the solver scales poorly with
the number of type variables because it visits all of the
as-yet-unbound type variables at each solving step. Second, it
eliminates a number of redundant by-name lookups in cases where we
already know which associated type we want.
Overall, this change provides a 25% speedup when type-checking the
standard library.
Various parts of the type checker (related to enum == synthesis) rely
on == for Ints being a module-scope function, which is silly. Remove
the restriction. Fixes rdar://problem/29029561.
This gives us a concept we can eventually use to cache the lowered physical layout of fragile structs and classes, and more immediately, concretize the layout of closure boxes in a way that lets us represent the capture of generic environments and multiple captured values without compromising the "nominal" nature of box layouts. To start exercising the basic implementation, change the representation of SILBoxType to be in terms of a SILLayout, though avoid any immediate functionality change by preserving the single-boxed-type interface for now.
Sugared GenericTypeParamTypes point to GenericTypeParamDecls,
allowing the name of the parameter as written by the user to be
recovered. Canonical GenericTypeParamTypes on the other hand
only store a depth and index, without referencing the original
declaration.
When printing SIL, we wish to output the original generic parameter
names, even though SIL only uses canonical types. Previously,
we used to accomplish this by mapping the generic parameter to an
archetype and printing the name of the archetype. This was not
adequate if multiple generic parameters mapped to the same
archetype, or if a generic parameter was mapped to a concrete type.
The new approach preserves the original sugared types in the
GenericEnvironment, adding a new GenericEnvironment::getSugaredType()
method.
There are also some other assorted simplifications made possible
by this.
Unfortunately this makes GenericEnvironments use a bit more memory,
however I have more improvements coming that will offset the gains,
in addition to making substitution lists smaller also.
Similar to “isTypeParameter,” this new entry point determines whether the type is a type variable or a nested type of a type thereof. The latter case isn’t actually formed yet, so this is NFC staging the trivial bits of this change.
In most places where we were checking "is<ErrorType>()", we now mean
"any error occurred". The few exceptions are in associated type
inference, code completion, and expression diagnostics, where we might
still work with partial errors.
Type::subst()'s "IgnoreMissing" option was fairly unprincipled, dropping
unsubstituted types into the resulting AST without any indication
whatsoever that anything went wrong. Replace this notion with a new
form of ErrorType that explicitly tracks which substituted type caused
the problem. It's still an ErrorType, but it prints like the
substituted type (which is important for code completion) and allows
us to step back to the substituted type if needed (which is used by
associated type inference). Then, allow Type::subst(), when the new
UseErrorTypes flag is passed, to form partially-substituted types that
contain errors, which both code completion and associated type
inference relied on.
Over time, I hope we can use error-types-with-original-types more
often to eliminate "<<error type>>" from diagnostics and teach
Type::subst() never to return a "null" type. Clients can check
"hasError()" to deal with failure cases rather than checking null.
Extend NSNumber bridging to cover not only `Int`, `UInt`, `Double`, and `Bool`, but all of the standard types as well. Extend the `TypePreservingNSNumber` subclass to accommodate all of these types, so that we preserve type identity for `AnyHashable` and dynamic casting of Swift-bridged NSNumbers. If a pure Cocoa NSNumber is cast, just trust that the user knows what they're doing.
This XFAILs a couple of serialization tests that attempt to build the Foundation overlay, but which don't properly handle `gyb` files.
There's a bit of a hack to deal with generic typealiases, but
overall this makes things more logical.
This is the last big refactoring before we can allow constrained
extensions to make generic parameters concrete. All that remains
is a small set of changes to SIL type lowering, and retooling
some diagnostics in Sema.
Long term, we want to refactor the AST to reflect the current
programming model in Swift. This would include refactoring
FunctionType to take a list of ParameterTypeElt, or something with a
better name, that can contain both the type and flags/bits that are
only specific to types in parameter position, such as @autoclosure and
@escaping. At the same time, noescape-by-default has severely hurt our
ability to print types without significant context, as we either have
to choose to too aggressively print @escaping or not print it in every
situation it occurs, or both.
As a gentle step towards the final solution, without uprooting our
overall AST structure, and as a way towards fixing the @escaping
printing ails, put these bits on the TupleTypeElt and ParenType, which
will serve as a model for what ParameterTypeElt will be like in the
future. Re-use these flags on CallArgParam, to leverage shared
knowledge in the type system. It is a little painful to tack onto
these types, but it's minor and will be overhauled soon, which will
eventually result in size savings and less complexity overall.
This includes all the constraint system adjustments to make these
types work and influence type equality and overload resolution as
desired. They are encoded in the module format. Additional tests
added.
- We were bailing out if the partial_apply's substitutions
contained archetypes, but there was no inherent reason
to do this. After fixing an issue with opened existential
tracking, this started to work.
- We were also bailing out if the callee was not a static
function_ref. Again, there's no reason to do this, because
we also emit partial_apply to form closures from
class_method and witness_method calls.
- There was a bug in the code for extending lifetimes of
@in parameters. Even if a parameter was an input parameter
to the method and not an alloc_stack, we have to copy
it into a new alloc_stack, because there might be
multiple invocations of an apply for a single partial_apply.
- There was also a bug where we would proceed to apply the
peephole to @unowned_inner_pointer functions, which is wrong.
IRGen's lowering of partial_apply has special handling there
and the resulting function type has an @owned result.
For every struct type for which the frameworks provides an NSValue category for boxing and unboxing values of that type, provide an _ObjectiveCBridgeable conformance in the Swift overlay that bridges that struct to NSValue, allowing the structs to be used naturally with id-as-Any APIs and Cocoa container classes. This is mostly a matter of gyb-ing out boilerplate using `NSValue.init(bytes:objCType:)` to construct the instance, `NSValue.objCType` to check its type when casting, and `NSValue.getValue(_:)` to extract the unboxed value, though there are a number of special snowflake cases that need special accommodation:
- To maintain proper layering, CoreGraphics structs need to be bridged in the Foundation overlay.
- AVFoundation provides the NSValue boxing categories for structs owned by CoreMedia, but it does so using its own internal subclasses of NSValue, and these subclasses do not interop properly with the standard `NSValue` subclasses instantiated by Foundation. To do the right thing, we therefore have to let AVFoundation provide the bridging implementation for the CoreMedia types, and we have to use its category methods to do so.
- SceneKit provides NSValue categories to box and unbox SCNVector3, SCNVector4, and SCNMatrix4; however, the methods it provides do so in an unusual way. SCNVector3 and SCNVector4 are packaged into `CGRect`s and then the CGRect is boxed using `valueWithCGRect:`. SCNMatrix4 is copied into a CATransform3D, which is then boxed using `valueWithCATransform3D:` from CoreAnimation. To be consistent with what SceneKit does, use its category methods for these types as well, and when casting, check the type against the type encoding SceneKit uses rather than the type encoding of the expected type.
id-as-Any lets you pass Optional to an ObjC API that takes `nonnull id`, and also lets you bridge containers of `Optional` to `NSArray` etc. When this occurs, we can unwrap the value and bridge it so that inhabited optionals still pass into ObjC in the expected way, but we need something to represent `none` other than the `nil` pointer. Cocoa provides `NSNull` as the canonical "null for containers" object, which is the least bad of many possible answers. If we happen to have the rare nested optional `T??`, there is no precedented analog for these in Cocoa, so just generate a unique sentinel object to preserve the `nil`-ness depth so we at least don't lose information round-tripping across the ObjC-Swift bridge.
Making Optional conform to _ObjectiveCBridgeable is more or less enough to make this all work, though there are a few additional edge case things that need to be fixed up. We don't want to accept `AnyObject??` as an @objc-compatible type, so special-case Optional in `getForeignRepresentable`.
Implements SR-0140 (rdar://problem/27905315).
id-as-Any lets you pass Optional to an ObjC API that takes `nonnull id`, and also lets you bridge containers of `Optional` to `NSArray` etc. When this occurs, we can unwrap the value and bridge it so that inhabited optionals still pass into ObjC in the expected way, but we need something to represent `none` other than the `nil` pointer. Cocoa provides `NSNull` as the canonical "null for containers" object, which is the least bad of many possible answers. If we happen to have the rare nested optional `T??`, there is no precedented analog for these in Cocoa, so just generate a unique sentinel object to preserve the `nil`-ness depth so we at least don't lose information round-tripping across the ObjC-Swift bridge.
Making Optional conform to _ObjectiveCBridgeable is more or less enough to make this all work, though there are a few additional edge case things that need to be fixed up. We don't want to accept `AnyObject??` as an @objc-compatible type, so special-case Optional in `getForeignRepresentable`.
Implements SR-0140 (rdar://problem/27905315).
Now that the previous patches have shaken out implicit assumptions
about the order of generic requirements and substitutions, we can
make a more radical change, dropping redundant protocol requirements
when building the original generic signature.
This means that the canonical ordering and minimization that we
used to only perform when building the mangling signature is done
all of the time, and hence getCanonicalManglingSignature() can go
away.
Usages now either call getCanonicalSignature(), or operate on the
original signature directly.
ExprHandle is a relic from a horrible time when expressions made their
way into the type system via default arguments. It's been unnecessary
for a long time, so get rid of it.
We were optimizing away unused pattern binding initializer contexts in
both the parser and in semantic analysis, which led to a
somewhat-unpredictable set of DeclContexts in the AST. Normalize
everything by always creating these contexts.
A GenericEnvironment stores the mapping between GenericTypeParamTypes
and context archetypes (or eventually, concrete types, once we allow
extensions to constrain a generic parameter to a concrete type).
The goals here are two-fold:
- Eliminate the GenericTypeParamDecl::getArchetype() method, and
always use mapTypeIntoContext() instead
- Replace SILFunction::ContextGenericParams with a GenericEnvironment
This patch adds the new data type as well as serializer and AST
verifier support. but nothing else uses it yet.
Note that GenericSignature::get() now asserts if there are no
generic parameters, instead of returning null. This requires a
few tweaks here and there.
Simplify e.g., ASTContext::getBridgedToObjC(), which no longer needs
the optional return.
Eliminate the now-unused constraint kind for checking bridging to
Objective-C.
Like NSObject, CFType has primitive operations CFEqual and CFHash,
so Swift should allow those types to show up in Hashable positions
(like dictionaries). The most general way to do this was to
introduce a new protocol, _CFObject, and then have the importer
automatically make all CF types conform to it.
This did require one additional change: the == implementation that
calls through to CFEqual is in a new CoreFoundation overlay, but the
conformance is in the underlying Clang module. Therefore, operator
lookup for conformances has been changed to look in the overlay for
an imported declaration (if there is one).
https://bugs.swift.org/browse/SR-2388
This allows String, Array, Dictionary, and Set to be passed as variadic arguments to Cocoa APIs like NSLog, NSPredicate, stringWithFormat:, etc. rdar://problem/27651717