mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Distinguish conformance and superclass generic requirements.
As part of this, use a different enum for parsed generic requirements. NFC except that I noticed that ASTWalker wasn't visiting the second type in a conformance constraint; fixing this seems to have no effect beyond producing better IDE annotations.
This commit is contained in:
@@ -885,6 +885,20 @@ void *allocateMemoryForDecl(AllocatorTy &allocator, size_t baseSize,
|
||||
return mem;
|
||||
}
|
||||
|
||||
enum class RequirementReprKind : unsigned int {
|
||||
/// A type bound T : P, where T is a type that depends on a generic
|
||||
/// parameter and P is some type that should bound T, either as a concrete
|
||||
/// supertype or a protocol to which T must conform.
|
||||
TypeConstraint,
|
||||
|
||||
/// A same-type requirement T == U, where T and U are types that shall be
|
||||
/// equivalent.
|
||||
SameType,
|
||||
|
||||
// Note: there is code that packs this enum in a 2-bit bitfield. Audit users
|
||||
// when adding enumerators.
|
||||
};
|
||||
|
||||
/// \brief A single requirement in a 'where' clause, which places additional
|
||||
/// restrictions on the generic parameters or associated types of a generic
|
||||
/// function, type, or protocol.
|
||||
@@ -895,14 +909,14 @@ void *allocateMemoryForDecl(AllocatorTy &allocator, size_t baseSize,
|
||||
/// \c GenericParamList assumes these are POD-like.
|
||||
class RequirementRepr {
|
||||
SourceLoc SeparatorLoc;
|
||||
RequirementKind Kind : 2;
|
||||
RequirementReprKind Kind : 2;
|
||||
bool Invalid : 1;
|
||||
TypeLoc Types[2];
|
||||
/// Set during deserialization; used to print out the requirements accurately
|
||||
/// for the generated interface.
|
||||
StringRef AsWrittenString;
|
||||
|
||||
RequirementRepr(SourceLoc SeparatorLoc, RequirementKind Kind,
|
||||
RequirementRepr(SourceLoc SeparatorLoc, RequirementReprKind Kind,
|
||||
TypeLoc FirstType, TypeLoc SecondType)
|
||||
: SeparatorLoc(SeparatorLoc), Kind(Kind), Invalid(false),
|
||||
Types{FirstType, SecondType} { }
|
||||
@@ -910,7 +924,7 @@ class RequirementRepr {
|
||||
void printImpl(raw_ostream &OS, bool AsWritten) const;
|
||||
|
||||
public:
|
||||
/// \brief Construct a new conformance requirement.
|
||||
/// \brief Construct a new type-constraint requirement.
|
||||
///
|
||||
/// \param Subject The type that must conform to the given protocol or
|
||||
/// composition, or be a subclass of the given class type.
|
||||
@@ -918,10 +932,10 @@ public:
|
||||
/// this requirement was implied.
|
||||
/// \param Constraint The protocol or protocol composition to which the
|
||||
/// subject must conform, or superclass from which the subject must inherit.
|
||||
static RequirementRepr getConformance(TypeLoc Subject,
|
||||
SourceLoc ColonLoc,
|
||||
TypeLoc Constraint) {
|
||||
return { ColonLoc, RequirementKind::Conformance, Subject, Constraint };
|
||||
static RequirementRepr getTypeConstraint(TypeLoc Subject,
|
||||
SourceLoc ColonLoc,
|
||||
TypeLoc Constraint) {
|
||||
return { ColonLoc, RequirementReprKind::TypeConstraint, Subject, Constraint };
|
||||
}
|
||||
|
||||
/// \brief Construct a new same-type requirement.
|
||||
@@ -931,13 +945,13 @@ public:
|
||||
/// an invalid location if this requirement was implied.
|
||||
/// \param SecondType The second type.
|
||||
static RequirementRepr getSameType(TypeLoc FirstType,
|
||||
SourceLoc EqualLoc,
|
||||
TypeLoc SecondType) {
|
||||
return { EqualLoc, RequirementKind::SameType, FirstType, SecondType };
|
||||
SourceLoc EqualLoc,
|
||||
TypeLoc SecondType) {
|
||||
return { EqualLoc, RequirementReprKind::SameType, FirstType, SecondType };
|
||||
}
|
||||
|
||||
/// \brief Determine the kind of requirement
|
||||
RequirementKind getKind() const { return Kind; }
|
||||
RequirementReprKind getKind() const { return Kind; }
|
||||
|
||||
/// \brief Determine whether this requirement is invalid.
|
||||
bool isInvalid() const { return Invalid; }
|
||||
@@ -945,98 +959,98 @@ public:
|
||||
/// \brief Mark this requirement invalid.
|
||||
void setInvalid() { Invalid = true; }
|
||||
|
||||
/// \brief For a conformance requirement, return the subject of the
|
||||
/// \brief For a type-bound requirement, return the subject of the
|
||||
/// conformance relationship.
|
||||
Type getSubject() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[0].getType();
|
||||
}
|
||||
|
||||
TypeRepr *getSubjectRepr() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[0].getTypeRepr();
|
||||
}
|
||||
|
||||
TypeLoc &getSubjectLoc() {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[0];
|
||||
}
|
||||
|
||||
const TypeLoc &getSubjectLoc() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[0];
|
||||
}
|
||||
|
||||
/// \brief For a conformance requirement, return the protocol or to which
|
||||
/// \brief For a type-bound requirement, return the protocol or to which
|
||||
/// the subject conforms or superclass it inherits.
|
||||
Type getConstraint() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[1].getType();
|
||||
}
|
||||
|
||||
TypeLoc &getConstraintLoc() {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[1];
|
||||
}
|
||||
|
||||
const TypeLoc &getConstraintLoc() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return Types[1];
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the ':' in an explicitly-written
|
||||
/// conformance requirement.
|
||||
SourceLoc getColonLoc() const {
|
||||
assert(getKind() == RequirementKind::Conformance);
|
||||
assert(getKind() == RequirementReprKind::TypeConstraint);
|
||||
return SeparatorLoc;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the first type of a same-type requirement.
|
||||
Type getFirstType() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[0].getType();
|
||||
}
|
||||
|
||||
TypeRepr *getFirstTypeRepr() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[0].getTypeRepr();
|
||||
}
|
||||
|
||||
TypeLoc &getFirstTypeLoc() {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[0];
|
||||
}
|
||||
|
||||
const TypeLoc &getFirstTypeLoc() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[0];
|
||||
}
|
||||
|
||||
/// \brief Retrieve the second type of a same-type requirement.
|
||||
Type getSecondType() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[1].getType();
|
||||
}
|
||||
|
||||
TypeRepr *getSecondTypeRepr() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[1].getTypeRepr();
|
||||
}
|
||||
|
||||
TypeLoc &getSecondTypeLoc() {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[1];
|
||||
}
|
||||
|
||||
const TypeLoc &getSecondTypeLoc() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return Types[1];
|
||||
}
|
||||
|
||||
/// \brief Retrieve the location of the '==' in an explicitly-written
|
||||
/// same-type requirement.
|
||||
SourceLoc getEqualLoc() const {
|
||||
assert(getKind() == RequirementKind::SameType);
|
||||
assert(getKind() == RequirementReprKind::SameType);
|
||||
return SeparatorLoc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user