Skip to content

Commit ae35500

Browse files
committed
Store TypeRepr in TypeValueExpr
1 parent f451d85 commit ae35500

File tree

9 files changed

+66
-87
lines changed

9 files changed

+66
-87
lines changed

include/swift/AST/Expr.h

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,29 +1449,22 @@ class TypeExpr : public Expr {
14491449
};
14501450

14511451
class TypeValueExpr : public Expr {
1452-
GenericTypeParamDecl *paramDecl;
14531452
TypeRepr *repr;
1454-
DeclNameLoc loc;
14551453
Type paramType;
14561454

1457-
/// Create a \c TypeValueExpr from a given generic value param decl.
1458-
TypeValueExpr(TypeRepr *repr, DeclNameLoc loc, GenericTypeParamDecl *paramDecl) :
1459-
Expr(ExprKind::TypeValue, /*implicit*/ false), paramDecl(paramDecl),
1460-
repr(repr), loc(loc), paramType(nullptr) {}
1455+
/// Create a \c TypeValueExpr from a given type representation.
1456+
TypeValueExpr(TypeRepr *repr) :
1457+
Expr(ExprKind::TypeValue, /*implicit*/ false), repr(repr),
1458+
paramType(nullptr) {}
14611459

14621460
public:
1463-
/// Create a \c TypeValueExpr for a given \c GenericTypeParamDecl.
1461+
/// Create a \c TypeValueExpr for a given \c TypeDecl.
14641462
///
14651463
/// The given location must be valid.
1466-
static TypeValueExpr *createForDecl(DeclNameLoc Loc, GenericTypeParamDecl *D);
1464+
static TypeValueExpr *createForDecl(DeclNameLoc loc, TypeDecl *d,
1465+
DeclContext *dc);
14671466

1468-
/// Create a \c TypeValueExpr for a member of the given parent \c TypeRepr.
1469-
static TypeValueExpr *createForMemberDecl(TypeRepr *repr, DeclNameLoc loc,
1470-
GenericTypeParamDecl *d);
1471-
1472-
GenericTypeParamDecl *getParamDecl() const {
1473-
return paramDecl;
1474-
}
1467+
GenericTypeParamDecl *getParamDecl() const;
14751468

14761469
TypeRepr *getRepr() const {
14771470
return repr;
@@ -1489,15 +1482,7 @@ class TypeValueExpr : public Expr {
14891482
this->paramType = paramType;
14901483
}
14911484

1492-
/// Retrieves the underlying value type of the parameter type referenced by
1493-
/// this expression.
1494-
Type getValueType() const {
1495-
return paramDecl->getValueType();
1496-
}
1497-
1498-
SourceRange getSourceRange() const {
1499-
return loc.getSourceRange();
1500-
}
1485+
SourceRange getSourceRange() const;
15011486

15021487
static bool classof(const Expr *E) {
15031488
return E->getKind() == ExprKind::TypeValue;

lib/AST/Expr.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2441,19 +2441,22 @@ bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const {
24412441
return false;
24422442
}
24432443

2444-
TypeValueExpr *TypeValueExpr::createForDecl(DeclNameLoc loc,
2445-
GenericTypeParamDecl *paramDecl) {
2446-
auto &ctx = paramDecl->getASTContext();
2444+
TypeValueExpr *TypeValueExpr::createForDecl(DeclNameLoc loc, TypeDecl *decl,
2445+
DeclContext *dc) {
2446+
auto &ctx = decl->getASTContext();
24472447
ASSERT(loc.isValid());
2448-
return new (ctx) TypeValueExpr(/*repr*/ nullptr, loc, paramDecl);
2448+
auto repr = UnqualifiedIdentTypeRepr::create(ctx, loc, decl->createNameRef());
2449+
repr->setValue(decl, dc);
2450+
return new (ctx) TypeValueExpr(repr);
24492451
}
24502452

2451-
TypeValueExpr *TypeValueExpr::createForMemberDecl(TypeRepr *repr,
2452-
DeclNameLoc loc,
2453-
GenericTypeParamDecl *paramDecl) {
2454-
auto &ctx = paramDecl->getASTContext();
2455-
ASSERT(loc.isValid());
2456-
return new (ctx) TypeValueExpr(repr, loc, paramDecl);
2453+
GenericTypeParamDecl *TypeValueExpr::getParamDecl() const {
2454+
auto declRefRepr = cast<DeclRefTypeRepr>(getRepr());
2455+
return cast<GenericTypeParamDecl>(declRefRepr->getBoundDecl());
2456+
}
2457+
2458+
SourceRange TypeValueExpr::getSourceRange() const {
2459+
return getRepr()->getSourceRange();
24572460
}
24582461

24592462
ExistentialArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {

lib/AST/NameLookup.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2742,7 +2742,8 @@ QualifiedLookupRequest::evaluate(Evaluator &eval, const DeclContext *DC,
27422742
// Qualified name lookup can find generic value parameters.
27432743
auto gpList = current->getGenericParams();
27442744

2745-
if (gpList && !member.isSpecial()) {
2745+
// .. But not in type contexts (yet)
2746+
if (!(options & NL_OnlyTypes) && gpList && !member.isSpecial()) {
27462747
auto gp = gpList->lookUpGenericParam(member.getBaseIdentifier());
27472748

27482749
if (gp && gp->isValue()) {

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,7 @@ namespace {
16401640
if (auto gp = dyn_cast<GenericTypeParamDecl>(member)) {
16411641
if (gp->isValue()) {
16421642
auto refType = adjustedOpenedType;
1643-
auto ref = TypeValueExpr::createForDecl(memberLoc, gp);
1643+
auto ref = TypeValueExpr::createForDecl(memberLoc, gp, dc);
16441644
cs.setType(ref, refType);
16451645

16461646
auto gpTy = gp->getDeclaredInterfaceType();

lib/Sema/CSGen.cpp

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,25 +1723,15 @@ namespace {
17231723
}
17241724

17251725
Type visitTypeValueExpr(TypeValueExpr *E) {
1726-
auto ty = E->getParamDecl()->getDeclaredInterfaceType();
1726+
auto declRefRepr = cast<DeclRefTypeRepr>(E->getRepr());
1727+
auto resolvedTy = resolveTypeReferenceInExpression(declRefRepr,
1728+
TypeResolverContext::InExpression,
1729+
CS.getConstraintLocator(E));
17271730

1728-
// If we have a type representation for this type value, then we're in a
1729-
// context where we're statically accessing the generic parameter by name
1730-
// from a qualified name. E.g. 'A<123>.b'. This context may or may not
1731-
// have a generic environment from which we can map our parameter to.
1732-
if (auto repr = E->getRepr()) {
1733-
auto resolvedTy =
1734-
resolveTypeReferenceInExpression(repr,
1735-
TypeResolverContext::InExpression,
1736-
CS.getConstraintLocator(E));
1737-
1738-
auto paramType = ty.subst(resolvedTy->getContextSubstitutionMap());
1739-
E->setParamType(paramType);
1740-
return E->getParamDecl()->getValueType();
1741-
}
1731+
if (!resolvedTy || resolvedTy->hasError())
1732+
return Type();
17421733

1743-
auto paramType = CS.DC->mapTypeIntoContext(ty);
1744-
E->setParamType(paramType);
1734+
E->setParamType(resolvedTy);
17451735
return E->getParamDecl()->getValueType();
17461736
}
17471737

lib/Sema/PreCheckTarget.cpp

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -817,8 +817,7 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
817817
: D->getInterfaceType());
818818
} else {
819819
if (makeTypeValue) {
820-
return TypeValueExpr::createForDecl(UDRE->getNameLoc(),
821-
cast<GenericTypeParamDecl>(D));
820+
return TypeValueExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
822821
} else {
823822
return TypeExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
824823
}
@@ -1096,10 +1095,10 @@ class PreCheckTarget final : public ASTWalker {
10961095
/// Simplify expressions which are type sugar productions that got parsed
10971096
/// as expressions due to the parser not knowing which identifiers are
10981097
/// type names.
1099-
Expr *simplifyTypeExpr(Expr *E);
1098+
TypeExpr *simplifyTypeExpr(Expr *E);
11001099

11011100
/// Simplify unresolved dot expressions which are nested type productions.
1102-
Expr *simplifyNestedTypeExpr(UnresolvedDotExpr *UDE);
1101+
TypeExpr *simplifyNestedTypeExpr(UnresolvedDotExpr *UDE);
11031102

11041103
TypeExpr *simplifyUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *USE);
11051104

@@ -1726,7 +1725,7 @@ void PreCheckTarget::diagnoseOutOfPlaceSingleValueStmtExprs(
17261725
}
17271726
}
17281727

1729-
Expr *PreCheckTarget::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
1728+
TypeExpr *PreCheckTarget::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
17301729
if (!UDE->getName().isSimpleName() ||
17311730
UDE->getName().isSpecial())
17321731
return nullptr;
@@ -1841,19 +1840,8 @@ Expr *PreCheckTarget::simplifyNestedTypeExpr(UnresolvedDotExpr *UDE) {
18411840
// If there is no nested type with this name, we have a lookup of
18421841
// a non-type member, so leave the expression as-is.
18431842
if (Result.size() == 1) {
1844-
auto resultDecl = Result.front().Member;
1845-
1846-
if (resultDecl &&
1847-
isa<GenericTypeParamDecl>(resultDecl) &&
1848-
cast<GenericTypeParamDecl>(resultDecl)->isValue()) {
1849-
auto gtpd = cast<GenericTypeParamDecl>(resultDecl);
1850-
return TypeValueExpr::createForMemberDecl(InnerTypeRepr,
1851-
UDE->getNameLoc(), gtpd);
1852-
1853-
} else {
1854-
return TypeExpr::createForMemberDecl(InnerTypeRepr, UDE->getNameLoc(),
1855-
resultDecl);
1856-
}
1843+
return TypeExpr::createForMemberDecl(InnerTypeRepr, UDE->getNameLoc(),
1844+
Result.front().Member);
18571845
}
18581846
}
18591847

@@ -2132,7 +2120,7 @@ static bool isTildeOperator(Expr *expr) {
21322120
/// Simplify expressions which are type sugar productions that got parsed
21332121
/// as expressions due to the parser not knowing which identifiers are
21342122
/// type names.
2135-
Expr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
2123+
TypeExpr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
21362124
// If it's already a type expression, return it.
21372125
if (auto typeExpr = dyn_cast<TypeExpr>(E))
21382126
return typeExpr;
@@ -2331,7 +2319,7 @@ Expr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
23312319

23322320
// When simplifying a type expr like "(P1 & P2) -> (P3 & P4) -> Int",
23332321
// it may have been folded at the same time; recursively simplify it.
2334-
if (auto ArgsTypeExpr = dyn_cast_or_null<TypeExpr>(simplifyTypeExpr(E))) {
2322+
if (auto ArgsTypeExpr = simplifyTypeExpr(E)) {
23352323
auto ArgRepr = ArgsTypeExpr->getTypeRepr();
23362324
if (auto *TTyRepr = dyn_cast<TupleTypeRepr>(ArgRepr))
23372325
return TTyRepr;
@@ -2352,7 +2340,7 @@ Expr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
23522340

23532341
// When simplifying a type expr like "P1 & P2 -> P3 & P4 -> Int",
23542342
// it may have been folded at the same time; recursively simplify it.
2355-
if (auto ArgsTypeExpr = dyn_cast_or_null<TypeExpr>(simplifyTypeExpr(E)))
2343+
if (auto ArgsTypeExpr = simplifyTypeExpr(E))
23562344
return ArgsTypeExpr->getTypeRepr();
23572345
return nullptr;
23582346
};
@@ -2391,8 +2379,7 @@ Expr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
23912379
// Fold '~P' into a composition type.
23922380
if (auto *unaryExpr = dyn_cast<PrefixUnaryExpr>(E)) {
23932381
if (isTildeOperator(unaryExpr->getFn())) {
2394-
if (auto operand = dyn_cast_or_null<TypeExpr>(
2395-
simplifyTypeExpr(unaryExpr->getOperand()))) {
2382+
if (auto operand = simplifyTypeExpr(unaryExpr->getOperand())) {
23962383
auto inverseTypeRepr = new (Ctx) InverseTypeRepr(
23972384
unaryExpr->getLoc(), operand->getTypeRepr());
23982385
return new (Ctx) TypeExpr(inverseTypeRepr);
@@ -2412,7 +2399,7 @@ Expr *PreCheckTarget::simplifyTypeExpr(Expr *E) {
24122399
// If the lhs is another binary expression, we have a multi element
24132400
// composition: 'A & B & C' is parsed as ((A & B) & C); we get
24142401
// the protocols from the lhs here
2415-
if (auto expr = dyn_cast_or_null<TypeExpr>(simplifyTypeExpr(lhsExpr)))
2402+
if (auto expr = simplifyTypeExpr(lhsExpr))
24162403
if (auto *repr = dyn_cast<CompositionTypeRepr>(expr->getTypeRepr()))
24172404
// add the protocols to our list
24182405
for (auto proto : repr->getTypes())

lib/Sema/TypeCheckType.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6335,6 +6335,18 @@ Type TypeChecker::substMemberTypeWithBase(TypeDecl *member,
63356335
resultType = TypeAliasType::get(aliasDecl, sugaredBaseTy, {}, resultType);
63366336
}
63376337

6338+
// However, if overload resolution finds a value generic decl from name
6339+
// lookup, replace the returned member type to be the underlying value type
6340+
// of the generic.
6341+
//
6342+
// This can occur in code that does something like: 'type(of: x).a' where
6343+
// 'a' is the static value generic member.
6344+
if (auto gp = dyn_cast<GenericTypeParamDecl>(member)) {
6345+
if (gp->isValue()) {
6346+
resultType = gp->getValueType();
6347+
}
6348+
}
6349+
63386350
return resultType;
63396351
}
63406352

lib/Sema/TypeOfReference.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,16 +1557,11 @@ DeclReferenceType ConstraintSystem::getTypeOfMemberReference(
15571557
// Wrap it in a metatype.
15581558
memberTy = MetatypeType::get(memberTy);
15591559

1560-
// However, if overload resolution finds a value generic decl from name
1561-
// lookup, replace the returned member type to be the underlying value type
1562-
// of the generic.
1563-
//
1564-
// This can occur in code that does something like: 'type(of: x).a' where
1565-
// 'a' is the static value generic member.
1566-
if (auto gp = dyn_cast<GenericTypeParamDecl>(typeDecl)) {
1567-
if (gp->isValue()) {
1568-
memberTy = gp->getValueType();
1569-
}
1560+
// If this is a value generic, undo the wrapping. 'substMemberTypeWithBase'
1561+
// returns the underlying value type of the value generic (e.g. 'Int').
1562+
if (isa<GenericTypeParamDecl>(value) &&
1563+
cast<GenericTypeParamDecl>(value)->isValue()) {
1564+
memberTy = memberTy->castTo<MetatypeType>()->getInstanceType();
15701565
}
15711566

15721567
auto openedType = FunctionType::get({baseObjParam}, memberTy);

test/Sema/value_generics.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,3 +181,9 @@ func testTypeOf2<let c: Int>(_: E<Int, c>.Type) -> Int {
181181
let x = E<Int, c>(b: "")
182182
return type(of: x).b // OK
183183
}
184+
185+
struct H<let I: Int> { // expected-note {{'I' previously declared here}}
186+
struct I {} // expected-error {{invalid redeclaration of 'I'}}
187+
}
188+
189+
typealias J = E<Int, 123>.b // expected-error {{static property 'b' is not a member type of 'E<Int, 123>'}}

0 commit comments

Comments
 (0)