Skip to content

Commit e0f2b81

Browse files
committed
Add serialization and parser tests for SIL
1 parent 4f07c06 commit e0f2b81

File tree

13 files changed

+116
-34
lines changed

13 files changed

+116
-34
lines changed

docs/SIL.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7762,6 +7762,20 @@ element value operand is the projected element type of the pack element
77627762
and must be structurally well-typed for the given index and pack type;
77637763
see the structural type matching rules for pack indices.
77647764

7765+
Value Generics
7766+
~~~~~~~~~~~~~~~~~
7767+
7768+
type_value
7769+
```````````
7770+
7771+
::
7772+
7773+
sil-instruction ::= 'type_value' sil-type 'for' sil-identifier
7774+
7775+
Produce the dynamic value of the given value generic, which must be a formal
7776+
value generic type. The value of the instruction has the type of whatever the
7777+
underlying value generic's type is. For right now that is limited to ``Int``.
7778+
77657779
Unchecked Conversions
77667780
~~~~~~~~~~~~~~~~~~~~~
77677781

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8023,7 +8023,7 @@ ERROR(integer_type_not_accepted,none,
80238023
ERROR(value_generic_unexpected,none,
80248024
"using value generic %0 here is not allowed", (Type))
80258025
ERROR(missing_value_generic_type,none,
8026-
"value generic 'let %0' must have an explicit value type declared", (Identifier))
8026+
"value generic %0 must have an explicit value type declared", (Identifier))
80278027

80288028
#define UNDEFINE_DIAGNOSTIC_MACROS
80298029
#include "DefineDiagnosticMacros.h"

lib/AST/ASTDumper.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,19 @@ namespace {
11761176
printCommon(decl, "generic_type_param", label);
11771177
printField(decl->getDepth(), "depth");
11781178
printField(decl->getIndex(), "index");
1179+
1180+
switch (decl->getParamKind()) {
1181+
case GenericTypeParamKind::Type:
1182+
printField((StringRef)"type", "param_kind");
1183+
break;
1184+
case GenericTypeParamKind::Pack:
1185+
printField((StringRef)"pack", "param_kind");
1186+
break;
1187+
case GenericTypeParamKind::Value:
1188+
printField((StringRef)"value", "param_kind");
1189+
break;
1190+
}
1191+
11791192
printFoot();
11801193
}
11811194

@@ -4282,10 +4295,18 @@ namespace {
42824295
printField(T->getIndex(), "index");
42834296
if (!T->isCanonical())
42844297
printFieldQuoted(T->getName(), "name");
4285-
printFlag(T->isParameterPack(), "pack");
42864298

4287-
if (T->isValue())
4288-
printRec(T->getValueType(), "value");
4299+
switch (T->getParamKind()) {
4300+
case GenericTypeParamKind::Type:
4301+
printField((StringRef)"type", "param_kind");
4302+
break;
4303+
case GenericTypeParamKind::Pack:
4304+
printField((StringRef)"pack", "param_kind");
4305+
break;
4306+
case GenericTypeParamKind::Value:
4307+
printField((StringRef)"value", "param_kind");
4308+
printRec(T->getValueType(), "value_type");
4309+
}
42894310

42904311
printFoot();
42914312
}

lib/AST/ASTPrinter.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,10 +1855,24 @@ void PrintAST::printSingleDepthOfGenericSignature(
18551855
GP);
18561856
Printer.printName(GP->getName(),
18571857
PrintNameContext::GenericParameter);
1858+
1859+
if (param->isValue()) {
1860+
Printer << " : ";
1861+
printType(param->getValueType());
1862+
}
1863+
18581864
Printer.printStructurePost(PrintStructureKind::GenericParameter,
18591865
GP);
18601866
} else {
1867+
if (param->isValue())
1868+
Printer << "let ";
1869+
18611870
printType(param);
1871+
1872+
if (param->isValue()) {
1873+
Printer << " : ";
1874+
printType(param->getValueType());
1875+
}
18621876
}
18631877
},
18641878
[&] { Printer << ", "; });
@@ -7173,7 +7187,6 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
71737187
void visitGenericTypeParamType(GenericTypeParamType *T) {
71747188
auto printPrefix = [&]{
71757189
if (T->isParameterPack()) printEach();
7176-
if (T->isValue()) printLet();
71777190
};
71787191

71797192
if (T->isCanonical()) {

lib/AST/Requirement.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ CheckRequirementResult Requirement::checkRequirement(
154154
return CheckRequirementResult::Success;
155155
}
156156

157-
case RequirementKind::Superclass: {
157+
case RequirementKind::Superclass:
158158
if (auto packType = firstType->getAs<PackType>()) {
159159
return expandPackRequirement(packType);
160160
}
@@ -163,23 +163,20 @@ CheckRequirementResult Requirement::checkRequirement(
163163
return CheckRequirementResult::Success;
164164

165165
return CheckRequirementResult::RequirementFailure;
166-
}
167166

168-
case RequirementKind::SameType: {
167+
case RequirementKind::SameType:
169168
if (firstType->isEqual(getSecondType()))
170169
return CheckRequirementResult::Success;
171170

172171
return CheckRequirementResult::RequirementFailure;
173-
}
174172

175-
case RequirementKind::SameShape: {
173+
case RequirementKind::SameShape:
176174
if (firstType->getReducedShape() ==
177175
getSecondType()->getReducedShape())
178176
return CheckRequirementResult::Success;
179177

180178
return CheckRequirementResult::RequirementFailure;
181179
}
182-
}
183180

184181
llvm_unreachable("Bad requirement kind");
185182
}
@@ -253,13 +250,11 @@ int Requirement::compare(const Requirement &other) const {
253250
abort();
254251
}
255252

256-
auto decl1 = getProtocolDecl();
257-
auto decl2 = other.getProtocolDecl();
258-
259-
int compareDecls = TypeDecl::compare(decl1, decl2);
260-
assert(compareDecls != 0 && "Duplicate decl requirements");
253+
int compareProtos =
254+
TypeDecl::compare(getProtocolDecl(), other.getProtocolDecl());
255+
assert(compareProtos != 0 && "Duplicate conformance requirements");
261256

262-
return compareDecls;
257+
return compareProtos;
263258
}
264259

265260
static std::optional<CheckRequirementsResult>

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3097,7 +3097,6 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
30973097
CanType paramType;
30983098
if (parseSILType(Ty) ||
30993099
parseVerbatim("for") ||
3100-
P.parseToken(tok::sil_dollar, diag::expected_tok_in_sil_instr, "$") ||
31013100
parseASTType(paramType))
31023101
return true;
31033102

lib/Sema/TypeCheckType.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4942,12 +4942,13 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
49424942
result = applyNonEscapingIfNecessary(result, options);
49434943

49444944
// Referencing a value generic by name, e.g. 'let N' and referencing 'N', is
4945-
// only valid as a generic argument, in generic requirements, and when being
4946-
// used as an expression.
4945+
// only valid as a generic argument, in generic requirements, when being
4946+
// used as an expression, and in SIL mode.
49474947
if (result->isValueParameter() &&
49484948
!(options.isGenericArgument() ||
49494949
options.isGenericRequirement() ||
4950-
options.isAnyExpr())) {
4950+
options.isAnyExpr() ||
4951+
options.contains(TypeResolutionFlags::SILMode))) {
49514952
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
49524953
diagnose(repr->getNameLoc(), diag::value_generic_unexpected, result);
49534954
}

lib/Serialization/Deserialization.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,16 @@ ModuleFile::getGenericSignatureChecked(serialization::GenericSignatureID ID) {
15981598
auto *paramDecl = GenericTypeParamDecl::createDeserialized(
15991599
getAssociatedModule(), name, paramTy->getDepth(),
16001600
paramTy->getIndex(), paramTy->getParamKind());
1601+
1602+
// If we're dealing with a value generic, the parameter type already
1603+
// serializes the value type. Inform the request evaluator that we don't
1604+
// need to recompute this value for the param decl.
1605+
if (paramTy->isValue()) {
1606+
paramDecl->getASTContext().evaluator.cacheOutput(
1607+
GenericTypeParamDeclGetValueTypeRequest{paramDecl},
1608+
paramTy->getValueType());
1609+
}
1610+
16011611
paramTy = paramDecl->getDeclaredInterfaceType()
16021612
->castTo<GenericTypeParamType>();
16031613
}
@@ -3466,27 +3476,37 @@ class DeclDeserializer {
34663476
StringRef blobData) {
34673477
IdentifierID nameID;
34683478
bool isImplicit;
3469-
unsigned rawParamKind;
3470-
unsigned depth;
3471-
unsigned index;
3479+
TypeID interfaceTypeID;
34723480

34733481
decls_block::GenericTypeParamDeclLayout::readRecord(
3474-
scratch, nameID, isImplicit, rawParamKind, depth, index);
3482+
scratch, nameID, isImplicit, interfaceTypeID);
34753483

3476-
auto paramKind = getActualParamKind(rawParamKind);
3477-
if (!paramKind)
3478-
return MF.diagnoseFatal();
3484+
auto interfaceTy = MF.getTypeChecked(interfaceTypeID);
3485+
if (!interfaceTy)
3486+
return interfaceTy.takeError();
3487+
3488+
auto paramTy = interfaceTy.get()->castTo<GenericTypeParamType>();
34793489

34803490
// Always create GenericTypeParamDecls in the associated file; the real
34813491
// context will reparent them.
34823492
auto *DC = MF.getFile();
34833493
auto *genericParam = GenericTypeParamDecl::createDeserialized(
3484-
DC, MF.getIdentifier(nameID), depth, index, *paramKind);
3494+
DC, MF.getIdentifier(nameID), paramTy->getDepth(), paramTy->getIndex(),
3495+
paramTy->getParamKind());
34853496
declOrOffset = genericParam;
34863497

34873498
if (isImplicit)
34883499
genericParam->setImplicit();
34893500

3501+
// If we're dealing with a value generic, the parameter type already
3502+
// serializes the value type. Inform the request evaluator that we don't
3503+
// need to recompute this value for the param decl.
3504+
if (paramTy->isValue()) {
3505+
ctx.evaluator.cacheOutput(
3506+
GenericTypeParamDeclGetValueTypeRequest{genericParam},
3507+
paramTy->getValueType());
3508+
}
3509+
34903510
return genericParam;
34913511
}
34923512

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,9 +1491,7 @@ namespace decls_block {
14911491
using GenericTypeParamDeclLayout = BCRecordLayout<GENERIC_TYPE_PARAM_DECL,
14921492
IdentifierIDField, // name
14931493
BCFixed<1>, // implicit flag
1494-
GenericParamKindField, // param kind
1495-
BCVBR<4>, // depth
1496-
BCVBR<4> // index
1494+
TypeIDField // interface type
14971495
>;
14981496

14991497
using AssociatedTypeDeclLayout = BCRecordLayout<

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4198,8 +4198,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
41984198
S.Out, S.ScratchRecord, abbrCode,
41994199
S.addDeclBaseNameRef(genericParam->getName()),
42004200
genericParam->isImplicit(),
4201-
getRawStableGenericParamKind(genericParam->getParamKind()),
4202-
genericParam->getDepth(), genericParam->getIndex());
4201+
S.addTypeRef(genericParam->getDeclaredInterfaceType()->getCanonicalType()));
42034202
}
42044203

42054204
void visitAssociatedTypeDecl(const AssociatedTypeDecl *assocType) {

0 commit comments

Comments
 (0)