Skip to content

Plumb the "Is Type Sequence" Bit Through the Surface AST #40059

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 1 commit into from
Nov 9, 2021
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
19 changes: 15 additions & 4 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,11 +486,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
SWIFT_INLINE_BITFIELD_EMPTY(TypeDecl, ValueDecl);
SWIFT_INLINE_BITFIELD_EMPTY(AbstractTypeParamDecl, TypeDecl);

SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, AbstractTypeParamDecl, 16+16,
SWIFT_INLINE_BITFIELD_FULL(GenericTypeParamDecl, AbstractTypeParamDecl, 16+16+1,
: NumPadBits,

Depth : 16,
Index : 16
Index : 16,
TypeSequence : 1
);

SWIFT_INLINE_BITFIELD_EMPTY(GenericTypeDecl, TypeDecl);
Expand Down Expand Up @@ -2883,7 +2884,7 @@ class GenericTypeParamDecl : public AbstractTypeParamDecl {
/// \param name The name of the generic parameter.
/// \param nameLoc The location of the name.
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
unsigned depth, unsigned index);
bool isTypeSequence, unsigned depth, unsigned index);

/// The depth of this generic type parameter, i.e., the number of outer
/// levels of generic parameter lists that enclose this type parameter.
Expand All @@ -2905,6 +2906,15 @@ class GenericTypeParamDecl : public AbstractTypeParamDecl {
assert(Bits.GenericTypeParamDecl.Depth == depth && "Truncation");
}

/// Returns \c true if this generic type parameter is declared as a type
/// sequence.
///
/// \code
/// func foo<@_typeSequence T>(_ : T...) { }
/// struct Foo<@_typeSequence T> { }
/// \encode
bool isTypeSequence() const { return Bits.GenericTypeParamDecl.TypeSequence; }

/// The index of this generic type parameter within its generic parameter
/// list.
///
Expand Down Expand Up @@ -7594,7 +7604,8 @@ inline bool Decl::isPotentiallyOverridable() const {
}

inline GenericParamKey::GenericParamKey(const GenericTypeParamDecl *d)
: Depth(d->getDepth()), Index(d->getIndex()) { }
: TypeSequence(d->isTypeSequence()), Depth(d->getDepth()),
Index(d->getIndex()) {}

inline const GenericContext *Decl::getAsGenericContext() const {
switch (getKind()) {
Expand Down
20 changes: 12 additions & 8 deletions include/swift/AST/GenericParamKey.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,19 @@ class GenericTypeParamType;
/// A fully-abstracted generic type parameter key, maintaining only the depth
/// and index of the generic parameter.
struct GenericParamKey {
unsigned Depth : 16;
unsigned TypeSequence : 1;
unsigned Depth : 15;
unsigned Index : 16;

GenericParamKey(unsigned depth, unsigned index)
: Depth(depth), Index(index) { }
GenericParamKey(bool isTypeSequence, unsigned depth, unsigned index)
: TypeSequence(isTypeSequence), Depth(depth), Index(index) {}

GenericParamKey(const GenericTypeParamDecl *d);
GenericParamKey(const GenericTypeParamType *d);

friend bool operator==(GenericParamKey lhs, GenericParamKey rhs) {
return lhs.Depth == rhs.Depth && lhs.Index == rhs.Index;
return lhs.TypeSequence == rhs.TypeSequence && lhs.Depth == rhs.Depth &&
lhs.Index == rhs.Index;
}

friend bool operator!=(GenericParamKey lhs, GenericParamKey rhs) {
Expand Down Expand Up @@ -100,18 +102,20 @@ namespace llvm {
template<>
struct DenseMapInfo<swift::GenericParamKey> {
static inline swift::GenericParamKey getEmptyKey() {
return {0xFFFF, 0xFFFF};
return {true, 0xFFFF, 0xFFFF};
}
static inline swift::GenericParamKey getTombstoneKey() {
return {0xFFFE, 0xFFFE};
return {true, 0xFFFE, 0xFFFE};
}

static inline unsigned getHashValue(swift::GenericParamKey k) {
return DenseMapInfo<unsigned>::getHashValue(k.Depth << 16 | k.Index);
return DenseMapInfo<unsigned>::getHashValue(
k.Depth << 16 | k.Index | ((k.TypeSequence ? 1 : 0) << 30));
}
static bool isEqual(swift::GenericParamKey a,
swift::GenericParamKey b) {
return a.Depth == b.Depth && a.Index == b.Index;
return a.TypeSequence == b.TypeSequence && a.Depth == b.Depth &&
a.Index == b.Index;
}
};

Expand Down
39 changes: 26 additions & 13 deletions include/swift/AST/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -5704,15 +5704,17 @@ const Type *ArchetypeType::getSubclassTrailingObjects() const {
///
/// \sa GenericTypeParamDecl
class GenericTypeParamType : public SubstitutableType {
static constexpr unsigned TYPE_SEQUENCE_BIT = (1 << 30);

using DepthIndexTy = llvm::PointerEmbeddedInt<unsigned, 31>;

/// The generic type parameter or depth/index.
llvm::PointerUnion<GenericTypeParamDecl *, DepthIndexTy> ParamOrDepthIndex;

public:
/// Retrieve a generic type parameter at the given depth and index.
static GenericTypeParamType *get(unsigned depth, unsigned index,
const ASTContext &ctx);
static GenericTypeParamType *get(bool isTypeSequence, unsigned depth,
unsigned index, const ASTContext &ctx);

/// Retrieve the declaration of the generic type parameter, or null if
/// there is no such declaration.
Expand Down Expand Up @@ -5747,6 +5749,15 @@ class GenericTypeParamType : public SubstitutableType {
/// Here 'T' and 'U' have indexes 0 and 1, respectively. 'V' has index 0.
unsigned getIndex() const;

/// Returns \c true if this generic type parameter is declared as a type
/// sequence.
///
/// \code
/// func foo<@_typeSequence T>(_ : T...) { }
/// struct Foo<@_typeSequence T> { }
/// \encode
bool isTypeSequence() const;

// Implement isa/cast/dyncast/etc.
static bool classof(const TypeBase *T) {
return T->getKind() == TypeKind::GenericTypeParam;
Expand All @@ -5760,18 +5771,19 @@ class GenericTypeParamType : public SubstitutableType {
RecursiveTypeProperties::HasTypeParameter),
ParamOrDepthIndex(param) { }

explicit GenericTypeParamType(unsigned depth,
unsigned index,
const ASTContext &ctx)
: SubstitutableType(TypeKind::GenericTypeParam, &ctx,
RecursiveTypeProperties::HasTypeParameter),
ParamOrDepthIndex(depth << 16 | index) { }
explicit GenericTypeParamType(bool isTypeSequence, unsigned depth,
unsigned index, const ASTContext &ctx)
: SubstitutableType(TypeKind::GenericTypeParam, &ctx,
RecursiveTypeProperties::HasTypeParameter),
ParamOrDepthIndex(depth << 16 | index |
((isTypeSequence ? 1 : 0) << 30)) {}
};
BEGIN_CAN_TYPE_WRAPPER(GenericTypeParamType, SubstitutableType)
static CanGenericTypeParamType get(unsigned depth, unsigned index,
const ASTContext &C) {
return CanGenericTypeParamType(GenericTypeParamType::get(depth, index, C));
}
static CanGenericTypeParamType get(bool isTypeSequence, unsigned depth,
unsigned index, const ASTContext &C) {
return CanGenericTypeParamType(
GenericTypeParamType::get(isTypeSequence, depth, index, C));
}
END_CAN_TYPE_WRAPPER(GenericTypeParamType, SubstitutableType)

/// A type that refers to a member type of some type that is dependent on a
Expand Down Expand Up @@ -6323,7 +6335,8 @@ constexpr bool TypeBase::isSugaredType<id##Type>() { \
#include "swift/AST/TypeNodes.def"

inline GenericParamKey::GenericParamKey(const GenericTypeParamType *p)
: Depth(p->getDepth()), Index(p->getIndex()) { }
: TypeSequence(p->isTypeSequence()), Depth(p->getDepth()),
Index(p->getIndex()) {}

inline TypeBase *TypeBase::getDesugaredType() {
if (!isa<SugarType>(this))
Expand Down
28 changes: 18 additions & 10 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3704,15 +3704,17 @@ GenericFunctionType::GenericFunctionType(
}
}

GenericTypeParamType *GenericTypeParamType::get(unsigned depth, unsigned index,
GenericTypeParamType *GenericTypeParamType::get(bool isTypeSequence,
unsigned depth, unsigned index,
const ASTContext &ctx) {
auto known = ctx.getImpl().GenericParamTypes.find({ depth, index });
const auto depthKey = depth | ((isTypeSequence ? 1 : 0) << 30);
auto known = ctx.getImpl().GenericParamTypes.find({depthKey, index});
if (known != ctx.getImpl().GenericParamTypes.end())
return known->second;

auto result = new (ctx, AllocationArena::Permanent)
GenericTypeParamType(depth, index, ctx);
ctx.getImpl().GenericParamTypes[{depth, index}] = result;
GenericTypeParamType(isTypeSequence, depth, index, ctx);
ctx.getImpl().GenericParamTypes[{depthKey, index}] = result;
return result;
}

Expand Down Expand Up @@ -4366,8 +4368,10 @@ CanOpenedArchetypeType OpenedArchetypeType::get(Type existential,
::new (mem) OpenedArchetypeType(ctx, existential,
protos, layoutSuperclass,
layoutConstraint, *knownID);
result->InterfaceType = GenericTypeParamType::get(0, 0, ctx);

result->InterfaceType =
GenericTypeParamType::get(/*type sequence*/ false,
/*depth*/ 0, /*index*/ 0, ctx);

openedExistentialArchetypes[*knownID] = result;
return CanOpenedArchetypeType(result);
}
Expand Down Expand Up @@ -5011,8 +5015,9 @@ ASTContext::getClangTypeForIRGen(Type ty) {
CanGenericSignature ASTContext::getSingleGenericParameterSignature() const {
if (auto theSig = getImpl().SingleGenericParameterSignature)
return theSig;

auto param = GenericTypeParamType::get(0, 0, *this);

auto param = GenericTypeParamType::get(/*type sequence*/ false,
/*depth*/ 0, /*index*/ 0, *this);
auto sig = GenericSignature::get(param, { });
auto canonicalSig = CanGenericSignature(sig);
getImpl().SingleGenericParameterSignature = canonicalSig;
Expand Down Expand Up @@ -5041,7 +5046,9 @@ CanGenericSignature ASTContext::getOpenedArchetypeSignature(Type type) {
if (found != getImpl().ExistentialSignatures.end())
return found->second;

auto genericParam = GenericTypeParamType::get(0, 0, *this);
auto genericParam =
GenericTypeParamType::get(/*type sequence*/ false,
/*depth*/ 0, /*index*/ 0, *this);
Requirement requirement(RequirementKind::Conformance, genericParam,
existential);
auto genericSig = buildGenericSignature(*this,
Expand Down Expand Up @@ -5126,7 +5133,8 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
}

return CanGenericTypeParamType::get(
gp->getDepth() - baseDepth + derivedDepth, gp->getIndex(), *this);
gp->isTypeSequence(), gp->getDepth() - baseDepth + derivedDepth,
gp->getIndex(), *this);
};

auto lookupConformanceFn =
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTDemangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ Type ASTBuilder::createMetatypeType(Type instance,

Type ASTBuilder::createGenericTypeParameterType(unsigned depth,
unsigned index) {
return GenericTypeParamType::get(depth, index, Ctx);
return GenericTypeParamType::get(/*type sequence*/ false, depth, index, Ctx);
}

Type ASTBuilder::createDependentMemberType(StringRef member,
Expand Down
6 changes: 3 additions & 3 deletions lib/AST/Builtins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ static GenericTypeParamDecl*
createGenericParam(ASTContext &ctx, const char *name, unsigned index) {
ModuleDecl *M = ctx.TheBuiltinModule;
Identifier ident = ctx.getIdentifier(name);
auto genericParam =
new (ctx) GenericTypeParamDecl(&M->getMainFile(FileUnitKind::Builtin),
ident, SourceLoc(), 0, index);
auto genericParam = new (ctx) GenericTypeParamDecl(
&M->getMainFile(FileUnitKind::Builtin), ident, SourceLoc(),
/*type sequence*/ false, 0, index);
return genericParam;
}

Expand Down
6 changes: 4 additions & 2 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4043,12 +4043,14 @@ AbstractTypeParamDecl::getConformingProtocols() const {

GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
SourceLoc nameLoc,
unsigned depth, unsigned index)
: AbstractTypeParamDecl(DeclKind::GenericTypeParam, dc, name, nameLoc) {
bool isTypeSequence, unsigned depth,
unsigned index)
: AbstractTypeParamDecl(DeclKind::GenericTypeParam, dc, name, nameLoc) {
Bits.GenericTypeParamDecl.Depth = depth;
assert(Bits.GenericTypeParamDecl.Depth == depth && "Truncation");
Bits.GenericTypeParamDecl.Index = index;
assert(Bits.GenericTypeParamDecl.Index == index && "Truncation");
Bits.GenericTypeParamDecl.TypeSequence = isTypeSequence;
auto &ctx = dc->getASTContext();
auto type = new (ctx, AllocationArena::Permanent) GenericTypeParamType(this);
setInterfaceType(MetatypeType::get(type, ctx));
Expand Down
5 changes: 2 additions & 3 deletions lib/AST/GenericParamList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ GenericParamList::clone(DeclContext *dc) const {
SmallVector<GenericTypeParamDecl *, 2> params;
for (auto param : getParams()) {
auto *newParam = new (ctx) GenericTypeParamDecl(
dc, param->getName(), SourceLoc(),
GenericTypeParamDecl::InvalidDepth,
param->getIndex());
dc, param->getName(), SourceLoc(), param->isTypeSequence(),
GenericTypeParamDecl::InvalidDepth, param->getIndex());
newParam->setImplicit(true);
params.push_back(newParam);
}
Expand Down
23 changes: 11 additions & 12 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,9 +2816,9 @@ static Type formDependentType(GenericTypeParamType *base,
/// parameter key, then following the path of associated types.
static Type formDependentType(ASTContext &ctx, GenericParamKey genericParam,
RelativeRewritePath path) {
return formDependentType(GenericTypeParamType::get(genericParam.Depth,
genericParam.Index,
ctx),
return formDependentType(GenericTypeParamType::get(genericParam.TypeSequence,
genericParam.Depth,
genericParam.Index, ctx),
path);
}

Expand Down Expand Up @@ -3306,9 +3306,9 @@ bool GenericSignatureBuilder::addSameTypeRewriteRule(CanType type1,
}

// Add the rewrite rule.
Type firstBase =
GenericTypeParamType::get(path1.getBase()->Depth, path1.getBase()->Index,
getASTContext());
Type firstBase = GenericTypeParamType::get(
path1.getBase()->TypeSequence, path1.getBase()->Depth,
path1.getBase()->Index, getASTContext());
CanType baseAnchor =
getCanonicalTypeParameter(firstBase)->getCanonicalType();
auto root = Impl->getOrCreateRewriteTreeRoot(baseAnchor);
Expand All @@ -3317,10 +3317,9 @@ bool GenericSignatureBuilder::addSameTypeRewriteRule(CanType type1,

Type GenericSignatureBuilder::getCanonicalTypeParameter(Type type) {
auto initialPath = RewritePath::createPath(type);
auto genericParamType =
GenericTypeParamType::get(initialPath.getBase()->Depth,
initialPath.getBase()->Index,
getASTContext());
auto genericParamType = GenericTypeParamType::get(
initialPath.getBase()->TypeSequence, initialPath.getBase()->Depth,
initialPath.getBase()->Index, getASTContext());

unsigned startIndex = 0;
Type currentType = genericParamType;
Expand Down Expand Up @@ -3357,8 +3356,8 @@ Type GenericSignatureBuilder::getCanonicalTypeParameter(Type type) {
// If this is an absolute path, use the new base.
if (auto newBase = match->second.getBase()) {
genericParamType =
GenericTypeParamType::get(newBase->Depth, newBase->Index,
getASTContext());
GenericTypeParamType::get(newBase->TypeSequence, newBase->Depth,
newBase->Index, getASTContext());
}

// Move back to the beginning; we may have opened up other rewrites.
Expand Down
3 changes: 2 additions & 1 deletion lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,8 @@ static ProtocolConformanceRef getBuiltinTupleTypeConformance(
SmallVector<TupleTypeElt, 4> genericElements;
SmallVector<Requirement, 4> conditionalRequirements;
for (const auto &elt : tupleType->getElements()) {
auto genericParam = GenericTypeParamType::get(0, genericParams.size(), ctx);
auto genericParam = GenericTypeParamType::get(/*type sequence*/ false, 0,
genericParams.size(), ctx);
genericParams.push_back(genericParam);
typeSubstitutions.push_back(elt.getRawType());
genericElements.push_back(elt.getWithType(genericParam));
Expand Down
5 changes: 3 additions & 2 deletions lib/AST/NameLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2566,8 +2566,9 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
// The generic parameter 'Self'.
auto &ctx = value->getASTContext();
auto selfId = ctx.Id_Self;
auto selfDecl = new (ctx) GenericTypeParamDecl(
proto, selfId, SourceLoc(), /*depth=*/0, /*index=*/0);
auto selfDecl = new (ctx)
GenericTypeParamDecl(proto, selfId, SourceLoc(),
/*type sequence=*/false, /*depth=*/0, /*index=*/0);
auto protoType = proto->getDeclaredInterfaceType();
InheritedEntry selfInherited[1] = {
InheritedEntry(TypeLoc::withoutLoc(protoType)) };
Expand Down
Loading