Skip to content

Commit acbae0c

Browse files
authored
Merge pull request #79618 from Azoy/another-bug-another-dollar
[AST] Directly store GTPD in TypeValueExpr
2 parents 3ef4db6 + 15c32e1 commit acbae0c

File tree

6 files changed

+35
-38
lines changed

6 files changed

+35
-38
lines changed

include/swift/AST/Expr.h

+17-17
Original file line numberDiff line numberDiff line change
@@ -1434,39 +1434,39 @@ class TypeExpr : public Expr {
14341434
};
14351435

14361436
class TypeValueExpr : public Expr {
1437-
TypeLoc paramTypeLoc;
1437+
GenericTypeParamDecl *paramDecl;
1438+
DeclNameLoc loc;
1439+
Type paramType;
14381440

1439-
public:
1440-
/// Create a \c TypeValueExpr from an underlying parameter \c TypeRepr.
1441-
TypeValueExpr(TypeRepr *paramRepr) :
1442-
Expr(ExprKind::TypeValue, /*implicit*/ false), paramTypeLoc(paramRepr) {}
1441+
/// Create a \c TypeValueExpr from a given generic value param decl.
1442+
TypeValueExpr(DeclNameLoc loc, GenericTypeParamDecl *paramDecl) :
1443+
Expr(ExprKind::TypeValue, /*implicit*/ false), paramDecl(paramDecl),
1444+
loc(loc), paramType(nullptr) {}
14431445

1444-
/// Create a \c TypeValueExpr for a given \c TypeDecl at the specified
1445-
/// location.
1446+
public:
1447+
/// Create a \c TypeValueExpr for a given \c GenericTypeParamDecl.
14461448
///
1447-
/// The given location must be valid. If it is not, you must use
1448-
/// \c TypeExpr::createImplicitForDecl instead.
1449-
static TypeValueExpr *createForDecl(DeclNameLoc Loc, TypeDecl *D,
1450-
DeclContext *DC);
1449+
/// The given location must be valid.
1450+
static TypeValueExpr *createForDecl(DeclNameLoc Loc, GenericTypeParamDecl *D);
14511451

1452-
TypeRepr *getParamTypeRepr() const {
1453-
return paramTypeLoc.getTypeRepr();
1452+
GenericTypeParamDecl *getParamDecl() const {
1453+
return paramDecl;
14541454
}
14551455

14561456
/// Retrieves the corresponding parameter type of the value referenced by this
14571457
/// expression.
1458-
ArchetypeType *getParamType() const {
1459-
return paramTypeLoc.getType()->castTo<ArchetypeType>();
1458+
Type getParamType() const {
1459+
return paramType;
14601460
}
14611461

14621462
/// Sets the corresponding parameter type of the value referenced by this
14631463
/// expression.
14641464
void setParamType(Type paramType) {
1465-
paramTypeLoc.setType(paramType);
1465+
this->paramType = paramType;
14661466
}
14671467

14681468
SourceRange getSourceRange() const {
1469-
return paramTypeLoc.getSourceRange();
1469+
return loc.getSourceRange();
14701470
}
14711471

14721472
static bool classof(const Expr *E) {

lib/AST/Expr.cpp

+5-7
Original file line numberDiff line numberDiff line change
@@ -2399,13 +2399,11 @@ bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const {
23992399
return false;
24002400
}
24012401

2402-
TypeValueExpr *TypeValueExpr::createForDecl(DeclNameLoc Loc, TypeDecl *Decl,
2403-
DeclContext *DC) {
2404-
ASTContext &C = Decl->getASTContext();
2405-
assert(Loc.isValid());
2406-
auto *Repr = UnqualifiedIdentTypeRepr::create(C, Loc, Decl->createNameRef());
2407-
Repr->setValue(Decl, DC);
2408-
return new (C) TypeValueExpr(Repr);
2402+
TypeValueExpr *TypeValueExpr::createForDecl(DeclNameLoc loc,
2403+
GenericTypeParamDecl *paramDecl) {
2404+
auto &ctx = paramDecl->getASTContext();
2405+
ASSERT(loc.isValid());
2406+
return new (ctx) TypeValueExpr(loc, paramDecl);
24092407
}
24102408

24112409
OpenedArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {

lib/Sema/CSApply.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -3219,7 +3219,7 @@ namespace {
32193219

32203220
Expr *visitTypeValueExpr(TypeValueExpr *expr) {
32213221
auto toType = simplifyType(cs.getType(expr));
3222-
assert(toType->isEqual(expr->getParamType()->getValueType()));
3222+
assert(toType->isEqual(expr->getParamDecl()->getValueType()));
32233223
cs.setType(expr, toType);
32243224
return expr;
32253225
}

lib/Sema/CSGen.cpp

+4-12
Original file line numberDiff line numberDiff line change
@@ -1681,18 +1681,10 @@ namespace {
16811681
}
16821682

16831683
Type visitTypeValueExpr(TypeValueExpr *E) {
1684-
auto locator = CS.getConstraintLocator(E);
1685-
auto type = resolveTypeReferenceInExpression(E->getParamTypeRepr(),
1686-
TypeResolverContext::InExpression,
1687-
locator);
1688-
1689-
if (!type || type->hasError()) {
1690-
return Type();
1691-
}
1692-
1693-
auto archetype = type->castTo<ArchetypeType>();
1694-
E->setParamType(archetype);
1695-
return archetype->getValueType();
1684+
auto ty = E->getParamDecl()->getDeclaredInterfaceType();
1685+
auto paramType = CS.DC->mapTypeIntoContext(ty);
1686+
E->setParamType(paramType);
1687+
return E->getParamDecl()->getValueType();
16961688
}
16971689

16981690
Type visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *expr) {

lib/Sema/PreCheckTarget.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,8 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
792792
: D->getInterfaceType());
793793
} else {
794794
if (makeTypeValue) {
795-
return TypeValueExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
795+
return TypeValueExpr::createForDecl(UDRE->getNameLoc(),
796+
cast<GenericTypeParamDecl>(D));
796797
} else {
797798
return TypeExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
798799
}

test/Sema/value_generics.swift

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ extension A where N: P {} // expected-error {{value generic type 'N' cannot conf
4242

4343
extension A where N == Int {} // expected-error {{cannot constrain value parameter 'N' to be type 'Int'}}
4444

45+
extension A where N == 123 {
46+
func thing() -> Int {
47+
N // OK (this used to crash the compiler in a concrete case 'where N == 123')
48+
}
49+
}
50+
4551
func b(with a: A<123>) {} // OK
4652
func c<let M: Int>(with a: A<M>) {} // OK
4753
func d<T>(with a: A<T>) {} // expected-error {{cannot pass type 'T' as a value for generic value 'N'}}

0 commit comments

Comments
 (0)