Skip to content

[GSB] Resolve type into an equivalence class without building a new PA. #12477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 12 additions & 37 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ class GenericSignatureBuilder {
std::vector<Constraint<LayoutConstraint>> layoutConstraints;

/// The members of the equivalence class.
///
/// This list of members is slightly ordered, in that the first
/// element always has a depth no greater than the depth of any other
/// member.
TinyPtrVector<PotentialArchetype *> members;

/// Describes a component within the graph of same-type constraints within
Expand Down Expand Up @@ -203,6 +207,9 @@ class GenericSignatureBuilder {
EquivalenceClass &operator=(const EquivalenceClass &) = delete;
EquivalenceClass &operator=(EquivalenceClass &&) = delete;

/// Add a new member to this equivalence class.
void addMember(PotentialArchetype *pa);

/// Record the conformance of this equivalence class to the given
/// protocol as found via the given requirement source.
///
Expand Down Expand Up @@ -758,6 +765,11 @@ class GenericSignatureBuilder {
resolvePotentialArchetype(Type type,
ArchetypeResolutionKind resolutionKind);

/// \brief Try to resolvew the equivalence class of the given type.
ResolveResult maybeResolveEquivalenceClass(
Type type,
ArchetypeResolutionKind resolutionKind);

/// \brief Resolve the equivalence class for the given type parameter,
/// which provides information about that type.
///
Expand Down Expand Up @@ -1593,42 +1605,13 @@ class GenericSignatureBuilder::PotentialArchetype {
return identifier.assocTypeOrConcrete;
}

/// Retrieve the set of protocols to which this potential archetype
/// conforms.
SmallVector<ProtocolDecl *, 4> getConformsTo() const {
SmallVector<ProtocolDecl *, 4> result;

if (auto equiv = getEquivalenceClassIfPresent()) {
for (const auto &entry : equiv->conformsTo)
result.push_back(entry.first);
}

return result;
}

/// Add a conformance to this potential archetype.
///
/// \returns true if the conformance was new, false if it already existed.
bool addConformance(ProtocolDecl *proto,
const RequirementSource *source,
GenericSignatureBuilder &builder);

/// Retrieve the superclass of this archetype.
Type getSuperclass() const {
if (auto equiv = getEquivalenceClassIfPresent())
return equiv->superclass;

return nullptr;
}

/// Retrieve the layout constraint of this archetype.
LayoutConstraint getLayout() const {
if (auto equivClass = getEquivalenceClassIfPresent())
return equivClass->layout;

return LayoutConstraint();
}

/// Retrieve the set of nested types.
const llvm::MapVector<Identifier, StoredNestedType> &getNestedTypes() const {
return NestedTypes;
Expand Down Expand Up @@ -1741,14 +1724,6 @@ class GenericSignatureBuilder::PotentialArchetype {
return false;
}

/// Get the concrete type this potential archetype is constrained to.
Type getConcreteType() const {
if (auto equivClass = getEquivalenceClassIfPresent())
return equivClass->concreteType;

return Type();
}

LLVM_ATTRIBUTE_DEPRECATED(
void dump() const,
"only for use within the debugger");
Expand Down
15 changes: 12 additions & 3 deletions lib/AST/ConformanceLookupTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,14 +448,23 @@ bool ConformanceLookupTable::addProtocol(NominalTypeDecl *nominal,
return false;

case ConformanceEntryKind::Implied:
// An implied conformance is better than a synthesized one.
// Ignore implied circular protocol inheritance
if (kind == ConformanceEntryKind::Synthesized ||
existingEntry->getProtocol() == protocol)
if (existingEntry->getProtocol() == protocol)
return false;

// An implied conformance is better than a synthesized one, unless
// the implied conformance was deserialized.
if (kind == ConformanceEntryKind::Synthesized &&
existingEntry->getDeclContext()->getParentSourceFile() == nullptr)
return false;

break;

case ConformanceEntryKind::Synthesized:
// An implied conformance is better unless it was deserialized.
if (dc->getParentSourceFile() == nullptr)
return false;

break;
}
}
Expand Down
Loading