mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Sema: Another fix for protocol self-conformance
It looks like we were checking in the wrong place, as a result we didn't
catch stuff like
class G<T : AnyObject> {}
_ = G<P>()
This would crash later in IRGen.
Make the conformsToProtocol() check do the right thing, and remove some
other miscellaneous diagnostics in the process. Also, make the
"type 'T' does not conform to protocol 'P'" diagnostic a bit more
detailed.
Unfortunately in a few instances we lose a more descriptive diagnostic to
a general 'cannot invoke 'foo' with argument list of type 'T'' error. The
argument matching diagnostics need to be addressed anyway though.
Fixes <rdar://problem/20311619>.
Swift SVN r29737
This commit is contained in:
@@ -769,6 +769,17 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
// existential's list of conformances and the existential conforms to
|
||||
// itself.
|
||||
if (type->isExistentialType()) {
|
||||
SmallVector<ProtocolDecl *, 4> protocols;
|
||||
type->getAnyExistentialTypeProtocols(protocols);
|
||||
|
||||
// Due to an IRGen limitation, witness tables cannot be passed from an
|
||||
// existential to an archetype parameter, so for now we restrict this to
|
||||
// @objc protocols.
|
||||
for (auto proto : protocols) {
|
||||
if (!proto->isObjC())
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
}
|
||||
|
||||
// If the existential type cannot be represented or the protocol does not
|
||||
// conform to itself, there's no point in looking further.
|
||||
if (!protocol->existentialConformsToSelf() ||
|
||||
@@ -783,10 +794,8 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
}
|
||||
|
||||
// Look for this protocol within the existential's list of conformances.
|
||||
SmallVector<ProtocolDecl *, 4> protocols;
|
||||
type->getAnyExistentialTypeProtocols(protocols);
|
||||
for (auto ap : protocols) {
|
||||
if (ap == protocol || ap->inheritsFrom(protocol)) {
|
||||
for (auto proto : protocols) {
|
||||
if (proto == protocol || proto->inheritsFrom(protocol)) {
|
||||
return { nullptr, ConformanceKind::Conforms };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user