Skip to content

Commit b9b6bb7

Browse files
slavapestovAzoy
authored andcommitted
AST: Introduce new kind of sugared GenericTypeParamType
This one just stores an identifier instead of a declaration.
1 parent 1ff1b94 commit b9b6bb7

File tree

8 files changed

+186
-107
lines changed

8 files changed

+186
-107
lines changed

include/swift/AST/Types.h

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "swift/AST/TypeAlignments.h"
3535
#include "swift/AST/TypeExpansionContext.h"
3636
#include "swift/Basic/ArrayRefView.h"
37+
#include "swift/Basic/Assertions.h"
3738
#include "swift/Basic/Debug.h"
3839
#include "swift/Basic/InlineBitfield.h"
3940
#include "swift/Basic/UUID.h"
@@ -562,6 +563,13 @@ class alignas(1 << TypeAlignInBits) TypeBase
562563
assert(Bits.TypeBase.Properties == properties.getBits() && "Bits dropped!");
563564
}
564565

566+
/// This is used when constructing GenericTypeParamTypes.
567+
void setCanonicalType(CanType type) {
568+
DEBUG_ASSERT(!Bits.TypeBase.IsCanonical);
569+
DEBUG_ASSERT(CanonicalType.isNull());
570+
CanonicalType = type;
571+
}
572+
565573
public:
566574
/// getKind - Return what kind of type this is.
567575
TypeKind getKind() const { return static_cast<TypeKind>(Bits.TypeBase.Kind); }
@@ -6966,12 +6974,17 @@ const Type *ArchetypeType::getSubclassTrailingObjects() const {
69666974
/// \sa GenericTypeParamDecl
69676975
class GenericTypeParamType : public SubstitutableType,
69686976
public llvm::FoldingSetNode {
6969-
static constexpr unsigned TYPE_SEQUENCE_BIT = (1 << 30);
6970-
6971-
using DepthIndexTy = llvm::PointerEmbeddedInt<unsigned, 31>;
6977+
/// A canonical generic parameter type is given by a depth, index, parameter
6978+
/// kind, and an optional value type. A sugared generic parameter type stores
6979+
/// a declaration or an identifier.
6980+
union {
6981+
GenericTypeParamDecl *Decl;
6982+
Identifier Name;
6983+
};
69726984

6973-
/// The generic type parameter or depth/index.
6974-
llvm::PointerUnion<GenericTypeParamDecl *, DepthIndexTy> ParamOrDepthIndex;
6985+
unsigned Depth : 15;
6986+
unsigned IsDecl : 1;
6987+
unsigned Index : 16;
69756988

69766989
/// The kind of generic type parameter this is.
69776990
GenericTypeParamKind ParamKind;
@@ -6984,39 +6997,44 @@ class GenericTypeParamType : public SubstitutableType,
69846997
Type ValueType;
69856998

69866999
public:
7000+
/// Retrieve a sugared generic type parameter type.
7001+
///
7002+
/// Note: This should only be called by the InterfaceTypeRequest.
7003+
static GenericTypeParamType *get(GenericTypeParamDecl *decl);
69877004

6988-
/// Retrieve a generic type parameter with the given kind, depth, index, and
6989-
/// optional value type.
7005+
/// Retrieve a sugared generic type parameter at the given depth and index.
7006+
static GenericTypeParamType *get(Identifier name,
7007+
GenericTypeParamKind paramKind,
7008+
unsigned depth, unsigned index,
7009+
Type valueType, const ASTContext &ctx);
7010+
7011+
/// Retrieve a canonical generic type parameter with the given kind, depth,
7012+
/// index, and optional value type.
69907013
static GenericTypeParamType *get(GenericTypeParamKind paramKind,
69917014
unsigned depth, unsigned index,
69927015
Type valueType, const ASTContext &ctx);
69937016

6994-
/// Retrieve a generic type parameter at the given depth and index.
7017+
/// Retrieve a canonical generic type parameter at the given depth and index.
69957018
static GenericTypeParamType *getType(unsigned depth, unsigned index,
69967019
const ASTContext &ctx);
69977020

6998-
/// Retrieve a generic parameter pack at the given depth and index.
7021+
/// Retrieve a canonical generic parameter pack at the given depth and index.
69997022
static GenericTypeParamType *getPack(unsigned depth, unsigned index,
70007023
const ASTContext &ctx);
70017024

7002-
/// Retrieve a generic value parameter at the given depth and index with the
7003-
/// given value type.
7025+
/// Retrieve a canonical generic value parameter at the given depth and index
7026+
/// with the given value type.
70047027
static GenericTypeParamType *getValue(unsigned depth, unsigned index,
70057028
Type valueType, const ASTContext &ctx);
70067029

7007-
/// Retrieve a generic type parameter for the given generic type param decl.
7008-
///
7009-
/// Note: This should only be called by the GenericTypeParamDecl constructor.
7010-
static GenericTypeParamType *get(GenericTypeParamDecl *param);
7011-
70127030
/// If this is an opaque parameter, return the declaration of the
70137031
/// parameter, otherwise null.
70147032
GenericTypeParamDecl *getOpaqueDecl() const;
70157033

70167034
/// Retrieve the declaration of the generic type parameter, or null if
70177035
/// there is no such declaration.
70187036
GenericTypeParamDecl *getDecl() const {
7019-
return ParamOrDepthIndex.dyn_cast<GenericTypeParamDecl *>();
7037+
return (IsDecl ? Decl : nullptr);
70207038
}
70217039

70227040
/// Retrieve the kind of generic type parameter this type is referencing.
@@ -7037,7 +7055,9 @@ class GenericTypeParamType : public SubstitutableType,
70377055
/// \endcode
70387056
///
70397057
/// Here 'T' has depth 0 and 'U' has depth 1. Both have index 0.
7040-
unsigned getDepth() const;
7058+
unsigned getDepth() const {
7059+
return Depth;
7060+
}
70417061

70427062
/// The index of this generic type parameter within its generic parameter
70437063
/// list.
@@ -7049,7 +7069,9 @@ class GenericTypeParamType : public SubstitutableType,
70497069
/// \endcode
70507070
///
70517071
/// Here 'T' and 'U' have indexes 0 and 1, respectively. 'V' has index 0.
7052-
unsigned getIndex() const;
7072+
unsigned getIndex() const {
7073+
return Index;
7074+
}
70537075

70547076
/// Returns \c true if this type parameter is declared as a pack.
70557077
///
@@ -7073,14 +7095,17 @@ class GenericTypeParamType : public SubstitutableType,
70737095
Type getValueType() const;
70747096

70757097
void Profile(llvm::FoldingSetNodeID &ID) {
7076-
Profile(ID, getParamKind(), getDepth(), getIndex(), getValueType());
7098+
Profile(ID, getParamKind(), getDepth(), getIndex(), getValueType(),
7099+
getName());
70777100
}
7078-
static void Profile(llvm::FoldingSetNodeID &ID, GenericTypeParamKind paramKind,
7079-
unsigned depth, unsigned index, Type valueType) {
7101+
static void Profile(llvm::FoldingSetNodeID &ID,
7102+
GenericTypeParamKind paramKind, unsigned depth,
7103+
unsigned index, Type valueType, Identifier name) {
70807104
ID.AddInteger((uint8_t)paramKind);
70817105
ID.AddInteger(depth);
70827106
ID.AddInteger(index);
70837107
ID.AddPointer(valueType.getPointer());
7108+
ID.AddPointer(name.get());
70847109
}
70857110

70867111
// Implement isa/cast/dyncast/etc.
@@ -7091,16 +7116,19 @@ class GenericTypeParamType : public SubstitutableType,
70917116
private:
70927117
friend class GenericTypeParamDecl;
70937118

7094-
explicit GenericTypeParamType(RecursiveTypeProperties props)
7095-
: SubstitutableType(TypeKind::GenericTypeParam, nullptr, props) {}
7119+
explicit GenericTypeParamType(GenericTypeParamDecl *param,
7120+
RecursiveTypeProperties props);
7121+
7122+
/// Note: We have no way to recover an ASTContext from an Identifier, so the
7123+
/// initialization of an identifier-sugared generic parameter type receives
7124+
/// the canonical type.
7125+
explicit GenericTypeParamType(Identifier name, GenericTypeParamType *canType,
7126+
const ASTContext &ctx);
70967127

7097-
explicit GenericTypeParamType(GenericTypeParamKind paramKind,
7098-
unsigned depth, unsigned index, Type valueType,
7128+
explicit GenericTypeParamType(GenericTypeParamKind paramKind, unsigned depth,
7129+
unsigned index, Type valueType,
70997130
RecursiveTypeProperties props,
7100-
const ASTContext &ctx)
7101-
: SubstitutableType(TypeKind::GenericTypeParam, &ctx, props),
7102-
ParamOrDepthIndex(depth << 16 | index),
7103-
ParamKind(paramKind), ValueType(valueType) {}
7131+
const ASTContext &ctx);
71047132
};
71057133
BEGIN_CAN_TYPE_WRAPPER(GenericTypeParamType, SubstitutableType)
71067134
static CanGenericTypeParamType getType(unsigned depth, unsigned index,

lib/AST/ASTContext.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4755,12 +4755,14 @@ GenericFunctionType::GenericFunctionType(
47554755
}
47564756
}
47574757

4758-
GenericTypeParamType *GenericTypeParamType::get(GenericTypeParamKind paramKind,
4758+
GenericTypeParamType *GenericTypeParamType::get(Identifier name,
4759+
GenericTypeParamKind paramKind,
47594760
unsigned depth, unsigned index,
47604761
Type valueType,
47614762
const ASTContext &ctx) {
47624763
llvm::FoldingSetNodeID id;
4763-
GenericTypeParamType::Profile(id, paramKind, depth, index, valueType);
4764+
GenericTypeParamType::Profile(id, paramKind, depth, index, valueType,
4765+
name);
47644766

47654767
void *insertPos;
47664768
if (auto gpTy = ctx.getImpl().GenericParamTypes.FindNodeOrInsertPos(id, insertPos))
@@ -4776,6 +4778,23 @@ GenericTypeParamType *GenericTypeParamType::get(GenericTypeParamKind paramKind,
47764778
return result;
47774779
}
47784780

4781+
GenericTypeParamType *GenericTypeParamType::get(GenericTypeParamDecl *param) {
4782+
RecursiveTypeProperties props = RecursiveTypeProperties::HasTypeParameter;
4783+
if (param->isParameterPack())
4784+
props |= RecursiveTypeProperties::HasParameterPack;
4785+
4786+
return new (param->getASTContext(), AllocationArena::Permanent)
4787+
GenericTypeParamType(param, props);
4788+
}
4789+
4790+
GenericTypeParamType *GenericTypeParamType::get(GenericTypeParamKind paramKind,
4791+
unsigned depth, unsigned index,
4792+
Type valueType,
4793+
const ASTContext &ctx) {
4794+
return GenericTypeParamType::get(Identifier(), paramKind, depth, index,
4795+
valueType, ctx);
4796+
}
4797+
47794798
GenericTypeParamType *GenericTypeParamType::getType(unsigned depth,
47804799
unsigned index,
47814800
const ASTContext &ctx) {

lib/AST/Decl.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5670,10 +5670,6 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
56705670

56715671
if (this->isValue())
56725672
*getTrailingObjects<SourceLoc>() = specifierLoc;
5673-
5674-
auto &ctx = dc->getASTContext();
5675-
auto type = GenericTypeParamType::get(this);
5676-
setInterfaceType(MetatypeType::get(type, ctx));
56775673
}
56785674

56795675
GenericTypeParamDecl *GenericTypeParamDecl::create(

lib/AST/Type.cpp

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,21 +1663,11 @@ CanType TypeBase::computeCanonicalType() {
16631663
case TypeKind::GenericTypeParam: {
16641664
GenericTypeParamType *gp = cast<GenericTypeParamType>(this);
16651665
auto gpDecl = gp->getDecl();
1666-
1667-
// If we haven't set a depth for this generic parameter, try to do so.
1668-
// FIXME: This is a dreadful hack.
1669-
if (gpDecl->getDepth() == GenericTypeParamDecl::InvalidDepth) {
1670-
auto *dc = gpDecl->getDeclContext();
1671-
auto *gpList = dc->getAsDecl()->getAsGenericContext()->getGenericParams();
1672-
gpList->setDepth(dc->getGenericContextDepth());
1673-
}
1674-
1675-
assert(gpDecl->getDepth() != GenericTypeParamDecl::InvalidDepth &&
1676-
"parameter hasn't been validated");
1666+
auto &C = gpDecl->getASTContext();
16771667
Result =
1678-
GenericTypeParamType::get(gpDecl->getParamKind(), gpDecl->getDepth(),
1679-
gpDecl->getIndex(), gpDecl->getValueType(),
1680-
gpDecl->getASTContext());
1668+
GenericTypeParamType::get(gp->getParamKind(), gp->getDepth(),
1669+
gp->getIndex(), gp->getValueType(),
1670+
C);
16811671
break;
16821672
}
16831673

@@ -1986,35 +1976,46 @@ ArrayRef<Type> TypeAliasType::getDirectGenericArgs() const {
19861976
return getSubstitutionMap().getInnermostReplacementTypes();
19871977
}
19881978

1989-
GenericTypeParamType *GenericTypeParamType::get(GenericTypeParamDecl *param) {
1990-
auto &ctx = param->getASTContext();
1991-
1992-
RecursiveTypeProperties props = RecursiveTypeProperties::HasTypeParameter;
1993-
if (param->isParameterPack())
1994-
props |= RecursiveTypeProperties::HasParameterPack;
1995-
1996-
auto type = new (ctx, AllocationArena::Permanent) GenericTypeParamType(props);
1997-
type->ParamOrDepthIndex = param;
1998-
type->ParamKind = param->getParamKind();
1999-
return type;
2000-
}
2001-
2002-
unsigned GenericTypeParamType::getDepth() const {
2003-
if (auto param = getDecl()) {
2004-
return param->getDepth();
2005-
}
2006-
2007-
auto fixedNum = ParamOrDepthIndex.get<DepthIndexTy>();
2008-
return (fixedNum & ~GenericTypeParamType::TYPE_SEQUENCE_BIT) >> 16;
2009-
}
2010-
2011-
unsigned GenericTypeParamType::getIndex() const {
2012-
if (auto param = getDecl()) {
2013-
return param->getIndex();
2014-
}
2015-
2016-
auto fixedNum = ParamOrDepthIndex.get<DepthIndexTy>();
2017-
return fixedNum & 0xFFFF;
1979+
GenericTypeParamType::GenericTypeParamType(GenericTypeParamDecl *param,
1980+
RecursiveTypeProperties props)
1981+
: SubstitutableType(TypeKind::GenericTypeParam, nullptr, props),
1982+
Decl(param) {
1983+
ASSERT(param->getDepth() != GenericTypeParamDecl::InvalidDepth);
1984+
Depth = param->getDepth();
1985+
IsDecl = true;
1986+
Index = param->getIndex();
1987+
ParamKind = param->getParamKind();
1988+
ValueType = param->getValueType();
1989+
}
1990+
1991+
GenericTypeParamType::GenericTypeParamType(Identifier name,
1992+
GenericTypeParamType *canType,
1993+
const ASTContext &ctx)
1994+
: SubstitutableType(TypeKind::GenericTypeParam, nullptr,
1995+
canType->getRecursiveProperties()),
1996+
Decl(nullptr) {
1997+
Name = name;
1998+
Depth = canType->getDepth();
1999+
IsDecl = false;
2000+
Index = canType->getIndex();
2001+
ParamKind = canType->getParamKind();
2002+
ValueType = canType->getValueType();
2003+
2004+
setCanonicalType(CanType(canType));
2005+
}
2006+
2007+
GenericTypeParamType::GenericTypeParamType(GenericTypeParamKind paramKind,
2008+
unsigned depth, unsigned index,
2009+
Type valueType,
2010+
RecursiveTypeProperties props,
2011+
const ASTContext &ctx)
2012+
: SubstitutableType(TypeKind::GenericTypeParam, &ctx, props),
2013+
Decl(nullptr) {
2014+
Depth = depth;
2015+
IsDecl = false;
2016+
Index = index;
2017+
ParamKind = paramKind;
2018+
ValueType = valueType;
20182019
}
20192020

20202021
GenericTypeParamDecl *GenericTypeParamType::getOpaqueDecl() const {
@@ -2028,14 +2029,19 @@ Identifier GenericTypeParamType::getName() const {
20282029
// Use the declaration name if we still have that sugar.
20292030
if (auto decl = getDecl())
20302031
return decl->getName();
2031-
2032+
2033+
if (!isCanonical())
2034+
return Name;
2035+
20322036
// Otherwise, we're canonical. Produce an anonymous '<tau>_n_n' name.
2033-
assert(isCanonical());
2037+
20342038
// getASTContext() doesn't actually mutate an already-canonical type.
20352039
auto &C = const_cast<GenericTypeParamType*>(this)->getASTContext();
20362040
auto &names = C.CanonicalGenericTypeParamTypeNames;
2037-
unsigned depthIndex = ParamOrDepthIndex.get<DepthIndexTy>();
2038-
auto cached = names.find(depthIndex);
2041+
2042+
auto key = (getDepth() << 16) | getIndex();
2043+
2044+
auto cached = names.find(key);
20392045
if (cached != names.end())
20402046
return cached->second;
20412047

@@ -2046,7 +2052,7 @@ Identifier GenericTypeParamType::getName() const {
20462052

20472053
os << tau << getDepth() << '_' << getIndex();
20482054
Identifier name = C.getIdentifier(os.str());
2049-
names.insert({depthIndex, name});
2055+
names.insert({key, name});
20502056
return name;
20512057
}
20522058

lib/Sema/TypeCheckDecl.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2418,11 +2418,24 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const {
24182418
case DeclKind::MissingMember:
24192419
case DeclKind::Module:
24202420
case DeclKind::OpaqueType:
2421-
case DeclKind::GenericTypeParam:
24222421
case DeclKind::MacroExpansion:
24232422
llvm_unreachable("should not get here");
24242423
return Type();
24252424

2425+
case DeclKind::GenericTypeParam: {
2426+
auto *paramDecl = cast<GenericTypeParamDecl>(D);
2427+
2428+
// If we haven't set a depth for this generic parameter yet, do so.
2429+
if (paramDecl->getDepth() == GenericTypeParamDecl::InvalidDepth) {
2430+
auto *dc = paramDecl->getDeclContext();
2431+
auto *gpList = dc->getAsDecl()->getAsGenericContext()->getGenericParams();
2432+
gpList->setDepth(dc->getGenericContextDepth());
2433+
}
2434+
2435+
auto type = GenericTypeParamType::get(paramDecl);
2436+
return MetatypeType::get(type, Context);
2437+
}
2438+
24262439
case DeclKind::AssociatedType: {
24272440
auto assocType = cast<AssociatedTypeDecl>(D);
24282441
auto interfaceTy = assocType->getDeclaredInterfaceType();

0 commit comments

Comments
 (0)