Now that `InferredGenericSignatureRequest` creates
`StructuralRequirement`s from of the generic signature with valid source
locations, additional redundancy warnings are produced. Update tests
with the new warnings.
This enabled a gross idiom that should not have been allowed in the first place:
typealias G<T> = Any where T : P
protocol P {}
protocol Q : G<Self> {} // Q inherits from P now!
I'd like to ban this, assuming nothing is actually relying on this behavior.
We rebuild a generic signature after dropping conformance requirements
made redundant by a superclass or concrete type requirement.
When rebuilding the signature, preserve the source locations of the
original requirements, and only perform diagnostics on the rebuilt
signature.
This fixes an issue where we would emit a redundant requirement
warning even though the requirement in question was not actually
redundant.
This also avoids some unnecessary work. Most of the code in
finalize() does not need to be run twice, once before and once after
rebuilding the signature. Now we only run it after rebuilding the
signature.
Note that this regresses diagnostics in one narrow case where we
would previously diagnose a conflicting concrete type requirement.
This will be fixed once concrete type diagnostics are moved over
to use the new ExplicitRequirement infrastructure, just like all
other kinds already do.
Fixes rdar://problem/77462797.
This fixes a regression from the new redundant requirements algorithm
and paves the way for removing the notion of 'derived via concrete'
requirements.
This rewrites the existing redundant requirements algorithm
to be simpler, and fix an incorrect behavior in the case where
we're building a protocol requirement signature.
Consider the following example:
protocol P {
associatedtype A : P
associatedtype B : P where A.B == B
}
The requirement B : P has two conformance paths here:
(B : P)
(A : P)(B : P)
The naive redundancy algorithm would conclude that (B : P) is
redundant because it can be derived as (A : P)(B : P). However,
if we drop (B : P), we lose the derived conformance path
as well, since it involves the same requirement (B : P).
The above example actually worked before this change, because we
handled this case in getMinimalConformanceSource() by dropping any
derived conformance paths that involve the requirement itself
appearing in the "middle" of the path.
However, this is insufficient because you can have a "cycle"
here with length more than 1. For example,
protocol P {
associatedtype A : P where A == B.C
associatedtype B : P where B == A.C
associatedtype C : P where C == A.B
}
The requirement A : P has two conformance paths here:
(A : P)
(B : P)(C : P)
Similarly, B : P has these two paths:
(B : P)
(A : P)(C : P)
And C : P has these two paths:
(C : P)
(A : P)(B : P)
Since each one of A : P, B : P and C : P has a derived conformance
path that does not involve itself, we would conclude that all three
were redundant. But this was wrong; while (B : P)(C : P) is a valid
derived path for A : P that allows us to drop A : P, once we commit to
dropping A : P, we can no longer use the other derived paths
(A : P)(C : P) for B : P, and (A : P)(B : P) for C : P, respectively,
because they involve A : P, which we dropped.
The problem is that we were losing information here. The explicit
requirement A : P can be derived as (B : P)(C : P), but we would
just say that it was implied by B : P alone.
For non-protocol generic signatures, just looking at the root is
still sufficient.
However, when building a requirement signature of a self-recursive
protocol, instead of looking at the root explicit requirement only,
we need to look at _all_ intermediate steps in the path that involve
the same protocol.
This is implemented in a new getBaseRequirements() method, which
generalizes the operation of getting the explicit requirement at
the root of a derived conformance path by returning a vector of
one or more explicit requirements that appear in the path.
Also the new algorithm computes redundancy online instead of building
a directed graph and then computing SCCs. This is possible by
recording newly-discovered redundant requirements immediately,
and then using the set of so-far-redundant requirements when
evaluating a path.
This commit introduces a small regression in an existing test case
involving a protocol with a 'derived via concrete' requirement.
Subsequent commits in this PR fix the regression and remove the
'derived via concrete' mechanism, since it is no longer necessary.
Fixes https://bugs.swift.org/browse/SR-14510 / rdar://problem/76883924.
We rebuild a signature after dropping redundant conformance requirements,
since conformance requirements change the canonical type and conformance
access path computation.
When doing this, instead of using the canonical requirements from the
signature, use the original as-written requirements.
This fixes some weirdness around concrete same-type requirements.
There's a philosophical benefit here too -- since we rebuild the
signature without ever having built the old signature, we never create
an invalid GenericSignature in the ASTContext.
Fixes rdar://problem/75690903.
This almost completely guts checkConformanceConstraints(), and
removes a usage of checkConstraintList().
Yet another one of those refactorings that leaves the GSB in an
intermediate state, with some new logic that's cleaner, while
leaving behind old code for other use cases that haven't been
refactored yet.
To preserve correct behavior under substitution, the parent type
of a protocol type alias must be the 'Self' generic parameter and
not the protocol's existential type.
Flush it and the early validation hack now that we can delay computing the underlying interface type on demand and have taught type resolution to honor the structural type of a typealias.
This changes the way requirement signatures are spelled as a side effect.
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.
When extending a type via a generic typealias, where the type parameters of
the underlying nominal type line up precisely with those of the
generic typealias and its specialization of the underlying nominal
type (a so-called "pass-through" typealias in the new code), maintain
type sugar in the extension declaration.
This new type sugar enables inference of type requirements from the
generic typealias, which is both useful by itself (it lets the type
requirements on generic typealiases be meaningful for extensions like
they are elsewhere), and also addresses a source-compatability
regression where an extension of `CountableRange` will now infer the
requirement `Bound: Comparable`.
Fixes SR-6907 / rdar://problem/29066394.
Generic typealiases can add requirements that aren't used by their
underlying type. For example, CountableRange in the standard library:
public typealias CountableRange<Bound: Comparable> = Range<Bound>
Perform requirement inference based on uses of generic typealiases,
such that a generic function like this:
func f<T>(_: CountableRange<T>) { }
will infer T: Bound from the use of CountableRange.
Note that this does not yet work for extensions.
* Make Range conditionally a Collection
* Convert ClosedRange to conditionally a collection
* De-gyb Range/ClosedRange, refactoring some methods.
* Remove use of Countable{Closed}Range from stdlib
* Remove Countable use from Foundation
* Fix test errors and warnings resulting from Range/CountableRange collapse
* fix prespecialize test for new mangling
* Update CoreAudio use of CountableRange
* Update SwiftSyntax use of CountableRange
* Restore ClosedRange.Index: Hashable conformance
* Move fixed typechecker slowness test for array-of-ranges from slow to fast, yay
* Apply Doug's patch to loosen test to just check for error
A type Foo<...>.Bar may only exist conditionally (i.e. constraints on the
generic parameters of Foo), in which case those conditional requirements
should be implied when Foo<...>.Bar is mentioned.
Fixes SR-6850.
* Refactor Indices and Slice to use conditional conformance
* Replace ReversedRandomAccessCollection with a conditional extension
* Refactor some types into struct+extensions
* Revise Slice documentation
* Fix test cases for adoption of conditional conformances.
* [RangeReplaceableCollection] Eliminate unnecessary slicing subscript operator.
* Add -enable-experimental-conditional-conformances to test.
* Gruesome workaround for crasher in MutableSlice tests
Conditional conformances aren't quite ready yet for Swift 4.1, so
introduce the flag `-enable-experimental-conditional-conformances` to
enable conditional conformaces, and an error when one declares a
conditional conformance without specifying the flag.
Add this flag when building the standard library (which will vend
conditional conformances) and to all of the tests that need it.
Fixes rdar://problem/35728337.
Previously, we were inferring requirements from types within the definitions
of protocols, e.g., given something like:
protocol P {
associatedtype A: Collection
associatedtype B where A.Element == Set<B>
}
we would infer that B: Hashable. The code for doing this was actually
incorrect due to its mis-use of requirement sources, causing a few
crashers. Plus, it's not a good idea in general because it hides the
actual requirements on B. Stop doing this.
Also stop trying to infer requirements from conditional
requirements---those have already been canonicalized and minimized, so
there's nothing to infer from.
The first step in enumerating the minimal, canonical set of requirements for
a generic signature is identifying which "subject" types will show up in
the left-hand side of the requirements. Previously, this would require us
to realize all of the potential archetypes, and perform a number of
archetype-anchor computations and comparisons.
Replace that with a simpler walk over the equivalence classes,
identifying the anchor types within each derived same-type component
of those equivalence classes, which form the subject types. This is
more straightforward, doesn't rely on potential archetypes, simplifies
the code, and eliminates a silly O(n^2)-for-small-n that's been
bothering me for a while.
Associated type redeclarations occasionally occur to push around
associated type witness inference. Suppress the warning about redeclarations
that add no requirements (i.e., have neither an inheritance nor a
where clause).
When we have an equivalence class that contains two unrelated
associated types with the same name, infer a same-type constraint
between those two associated types. This is a more principled way to
introduce these constraints that we had before, fixing a
recently-introduced regression.
Use the "override" information in associated type declarations to provide
AST-level access to the associated type "anchor", i.e., the canonical
associated type that will be used in generic signatures, mangling,
etc.
In the Generic Signature Builder, only build potential archetypes for
associated types that are anchors, which reduces the number of
potential archetypes we build when type-checking the standard library
by 14% and type-checking time for the standard library by 16%.
There's a minor regression here in some generic signatures that were
accidentally getting (correct) same-type constraints. There were
existing bugs in this area already (Huon found some of them), while
will be addressed as a follow-up.
Fies SR-5726, where we were failing to type-check due to missed
associated type constraints.
Introduce (recursive) constraints that make the *Collection constraint
of SubSequence match that of its enclosing *Collection, e.g.,
MutableCollection.SubSequence conforms to MutableCollection.
Fixes rdar://problem/20715031 and more of SR-3453.
The full state of the GSB isn’t all that useful for testing, creates a ton of noise and gets in the way of some cleanups we’d like to make in the interface.
Stop dumping it as part of `-debug-generic-signatures`.