The lookupDirect means that we can see type declarations nested inside of a protocol. If we do not filter these invalid declarations, we will offer a bogus fixit on top of a cycle diagnostic. Remove these types from consideration entirely so we don't crash and don't offer bogus fixits.
Resolves rdar://57003317
By convention, most structs and classes in the Swift compiler include a `dump()` method which prints debugging information. This method is meant to be called only from the debugger, but this means they’re often unused and may be eliminated from optimized binaries. On the other hand, some parts of the compiler call `dump()` methods directly despite them being intended as a pure debugging aid. clang supports attributes which can be used to avoid these problems, but they’re used very inconsistently across the compiler.
This commit adds `SWIFT_DEBUG_DUMP` and `SWIFT_DEBUG_DUMPER(<name>(<params>))` macros to declare `dump()` methods with the appropriate set of attributes and adopts this macro throughout the frontend. It does not pervasively adopt this macro in SILGen, SILOptimizer, or IRGen; these components use `dump()` methods in a different way where they’re frequently called from debugging code. Nor does it adopt it in runtime components like swiftRuntime and swiftReflection, because I’m a bit worried about size.
Despite the large number of files and lines affected, this change is NFC.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
The GSB will try to form and note invalid constraints, but there are
a few paths that aren't prepared for error types to pop up. Add
a defensive check to formProtocolRelativeType to make sure we don't wind
up force-casting an error type.
Fixes rdar://56116278
TypeCheckPattern used to splat the interface type into this, and
different parts of the compiler would check one or the other. There is
now one source of truth: The interface type. The type repr is now just
a signal that the user has written an explicit type annotation on
a parameter. For variables, we will eventually be able to just grab
this information from the parent pattern.
This relied on UB as per [meta.rqmts]p4
(http://eel.is/c++draft/meta#rqmts-4) and has been UB since C++11
20.9.2p1 has the same restriction.
MSVC 19.24 became more stringent and silently ignores this now,
preventing the Swift build. Require the user to explicitly pass in
`-DSWIFT_PERMIT_UNDEFINED_BEHAVIOR` to get the dump functionality.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
Remove the parent signature from consideration when computing the
generic signature for an extension. This cuts off a series of crashers
that involved nested extensions with trailing where clauses a la
extension Foo {
extension Foo where Self.Undefined == Bar {
}
}
The inner (invalid) extension technically has a parent signature from
Foo itself. Adding that signature to the GSB means when we go to
register the inner extension's generic parameters we crash.
Since extensions have to occur at the top level, just remove the parent
signature from consideration.
Fixes rdar://55502661
Use the interface type of the underlying type in the GSB in as many
cases as possible except for one important one: requirement signature
computation. There, use the structural type so we don't wind up
recursively validating the requirements of an incomplete protocol.
Most of AST, Parse, and Sema deal with FileUnits regularly, but SIL
and IRGen certainly don't. Split FileUnit out into its own header to
cut down on recompilation times when something changes.
No functionality change.
This avoids making the structural type dependent on whether the interface type has been computed and neatly avoids special-casing non-parsed declarations which set their underlying type up front.
Computing the interface type of a typealias used to push validation forward and recompute the interface type on the fly. This was fragile and inconsistent with the way interface types are computed in the rest of the decls. Separate these two notions, and plumb through explicit interface type computations with the same "computeType" idiom. This will better allow us to identify the places where we have to force an interface type computation.
Also remove access to the underlying type loc. It's now just a cache location the underlying type request will use. Push a type repr accessor to the places that need it, and push the underlying type accessor for everywhere else. Getting the structural type is still preferred for pre-validated computations.
This required the resetting of a number of places where we were - in many cases tacitly - asking the question "does the interface type exist". This enables the removal of validateDeclForNameLookup
Computing the generic signature changes the way that cycles appear in the compiler. For now, break these cycles. We should investigate each place where hasComputedGenericSignature() is used in service of breaking cycles. See rdar://55263708
Unify a bunch of quasi-independent callsites into a single request that
builds up a generic signature from a variety of inference sources. This
draws the extension typealias workaround for SE-0229 into TypeCheckDecl
where we can better work on refactoring it. The goal is to use this as
a springboard to requests that compute generic environments for various
and sundry decls.
When a request for an abstract generic signature contains noncanonical
types, first compute the abstract generic signature for the
canonicalized types, then map back to the provided generic
parameters. Clients of this request generally work in canonical types
already, but it's a small win.
Introduce a request to form an abstract generic signature given a
base signature, additional generic parameters, and additional
requirements. It is meant to provide a caching layer in front of the
generic signature builder.
Switch one direct client of the generic signature builder over to this
mechanism, the formation of a generic signature for an existential
type.
We've fixed a number of bugs recently where callers did not expect
to get a null Type out of subst(). This occurs particularly often
in SourceKit, where the input AST is often invalid and the types
resulting from substitution are mostly used for display.
Let's fix all these potential problems in one fell swoop by changing
subst() to always return a Type, possibly one containing ErrorTypes.
Only a couple of places depended on the old behavior, and they were
easy enough to change from checking for a null Type to checking if
the result responds with true to hasError().
Also while we're at it, simplify a few call sites of subst().
-verify-generic-signatures didn't catch the bad case from
<https://bugs.swift.org/browse/SR-10752>. Add a new check and
make sure it now catches this kind of failure.
This check wasn't ever correct, because the fact that the the protocol comes
from another module doesn't change the fact that the type is valid for lookup
within this module. It incorrectly rejects the following, valid code:
```swift
// In A.swift
public protocol A {}
```
```
// In B.swift
import A
extension A {
typealias B = Int
func b(_ b: Self.B) {}
}
```
The GSB should avoid triggering declaration validation where
possible, to avoid problems resulting from circularity and as
a general performance rule-of-thumb.
This last call was there to catch self-recursive protocol
typealiases. However, we can diagnose this problem elsewhere,
which allows us to emit a more accurate diagnostic as well.
Replace most remaining uses of isRequirementSignatureComputed by
isRequirementSignatureComputing which uses Evaluator::hasActiveRequest
to detect if the requirements are currently being computed.
Replaces the explicit call to computeRequirementSignature from
validateDecl with a lazy getRequirementSignature. A side effect is that
the generic params of a ProtocolDecl are no longer computed from
validateDecl and must be computed lazily too.
Opaque result type archetypes can involve type variables, which
then get introduced into GenericSignatureBuilders and the
generated GenericSignatures. Allocate them in the proper arena
So we don’t end up with use-after-free errors.
Fixes rdar://problem/50309503.
Fixes crashes in 28437-swift-typechecker-validatedecl.swift (from previous commit)
and the compiler crasher 28861-gpdecl-getdepth-generictypeparamdecl-
invaliddepth-parameter-hasnt-been-validated.swift.
Swap the `array_pod_sort` to `sort`. `array_pod_sort` is meant to be
used with POD types only. Switching to `std:sort` should be slightly
faster, and more importantly, allows the emission of the warnings on
Windows to be sorted identically to Linux and macOS.
Calling DependentMemberType::get() repeatedly pollutes the processor
caches because the global hash table can be quite large. With this
change, we either precompute DependentMemberTypes or cache them on
demand. This change makes the release/no-assert build of
Swift.swiftmodule 4.1% faster.
We generated a mix of "inferred" and "nested type name match"
constraints for the case where we had two nested types with the same
name and inferred that they are equal. Make them consistent by always
using nested type name match constraints. This fixes a bug where we
would get different canonical generic signatures in different source
files because we inferred the same-type constraint with different
requirement sources.
Fixes rdar://problem/48049725.