@@ -257,6 +257,17 @@ enumElementPayloadSubpattern(EnumElementDecl *enumElementDecl,
257
257
return pat;
258
258
}
259
259
260
+ // / Build a type-checked integer literal.
261
+ static IntegerLiteralExpr *buildIntegerLiteral (ASTContext &C, unsigned index) {
262
+ Type intType = C.getIntDecl ()->getDeclaredType ();
263
+
264
+ auto literal = IntegerLiteralExpr::createFromUnsigned (C, index);
265
+ literal->setType (intType);
266
+ literal->setBuiltinInitializer (C.getIntBuiltinInitDecl (C.getIntDecl ()));
267
+
268
+ return literal;
269
+ }
270
+
260
271
// / Create AST statements which convert from an enum to an Int with a switch.
261
272
// / \p stmts The generated statements are appended to this vector.
262
273
// / \p parentDC Either an extension or the enum itself.
@@ -298,15 +309,20 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
298
309
SourceLoc (), SourceLoc (),
299
310
Identifier (), elt, nullptr );
300
311
pat->setImplicit ();
312
+ pat->setType (enumType);
301
313
302
314
auto labelItem = CaseLabelItem (pat);
303
315
304
316
// generate: indexVar = <index>
305
- auto indexExpr = IntegerLiteralExpr::createFromUnsigned (C, index++);
317
+ auto indexExpr = buildIntegerLiteral (C, index++);
318
+
306
319
auto indexRef = new (C) DeclRefExpr (indexVar, DeclNameLoc (),
307
- /* implicit*/ true );
320
+ /* implicit*/ true ,
321
+ AccessSemantics::Ordinary,
322
+ LValueType::get (intType));
308
323
auto assignExpr = new (C) AssignExpr (indexRef, SourceLoc (),
309
324
indexExpr, /* implicit*/ true );
325
+ assignExpr->setType (TupleType::getEmpty (C));
310
326
auto body = BraceStmt::create (C, SourceLoc (), ASTNode (assignExpr),
311
327
SourceLoc ());
312
328
cases.push_back (CaseStmt::create (C, SourceLoc (), labelItem, SourceLoc (),
@@ -316,7 +332,9 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
316
332
317
333
// generate: switch enumVar { }
318
334
auto enumRef = new (C) DeclRefExpr (enumVarDecl, DeclNameLoc (),
319
- /* implicit*/ true );
335
+ /* implicit*/ true ,
336
+ AccessSemantics::Ordinary,
337
+ enumVarDecl->getType ());
320
338
auto switchStmt = SwitchStmt::create (LabeledStmtInfo (), SourceLoc (), enumRef,
321
339
SourceLoc (), cases, SourceLoc (), C);
322
340
@@ -381,17 +399,23 @@ deriveBodyEquatable_enum_uninhabited_eq(AbstractFunctionDecl *eqDecl, void *) {
381
399
SmallVector<ASTNode, 0 > cases;
382
400
383
401
// switch (a, b) { }
384
- auto aRef = new (C) DeclRefExpr (aParam, DeclNameLoc (), /* implicit*/ true );
385
- auto bRef = new (C) DeclRefExpr (bParam, DeclNameLoc (), /* implicit*/ true );
402
+ auto aRef = new (C) DeclRefExpr (aParam, DeclNameLoc (), /* implicit*/ true ,
403
+ AccessSemantics::Ordinary,
404
+ aParam->getType ());
405
+ auto bRef = new (C) DeclRefExpr (bParam, DeclNameLoc (), /* implicit*/ true ,
406
+ AccessSemantics::Ordinary,
407
+ bParam->getType ());
408
+ TupleTypeElt abTupleElts[2 ] = { aParam->getType (), bParam->getType () };
386
409
auto abExpr = TupleExpr::create (C, SourceLoc (), {aRef, bRef}, {}, {},
387
410
SourceLoc (), /* HasTrailingClosure*/ false ,
388
- /* implicit*/ true );
411
+ /* implicit*/ true ,
412
+ TupleType::get (abTupleElts, C));
389
413
auto switchStmt = SwitchStmt::create (LabeledStmtInfo (), SourceLoc (), abExpr,
390
414
SourceLoc (), cases, SourceLoc (), C);
391
415
statements.push_back (switchStmt);
392
416
393
417
auto body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc ());
394
- return { body, /* isTypeChecked=*/ false };
418
+ return { body, /* isTypeChecked=*/ true };
395
419
}
396
420
397
421
// / Derive the body for an '==' operator for an enum that has no associated
@@ -439,16 +463,20 @@ deriveBodyEquatable_enum_noAssociatedValues_eq(AbstractFunctionDecl *eqDecl,
439
463
fnType);
440
464
}
441
465
466
+ TupleTypeElt abTupleElts[2 ] = { aIndex->getType (), bIndex->getType () };
442
467
TupleExpr *abTuple = TupleExpr::create (C, SourceLoc (), { aIndex, bIndex },
443
468
{ }, { }, SourceLoc (),
444
469
/* HasTrailingClosure*/ false ,
445
- /* Implicit*/ true );
470
+ /* Implicit*/ true ,
471
+ TupleType::get (abTupleElts, C));
446
472
447
- auto *cmpExpr = new (C) BinaryExpr (cmpFuncExpr, abTuple, /* implicit*/ true );
473
+ auto *cmpExpr = new (C) BinaryExpr (
474
+ cmpFuncExpr, abTuple, /* implicit*/ true ,
475
+ fnType->castTo <FunctionType>()->getResult ());
448
476
statements.push_back (new (C) ReturnStmt (SourceLoc (), cmpExpr));
449
477
450
478
BraceStmt *body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc ());
451
- return { body, /* isTypeChecked=*/ false };
479
+ return { body, /* isTypeChecked=*/ true };
452
480
}
453
481
454
482
// / Derive the body for an '==' operator for an enum where at least one of the
@@ -1132,19 +1160,49 @@ deriveBodyHashable_hashValue(AbstractFunctionDecl *hashValueDecl, void *) {
1132
1160
ASTContext &C = parentDC->getASTContext ();
1133
1161
1134
1162
// return _hashValue(for: self)
1135
- auto *hashFunc = C.getHashValueForDecl ();
1136
- auto hashExpr = new (C) DeclRefExpr (hashFunc, DeclNameLoc (),
1137
- /* implicit*/ true );
1163
+
1164
+ // 'self'
1138
1165
auto selfDecl = hashValueDecl->getImplicitSelfDecl ();
1166
+ Type selfType = selfDecl->getType ();
1139
1167
auto selfRef = new (C) DeclRefExpr (selfDecl, DeclNameLoc (),
1140
- /* implicit*/ true );
1168
+ /* implicit*/ true ,
1169
+ AccessSemantics::Ordinary,
1170
+ selfType);
1171
+
1172
+ // _hashValue(for:)
1173
+ auto *hashFunc = C.getHashValueForDecl ();
1174
+ if (!hashFunc->hasInterfaceType ())
1175
+ static_cast <TypeChecker *>(C.getLazyResolver ())->validateDecl (hashFunc);
1176
+
1177
+ auto substitutions = SubstitutionMap::get (
1178
+ hashFunc->getGenericSignature (),
1179
+ [&](SubstitutableType *dependentType) {
1180
+ if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
1181
+ if (gp->getDepth () == 0 && gp->getIndex () == 0 )
1182
+ return selfType;
1183
+ }
1184
+
1185
+ return Type (dependentType);
1186
+ },
1187
+ LookUpConformanceInModule (hashValueDecl->getModuleContext ()));
1188
+ ConcreteDeclRef hashFuncRef (hashFunc, substitutions);
1189
+
1190
+ Type hashFuncType = hashFunc->getInterfaceType ().subst (substitutions);
1191
+ auto hashExpr = new (C) DeclRefExpr (hashFuncRef, DeclNameLoc (),
1192
+ /* implicit*/ true ,
1193
+ AccessSemantics::Ordinary,
1194
+ hashFuncType);
1195
+ Type hashFuncResultType =
1196
+ hashFuncType->castTo <AnyFunctionType>()->getResult ();
1141
1197
auto callExpr = CallExpr::createImplicit (C, hashExpr,
1142
1198
{ selfRef }, { C.Id_for });
1199
+ callExpr->setType (hashFuncResultType);
1200
+
1143
1201
auto returnStmt = new (C) ReturnStmt (SourceLoc (), callExpr);
1144
1202
1145
1203
auto body = BraceStmt::create (C, SourceLoc (), {returnStmt}, SourceLoc (),
1146
1204
/* implicit*/ true );
1147
- return { body, /* isTypeChecked=*/ false };
1205
+ return { body, /* isTypeChecked=*/ true };
1148
1206
}
1149
1207
1150
1208
// / Derive a 'hashValue' implementation.
0 commit comments