Skip to content

Commit a6b957c

Browse files
committed
rustc: Tweak Literal APIs of proc_macro
This commit tweaks the public api of the `proc_macro::Literal` structure to solve #48889, an issue about negative integers and their representation in `proc_macro` tokens. Currently the compiler assumes that all integer tokens are *positive* integers rather than embedding a negative sign. The negative sign is a separate token from the integer itself. Currently there's a function like: impl Literal { pub fn i32(i: i32) -> Literal; } but unfortunately this doesn't work for negative integers. When called with negative integers weird errors end up getting thrown later during the parsing process. This function tweaks the definitions to instead use: impl Literal { pub fn i32(i: u32) -> Literal; } This construction makes it more clear that negative arguments are not supported. This additionally allows literals like `-128i8` where `128`, the positive integer part of this literal, isn't representable in `i8`. By taking an unsigned number in each constructor we can allow constructing the minimum literal for each signed type as well. The final tweak of this commit is to panic in `Literal::{f32, f64}` if the input number is negative. This is similar to how infinite/nan literals are handled today (they panic) and constructing a literal should be possible by negating a float and then separately passing in a literal. Closes #48889
1 parent fedce67 commit a6b957c

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

src/libproc_macro/lib.rs

+28-6
Original file line numberDiff line numberDiff line change
@@ -471,24 +471,37 @@ impl fmt::Display for Literal {
471471
}
472472

473473
macro_rules! int_literals {
474-
($($int_kind:ident),*) => {$(
474+
($($int_kind:ident => $signed:ident,)*) => {$(
475475
/// Integer literal.
476476
#[unstable(feature = "proc_macro", issue = "38356")]
477-
pub fn $int_kind(n: $int_kind) -> Literal {
478-
Literal::typed_integer(n as i128, stringify!($int_kind))
477+
pub fn $int_kind(n: $signed) -> Literal {
478+
Literal::typed_integer(n as u128, stringify!($int_kind))
479+
}
480+
481+
/// Integer literal.
482+
#[unstable(feature = "proc_macro", issue = "38356")]
483+
pub fn $signed(n: $signed) -> Literal {
484+
Literal::typed_integer(n as u128, stringify!($signed))
479485
}
480486
)*}
481487
}
482488

483489
impl Literal {
484490
/// Integer literal
485491
#[unstable(feature = "proc_macro", issue = "38356")]
486-
pub fn integer(n: i128) -> Literal {
492+
pub fn integer(n: u128) -> Literal {
487493
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())), None))
488494
}
489495

490-
int_literals!(u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);
491-
fn typed_integer(n: i128, kind: &'static str) -> Literal {
496+
int_literals!(
497+
i8 => u8,
498+
i16 => u16,
499+
i32 => u32,
500+
i64 => u64,
501+
isize => usize,
502+
);
503+
504+
fn typed_integer(n: u128, kind: &'static str) -> Literal {
492505
Literal(token::Literal(token::Lit::Integer(Symbol::intern(&n.to_string())),
493506
Some(Symbol::intern(kind))))
494507
}
@@ -499,6 +512,9 @@ impl Literal {
499512
if !n.is_finite() {
500513
panic!("Invalid float literal {}", n);
501514
}
515+
if n.is_sign_negative() {
516+
panic!("float literal cannot be negative {}", n);
517+
}
502518
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())), None))
503519
}
504520

@@ -508,6 +524,9 @@ impl Literal {
508524
if !n.is_finite() {
509525
panic!("Invalid f32 literal {}", n);
510526
}
527+
if n.is_sign_negative() {
528+
panic!("f32 literal cannot be negative {}", n);
529+
}
511530
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())),
512531
Some(Symbol::intern("f32"))))
513532
}
@@ -518,6 +537,9 @@ impl Literal {
518537
if !n.is_finite() {
519538
panic!("Invalid f64 literal {}", n);
520539
}
540+
if n.is_sign_negative() {
541+
panic!("f64 literal cannot be negative {}", n);
542+
}
521543
Literal(token::Literal(token::Lit::Float(Symbol::intern(&n.to_string())),
522544
Some(Symbol::intern("f64"))))
523545
}

src/libproc_macro/quote.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl<'a> Quote for &'a str {
156156

157157
impl Quote for usize {
158158
fn quote(self) -> TokenStream {
159-
TokenNode::Literal(Literal::integer(self as i128)).into()
159+
TokenNode::Literal(Literal::integer(self as u128)).into()
160160
}
161161
}
162162

0 commit comments

Comments
 (0)