Skip to content

Commit 0df42e9

Browse files
committed
Lower UDRE to TypeValue if it references a value generic
1 parent 7eb93b8 commit 0df42e9

16 files changed

+112
-82
lines changed

include/swift/AST/Expr.h

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,8 +1385,47 @@ class TypeExpr : public Expr {
13851385
return E->getKind() == ExprKind::Type;
13861386
}
13871387
};
1388-
1389-
1388+
1389+
class TypeValueExpr : public Expr {
1390+
TypeLoc paramTypeLoc;
1391+
1392+
public:
1393+
/// Create a \c TypeValueExpr from an underlying parameter \c TypeRepr.
1394+
TypeValueExpr(TypeRepr *paramRepr) :
1395+
Expr(ExprKind::TypeValue, /*implicit*/ false), paramTypeLoc(paramRepr) {}
1396+
1397+
/// Create a \c TypeValueExpr for a given \c TypeDecl at the specified
1398+
/// location.
1399+
///
1400+
/// The given location must be valid. If it is not, you must use
1401+
/// \c TypeExpr::createImplicitForDecl instead.
1402+
static TypeValueExpr *createForDecl(DeclNameLoc Loc, TypeDecl *D,
1403+
DeclContext *DC);
1404+
1405+
TypeRepr *getParamTypeRepr() const {
1406+
return paramTypeLoc.getTypeRepr();
1407+
}
1408+
1409+
/// Retrieves the corresponding parameter type of the value referenced by this
1410+
/// expression.
1411+
ArchetypeType *getParamType() const {
1412+
return paramTypeLoc.getType()->castTo<ArchetypeType>();
1413+
}
1414+
1415+
/// Sets the corresponding parameter type of the value referenced by this
1416+
/// expression.
1417+
void setParamType(Type paramType) {
1418+
paramTypeLoc.setType(paramType);
1419+
}
1420+
1421+
SourceRange getSourceRange() const {
1422+
return paramTypeLoc.getSourceRange();
1423+
}
1424+
1425+
static bool classof(const Expr *E) {
1426+
return E->getKind() == ExprKind::TypeValue;
1427+
}
1428+
};
13901429

13911430
/// A reference to another initializer from within a constructor body,
13921431
/// either to a delegating initializer or to a super.init invocation.
@@ -3531,18 +3570,6 @@ class ActorIsolationErasureExpr : public ImplicitConversionExpr {
35313570
}
35323571
};
35333572

3534-
/// The implicit conversion from a variable generic metatype to its underlying
3535-
/// value type.
3536-
class TypeValueExpr : public ImplicitConversionExpr {
3537-
public:
3538-
TypeValueExpr(Expr *subExpr, Type ty)
3539-
: ImplicitConversionExpr(ExprKind::TypeValue, subExpr, ty) {}
3540-
3541-
static bool classof(const Expr *E) {
3542-
return E->getKind() == ExprKind::TypeValue;
3543-
}
3544-
};
3545-
35463573
/// Extracts the isolation of a dynamically isolated function value.
35473574
class ExtractFunctionIsolationExpr : public Expr {
35483575
/// The function value expression from which to extract the

include/swift/AST/ExprNodes.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,8 +191,7 @@ ABSTRACT_EXPR(ImplicitConversion, Expr)
191191
EXPR(LinearFunctionExtractOriginal, ImplicitConversionExpr)
192192
EXPR(LinearToDifferentiableFunction, ImplicitConversionExpr)
193193
EXPR(ActorIsolationErasure, ImplicitConversionExpr)
194-
EXPR(TypeValue, ImplicitConversionExpr)
195-
EXPR_RANGE(ImplicitConversion, Load, TypeValue)
194+
EXPR_RANGE(ImplicitConversion, Load, ActorIsolationErasure)
196195
ABSTRACT_EXPR(ExplicitCast, Expr)
197196
ABSTRACT_EXPR(CheckedCast, ExplicitCastExpr)
198197
EXPR(ForcedCheckedCast, CheckedCastExpr)
@@ -218,8 +217,9 @@ UNCHECKED_EXPR(OneWay, Expr)
218217
EXPR(Tap, Expr)
219218
UNCHECKED_EXPR(TypeJoin, Expr)
220219
EXPR(MacroExpansion, Expr)
220+
EXPR(TypeValue, Expr)
221221
// Don't forget to update the LAST_EXPR below when adding a new Expr here.
222-
LAST_EXPR(MacroExpansion)
222+
LAST_EXPR(TypeValue)
223223

224224
#undef EXPR_RANGE
225225
#undef LITERAL_EXPR

include/swift/Sema/Constraint.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,6 @@ enum class ConversionRestrictionKind {
314314
/// - Unsafe[Mutable]RawPointer -> Unsafe[Mutable]Pointer<[U]Int>
315315
/// - Unsafe[Mutable]Pointer<Int{8, 16, ...}> <-> Unsafe[Mutable]Pointer<UInt{8, 16, ...}>
316316
PointerToCPointer,
317-
/// Implicit conversion from a value generic metatype to its underlying value
318-
/// type.
319-
///
320-
/// '(let N).Type' -> 'Int'
321-
ValueGeneric,
322317
};
323318

324319
/// Specifies whether a given conversion requires the creation of a temporary

lib/AST/ASTDumper.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3261,7 +3261,12 @@ class PrintExpr : public ExprVisitor<PrintExpr, void, StringRef>,
32613261

32623262
void visitTypeValueExpr(TypeValueExpr *E, StringRef label) {
32633263
printCommon(E, "type_value_expr", label);
3264-
printRec(E->getSubExpr());
3264+
3265+
PrintOptions PO;
3266+
PO.PrintTypesForDebugging = true;
3267+
printFieldQuoted(Type(E->getParamType()).getString(PO), "param_type",
3268+
TypeColor);
3269+
32653270
printFoot();
32663271
}
32673272
};

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5320,7 +5320,9 @@ void PrintAST::visitMacroExpansionExpr(MacroExpansionExpr *expr) {
53205320
}
53215321

53225322
void PrintAST::visitTypeValueExpr(TypeValueExpr *expr) {
5323-
visit(expr->getSubExpr());
5323+
// Explicitly don't use 'printType' with 'getParamType' because that will
5324+
// print the preceeding 'let N' which is illegal in source.
5325+
expr->getParamTypeRepr()->print(Printer, Options);
53245326
}
53255327

53265328
void PrintAST::visitBraceStmt(BraceStmt *stmt) {

lib/AST/ASTWalker.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,10 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
14371437
return E;
14381438
}
14391439

1440+
Expr *visitTypeValueExpr(TypeValueExpr *E) {
1441+
return E;
1442+
}
1443+
14401444
//===--------------------------------------------------------------------===//
14411445
// Everything Else
14421446
//===--------------------------------------------------------------------===//

lib/AST/Expr.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,6 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
459459
PASS_THROUGH_REFERENCE(UnderlyingToOpaque, getSubExpr);
460460
PASS_THROUGH_REFERENCE(Unreachable, getSubExpr);
461461
PASS_THROUGH_REFERENCE(ActorIsolationErasure, getSubExpr);
462-
PASS_THROUGH_REFERENCE(TypeValue, getSubExpr);
463462
NO_REFERENCE(Coerce);
464463
NO_REFERENCE(ForcedCheckedCast);
465464
NO_REFERENCE(ConditionalCheckedCast);
@@ -480,6 +479,7 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
480479
NO_REFERENCE(Tap);
481480
NO_REFERENCE(TypeJoin);
482481
SIMPLE_REFERENCE(MacroExpansion, getMacroRef);
482+
NO_REFERENCE(TypeValue);
483483

484484
#undef SIMPLE_REFERENCE
485485
#undef NO_REFERENCE
@@ -2371,6 +2371,15 @@ bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const {
23712371
return false;
23722372
}
23732373

2374+
TypeValueExpr *TypeValueExpr::createForDecl(DeclNameLoc Loc, TypeDecl *Decl,
2375+
DeclContext *DC) {
2376+
ASTContext &C = Decl->getASTContext();
2377+
assert(Loc.isValid());
2378+
auto *Repr = UnqualifiedIdentTypeRepr::create(C, Loc, Decl->createNameRef());
2379+
Repr->setValue(Decl, DC);
2380+
return new (C) TypeValueExpr(Repr);
2381+
}
2382+
23742383
OpenedArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {
23752384
auto type = getOpaqueValue()->getType()->getRValueType();
23762385
while (auto metaTy = type->getAs<MetatypeType>())

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6788,8 +6788,7 @@ RValue RValueEmitter::visitCurrentContextIsolationExpr(
67886788
}
67896789

67906790
RValue RValueEmitter::visitTypeValueExpr(TypeValueExpr *E, SGFContext C) {
6791-
auto metatype = E->getSubExpr()->getType()->castTo<MetatypeType>();
6792-
auto paramType = metatype->getInstanceType()->getCanonicalType();
6791+
auto paramType = E->getParamType()->getCanonicalType();
67936792

67946793
return RValue(SGF, E, ManagedValue::forObjectRValueWithoutOwnership(
67956794
SGF.B.createTypeValue(E, SGF.getLoweredType(E->getType()), paramType)));

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,6 +3207,13 @@ namespace {
32073207
return expr;
32083208
}
32093209

3210+
Expr *visitTypeValueExpr(TypeValueExpr *expr) {
3211+
auto toType = simplifyType(cs.getType(expr));
3212+
assert(toType->isEqual(expr->getParamType()->getValueType()));
3213+
cs.setType(expr, toType);
3214+
return expr;
3215+
}
3216+
32103217
Expr *visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *expr) {
32113218
cs.setType(expr, expr->getDecl()->getInitializerInterfaceType());
32123219
return expr;
@@ -7308,10 +7315,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
73087315
finishApply(implicitInit, toType, callLocator, callLocator);
73097316
return implicitInit;
73107317
}
7311-
7312-
case ConversionRestrictionKind::ValueGeneric: {
7313-
return cs.cacheType(new (ctx) TypeValueExpr(expr, toType));
7314-
}
73157318
}
73167319
}
73177320

lib/Sema/CSDiagnostics.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7843,7 +7843,6 @@ void NonEphemeralConversionFailure::emitSuggestionNotes() const {
78437843
case ConversionRestrictionKind::ObjCTollFreeBridgeToCF:
78447844
case ConversionRestrictionKind::CGFloatToDouble:
78457845
case ConversionRestrictionKind::DoubleToCGFloat:
7846-
case ConversionRestrictionKind::ValueGeneric:
78477846
llvm_unreachable("Expected an ephemeral conversion!");
78487847
}
78497848
}

0 commit comments

Comments
 (0)