The core definitions of CGPoint and other types were pushed down from
CoreGraphics to CoreFoundation. This test indirectly depends on the conformance
of those types to CustomReflectable, but nothing in the test was using those
conformances explicitly and so libswiftCoreGraphics would not be auto-linked
when the test is compiled at a high enough deployment target. Use the
conformances directly to force linkage.
Resolves rdar://121343931
Passing in the declared interface type to checkConformance() here
masked a silent failure where if the type declaration was generic
and the conformance conditional, the conditional requirement check
would fail. As a result, we did not diagnose the absence of
@retroactive, nor the unnecessary presence of it.
Since we only care about the existence of some conformance, we
can use lookupConformance() instead.
Make `init(catching:)` and `get()` use typed throws. The former infers
the `Failure` type from the closure provided (once full type inference
is in place) and the latter only throws errors of the `Failure` type.
original source location of a macro expansion when walking up the ancestor
list.
The original source range of a macro expansion buffer contains the entire
range of the code that is replaced by the expansion. In some cases, the
original code is type checked, so ASTScope needs to represent both the
original code and the macro-expanded code in the scope tree.
For accessor macros, the original code -- the initializer expression of
the property -- is type checked, but not before macro expansion, so
unqualified lookup must deal with the scope tree for the initializer and
the expanded accessors. The accessors are inserted in the tree after the
initializer scope, but the `isBeforeInSource` was using the start location
of the original source range for macro expansions, so the accessor scopes
were incorrectly considered to be ordered before a source location in the
initializer expression, which caused unqualified lookup of local variables
within the initializer to fail.
These tests are testing changes that aren't present in older runtimes:
test/stdlib/SwiftValueNSObject.swift
test/stdlib/SwiftObjectNSObject.swift
test/stdlib/BridgeEquatableToObjC.swift
And this test looks for some wording that's different on older runtimes. This one already does availability checks, so we change the requirements to SwiftStdlib 5.11:
test/Casting/CastTraps.swift.gyb
* Add concrete overload for on all stdlib integer types.
* Add very basic tests for type inference of comparands.
* Add a comment explaining why these overloads are present.
This fixes a recent regression introduced in the changes to make
TRC construction lazier in b33a71d64f.
Calling VarDecl::hasInitialValue() can ask for attached property
wrappers, which can trigger macro expansion. However, macro
expansion can result in TRC construction, causing a cycle.
Instead, just always build a lazy TRC for the initializer. It
might not be needed, but it's safest to not ask anything of the
VarDecl at all.
Fixes rdar://118452948.
Make SwiftValue hash/equality work the same as SwiftObject
For Equatable types that are not Hashable, this proxies ObjC `-isEqual:` to Swift `Equatable` and returns a constant for ObjC `-hash`
This entire suite was copied wholesale from SwiftObjectNSObject.
Some of it may not apply, very little of it has been critically
evaluated. But it should help avoid unexpected changes in SwiftValue behavior.
Update PR #68720 with lessons learned in reviewing #69464
Background:
* SwiftValue can expose Swift value types (structs/enums)
to ObjC by wrapping them in an Obj-C object on the heap
* SwiftObject is the Obj-C type that Swift class objects all
inherit from (when viewed from Obj-C). This allows arbitrary
Swift class objects to be passed into Obj-C.
History:
* PR #4124 made Obj-C `-hash` and `-isEqual:` work for SwiftValue for Hashable Swift types
* PR #68720 extended SwiftValue to also support Equatable Swift types
* PR #69464 added similar support to SwiftObject
In the process of working through #69464, we found a better way
to handle an ObjC request for `-hash` for a type that is Swift
Equatable but not Hashable. This PR updates SwiftValue to use
the same approach. The approach considers three cases:
1. A Hashable type can forward both `-hash` and `-isEqual:` to
the Swift object.
2. A type that is neither Equatable nor Hashable can implement
`-isEqual:` as the identity check and `-hash` as returning
the address of the object in memory.
3. A type is that Equatable but not Hashable is more complex.
In this last case, we can easily forward `-isEqual:` to the
Equatable conformance but ObjC also requires us to
always provide a compatible `-hash` implementation.
The only way to do this is to have `-hash` return a constant,
but that is a very bad idea in general, so we're also including
a log message whenever we see a request for `-hash` on
a Swift value that is Equatable but not Hashable.
To limit performance problems from the logging itself, we
emit the log message only once for each type.
This is worth telling people about:
Since we're being asked for the hash value, that probably means someone is
trying to put this object into some form of set or dictionary. But we don't know
anything about the Equatable implementation, so the only valid hash value we can
possibly return is a constant. And hash table implementations typically degrade
into unsorted lists when provided constant hash values.
Note: In order to avoid hammering the logs, we only emit the
warning once for each class that hits this path.
For an Equatable type, we need a hash implementation that
is compatible with any possible definition of `==`.
Conservatively, that means `-hash` must return a constant.
For non-Equatable types, we know that `==` is identity based,
so we can get better hash behavior by using the object address.
Caveat: This means that non-Equatable types will do two
protocol conformance checks on every call to `hash`.
Swift objects can implement Equatable without implementing
Hashable. Obj-C NSObject always provides both.
Now that we bridge Swift Equatable to Obj-C `-isEqual:`,
we have to be conservative with how we expose `-hash`
for Swift types that are Equatable but not Hashable.
This looks like "incomplete hashing" of such types.
If a Swift type implements Equatable and/or Hashable and
we then pass that object into ObjC, we want ObjC
`isEqual:` and `hashValue` to use that. This allows
ObjC code to build ObjC collections of Swift objects.
* Support for Hashable struct/enum types was implemented in #4124
* Support for Equatable struct/enum types was implemented in #68720
* This implements support for Hashable and Equatable _class_ types
Caveats:
1. This does a lot of dynamic lookup work for each operation, so is
inherently rather slow. Unlike the struct/enum case, there is no convenient
place to cache the conformance information, so it's not clear that there is a
viable way to make it significantly faster.
2. This is a behavioral change to low-level support code. There is a
risk of breaking code that may be relying on the old behavior.