Skip to content

Commit 15035bf

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-next
2 parents 2ffdd08 + 18f4500 commit 15035bf

22 files changed

+163
-102
lines changed

include/swift/AST/Expr.h

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,9 @@ class alignas(8) Expr {
157157
HasTrailingClosure : 1
158158
);
159159

160-
SWIFT_INLINE_BITFIELD(NumberLiteralExpr, LiteralExpr, 1,
161-
IsNegative : 1
160+
SWIFT_INLINE_BITFIELD(NumberLiteralExpr, LiteralExpr, 1+1,
161+
IsNegative : 1,
162+
IsExplicitConversion : 1
162163
);
163164

164165
SWIFT_INLINE_BITFIELD(StringLiteralExpr, LiteralExpr, 3+1+1,
@@ -744,7 +745,9 @@ class NumberLiteralExpr : public LiteralExpr {
744745
/// The value of the literal as an ASTContext-owned string. Underscores must
745746
/// be stripped.
746747
StringRef Val; // Use StringRef instead of APInt or APFloat, which leak.
747-
748+
ConcreteDeclRef BuiltinInitializer;
749+
ConcreteDeclRef Initializer;
750+
748751
protected:
749752
SourceLoc MinusLoc;
750753
SourceLoc DigitsLoc;
@@ -755,6 +758,7 @@ class NumberLiteralExpr : public LiteralExpr {
755758
: LiteralExpr(Kind, Implicit), Val(Val), DigitsLoc(DigitsLoc)
756759
{
757760
Bits.NumberLiteralExpr.IsNegative = false;
761+
Bits.NumberLiteralExpr.IsExplicitConversion = false;
758762
}
759763

760764
bool isNegative() const { return Bits.NumberLiteralExpr.IsNegative; }
@@ -763,6 +767,13 @@ class NumberLiteralExpr : public LiteralExpr {
763767
Bits.NumberLiteralExpr.IsNegative = true;
764768
}
765769

770+
bool isExplicitConversion() const {
771+
return Bits.NumberLiteralExpr.IsExplicitConversion;
772+
}
773+
void setExplicitConversion(bool isExplicitConversion = true) {
774+
Bits.NumberLiteralExpr.IsExplicitConversion = isExplicitConversion;
775+
}
776+
766777
StringRef getDigitsText() const { return Val; }
767778

768779
SourceRange getSourceRange() const {
@@ -780,6 +791,32 @@ class NumberLiteralExpr : public LiteralExpr {
780791
return DigitsLoc;
781792
}
782793

794+
/// Retrieve the builtin initializer that will be used to construct the
795+
/// boolean literal.
796+
///
797+
/// Any type-checked boolean literal will have a builtin initializer, which is
798+
/// called first to form a concrete Swift type.
799+
ConcreteDeclRef getBuiltinInitializer() const { return BuiltinInitializer; }
800+
801+
/// Set the builtin initializer that will be used to construct the boolean
802+
/// literal.
803+
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
804+
BuiltinInitializer = builtinInitializer;
805+
}
806+
807+
/// Retrieve the initializer that will be used to construct the boolean
808+
/// literal from the result of the initializer.
809+
///
810+
/// Only boolean literals that have no builtin literal conformance will have
811+
/// this initializer, which will be called on the result of the builtin
812+
/// initializer.
813+
ConcreteDeclRef getInitializer() const { return Initializer; }
814+
815+
/// Set the initializer that will be used to construct the boolean literal.
816+
void setInitializer(ConcreteDeclRef initializer) {
817+
Initializer = initializer;
818+
}
819+
783820
static bool classof(const Expr *E) {
784821
return E->getKind() >= ExprKind::First_NumberLiteralExpr
785822
&& E->getKind() <= ExprKind::Last_NumberLiteralExpr;
@@ -1125,37 +1162,32 @@ class MagicIdentifierLiteralExpr : public LiteralExpr {
11251162
= static_cast<unsigned>(encoding);
11261163
}
11271164

1128-
/// Retrieve the builtin initializer that will be used to construct the string
1165+
/// Retrieve the builtin initializer that will be used to construct the
11291166
/// literal.
11301167
///
1131-
/// Any type-checked string literal will have a builtin initializer, which is
1168+
/// Any type-checked literal will have a builtin initializer, which is
11321169
/// called first to form a concrete Swift type.
11331170
ConcreteDeclRef getBuiltinInitializer() const {
1134-
assert(isString() && "Magic identifier literal is not a string");
11351171
return BuiltinInitializer;
11361172
}
11371173

1138-
/// Set the builtin initializer that will be used to construct the string
1139-
/// literal.
1174+
/// Set the builtin initializer that will be used to construct the literal.
11401175
void setBuiltinInitializer(ConcreteDeclRef builtinInitializer) {
1141-
assert(isString() && "Magic identifier literal is not a string");
11421176
BuiltinInitializer = builtinInitializer;
11431177
}
11441178

1145-
/// Retrieve the initializer that will be used to construct the string
1146-
/// literal from the result of the initializer.
1179+
/// Retrieve the initializer that will be used to construct the literal from
1180+
/// the result of the initializer.
11471181
///
1148-
/// Only string literals that have no builtin literal conformance will have
1182+
/// Only literals that have no builtin literal conformance will have
11491183
/// this initializer, which will be called on the result of the builtin
11501184
/// initializer.
11511185
ConcreteDeclRef getInitializer() const {
1152-
assert(isString() && "Magic identifier literal is not a string");
11531186
return Initializer;
11541187
}
11551188

1156-
/// Set the initializer that will be used to construct the string literal.
1189+
/// Set the initializer that will be used to construct the literal.
11571190
void setInitializer(ConcreteDeclRef initializer) {
1158-
assert(isString() && "Magic identifier literal is not a string");
11591191
Initializer = initializer;
11601192
}
11611193

lib/AST/ASTDumper.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,11 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
18201820
PrintWithColorRAII(OS, LiteralValueColor) << E->getDigitsText();
18211821
else
18221822
PrintWithColorRAII(OS, LiteralValueColor) << E->getValue();
1823+
PrintWithColorRAII(OS, LiteralValueColor) << " builtin_initializer=";
1824+
E->getBuiltinInitializer().dump(
1825+
PrintWithColorRAII(OS, LiteralValueColor).getOS());
1826+
PrintWithColorRAII(OS, LiteralValueColor) << " initializer=";
1827+
E->getInitializer().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
18231828
PrintWithColorRAII(OS, ParenthesisColor) << ')';
18241829
}
18251830
void visitFloatLiteralExpr(FloatLiteralExpr *E) {
@@ -1868,12 +1873,12 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
18681873

18691874
if (E->isString()) {
18701875
OS << " encoding="
1871-
<< getStringLiteralExprEncodingString(E->getStringEncoding())
1872-
<< " builtin_initializer=";
1873-
E->getBuiltinInitializer().dump(OS);
1874-
OS << " initializer=";
1875-
E->getInitializer().dump(OS);
1876+
<< getStringLiteralExprEncodingString(E->getStringEncoding());
18761877
}
1878+
OS << " builtin_initializer=";
1879+
E->getBuiltinInitializer().dump(OS);
1880+
OS << " initializer=";
1881+
E->getInitializer().dump(OS);
18771882
PrintWithColorRAII(OS, ParenthesisColor) << ')';
18781883
}
18791884

lib/AST/Expr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,8 @@ APInt IntegerLiteralExpr::getRawValue() const {
876876
APInt IntegerLiteralExpr::getValue() const {
877877
assert(!getType().isNull() && "Semantic analysis has not completed");
878878
assert(!getType()->hasError() && "Should have a valid type");
879+
if (!getType()->is<AnyBuiltinIntegerType>())
880+
return getRawValue();
879881
auto width = getType()->castTo<AnyBuiltinIntegerType>()->getWidth();
880882
return width.parse(getDigitsText(), /*radix*/ 0, isNegative());
881883
}

lib/SILGen/SILGenApply.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5537,6 +5537,16 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
55375537
builtinLiteralArgs = RValue(*this, {boolManaged}, ty);
55385538
builtinInit = booleanLiteral->getBuiltinInitializer();
55395539
init = booleanLiteral->getInitializer();
5540+
} else if (auto integerLiteral = dyn_cast<IntegerLiteralExpr>(literal)) {
5541+
ManagedValue integerManaged =
5542+
ManagedValue::forUnmanaged(B.createIntegerLiteral(
5543+
integerLiteral,
5544+
SILType::getBuiltinIntegerLiteralType(getASTContext()),
5545+
integerLiteral->getRawValue()));
5546+
CanType ty = integerManaged.getType().getASTType()->getCanonicalType();
5547+
builtinLiteralArgs = RValue(*this, {integerManaged}, ty);
5548+
builtinInit = integerLiteral->getBuiltinInitializer();
5549+
init = integerLiteral->getInitializer();
55405550
} else {
55415551
ASTContext &ctx = getASTContext();
55425552
SourceLoc loc = literal->getStartLoc();
@@ -5566,7 +5576,23 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
55665576
}
55675577

55685578
case MagicIdentifierLiteralExpr::Line:
5569-
case MagicIdentifierLiteralExpr::Column:
5579+
case MagicIdentifierLiteralExpr::Column: {
5580+
SourceLoc Loc = literal->getStartLoc();
5581+
unsigned Value = 0;
5582+
if (Loc.isValid()) {
5583+
Value = magicLiteral->getKind() == MagicIdentifierLiteralExpr::Line
5584+
? ctx.SourceMgr.getLineAndColumn(Loc).first
5585+
: ctx.SourceMgr.getLineAndColumn(Loc).second;
5586+
}
5587+
5588+
auto Ty = SILType::getBuiltinIntegerLiteralType(ctx);
5589+
SILValue V = B.createIntegerLiteral(literal, Ty, Value);
5590+
builtinLiteralArgs = RValue(*this, {ManagedValue::forUnmanaged(V)},
5591+
Ty.getASTType()->getCanonicalType());
5592+
builtinInit = magicLiteral->getBuiltinInitializer();
5593+
init = magicLiteral->getInitializer();
5594+
break;
5595+
}
55705596
case MagicIdentifierLiteralExpr::DSOHandle:
55715597
llvm_unreachable("handled elsewhere");
55725598
}

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,10 @@ RValue RValueEmitter::visitNilLiteralExpr(NilLiteralExpr *E, SGFContext C) {
952952

953953
RValue RValueEmitter::visitIntegerLiteralExpr(IntegerLiteralExpr *E,
954954
SGFContext C) {
955-
return RValue(SGF, E,
956-
ManagedValue::forUnmanaged(SGF.B.createIntegerLiteral(E)));
955+
if (E->getType()->is<AnyBuiltinIntegerType>())
956+
return RValue(SGF, E,
957+
ManagedValue::forUnmanaged(SGF.B.createIntegerLiteral(E)));
958+
return SGF.emitLiteral(E, C);
957959
}
958960
RValue RValueEmitter::visitFloatLiteralExpr(FloatLiteralExpr *E,
959961
SGFContext C) {
@@ -3724,31 +3726,12 @@ visitKeyPathApplicationExpr(KeyPathApplicationExpr *E, SGFContext C) {
37243726

37253727
RValue RValueEmitter::
37263728
visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) {
3727-
ASTContext &Ctx = SGF.getASTContext();
3728-
SILType Ty = SGF.getLoweredLoadableType(E->getType());
3729-
SourceLoc Loc = E->getStartLoc();
3730-
37313729
switch (E->getKind()) {
37323730
case MagicIdentifierLiteralExpr::File:
37333731
case MagicIdentifierLiteralExpr::Function:
3732+
case MagicIdentifierLiteralExpr::Line:
3733+
case MagicIdentifierLiteralExpr::Column:
37343734
return SGF.emitLiteral(E, C);
3735-
case MagicIdentifierLiteralExpr::Line: {
3736-
unsigned Value = 0;
3737-
if (Loc.isValid())
3738-
Value = Ctx.SourceMgr.getLineAndColumn(Loc).first;
3739-
3740-
SILValue V = SGF.B.createIntegerLiteral(E, Ty, Value);
3741-
return RValue(SGF, E, ManagedValue::forUnmanaged(V));
3742-
}
3743-
case MagicIdentifierLiteralExpr::Column: {
3744-
unsigned Value = 0;
3745-
if (Loc.isValid())
3746-
Value = Ctx.SourceMgr.getLineAndColumn(Loc).second;
3747-
3748-
SILValue V = SGF.B.createIntegerLiteral(E, Ty, Value);
3749-
return RValue(SGF, E, ManagedValue::forUnmanaged(V));
3750-
}
3751-
37523735
case MagicIdentifierLiteralExpr::DSOHandle: {
37533736
auto SILLoc = SILLocation(E);
37543737
auto UnsafeRawPointer = SGF.getASTContext().getUnsafeRawPointerDecl();

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ constantFoldAndCheckIntegerConversions(BuiltinInst *BI,
755755
UserSrcTy = CE->getArg()->getType();
756756
UserDstTy = CE->getType();
757757
}
758+
} else if (auto *ILE = Loc.getAsASTNode<IntegerLiteralExpr>()) {
759+
UserDstTy = ILE->getType();
758760
}
759761

760762
// Assume that we're converting from a literal if the source type is
@@ -1057,6 +1059,9 @@ bool isHexLiteralInSource(FloatLiteralInst *flitInst) {
10571059
bool maybeExplicitFPCons(BuiltinInst *BI, const BuiltinInfo &Builtin) {
10581060
assert(Builtin.ID == BuiltinValueKind::FPTrunc ||
10591061
Builtin.ID == BuiltinValueKind::IntToFPWithOverflow);
1062+
if (auto *literal = BI->getLoc().getAsASTNode<NumberLiteralExpr>()) {
1063+
return literal->isExplicitConversion();
1064+
}
10601065

10611066
auto *callExpr = BI->getLoc().getAsASTNode<CallExpr>();
10621067
if (!callExpr || !dyn_cast<ConstructorRefCallExpr>(callExpr->getFn()))
@@ -1218,7 +1223,9 @@ case BuiltinValueKind::id:
12181223
SrcVal, /*IsSigned=*/true, APFloat::rmNearestTiesToEven);
12191224

12201225
SILLocation Loc = BI->getLoc();
1221-
const ApplyExpr *CE = Loc.getAsASTNode<ApplyExpr>();
1226+
const Expr *CE = Loc.getAsASTNode<ApplyExpr>();
1227+
if (!CE)
1228+
CE = Loc.getAsASTNode<LiteralExpr>();
12221229

12231230
bool overflow = ConversionStatus & APFloat::opOverflow;
12241231
bool inexact = ConversionStatus & APFloat::opInexact;

lib/Sema/CSApply.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,19 +1778,15 @@ namespace {
17781778
DeclName builtinInitName(tc.Context, DeclBaseName::createConstructor(),
17791779
{ tc.Context.Id_builtinIntegerLiteral });
17801780

1781-
return convertLiteral(
1782-
expr,
1783-
type,
1784-
cs.getType(expr),
1785-
protocol,
1786-
tc.Context.Id_IntegerLiteralType,
1787-
initName,
1788-
builtinProtocol,
1789-
tc.Context.TheIntegerLiteralType,
1790-
builtinInitName,
1791-
nullptr,
1792-
diag::integer_literal_broken_proto,
1793-
diag::builtin_integer_literal_broken_proto);
1781+
auto *result = convertLiteralInPlace(
1782+
expr, type, protocol, tc.Context.Id_IntegerLiteralType, initName,
1783+
builtinProtocol, builtinInitName, diag::integer_literal_broken_proto,
1784+
diag::builtin_integer_literal_broken_proto);
1785+
if (result) {
1786+
// TODO: It seems that callers expect this to have types assigned...
1787+
result->setType(cs.getType(result));
1788+
}
1789+
return result;
17941790
}
17951791

17961792
Expr *visitNilLiteralExpr(NilLiteralExpr *expr) {
@@ -3556,7 +3552,11 @@ namespace {
35563552
});
35573553
}
35583554

3559-
literalInit->setImplicit(false);
3555+
if (auto *literal = dyn_cast<NumberLiteralExpr>(literalInit)) {
3556+
literal->setExplicitConversion();
3557+
} else {
3558+
literalInit->setImplicit(false);
3559+
}
35603560

35613561
cs.setType(expr, toType);
35623562
// Keep the coercion around, because it contains the source range
@@ -6981,6 +6981,8 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
69816981
stringLiteral->setBuiltinInitializer(witness);
69826982
else if (auto booleanLiteral = dyn_cast<BooleanLiteralExpr>(literal))
69836983
booleanLiteral->setBuiltinInitializer(witness);
6984+
else if (auto numberLiteral = dyn_cast<NumberLiteralExpr>(literal))
6985+
numberLiteral->setBuiltinInitializer(witness);
69846986
else {
69856987
cast<MagicIdentifierLiteralExpr>(literal)
69866988
->setBuiltinInitializer(witness);
@@ -7030,6 +7032,8 @@ Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
70307032
stringLiteral->setInitializer(witness);
70317033
else if (auto booleanLiteral = dyn_cast<BooleanLiteralExpr>(literal))
70327034
booleanLiteral->setInitializer(witness);
7035+
else if (auto numberLiteral = dyn_cast<NumberLiteralExpr>(literal))
7036+
numberLiteral->setInitializer(witness);
70337037
else
70347038
cast<MagicIdentifierLiteralExpr>(literal)->setInitializer(witness);
70357039

lib/Sema/CSDiagnostics.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,12 @@ bool AssignmentFailure::diagnoseAsError() {
937937
return true;
938938
}
939939

940+
if (auto LE = dyn_cast<LiteralExpr>(immInfo.first)) {
941+
emitDiagnostic(Loc, DeclDiagnostic, "literals are not mutable")
942+
.highlight(LE->getSourceRange());
943+
return true;
944+
}
945+
940946
// If the expression is the result of a call, it is an rvalue, not a mutable
941947
// lvalue.
942948
if (auto *AE = dyn_cast<ApplyExpr>(immInfo.first)) {

test/Frontend/dump-parse.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@
66
func foo(_ n: Int) -> Int {
77
// CHECK: (brace_stmt
88
// CHECK: (return_stmt
9-
// CHECK: (integer_literal_expr type='<null>' value=42)))
9+
// CHECK: (integer_literal_expr type='<null>' value=42 {{.*}})))
1010
// CHECK-AST: (brace_stmt
1111
// CHECK-AST: (return_stmt
12-
// CHECK-AST: (call_expr implicit type='Int'
13-
// CHECK-AST: (integer_literal_expr type='{{[^']+}}' {{.*}} value=42)
14-
return 42
12+
// CHECK-AST: (integer_literal_expr type='{{[^']+}}' {{.*}} value=42 {{.*}})
13+
return 42
1514
}
1615

1716
// -dump-parse should print an AST even though this code is invalid.

0 commit comments

Comments
 (0)