Skip to content

Commit d47d4ad

Browse files
authored
Rollup merge of #106844 - Ezrashaw:concat-negative-int-lit, r=dtolnay
allow negative numeric literals in `concat!` Fixes #106837 While *technically* negative numeric literals are implemented as unary operations, users can reasonably expect that negative literals are treated the same as positive literals.
2 parents ffc0b8a + 41856b0 commit d47d4ad

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed

compiler/rustc_builtin_macros/src/concat.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ pub fn expand_concat(
4242
has_errors = true;
4343
}
4444
},
45+
// We also want to allow negative numeric literals.
46+
ast::ExprKind::Unary(ast::UnOp::Neg, ref expr) if let ast::ExprKind::Lit(token_lit) = expr.kind => {
47+
match ast::LitKind::from_token_lit(token_lit) {
48+
Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")),
49+
Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")),
50+
Err(err) => {
51+
report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span);
52+
has_errors = true;
53+
}
54+
_ => missing_literal.push(e.span),
55+
}
56+
}
4557
ast::ExprKind::IncludedBytes(..) => {
4658
cx.span_err(e.span, "cannot concatenate a byte string literal")
4759
}
@@ -53,9 +65,10 @@ pub fn expand_concat(
5365
}
5466
}
5567
}
68+
5669
if !missing_literal.is_empty() {
5770
let mut err = cx.struct_span_err(missing_literal, "expected a literal");
58-
err.note("only literals (like `\"foo\"`, `42` and `3.14`) can be passed to `concat!()`");
71+
err.note("only literals (like `\"foo\"`, `-42` and `3.14`) can be passed to `concat!()`");
5972
err.emit();
6073
return DummyResult::any(sp);
6174
} else if has_errors {

tests/ui/macros/bad-concat.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error: expected a literal
44
LL | let _ = concat!(x, y, z, "bar");
55
| ^ ^ ^
66
|
7-
= note: only literals (like `"foo"`, `42` and `3.14`) can be passed to `concat!()`
7+
= note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
88

99
error: aborting due to previous error
1010

tests/ui/macros/concat.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ error: expected a literal
1616
LL | concat!(foo);
1717
| ^^^
1818
|
19-
= note: only literals (like `"foo"`, `42` and `3.14`) can be passed to `concat!()`
19+
= note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
2020

2121
error: expected a literal
2222
--> $DIR/concat.rs:5:13
2323
|
2424
LL | concat!(foo());
2525
| ^^^^^
2626
|
27-
= note: only literals (like `"foo"`, `42` and `3.14`) can be passed to `concat!()`
27+
= note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
2828

2929
error: aborting due to 4 previous errors
3030

tests/ui/macros/issue-106837.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
fn main() {
2+
concat!(-42);
3+
concat!(-3.14);
4+
5+
concat!(-"hello");
6+
//~^ ERROR expected a literal
7+
8+
concat!(--1);
9+
//~^ ERROR expected a literal
10+
}

tests/ui/macros/issue-106837.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error: expected a literal
2+
--> $DIR/issue-106837.rs:5:13
3+
|
4+
LL | concat!(-"hello");
5+
| ^^^^^^^^
6+
|
7+
= note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
8+
9+
error: expected a literal
10+
--> $DIR/issue-106837.rs:8:13
11+
|
12+
LL | concat!(--1);
13+
| ^^^
14+
|
15+
= note: only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
16+
17+
error: aborting due to 2 previous errors
18+

0 commit comments

Comments
 (0)