Stop creating ImplicitlyUnwrappedOptional<T> so that we can remove it
from the type system.
Enable the code that generates disjunctions for Optional<T> and
rewrites expressions based on the original declared type being 'T!'.
Most of the changes supporting this were previously merged to master,
but some things were difficult to merge to master without actually
removing IUOs from the type system:
- Dynamic member lookup and dynamic subscripting
- Changes to ensure the bridging peephole still works
Past commits have attempted to retain as much fidelity with how we
were printing things as possible. There are some cases where we still
are not printing things the same way:
- In diagnostics we will print '?' rather than '!'
- Some SourceKit and Code Completion output where we print a Type
rather than Decl.
Things like module printing via swift-ide-test attempt to print '!'
any place that we now have Optional types that were declared as IUOs.
There are some diagnostics regressions related to the fact that we can
no longer "look through" IUOs. For the same reason some output and
functionality changes in Code Completion. I have an idea of how we can
restore these, and have opened a bug to investigate doing so.
There are some small source compatibility breaks that result from
this change:
- Results of dynamic lookup that are themselves declared IUO can in
rare circumstances be inferred differently. This shows up in
test/ClangImporter/objc_parse.swift, where we have
var optStr = obj.nsstringProperty
Rather than inferring optStr to be 'String!?', we now infer this to
be 'String??', which is in line with the expectations of SE-0054.
The fact that we were only inferring the outermost IUO to be an
Optional in Swift 4 was a result of the incomplete implementation of
SE-0054 as opposed to a particular design. This should rarely cause
problems since in the common-case of actually using the property rather
than just assigning it to a value with inferred type, we will behave
the same way.
- Overloading functions with inout parameters strictly by a difference
in optionality (i.e. Optional<T> vs. ImplicitlyUnwrappedOptional<T>)
will result in an error rather than the diagnostic that was added
in Swift 4.1.
- Any place where '!' was being used where it wasn't supposed to be
allowed by SE-0054 will now treat the '!' as if it were '?'.
Swift 4.1 generates warnings for these saying that putting '!'
in that location is deprecated. These locations include for example
typealiases or any place where '!' is nested in another type like
`Int!?` or `[Int!]`.
This commit effectively means ImplicitlyUnwrappedOptional<T> is no
longer part of the type system, although I haven't actually removed
all of the code dealing with it yet.
ImplicitlyUnwrappedOptional<T> is is dead, long live implicitly
unwrapped Optional<T>!
Resolves rdar://problem/33272674.
Properties of Codable types which are optional and excluded via the CodingKeys enum should not require an explicit nil assignment, since in all other cases, optional vars get a default value of nil.
* Make Decodable synthesis lazy again
* Remove side effects from assertions
* Assert on superclass failable initializers (and verify via a unit test)
* Fix space typo
* Remove more needless instances of single-element arrays
* Unambiguously refer to init() in unit tests
* Add failable superclass init tests and a test to ensure Decodable fails to be inherited when superclass synthesis fails
* Add tests for structs to ensure they receive no-argument initializers where appropriate
* Use `isSpecificProtocol` instead of `==`
* Synthesize Encodable implementation lazily
* Don’t mark conformances as Used when they don’t need to be
* Avoid creating explicit one-element arrays
* Use lookupDirect instead of walking AST manually
* Produce diagnostic for Decodable classes whose non-Decodable superclass has a failable init
* Filter lazy vars manually since getStoredProperties() does not always do so
* Amend Decodable class diagnostic text
* Check for enum RawType errors only if the type was already validated
* Update unit tests to match changes
Classes which inherit from Codable classes inherit their Codable implementation (as opposed to synthesizing their own). In cases where they add their own storage, they will fail to inherit their superclass’s init(from:). In this case, we provide a diagnostic suggesting that init(from:) be overridden.
Classes which receive a synthesized Decodable implementation should be able to subclass non-Decodable classes (if the superclass has an accessible init()) method.
Also improve diagnostics when this is not the case.
Some types and members are synthesized by derived protocol conformances
(e.g. the CodingKeys member type or init(from:)/encode(to:) members
from Decodable/Encodable conformance) — however, they are not visible
in AST lookup if they have not been synthesized.
Exposes a LazyResolver callback for performing member synthesis where
relevant during qualified lookups to synthesize these members on demand
when needed.
The type of non-strong properties is wrapped in a ReferenceStorageType,
which does not conform to Codable. This needs to be unwrapped so the
inner reference type can be considered for Codable conformance.
Optional, Array, Set, and Dictionary currently all conform to Codable
regardless of the type they are generic on. Until conditional
conformance lands and we can rely on their conditional conformance, we
want to prevent Codable derived conformance if a type contains a
property of one of these types when we know it's actually going to fail
at runtime.
* Introduce diagnostics that explain why derivation of
Encodable/Decodable fail rather than just silently failing
* Allow properties with default values to be omitted from CodingKeys
enum and from encoding/decoding
* If `CodingKeys` is a typealias, reach through it more consistently to
get at the final target type
* Add unit tests to confirm this new behavior for classes and structs
NOTE: Although this made the diff bigger, standalone variables named
"type" have been renamed to "target" throughout, since the word "type"
may be ambiguous and makes debugging impossible. "target" is unique.
* 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