* [AST] Remove stored TypeLoc from TypedPattern
TypedPattern was only using this TypeLoc as a means to a TypeRepr, which
caused it to store the pattern type twice (through the superclass and through
the TypeLoc itself.)
This also fixes a bug where deserializing a TypedPattern doesn't store
the type correctly and generally cleans up TypedPattern initialization.
Resolves rdar://44144435
* Address review comments
Parsed declarations would create an untyped 'self' parameter;
synthesized, imported and deserialized declarations would get a
typed one.
In reality the type, if any, depends completely on the properties
of the function in question, so we can just lazily create the
'self' parameter when needed.
If the function already has a type, we give it a type right there;
otherwise, we check if a 'self' was already created when we
compute a function's type and set the type of 'self' then.
Use the usual bag of tricks to eliminating dependence on the
TypeChecker instance: static functions, LazyResolver callbacks, and
emitting diagnostics on decls/ASTContext.
- getAsDeclOrDeclExtensionContext -> getAsDecl
This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.
- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)
These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point. The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.
- getAsProtocolExtensionContext -> getExtendedProtocolDecl
Like the above, this didn't return the ExtensionDecl; it returned its
extended type.
This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
There are two general constructor forms here:
- One took the number of parameter lists, to be filled in later.
Now, this takes a boolean indicating if there is an implicit
'self'.
- The other one took the actual parameter lists and filled them
in right away. This now takes a separate 'self' ParamDecl and
ParameterList.
Instead of storing the number of parameter lists, an
AbstractFunctionDecl now only needs to store if there is a 'self'
or not.
I've updated most places that construct AbstractFunctionDecls to
properly use these new forms. In the ClangImporter, there is
more code that remains to be untangled, so we continue to build
multiple ParameterLists and unpack them into a ParamDecl and
ParameterList at the last minute.
Previously, some PBDs weren't being marked implicit even though the associated vars were implicit. PatternBindingDecl::createImplicit will be even nicer when we start parsing the location of the equals token.
The storage kind has been replaced with three separate "impl kinds",
one for each of the basic access kinds (read, write, and read/write).
This makes it far easier to mix-and-match implementations of different
accessors, as well as subtleties like implementing both a setter
and an independent read/write operation.
AccessStrategy has become a bit more explicit about how exactly the
access should be implemented. For example, the accessor-based kinds
now carry the exact accessor intended to be used. Also, I've shifted
responsibilities slightly between AccessStrategy and AccessSemantics
so that AccessSemantics::Ordinary can be used except in the sorts of
semantic-bypasses that accessor synthesis wants. This requires
knowing the correct DC of the access when computing the access strategy;
the upshot is that SILGenFunction now needs a DC.
Accessor synthesis has been reworked so that only the declarations are
built immediately; body synthesis can be safely delayed out of the main
decl-checking path. This caused a large number of ramifications,
especially for lazy properties, and greatly inflated the size of this
patch. That is... really regrettable. The impetus for changing this
was necessity: I needed to rework accessor synthesis to end its reliance
on distinctions like Stored vs. StoredWithTrivialAccessors, and those
fixes were exposing serious re-entrancy problems, and fixing that... well.
Breaking the fixes apart at this point would be a serious endeavor.
Introduce some metaprogramming of accessors and generally prepare
for storing less-structured accessor lists.
NFC except for a change to the serialization format.
'private' properties can't be accessed in extensions in Swift 3, so synthesizing
a conformance that reads from such things is going to be incorrect in an
extension.
This works for all protocols except for Decodable on non-final classes, because
the init requirement has to be 'required' and thus in the type's declaration.
Fixes most of https://bugs.swift.org/browse/SR-6803.
Instead of passing around a TypeChecker and three Decls (the nominal type, the
protocol, and the decl declaring the conformance) everywhere, we can just pass
one object.
This should be [NFC].
This removes the default implementation of hash(into:), and replaces it with automatic synthesis built into the compiler. Hashable can now be implemented by defining either hashValue or hash(into:) -- the compiler supplies the missing half automatically, in all cases.
To determine which hash(into:) implementation to generate, the synthesizer resolves hashValue -- if it finds a synthesized definition for it, then the generated hash(into:) body implements hashing from scratch, feeding components into the hasher. Otherwise, the body implements hash(into:) in terms of hashValue.
Since 'private' means "limit to the enclosing scope (and extensions
thereof)", putting it on a member means that the member can't be
accessed everywhere the type might show up. That's normally a good
thing, but it's not the desired effect for synthesized members used
for derived conformances, and when it comes to class initializers this
actually violates AST invariants.
rdar://problem/39478298
Implements the minimum specified by the SE-proposal.
* Add the CaseIterable protocol with AllCases associatedtype and
allCases requirement
* Automatic synthesis occurs for "simple" enums
- Caveat: Availability attributes suppress synthesis. This can be
lifted in the future
- Caveat: Conformance must be stated on the original type
declaration (just like synthesizing Equatable/Hashable)
- Caveat: Synthesis generates an [T]. A more efficient collection
- possibly even a lazy one - should be put here.
This has three principal advantages:
- It gives some additional type-safety when working
with known accessors.
- It makes it significantly easier to test whether a declaration
is an accessor and encourages the use of a common idiom.
- It saves a small amount of memory in both FuncDecl and its
serialized form.
The synthesized declarations should inherit the @_versioned attribute
from the type, just like they inherit access control.
Fixes <rdar://problem/34342955>.
"Accessibility" has a different meaning for app developers, so we've
already deliberately excised it from our diagnostics in favor of terms
like "access control" and "access level". Do the same in the compiler
now that we aren't constantly pulling things into the release branch.
This commit changes the 'Accessibility' enum to be named 'AccessLevel'.
In anticipation of future attributes, and perhaps the ability to
declare lvalues with specifiers other than 'let' and 'var', expand
the "isLet" bit into a more general "specifier" field.
This changes `getBaseName()` on `DeclName` to return a `DeclBaseName`
instead of an `Identifier`. All places that will continue to be
expecting an `Identifier` are changed to call `getBaseIdentifier` which
will later assert that the `DeclName` is actually backed by an
identifier and not a special name.
For transitional purposes, a conversion operator from `DeclBaseName` to
`Identifier` has been added that will be removed again once migration
to DeclBaseName has been completed in other parts of the compiler.
Unify approach to printing declaration names
Printing a declaration's name using `<<` and `getBaseName()` is be
independent of the return type of `getBaseName()` which will change in
the future from `Identifier` to `DeclBaseName`
* Allow CodingKey conformance to be automatically derived for enums
which have no raw type (with no associated values) and which have
a raw type of String or Int.
* Allow Encodable and Decodable conformance to be automatically derived
for classes and structs with Encodable/Decodable properties
* Add initial unit tests for verifying derived conformance
Enums with the ns_error_domain attribute represent codes for NSError,
which means Swift developers will expect to interact with them in
terms of Error. SE-0112 improved bridging for these enums to generate
a struct with the following form:
struct MyError: Error {
@objc enum Code: RawRepresentable {
case outOfMemory
case fileNotFound
}
var userInfo: [NSObject: AnyObject] { get }
static var outOfMemory: Code { get }
static var fileNotFound: Code { get }
}
where MyError.Code corresponds to the original MyError enum defined in
Objective-C. Until recently, both the enum and the synthesized struct
were marked as having the original enum as their "Clang node", but
that leads to problems: the struct isn't really ObjC-compatible, and
the two decls have the same USR. (The latter had already been worked
around.)
This commit changes the struct to be merely considered a synthesized
"external definition", with no associated Clang node. This meant
auditing everywhere that's looking for a Clang node and seeing which
ones applied to external definitions in general.
There is one regression in quality here: the generated struct is no
longer printed as part of the Swift interface for a header file, since
it's not actually a decl with a corresponding Clang node. The previous
change to AST printing mitigates this a little by at least indicating
that the enum has become a nested "Code" type.
A lot of files transitively include Expr.h, because it was
included from SILInstruction.h, SILLocation.h and SILDeclRef.h.
However in reality most of these files don't do anything
with Exprs, especially not anything in IRGen or the SILOptimizer.
Now we're down to 171 files in the frontend which depend on
Expr.h, which is still a lot but much better than before.
Fixes SR-2757.
Variables in capture lists are treated as 'let' constants, which can
result in misleading, incorrect diagnostics. Mark them as such in order
to produce better diagnostics, by adding an extra parameter to the
VarDecl initializer.
Alternatively, these variables could be marked as implicit, but that
results in other diagnostic problems: capture list variables that are
never used produce warnings, but these warnings aren't normally emitted for
implicit variables. Other assertions in the compiler also misfire when
these variables are treated as implicit.
Another alternative would be to walk up the AST and determine whether
the `VarDecl`, but there doesn't appear to be a way to do so.
First, ensure all ParamDecls that are synthesized from scratch are given
both a contextual type and an interface type.
For ParamDecls written in source, add a new recordParamType() method to
GenericTypeResolver. This calls setType() or setInterfaceType() as
appropriate.
Interestingly enough a handful of diagnostics in the test suite have
improved. I'm not sure why, but I'll take it.
The ParamDecl::createUnboundSelf() method is now only used in the parser,
and no longer sets the type of the self parameter to the unbound generic
type. This was wrong anyway, since the type was always being overwritten.
This allows us to remove DeclContext::getSelfTypeOfContext().
Also, ensure that FuncDecl::getBodyResultTypeLoc() always has an interface
type for synthesized declarations, eliminating a mapTypeOutOfContext()
call when computing the function interface type in configureInterfaceType().
Finally, clean up the logic for resolving the DynamicSelfType. We now
get the interface or contextual type of 'Self' via the resolver, instead
of always getting the contextual type and patching it up inside
configureInterfaceType().
After recent changes, this asserts on all decls that are not VarDecls,
so we can just enforce that statically now. Interestingly, this turns
up some dead code which would have asserted immediately if called.
Also, replace AnyFunctionRef::getType() with
AnyFunctionRef::getInterfaceType(), since the old
AnyFunctionRef::getType() would just assert when called on
a Decl.