Skip to content

Commit fba3130

Browse files
committed
Add default types to generic parameters
Update ASTPrinter.cpp
1 parent 6e6dc4b commit fba3130

26 files changed

+422
-35
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2893,12 +2893,13 @@ BridgedGenericParamList BridgedGenericParamList_createParsed(
28932893

28942894
SWIFT_NAME(
28952895
"BridgedGenericTypeParamDecl.createParsed(_:declContext:specifierLoc:"
2896-
"name:nameLoc:inheritedType:index:paramKind:)")
2896+
"name:nameLoc:inheritedType:defaultType:index:paramKind:)")
28972897
BridgedGenericTypeParamDecl BridgedGenericTypeParamDecl_createParsed(
28982898
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
28992899
swift::SourceLoc specifierLoc, swift::Identifier name,
29002900
swift::SourceLoc nameLoc, BridgedNullableTypeRepr opaqueInheritedType,
2901-
size_t index, swift::GenericTypeParamKind paramKind);
2901+
BridgedNullableTypeRepr defaultType, size_t index,
2902+
swift::GenericTypeParamKind paramKind);
29022903

29032904
SWIFT_NAME(
29042905
"BridgedTrailingWhereClause.createParsed(_:whereKeywordLoc:requirements:)")

include/swift/AST/Decl.h

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,10 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
625625
ParamKind : 3,
626626

627627
/// Whether this generic parameter represents an opaque type.
628-
IsOpaqueType : 1
628+
IsOpaqueType : 1,
629+
630+
/// Whether we have computed the default type.
631+
IsDefaultTypeComputed : 1
629632
);
630633

631634
SWIFT_INLINE_BITFIELD_FULL(AssociatedTypeDecl, TypeDecl, 1,
@@ -3888,6 +3891,10 @@ class GenericTypeParamDecl final
38883891
: public TypeDecl,
38893892
private llvm::TrailingObjects<GenericTypeParamDecl, TypeRepr *,
38903893
SourceLoc> {
3894+
// The default type.
3895+
TypeLoc DefaultType;
3896+
3897+
friend class GenericTypeParamDeclDefaultTypeRequest;
38913898
friend TrailingObjects;
38923899

38933900
size_t numTrailingObjects(OverloadToken<TypeRepr *>) const {
@@ -3902,6 +3909,9 @@ class GenericTypeParamDecl final
39023909
return 0;
39033910
}
39043911

3912+
/// Set the computed default type.
3913+
void setDefaultType(Type ty);
3914+
39053915
/// Construct a new generic type parameter.
39063916
///
39073917
/// \param dc The DeclContext in which the generic type parameter's owner
@@ -3920,7 +3930,8 @@ class GenericTypeParamDecl final
39203930
/// \param opaqueTypeRepr The TypeRepr of an opaque generic parameter.
39213931
///
39223932
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
3923-
SourceLoc specifierLoc, unsigned depth, unsigned index,
3933+
SourceLoc specifierLoc, TypeLoc defaultType,
3934+
unsigned depth, unsigned index,
39243935
GenericTypeParamKind paramKind, bool isOpaqueType,
39253936
TypeRepr *opaqueTypeRepr);
39263937

@@ -3943,6 +3954,7 @@ class GenericTypeParamDecl final
39433954
///
39443955
static GenericTypeParamDecl *create(DeclContext *dc, Identifier name,
39453956
SourceLoc nameLoc, SourceLoc specifierLoc,
3957+
TypeLoc defaultType,
39463958
unsigned depth, unsigned index,
39473959
GenericTypeParamKind paramKind,
39483960
bool isOpaqueType,
@@ -3956,8 +3968,8 @@ class GenericTypeParamDecl final
39563968
GenericTypeParamDecl(DeclContext *dc, Identifier name, SourceLoc nameLoc,
39573969
SourceLoc specifierLoc, unsigned depth, unsigned index,
39583970
GenericTypeParamKind paramKind)
3959-
: GenericTypeParamDecl(dc, name, nameLoc, specifierLoc, depth, index,
3960-
paramKind, false, nullptr) {
3971+
: GenericTypeParamDecl(dc, name, nameLoc, specifierLoc, TypeLoc(),
3972+
depth, index, paramKind, false, nullptr) {
39613973
}
39623974

39633975
/// Construct a deserialized generic type parameter.
@@ -3994,6 +4006,7 @@ class GenericTypeParamDecl final
39944006
static GenericTypeParamDecl *createParsed(DeclContext *dc, Identifier name,
39954007
SourceLoc nameLoc,
39964008
SourceLoc specifierLoc,
4009+
TypeLoc defaultType,
39974010
unsigned index,
39984011
GenericTypeParamKind paramKind);
39994012

@@ -4092,6 +4105,26 @@ class GenericTypeParamDecl final
40924105
return *getTrailingObjects<TypeRepr *>();
40934106
}
40944107

4108+
/// Check to see if we have a default type.
4109+
bool hasDefaultType() const {
4110+
// If we have a TypeRepr, return true immediately without kicking off
4111+
// a request.
4112+
return DefaultType.getTypeRepr() || getDefaultType();
4113+
}
4114+
4115+
/// Retrieve the default type as written in the source.
4116+
TypeRepr *getDefaultTypeRepr() const {
4117+
return DefaultType.getTypeRepr();
4118+
}
4119+
4120+
/// Retrieve the default type.
4121+
Type getDefaultType() const;
4122+
4123+
/// Retrieve the default type if computed, `None` otherwise.
4124+
///
4125+
/// \Note Should only be used for dumping.
4126+
std::optional<Type> getCachedDefaultType() const;
4127+
40954128
/// The index of this generic type parameter within its generic parameter
40964129
/// list.
40974130
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8905,5 +8905,19 @@ ERROR(invalid_redecl_of_file_isolation,none,
89058905
NOTE(invalid_redecl_of_file_isolation_prev,none,
89068906
"default isolation was previously declared here", ())
89078907

8908+
//===----------------------------------------------------------------------===//
8909+
// MARK: Default generics
8910+
//===----------------------------------------------------------------------===//
8911+
8912+
ERROR(default_generic_not_trailing,none,
8913+
"generic parameter %0 with default type %1 must be trailing",
8914+
(const GenericTypeParamDecl *, Type))
8915+
ERROR(default_generic_not_type,none,
8916+
"generic parameter %0 can only have a default type on type declarations",
8917+
(const GenericTypeParamDecl *))
8918+
ERROR(default_generic_parameter_pack,none,
8919+
"declaration %0 cannot have both parameter packs and generic parameters with default types",
8920+
(const Decl *))
8921+
89088922
#define UNDEFINE_DIAGNOSTIC_MACROS
89098923
#include "DefineDiagnosticMacros.h"

include/swift/AST/TypeCheckRequests.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5386,6 +5386,27 @@ class GenericTypeParamDeclGetValueTypeRequest
53865386
bool isCached() const { return true; }
53875387
};
53885388

5389+
/// Compute the default type of a generic type param.
5390+
class GenericTypeParamDeclDefaultTypeRequest
5391+
: public SimpleRequest<GenericTypeParamDeclDefaultTypeRequest,
5392+
Type(GenericTypeParamDecl *decl),
5393+
RequestFlags::SeparatelyCached> {
5394+
public:
5395+
using SimpleRequest::SimpleRequest;
5396+
5397+
private:
5398+
friend SimpleRequest;
5399+
5400+
// Evaluation.
5401+
Type evaluate(Evaluator &evaluator, GenericTypeParamDecl *decl) const;
5402+
5403+
public:
5404+
// Caching.
5405+
bool isCached() const { return true; }
5406+
std::optional<Type> getCachedResult() const;
5407+
void cacheResult(Type value) const;
5408+
};
5409+
53895410
class CustomDerivativesRequest
53905411
: public SimpleRequest<CustomDerivativesRequest,
53915412
evaluator::SideEffect(SourceFile *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,8 @@ SWIFT_REQUEST(TypeChecker, CustomDerivativesRequest,
635635

636636
SWIFT_REQUEST(TypeChecker, GenericTypeParamDeclGetValueTypeRequest,
637637
Type(const GenericTypeParamDecl *), Cached, NoLocationInfo)
638+
SWIFT_REQUEST(TypeChecker, GenericTypeParamDeclDefaultTypeRequest,
639+
Type(GenericTypeParamDecl *), SeparatelyCached, NoLocationInfo)
638640

639641
SWIFT_REQUEST(TypeChecker, SemanticAvailableAttrRequest,
640642
std::optional<SemanticAvailableAttr>

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,9 @@ EXPERIMENTAL_FEATURE(ImportMacroAliases, true)
548548
/// Enable borrow/mutate accessors
549549
EXPERIMENTAL_FEATURE(BorrowAndMutateAccessors, false)
550550

551+
/// Allow generics to have a default type, e.g. `<T = Int>`.
552+
EXPERIMENTAL_FEATURE(DefaultGenerics, false)
553+
551554
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
552555
#undef EXPERIMENTAL_FEATURE
553556
#undef UPCOMING_FEATURE

lib/AST/ASTDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,6 +2204,11 @@ namespace {
22042204
printRec(decl->getValueType(), Label::always("value_type"));
22052205
break;
22062206
}
2207+
2208+
if (decl->hasDefaultType()) {
2209+
printRec(decl->getDefaultType(), Label::always("default_type"));
2210+
}
2211+
22072212
printAttributes(decl);
22082213

22092214
printFoot();

lib/AST/ASTPrinter.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,11 @@ void PrintAST::printSingleDepthOfGenericSignature(
20222022
printType(param->getValueType());
20232023
}
20242024

2025+
if (GP->hasDefaultType()) {
2026+
Printer << " = ";
2027+
printType(GP->getDefaultType());
2028+
}
2029+
20252030
Printer.printStructurePost(PrintStructureKind::GenericParameter,
20262031
GP);
20272032
} else {
@@ -3660,6 +3665,11 @@ void PrintAST::visitGenericTypeParamDecl(GenericTypeParamDecl *decl) {
36603665
});
36613666

36623667
printInherited(decl);
3668+
3669+
if (decl->hasDefaultType()) {
3670+
Printer << " = ";
3671+
decl->getDefaultType().print(Printer, Options);
3672+
}
36633673
}
36643674

36653675
void PrintAST::visitAssociatedTypeDecl(AssociatedTypeDecl *decl) {
@@ -8376,17 +8386,7 @@ void GenericParamList::print(ASTPrinter &Printer,
83768386
interleave(
83778387
*this,
83788388
[&](const GenericTypeParamDecl *P) {
8379-
Printer << P->getName();
8380-
if (!P->getInherited().empty()) {
8381-
Printer << " : ";
8382-
8383-
auto loc = P->getInherited().getEntry(0);
8384-
if (willUseTypeReprPrinting(loc, nullptr, PO)) {
8385-
loc.getTypeRepr()->print(Printer, PO);
8386-
} else {
8387-
loc.getType()->print(Printer, PO);
8388-
}
8389-
}
8389+
P->print(Printer, PO);
83908390
},
83918391
[&] { Printer << ", "; });
83928392

lib/AST/Bridging/GenericsBridging.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,18 @@ BridgedGenericParamList BridgedGenericParamList_createParsed(
4545
BridgedGenericTypeParamDecl BridgedGenericTypeParamDecl_createParsed(
4646
BridgedASTContext cContext, BridgedDeclContext cDeclContext,
4747
SourceLoc specifierLoc, Identifier name, SourceLoc nameLoc,
48-
BridgedNullableTypeRepr bridgedInheritedType, size_t index,
48+
BridgedNullableTypeRepr bridgedInheritedType,
49+
BridgedNullableTypeRepr bridgedDefaultType, size_t index,
4950
swift::GenericTypeParamKind paramKind) {
51+
TypeLoc defaultType;
52+
53+
if (auto *defaultTypeRepr = bridgedDefaultType.unbridged()) {
54+
defaultType = TypeLoc(defaultTypeRepr);
55+
}
56+
5057
auto *decl = GenericTypeParamDecl::createParsed(
51-
cDeclContext.unbridged(), name, nameLoc, specifierLoc, index, paramKind);
58+
cDeclContext.unbridged(), name, nameLoc, specifierLoc, defaultType,
59+
index, paramKind);
5260

5361
if (auto *inheritedType = bridgedInheritedType.unbridged()) {
5462
auto entry = InheritedEntry(inheritedType);

lib/AST/Decl.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6088,11 +6088,13 @@ Type TypeAliasDecl::getStructuralType() const {
60886088
GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
60896089
SourceLoc nameLoc,
60906090
SourceLoc specifierLoc,
6091+
TypeLoc defaultType,
60916092
unsigned depth, unsigned index,
60926093
GenericTypeParamKind paramKind,
60936094
bool isOpaqueType,
60946095
TypeRepr *opaqueTypeRepr)
6095-
: TypeDecl(DeclKind::GenericTypeParam, dc, name, nameLoc, {}) {
6096+
: TypeDecl(DeclKind::GenericTypeParam, dc, name, nameLoc, {}),
6097+
DefaultType(defaultType) {
60966098
ASSERT(!(specifierLoc &&
60976099
!(paramKind == GenericTypeParamKind::Pack || paramKind == GenericTypeParamKind::Value)) &&
60986100
"'each' or 'let' keyword imply a parameter pack or value generic parameter");
@@ -6104,6 +6106,7 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
61046106
assert(Bits.GenericTypeParamDecl.Index == index && "Truncation");
61056107
Bits.GenericTypeParamDecl.ParamKind = (uint8_t) paramKind;
61066108
Bits.GenericTypeParamDecl.IsOpaqueType = isOpaqueType;
6109+
Bits.GenericTypeParamDecl.IsDefaultTypeComputed = false;
61076110

61086111
if (this->isOpaqueType())
61096112
*getTrailingObjects<TypeRepr *>() = opaqueTypeRepr;
@@ -6117,8 +6120,9 @@ GenericTypeParamDecl::GenericTypeParamDecl(DeclContext *dc, Identifier name,
61176120

61186121
GenericTypeParamDecl *GenericTypeParamDecl::create(
61196122
DeclContext *dc, Identifier name, SourceLoc nameLoc, SourceLoc specifierLoc,
6120-
unsigned depth, unsigned index, GenericTypeParamKind paramKind,
6121-
bool isOpaqueType, TypeRepr *opaqueTypeRepr) {
6123+
TypeLoc defaultType, unsigned depth, unsigned index,
6124+
GenericTypeParamKind paramKind, bool isOpaqueType,
6125+
TypeRepr *opaqueTypeRepr) {
61226126
auto &ctx = dc->getASTContext();
61236127

61246128
auto numTypeReprs = 0;
@@ -6136,37 +6140,39 @@ GenericTypeParamDecl *GenericTypeParamDecl::create(
61366140
numSourceLocs);
61376141
auto mem = ctx.Allocate(allocSize, alignof(GenericTypeParamDecl));
61386142
return new (mem)
6139-
GenericTypeParamDecl(dc, name, nameLoc, specifierLoc, depth, index,
6140-
paramKind, isOpaqueType, opaqueTypeRepr);
6143+
GenericTypeParamDecl(dc, name, nameLoc, specifierLoc, defaultType, depth,
6144+
index, paramKind, isOpaqueType, opaqueTypeRepr);
61416145
}
61426146

61436147
GenericTypeParamDecl *GenericTypeParamDecl::createDeserialized(
61446148
DeclContext *dc, Identifier name, unsigned depth, unsigned index,
61456149
GenericTypeParamKind paramKind, bool isOpaqueType) {
61466150
return GenericTypeParamDecl::create(dc, name, SourceLoc(), SourceLoc(),
6147-
depth, index, paramKind,
6151+
TypeLoc(), depth, index, paramKind,
61486152
isOpaqueType,
61496153
/*opaqueRepr*/ nullptr);
61506154
}
61516155

61526156
GenericTypeParamDecl *
61536157
GenericTypeParamDecl::createParsed(DeclContext *dc, Identifier name,
61546158
SourceLoc nameLoc, SourceLoc specifierLoc,
6155-
unsigned index,
6159+
TypeLoc defaultType, unsigned index,
61566160
GenericTypeParamKind paramKind) {
61576161
// We always create generic type parameters with an invalid depth.
61586162
// Semantic analysis fills in the depth when it processes the generic
61596163
// parameter list.
61606164
return GenericTypeParamDecl::create(
6161-
dc, name, nameLoc, specifierLoc, GenericTypeParamDecl::InvalidDepth,
6162-
index, paramKind, /*isOpaqueType*/ false, /*opaqueTypeRepr*/ nullptr);
6165+
dc, name, nameLoc, specifierLoc, defaultType,
6166+
GenericTypeParamDecl::InvalidDepth, index, paramKind,
6167+
/*isOpaqueType*/ false, /*opaqueTypeRepr*/ nullptr);
61636168
}
61646169

61656170
GenericTypeParamDecl *GenericTypeParamDecl::createImplicit(
61666171
DeclContext *dc, Identifier name, unsigned depth, unsigned index,
61676172
GenericTypeParamKind paramKind, TypeRepr *opaqueTypeRepr, SourceLoc nameLoc,
61686173
SourceLoc specifierLoc) {
61696174
auto *param = GenericTypeParamDecl::create(dc, name, nameLoc, specifierLoc,
6175+
TypeLoc(),
61706176
depth, index, paramKind,
61716177
(bool)opaqueTypeRepr,
61726178
opaqueTypeRepr);
@@ -6184,6 +6190,24 @@ Type GenericTypeParamDecl::getValueType() const {
61846190
return ty ? ty : ErrorType::get(ctx);
61856191
}
61866192

6193+
Type GenericTypeParamDecl::getDefaultType() const {
6194+
auto &ctx = getASTContext();
6195+
GenericTypeParamDeclDefaultTypeRequest req(const_cast<GenericTypeParamDecl *>(this));
6196+
return evaluateOrDefault(ctx.evaluator, req, Type());
6197+
}
6198+
6199+
std::optional<Type> GenericTypeParamDecl::getCachedDefaultType() const {
6200+
if (Bits.GenericTypeParamDecl.IsDefaultTypeComputed)
6201+
return DefaultType.getType();
6202+
6203+
return std::nullopt;
6204+
}
6205+
6206+
void GenericTypeParamDecl::setDefaultType(Type ty) {
6207+
DefaultType.setType(ty);
6208+
Bits.GenericTypeParamDecl.IsDefaultTypeComputed = true;
6209+
}
6210+
61876211
SourceRange GenericTypeParamDecl::getSourceRange() const {
61886212
auto startLoc = getNameLoc();
61896213
auto endLoc = getNameLoc();

0 commit comments

Comments
 (0)