This means all cross-module references and all mangled names will
consistently use the Swift 4 name (the canonical type), no special
handling required.
The main thing we lose here is that the Swift 4 names of imported
types become usable in Swift 3 mode without any diagnostics, similar
to how most language features introduced in Swift 4 are available in
Swift 3 mode. It also implies that the Swift 4 name will show up in
demangled names.
rdar://problem/31616162
(and similar for flag_enum)
This commit prepares the importer for a world in which NS_ENUM and
NS_OPTIONS have adopted the new Clang attributes 'enum_extensibility'
and 'flag_enum', but API notes are used to reverse the effect. Without
this there would be no transition path for adopting the standard Cocoa
macros, which have applied unconditionally up to now.
rdar://problem/18744821
(which can happen if an imported class has un-importable initializers)
Our initializer model guarantees that it's safe to inherit convenience
initializers when a subclass has implemented all designated
initializers, since each convenience initializer will be implemented
by calling one of the designated initializers. If one of the
designated initializers /can't/ be implemented in Swift, however,
then inheriting the convenience initializer would not be safe.
This is potentially a source-breaking change, so the importer will
only actually record that it failed to import something in when
compiling in Swift 4 mode.
rdar://problem/31563662
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.
These new Clang attributes identify whether an enum is intended to
represent an option set or not, and whether the set of cases listed in
the enum declaration is exhaustive. (Swift doesn't currently have a
closed/open distinction for enums, so treat any C enum with
enum_extensibility as a proper closed Swift enum, like we do with
NS_ENUM.)
Enums with neither attribute will continue to be imported as unique
types.
rdar://problem/28476618
In Swift 3, an Objective-C type like SomeClass <SomeProtocol> is
imported as SomeClass. The protocol qualification is erased unless
the class bound is 'id' or 'Class'.
Importing such types as class-constrained existentials is a source
breaking change, so the new behavior is only enabled in Swift 4
mode.
Furthermore as a transitional step the staging flag
-enable-experimental-subclass-existentials has to be passed in
also. The flag will soon be removed.
Add a 'hasExplicitAnyObject()' bit to ProtocolCompositionType
to represent canonical composition types containing '& AnyObject'.
Serialize this bit and take it into account when building
ExistentialLayouts.
Rename ProtocolCompositionType::getProtocols() to getMembers()
since it can contain classes now, and update a few usages that
need further attention with FIXMEs or asserts.
For now, nothing actually constructs these types, and they will
trigger arounds asserts. Upcoming patches will introduce support
for this.
Rather than requiring associated type witness inference to go and
figure out the _ObjectiveCType type from the other witnesses for imported
swift_wrapper/swift_newtype'd types, synthesize the typealias directly in the
importer. This is a simplification and a performance optimization.
Rather than requiring associated type witness inference to go and
figure out the Element type from the other witnesses for imported
OptionSet types, synthesize the typealias directly in the
importer. This is a simplification and a performance optimization.
Rather than requiring associated type witness inference to go and
figure out the RawValue type from the rawValue witnesses for imported,
RawRepresentable types, synthesize the typealias directly in the
importer. This is a simplification and a performance optimization.
When a type is renamed, we leave behind a "compatibility typealias"
whose underlying type uses the new name. For generic types, though, we
were using the generic parameters and environment of the original
type, which is completely bogus. "Fix" this by just dropping the
generic part entirely and making a typealias that refers to the
/unbound/ generic type, as if written as `typealias OldName = NewName`
instead of `typealias OldName<Element> = NewName<Element>`. The rest
of the compiler can handle that fine.