Skip to content

Commit 2d430d8

Browse files
committed
[GSB] Always pass a root potential archetype to a requirement source.
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.
1 parent dbf5782 commit 2d430d8

File tree

5 files changed

+165
-53
lines changed

5 files changed

+165
-53
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class GenericSignatureBuilder {
7373

7474
class RequirementSource;
7575

76+
class FloatingRequirementSource;
77+
7678
/// Describes a constraint that is bounded on one side by a concrete type.
7779
struct ConcreteConstraint {
7880
PotentialArchetype *archetype;
@@ -166,22 +168,22 @@ class GenericSignatureBuilder {
166168
/// previous example).
167169
bool
168170
addSameTypeRequirement(ResolvedType paOrT1, ResolvedType paOrT2,
169-
const RequirementSource *Source,
171+
FloatingRequirementSource Source,
170172
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
171173

172174
/// \brief Add a new same-type requirement between two fully resolved types
173175
/// (output of GenericSignatureBuilder::resolve).
174176
///
175177
/// The two types must not be incompatible concrete types.
176178
bool addSameTypeRequirement(ResolvedType paOrT1, ResolvedType paOrT2,
177-
const RequirementSource *Source);
179+
FloatingRequirementSource Source);
178180

179181
/// \brief Add a new same-type requirement between two unresolved types.
180182
///
181183
/// The types are resolved with \c GenericSignatureBuilder::resolve, and must
182184
/// not be incompatible concrete types.
183185
bool addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
184-
const RequirementSource *Source);
186+
FloatingRequirementSource Source);
185187

186188
/// \brief Add a new same-type requirement between two unresolved types.
187189
///
@@ -190,7 +192,7 @@ class GenericSignatureBuilder {
190192
/// types.
191193
bool
192194
addSameTypeRequirement(UnresolvedType paOrT1, UnresolvedType paOrT2,
193-
const RequirementSource *Source,
195+
FloatingRequirementSource Source,
194196
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
195197

196198
private:
@@ -218,7 +220,7 @@ class GenericSignatureBuilder {
218220
/// \param diagnoseMismatch Callback invoked when the types in the same-type
219221
/// requirement mismatch.
220222
bool addSameTypeRequirementBetweenConcrete(
221-
Type T1, Type T2, const RequirementSource *Source,
223+
Type T1, Type T2, FloatingRequirementSource Source,
222224
llvm::function_ref<void(Type, Type)> diagnoseMismatch);
223225

224226
/// Add the requirements placed on the given type parameter
@@ -294,9 +296,9 @@ class GenericSignatureBuilder {
294296
///
295297
/// \returns true if this requirement makes the set of requirements
296298
/// inconsistent, in which case a diagnostic will have been issued.
297-
bool addRequirement(const Requirement &req, const RequirementSource *source);
299+
bool addRequirement(const Requirement &req, FloatingRequirementSource source);
298300

299-
bool addRequirement(const Requirement &req, const RequirementSource *source,
301+
bool addRequirement(const Requirement &req, FloatingRequirementSource source,
300302
llvm::SmallPtrSetImpl<ProtocolDecl *> &Visited);
301303

302304
/// \brief Add a new requirement.
@@ -596,22 +598,23 @@ class GenericSignatureBuilder::RequirementSource : public llvm::FoldingSetNode {
596598

597599
public:
598600
/// Retrieve an abstract requirement source.
599-
static const RequirementSource *forAbstract(GenericSignatureBuilder &builder);
601+
static const RequirementSource *forAbstract(PotentialArchetype *root);
600602

601603
/// Retrieve a requirement source representing an explicit requirement
602604
/// stated in an 'inheritance' clause.
603-
static const RequirementSource *forExplicit(GenericSignatureBuilder &builder,
605+
static const RequirementSource *forExplicit(PotentialArchetype *root,
604606
const TypeRepr *typeRepr);
605607

606608
/// Retrieve a requirement source representing an explicit requirement
607609
/// stated in an 'where' clause.
608-
static const RequirementSource *forExplicit(GenericSignatureBuilder &builder,
610+
static const RequirementSource *forExplicit(
611+
PotentialArchetype *root,
609612
const RequirementRepr *requirementRepr);
610613

611614
/// Retrieve a requirement source representing a requirement that is
612615
/// inferred from some part of a generic declaration's signature, e.g., the
613616
/// parameter or result type of a generic function.
614-
static const RequirementSource *forInferred(GenericSignatureBuilder &builder,
617+
static const RequirementSource *forInferred(PotentialArchetype *root,
615618
const TypeRepr *typeRepr);
616619

617620
/// Retrieve a requirement source representing the requirement signature
@@ -728,6 +731,58 @@ class GenericSignatureBuilder::RequirementSource : public llvm::FoldingSetNode {
728731
void print(llvm::raw_ostream &out, SourceManager *SrcMgr) const;
729732
};
730733

734+
/// A requirement source that potentially lacks a root \c PotentialArchetype.
735+
/// The root will be supplied as soon as the appropriate dependent type is
736+
/// resolved.
737+
class GenericSignatureBuilder::FloatingRequirementSource {
738+
enum Kind {
739+
/// A fully-resolved requirement source, which does not need a root.
740+
Resolved,
741+
/// An explicit requirement source lacking a root.
742+
Explicit,
743+
/// An inferred requirement source lacking a root.
744+
Inferred
745+
} kind;
746+
747+
using Storage =
748+
llvm::PointerUnion3<const RequirementSource *, const TypeRepr *,
749+
const RequirementRepr *>;
750+
751+
Storage storage;
752+
753+
FloatingRequirementSource(Kind kind, Storage storage)
754+
: kind(kind), storage(storage) { }
755+
756+
public:
757+
/// Implicit conversion from a resolved requirement source.
758+
FloatingRequirementSource(const RequirementSource *source)
759+
: FloatingRequirementSource(Resolved, source) { }
760+
761+
static FloatingRequirementSource forAbstract() {
762+
return { Explicit, Storage() };
763+
}
764+
765+
static FloatingRequirementSource forExplicit(const TypeRepr *typeRepr) {
766+
return { Explicit, typeRepr };
767+
}
768+
769+
static FloatingRequirementSource forExplicit(
770+
const RequirementRepr *requirementRepr) {
771+
return { Explicit, requirementRepr };
772+
}
773+
774+
static FloatingRequirementSource forInferred(const TypeRepr *typeRepr) {
775+
return { Inferred, typeRepr };
776+
}
777+
778+
/// Retrieve the complete requirement source rooted at the given potential
779+
/// archetype.
780+
const RequirementSource *getSource(PotentialArchetype *pa) const;
781+
782+
/// Retrieve the source location for this requirement.
783+
SourceLoc getLoc() const;
784+
};
785+
731786
class GenericSignatureBuilder::PotentialArchetype {
732787
/// The parent of this potential archetype (for a nested type) or the
733788
/// generic signature builder in which this root resides.

0 commit comments

Comments
 (0)