Most of the time, "generics" means "cannot be exposed to Objective-C"
and certainly "cannot be exposed in the generated header", but there
is one exception: imported Objective-C parameterized types, and their
extensions. We were previously dropping this on the floor and printing
`Foo</* BarType */>` in the generated header, which is nonsense.
https://bugs.swift.org/browse/SR-3480
The list of directly inherited protocols of a ProtocolDecl is already
encoded in the requirement signature, as conformance constraints where
the subject is Self. Gather the list from there rather than separately
computing/storing the list of "inherited protocols".
* Add 'SWIFT_NORETURN' macro to the prologue. This macro is evaluated to
'__attribute__((noreturn))' where supported.
* Apply 'SWIFT_NORETURN' to 'isUninhabited()' methods.
The typedef `swift::Module` was a temporary solution that allowed
`swift::Module` to be renamed to `swift::ModuleDecl` without requiring
every single callsite to be modified.
Modify all the callsites, and get rid of the typedef.
These have historically been defined as protocols in Objective-C
(under a pile of macros), but when imported into Swift they're classes
instead. Reverse this bit of magic by hard-coding the prefix "OS_" and
the header <os/object.h>, and emitting the classic 'foo_bar_t'-style
type names.
rdar://problem/29790636
Initializers that don't look like init methods to ARC need to have
`SWIFT_METHOD_FAMILY(init)`.
Also tighten up the check for init-like methods to not consider e.g.
`initializeFoo` to be an init-like method.
Changes:
* Terminate all namespaces with the correct closing comment.
* Make sure argument names in comments match the corresponding parameter name.
* Remove redundant get() calls on smart pointers.
* Prefer using "override" or "final" instead of "virtual". Remove "virtual" where appropriate.
- TypeAliasDecl::getAliasType() is gone. Now, getDeclaredInterfaceType()
always returns the NameAliasType.
- NameAliasTypes now always desugar to the underlying type as an
interface type.
- The NameAliasType of a generic type alias no longer desugars to an
UnboundGenericType; call TypeAliasDecl::getUnboundGenericType() if you
want that.
- The "lazy mapTypeOutOfContext()" hack for deserialized TypeAliasDecls
is gone.
- The process of constructing a synthesized TypeAliasDecl is much simpler
now; instead of calling computeType(), setInterfaceType() and then
setting the recursive properties in the right order, just call
setUnderlyingType(), passing it either an interface type or a
contextual type.
In particular, many places weren't setting the recursive properties,
such as the ClangImporter and deserialization. This meant that queries
such as hasArchetype() or hasTypeParameter() would return incorrect
results on NameAliasTypes, which caused various subtle problems.
- Finally, add some more tests for generic typealiases, most of which
fail because they're still pretty broken.
* Add `SWIFT_WARN_UNUSED_RESULT` macro to prologue.
Evaluates to `__attribute__((warn_unused_result))` where supported.
* Emit `SWIFT_WARN_UNUSED_RESULT` attribute in generated ObjC headers
for all non-void methods, that don't have an @discardableResult
attribute.
Attribute is not emitted for initializers. Attribute is also not
emitted where the error convention leads to a return value for an
otherwise void returning method.
A pointless use of polymorphism -- the result values are not
interchangeable in any practical sense:
- For GenericTypeParamDecls, this returned getDeclaredInterfaceType(),
which is an interface type.
- For AssociatedTypeDecls, this returned the sugared AssociatedTypeType,
which desugars to an archetype.
- For TypeAliasDecls, this returned TypeAliasDecl::getAliasType(),
which desugars to a type containing archetypes.
- For NominalTypeDecls, this returned NominalTypeDecl::getDeclaredType(),
which is the unbound generic type, a special case used for inferring
generic arguments when they're not written in source.
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
I'm not sure why this didn't occur to me in 8282160d: of course if you
see a generic type with arguments, you need to see the @interface for
that type in order to supply the arguments. Maybe I was thinking the
generated interface would automatically import anything the module
itself imports, but that hasn't ever been true.
rdar://problem/28738008
This flag switches the "effective language version" of the compiler,
at least to any version supported (as of this change: "3" or "3.0").
At the moment nothing uses it except the language version build
configuration statements (#if swift(...)) and various other places
that report, encode, or otherwise check version numbers.
In the future, it's intended as scaffolding for backwards compatibility.
Fixes SR-2582
Simplify e.g., ASTContext::getBridgedToObjC(), which no longer needs
the optional return.
Eliminate the now-unused constraint kind for checking bridging to
Objective-C.
More specifically, don't try to emit a definition for them. Just fall
through to what we do for forward-declarations...which also needed some
fixing, to make sure we don't use a Swift typealias as its underlying
type but never import the underlying type.
https://bugs.swift.org/browse/SR-2352
Like Swift generics, Objective-C generics may have constraints; unlike
Swift generics, Objective-C doesn't do separate parsing and
type-checking passes. This means that any generic arguments for
constrained generic parameters must be fully-defined, in order to
check that they satisfy the constraints.
This commit addresses this problem with three different mechanisms,
one for each kind of declaration that might run into this issue:
- For classes, if a member references a type with constrained generic
parameter, and the corresponding argument type hasn't been printed
yet, that member is "delayed", which means it is put into a category
at the end of the file.
- Protocols cannot have categories, so for protocols we instead see if
we can print the definition of the other type first. To break
circular dependencies, the printer will not attempt this if both the
type and the protocol are already being depended on. This isn't
perfect (see below).
- Rather than delaying members of extensions, we just delay them
wholesale. This keeps related members together, but also has
problems (see below).
These approaches solve the most common cases while still not crashing
in the uncommon ones. However, there are still a number of problems:
- The protocol heuristic is overly negative, which means we may generate
an invalid header even when there's a reasonable ordering. For example,
a single class might inherit from a class A and conform to protocol P,
and protocol P depends on class A as a generic argument. In this case,
defining class A first is the right thing to do, but it's possible for
the printer to decide that there's circularity here and just forward-
declare A instead.
- Protocols really can be circular. This can be fixed by printing a
forward-declared protocol alongside the generic constraints, i.e.
'id <MoreThanNSCopying, NSCopying>' instead of just
'id <MoreThanNSCopying>'.
- Extensions can introduce protocols as well. This is not modeled at
all; if a member depends on a protocol conformance, it's assumed
that simply printing the class would be sufficient. This could be
fixed by checking how a generic argument satisfies its constraints,
possibly delaying individual members from extensions in order to
print them sooner.
- More cases I haven't thought about.
Test cases for some of these problems are in the new
circularity-errors.swift file, mostly to make sure the ObjC printer
doesn't crash when it encounters them.
rdar://problem/27109377
...because otherwise option sets that get imported as members using
NS_SWIFT_NAME are printed with an 'enum' tag, and the definition of
NS_OPTIONS only declares the typedef under C++.
We should come back and figure out something more principled for this
later, but for now this solves an issue with generated headers
imported into C++ translation units.
rdar://problem/27130343
Don't allow types conforming to 'Error' or protocol compositions
involving 'Error' to be reflected in Objective-C. We still allow
bridging conversions, but they are not statically bridged. Fixes
SR-2249/rdar://problem/27658940.
We would crash because 'Any' doesn't have a corresponding bridged type through the normal bridging mechanism. Handle this correctly, and correctly recognize 'AnyHashable' and 'Any' as the upper bounds of Dictionary, Set, and Array so we present the unqualified NS types in the generated header.
* [PrintAsObjC] Add unavailable attribute to non-inherited initializers
Initializers that aren't inherited by subclasses cannot be called, so we
should make this visible to Obj-C.
Due to SR-2211, non-inherited convenience initializers do not get this
same treatment.
* [PrintAsObjC] Add unavailable initializers for private overrides
When a public initializer is overridden with a private one, we need to
mark these as unavailable to Obj-C as they're not supposed to be
callable even though they do exist.
* Migrate from `UnsafePointer<Void>` to `UnsafeRawPointer`.
As proposed in SE-0107: UnsafeRawPointer.
`void*` imports as `UnsafeMutableRawPointer`.
`const void*` imports as `UnsafeRawPointer`.
Occurrences of `UnsafePointer<Void>` are replaced with UnsafeRawPointer.
* Migrate overlays from UnsafePointer<Void> to UnsafeRawPointer.
This requires explicit memory binding in several places,
particularly in NSData and CoreAudio.
* Fix a bunch of test cases for Void->Raw migration.
* qsort takes IUO values
* Bridge `Unsafe[Mutable]RawPointer as `void [const] *`.
* Parse #dsohandle as UnsafeMutableRawPointer
* Update a bunch of test cases for Void->Raw migration.
* Trivial fix for the SceneKit test case.
* Add an UnsafeRawPointer self initializer.
This is unfortunately necessary for assignment between types imported from C.
* Tiny simplification of the initializer.