Skip to content

Commit 23f3ba5

Browse files
committed
[GenericSig Builder] Track and canonicalize same-type-to-concrete constraints.
Track each same-type-to-concrete constraint on the potential archetype against which it was written, and ensure that the requirement sources for such same-type constraints stay with the potential archetypes on which they were described. This is similar to the way we track same-type constraints among potential archetypes. Use this information to canonicalize same-type-to-concrete constraints appropriately. For each connected component within an equivalence class of potential archetypes, select the best requirement source to the concrete type, or substitute in an abstract requirement source if none exists. This approach ensures that components that would be equivalent to that concrete type anyway get a derived source, while components that get the concrete-type equivalence by being tied to another To get here, we also needed to change the notion of the archetype anchor so that potential archetypes with no same-type constraints directly in their path are preferred over potential archetypes that do have a same-type constraint in their path. Otherwise, the anchor might be something that is always concrete and is, therefore, not terribly interesting. Fixes the new case that popped up in rdar://problem/30478915.
1 parent e7a4fbc commit 23f3ba5

File tree

4 files changed

+245
-133
lines changed

4 files changed

+245
-133
lines changed

include/swift/AST/GenericSignatureBuilder.h

+14-7
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,11 @@ class RequirementSource : public llvm::FoldingSetNode {
296296
/// path.
297297
bool isDerivedRequirement() const;
298298

299+
/// Whether the requirement is derived via some concrete conformance, e.g.,
300+
/// a concrete type's conformance to a protocol or a superclass's conformance
301+
/// to a protocol.
302+
bool isDerivedViaConcreteConformance() const;
303+
299304
/// Retrieve a source location that corresponds to the requirement.
300305
SourceLoc getLoc() const;
301306

@@ -712,7 +717,8 @@ class GenericSignatureBuilder::PotentialArchetype {
712717
/// constrained.
713718
Type ConcreteType;
714719

715-
/// The source of the concrete type requirement.
720+
/// The source of the concrete type requirement, if one was written
721+
/// on this potential archetype.
716722
const RequirementSource *ConcreteTypeSource = nullptr;
717723

718724
/// Whether this is an unresolved nested type.
@@ -936,15 +942,16 @@ class GenericSignatureBuilder::PotentialArchetype {
936942
SameTypeConstraints.end());
937943
}
938944

939-
/// Retrieve the source of the same-type constraint that maps this potential
940-
/// archetype to a concrete type.
941-
const RequirementSource *getConcreteTypeSource() const {
942-
if (Representative != this)
943-
return Representative->getConcreteTypeSource();
944-
945+
/// Retrieve the concrete type source as written on this potential archetype.
946+
const RequirementSource *getConcreteTypeSourceAsWritten() const {
945947
return ConcreteTypeSource;
946948
}
947949

950+
/// Find a source of the same-type constraint that maps this potential
951+
/// archetype to a concrete type somewhere in the equivalence class of this
952+
/// type.
953+
const RequirementSource *findAnyConcreteTypeSourceAsWritten() const;
954+
948955
/// \brief Retrieve (or create) a nested type with the given name.
949956
PotentialArchetype *getNestedType(Identifier Name,
950957
GenericSignatureBuilder &builder);

0 commit comments

Comments
 (0)