If a requirement is made redundant due to another requirement that was
inferred from the signature of a generic declaration, don't diagnose
the former as redundant. The user has likely written the requirement
explicitly for clarity purposes (e.g., to emphasize the Hashable
requirement on a function that takes a Set<T>). Removing the
requirement to silence the warning would make the code less clear.
This eliminates all of the annoying, spurious warnings from the build
of the overlays.
Introduce an API that determines the "conformance access path" that
one would follow to find the conformance of a given type parameter
(e.g., T.Iterator.Element) to a given protocol (e.g., Equatable). A
conformance access path starts at one of the explicit requirements
of that generic signature and then proceeds through zero or more
protocol-supplied requirements. For example, given this function:
func f<C: Collection>(_: C) { }
The conformance access path for "C.Iterator: IteratorProtocol" is
(C, Collection) -> (Self, Sequence) -> (Self.Iterator, IteratorProtocol)
because one starts with the explicit requirement "C: Collection", goes
to the inherited protocol requirement (the "Self" in Collection
conforms to Sequence) and then a requirement on the associated type
(Self.Iterator in Sequence conforms to IteratorProtocol).
This is all scaffolding now; it's intended to be used by IRGen (to
find the witness tables it needs) and SubstitutionMap (to dig out
conformances during substitution).
The ad hoc substitution functions here were really odd; use
SubstitutionMap directly, and pass it through to
GenericSignatureBuilder::addRequirement().
The stored dependent types in ProtocolRequirement elements within
requirement sources were incorrect for requirements created from the
requirement signature of another protocol, because we picked up the
already-substituted subject type. Thread the optional substitution map
through addRequirement(Requirement) as well, so we maintain the
original spelling of the stored dependent type.
This is a temporary fix; we should be able to recover the stored
dependent types from the potential archetypes in the requirement
source, so that we don't need to specify them explicitly at
construction time.
...and IRGen it into a call to __tsan_write1 in compiler-rt. This is
preparatory work for a later patch that will add an experimental
option to treat Swift inout accesses as TSan writes.
For a protocol requirement element within a requirement source, track
both the protocol in which the requirement was introduced as well as
the dependent type (relative to that protocol) on which the
requirement was introduced. This information is important when
reconstructing the path from a requirement-as-written to the location
of a desired protocol conformance.
Start reshuffling RequirementSource to store more information about
requirements in protocols. As a small step, track the source locations
for requirements written within the protocols themselves.
Note: there's a QoI regression here where we get duplicated
diagnostics (due to multiple generic signature builders being built
from a bad signature).
The use of floating sources allows us to carry through the protocol
information (i.e., "in which protocol do we look for this
information?") without immediately forming a new
RequirementSource. Yet more NFC refactoring for protocol-requirement
sources to carry more pertinent information.
This is preparation for a future patch adding experimental support to
treat Swift-level inout accesses as Thread Sanitizer writes. That patch will
extend the compiler so that additional TSan instrumentation is emitted
during SILGen, rather than solely during IRGen and at the LLVM level as occurs
now.
This patch adds a 'Sanitize' field to SILOptions and moves parsing of
'sanitize=...' to ParseSILArgs() from ParseIRGenArgs() where it is
now.
The sanitizer-coverage flag remains an IRGen-level option; SILGen does not
need to know about the coverage metric.
This was a remnant of the old generics implementation, where
all nested types were expanded into an AllArchetypes list.
For quite some time, this method no longer returned *all*
dependent types, only those with generic requirements on
them, and all if its remaining uses were a bit convoluted.
- In the generic specialization code, we used this to mangle
substitutions for generic parameters that are not subject
to a concrete same-type constraint.
A new GenericSignature::getSubstitutableParams()
function handles this use-case instead. It is similar
to getGenericParams(), but only returns generic parameters
which require substitution.
In the future, SubstitutionLists will only store replacement
types for these generic parameters, instead of the list of
types that we used to produce from getAllDependentTypes().
- In specialization mangling and speculative devirtualization,
we relied on SubstitutionLists having the same size and
order as getAllDependentTypes(). It's better to turn the
SubstitutionList into a SubstitutionMap instead, and do lookups
into the map.
- In the SIL parser, we were making a pass over the generic
requirements before looking at getAllDependentTypes();
enumeratePairedRequirements() gives the correct information
upfront.
- In SIL box serialization, we don't serialize the size of the
substitution list, since it's available from the generic
signature. Add a GenericSignature::getSubstitutionListSize()
method, but that will go away soon once SubstitionList
serialization only serializes replacement types for generic
parameters.
- A few remaining uses now call enumeratePairedRequirements()
directly.
to correctly handle generalized protocol requirements.
The major missing pieces here are that the conformance search
algorithms in both the AST (type substitution) and IRGen
(witness table reference emission) need to be rewritten to
back-track requirement sources, and the AST needs to actually
represent this stuff in NormalProtocolConformances instead
of just doing ???.
The new generality isn't tested yet; I'm looking into that,
but I wanted to get the abstractions in place first.
The protocol conformance checker verifies that all of the requirements
in the protocol's requirement signature are fulfilled. Save the
conformances from that check into the NormalProtocolConformance,
because this is the record of how that concrete type satisfies the
protocol requirements.
Compute, deserialize, and verify this information, but don't use it
for anything just yet. We'll use this to eliminate the "inherited
protocol map" and possibility some redundant type-witness
information.
This lets you match `case .foo` when `foo` resolves to any static member, instead of only a `case`, albeit without the exhaustiveness checking and subpattern capabilities of proper cases. While we're here, adjust the type system we set up for unresolved patterns embedded in expressions so that we give better signal in the error messages too.
Centralize the checking of a superclass constraint against a
same-type-to-concrete constraint. Additionally, produce a warning if
the superclass constraint is satisfied but is made redundant by an
existing same-type constraint.
Use the same infrastructure we have for same-type-to-concrete
constraints to check superclass constraints. Specifically,
* Track all superclass constraints; never "update" a requirement source
* Remove self-derived superclass constraints
* Pick the best superclass constraint within each connected component
of an equivalence class and use that for requirement generation.
* Diagnose conflicting superclass requirements during finalization
* Diagnose redundant superclass requirements (during finalization)
Introduce an operation on RequirementSource to determine whether a
constraint with such a source, when it lands on a given potential
archetype, is "self-derived": e.g., the final constraint is derived
from the original constraint. Remove such constraints from the system
during finalization, because otherwise they would make the original
constraint redundant.
Fixes rdar://problem/30478915, although we still need to apply this
same logic to other kinds of constraints in the system.
Use TrailingObjects to help us efficiently store the root potential
archetype within requirement sources, so we can reconstruct the
complete path from the point where a requirement was created to the
potential archetype it affects.
The test changes are because we are now dumping the root potential
archetype as part of -debug-generic-signatures.
Whenever we create a (root) requirement source, associate it with the
potential archetype on which the requirement is written. This lets us
follow a requirement source from the (stated or implied) requirement on
the root potential archetype to the effective requirement on the
resulting potential archetype.
Introduce FloatingRequirementSource for the cases where we need to
state what the root source is, but don't yet have a potential
archetype to attach it to. These get internally resolved to
RequirementSources as soon as possible.