Skip to content

Commit eb217bf

Browse files
committed
[Sema] Produce a type-checked AST when deriving the hashValue getter.
Should fix rdar://problem/54712316, a case where the non-type-checked AST was getting processed by SILGen.
1 parent 016acf3 commit eb217bf

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,19 +1132,47 @@ deriveBodyHashable_hashValue(AbstractFunctionDecl *hashValueDecl, void *) {
11321132
ASTContext &C = parentDC->getASTContext();
11331133

11341134
// return _hashValue(for: self)
1135-
auto *hashFunc = C.getHashValueForDecl();
1136-
auto hashExpr = new (C) DeclRefExpr(hashFunc, DeclNameLoc(),
1137-
/*implicit*/ true);
1135+
1136+
// 'self'
11381137
auto selfDecl = hashValueDecl->getImplicitSelfDecl();
1138+
Type selfType = selfDecl->getType();
11391139
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
1140-
/*implicit*/ true);
1140+
/*implicit*/ true,
1141+
AccessSemantics::Ordinary,
1142+
selfType);
1143+
1144+
// _hashValue(for:)
1145+
auto *hashFunc = C.getHashValueForDecl();
1146+
auto substitutions = SubstitutionMap::get(
1147+
hashFunc->getGenericSignature(),
1148+
[&](SubstitutableType *dependentType) {
1149+
if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
1150+
if (gp->getDepth() == 0 && gp->getIndex() == 0)
1151+
return selfType;
1152+
}
1153+
1154+
return Type(dependentType);
1155+
},
1156+
LookUpConformanceInModule(hashValueDecl->getModuleContext()));
1157+
ConcreteDeclRef hashFuncRef(hashFunc, substitutions);
1158+
1159+
1160+
Type hashFuncType = hashFunc->getInterfaceType().subst(substitutions);
1161+
auto hashExpr = new (C) DeclRefExpr(hashFuncRef, DeclNameLoc(),
1162+
/*implicit*/ true,
1163+
AccessSemantics::Ordinary,
1164+
hashFuncType);
1165+
Type hashFuncResultType =
1166+
hashFuncType->castTo<AnyFunctionType>()->getResult();
11411167
auto callExpr = CallExpr::createImplicit(C, hashExpr,
11421168
{ selfRef }, { C.Id_for });
1169+
callExpr->setType(hashFuncResultType);
1170+
11431171
auto returnStmt = new (C) ReturnStmt(SourceLoc(), callExpr);
11441172

11451173
auto body = BraceStmt::create(C, SourceLoc(), {returnStmt}, SourceLoc(),
11461174
/*implicit*/ true);
1147-
return { body, /*isTypeChecked=*/false };
1175+
return { body, /*isTypeChecked=*/true };
11481176
}
11491177

11501178
/// Derive a 'hashValue' implementation.

0 commit comments

Comments
 (0)