Merge pull request #78248 from Azoy/value-generic-static-member

[NameLookup] Allow value generics to show up as static members
This commit is contained in:
Alejandro Alonso
2025-04-16 08:03:46 -07:00
parent b684e716fe
commit 12919a2300
16 changed files with 256 additions and 38 deletions

View File

@@ -1631,6 +1631,29 @@ namespace {
// Build a member reference.
auto memberRef = resolveConcreteDeclRef(member, memberLocator);
// If our member reference is a value generic, then the resulting
// expression is the type value one to access the underlying parameter's
// value.
//
// This can occur in code that does something like: 'type(of: x).a' where
// 'a' is the static value generic member.
if (auto gp = dyn_cast<GenericTypeParamDecl>(member)) {
if (gp->isValue()) {
auto refType = adjustedOpenedType;
auto ref = TypeValueExpr::createForDecl(memberLoc, gp, dc);
cs.setType(ref, refType);
auto gpTy = gp->getDeclaredInterfaceType();
auto subs = baseTy->getContextSubstitutionMap();
ref->setParamType(gpTy.subst(subs));
auto result = new (ctx) DotSyntaxBaseIgnoredExpr(base, dotLoc, ref,
refType);
cs.setType(result, refType);
return result;
}
}
// If we're referring to a member type, it's just a type
// reference.
if (auto *TD = dyn_cast<TypeDecl>(member)) {
@@ -3223,8 +3246,20 @@ namespace {
Expr *visitTypeValueExpr(TypeValueExpr *expr) {
auto toType = simplifyType(cs.getType(expr));
assert(toType->isEqual(expr->getParamDecl()->getValueType()));
ASSERT(toType->isEqual(expr->getParamDecl()->getValueType()));
cs.setType(expr, toType);
auto declRefRepr = cast<DeclRefTypeRepr>(expr->getRepr());
auto resolvedTy =
TypeResolution::resolveContextualType(declRefRepr, cs.DC,
TypeResolverContext::InExpression,
nullptr, nullptr, nullptr);
if (!resolvedTy || resolvedTy->hasError())
return nullptr;
expr->setParamType(resolvedTy);
return expr;
}