Instead of just falling back to module lookup any time conformance
substitution fails, only do it in the case we know doesn't work.
This should shake out some more bugs, hopefully without causing
too much pain.
Looking up the conformance @dynamic_self C<T> : P simply returns
the normal conformance C<T> : P.
If we later apply a substitution map to the conformance to
specialize T, we would call isSpecialized() on the substituted
type, which would return false. We would then hit an assertion
because the type type @dynamic_self C<Int> is not equal to the
(erroneously unsubstituted) conformance type C<T>.
Tweak the logic slightly to avoid this.
NormalProtocolConformance has the only correct implementation of this
functionality. Instead, providing a safer getWitnessDecl() that
doesn't promise substitutions that are incorrect (and not actually
used by any clients).
A canonical conformance is defined as a conformance which:
- does not contain any non-canonical types.
- Its type and interface type should be canonical.
- Any referenced conformances should be canonical.
- Any used substitutions should be canonical as well.
A substitution is canonical if:
- its replacement type is canonical
- all of its conformances are canonical
There are a number of type witnesses that are introduced by the Clang
importer. Immediately resolve those witnesses *without* going through
the type checker, because there are cases (i.e., deserialized SIL)
where the conformance is created but there is no type checker around.
Fixes rdar://problem/30364905, rdar://problem/31053701,
rdar://problem/31565413 / SR-4565.
* Use the presence of an argument type to check for associated values
hasOnlyCasesWithoutAssociatedValues returns true for any serialized
enum declaration whether or not it has cases. This never really came
up because it's mostly relevant to Sema's proto-deriving mechanism. Fix
this by using the presence of the case's argument type instead.
* Separate checks for presence of cases and enum simplicity
Necessary because the old behavior was an artifact of the
implementation.
All of this information is recoverable from the more-general,
more-sane signature conformances, so stop
recording/serializing/deserializing all of this extra stuff.
When looking up a particular conformance in a SubstitutionMap, use the
associated generic signature to determine how to find that conformance
(via a conformance access path). Follow that conformance access path
to retrieve the desired conformance.
FIXME: There is still one failure, here
Constraints/generic_overload.swift
which appears to be because we either have the wrong generic signature
for the override case or we are looking in the wrong map.
ASTContext::getSpecializedConformance() already copies the
substitutions, so remove some AllocateCopy() calls.
Also, add a new overload taking a SubstitutionMap instead.
This allows removing some gatherAllSubstitutions() calls,
which have an allocation inside them.
Finally, remove the now-unused ModuleDecl parameter from
ProtocolConformance::subst() and make it public.
Reimplement these methods, making use of Type::subst() for
the former and the stored protocol conformances that correspond to the
protocol's requirement signature for the latter. This is enough to
emit witness tables with indirect conformance requirements in them.
This is a bit of a hack to dodge an assertion. In essence, it's a
harmless hack, but we'd like to make the handling of optional and
unavailable requirements more rigorous.
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.
The root cause is that NormalProtocolConformance::forEachValueWitness()
needs to skip protocol members that are not requirements.
Otherwise we end up passing such a non-requirement member down to
NormalProtocolConformance::getWitness() and hit an assert when we
cannot find it.
It looks like this code path was only ever hit from SourceKit.
The fix moves TypeChecker::isRequirement() to a method on ValueDecl,
and calls it in the right places.
Fixes <https://bugs.swift.org/browse/SR-3815>.
This reverts part of #4038 which made the compiler consider it to be an `Explicit` conformance, breaking source code that was accepted in Swift 3.0 which declared a raw type as well as explicit conformance to `RawRepresentable` (reported as rdar://problem/30386658). While I'm here, a couple of spot fixes:
- Ensure an enum's raw value exprs are type-checked before checking conformances of any of its extensions, since the RawRepresentable conformance derivation will blow up if the raw value exprs haven't been checked. Fixes an order dependency issue if `extension Foo: RawRepresentable {}` gets checked before `enum Foo: Int { ... }`.
- Don't display the custom `enum_declares_rawrep_with_raw_type` diagnostic if the source location for the enum's inheritance clause is invalid, so that we don't emit a dislocated diagnostic.
This method maps interface types to archetypes, which in general
requires a module for performing conformance lookups, if mapping
a member type of a generic parameter which has been made concrete.
However, in practice the types we are mapping here are all canonical
with respect to the generic signature, because they came from
GenericSignature::getAllDependentTypes(), so we actually don't need
to do conformance lookups.
This allows some code to be simplified.
SubstitutionList is going to be a more compact representation of
a SubstitutionMap, suitable for inline allocation inside another
object.
For now, it's just a typedef for ArrayRef<Substitution>.
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.
Officially kick SILBoxType over to be "nominal" in its layout, with generic layouts structurally parameterized only by formal types. Change SIL to lower a capture to a nongeneric box when possible, or a box capturing the enclosing generic context when necessary.
This is needed if we want to use Substitution::subst from inside Type::subst, which will be necessary for SILBoxTypes and maybe some day BoundGenericTypes. NFC yet.