Skip to content

Commit

Permalink
Auto merge of rust-lang#116633 - agluszak:fix-116631, r=<try>
Browse files Browse the repository at this point in the history
Do not inline integer linterals which are out of range in format_args!

Inlining integers (even those out of range) was introduced in rust-lang#106824.

Closes rust-lang#116631.
  • Loading branch information
bors committed Oct 11, 2023
2 parents 71704c4 + b0ae218 commit b67bddc
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 2 deletions.
20 changes: 20 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1795,6 +1795,26 @@ pub enum LitIntType {
Unsuffixed,
}

impl LitIntType {
pub const fn max_literal_value(&self) -> u128 {
match self {
LitIntType::Signed(IntTy::I8) => i8::MAX as u128,
LitIntType::Signed(IntTy::I16) => i16::MAX as u128,
LitIntType::Signed(IntTy::I32) => i32::MAX as u128,
LitIntType::Signed(IntTy::I64) => i64::MAX as u128,
LitIntType::Signed(IntTy::I128) => i128::MAX as u128,
LitIntType::Signed(IntTy::Isize) => isize::MAX as u128,
LitIntType::Unsigned(UintTy::U8) => u8::MAX as u128,
LitIntType::Unsigned(UintTy::U16) => u16::MAX as u128,
LitIntType::Unsigned(UintTy::U32) => u32::MAX as u128,
LitIntType::Unsigned(UintTy::U64) => u64::MAX as u128,
LitIntType::Unsigned(UintTy::U128) => u128::MAX,
LitIntType::Unsigned(UintTy::Usize) => usize::MAX as u128,
LitIntType::Unsuffixed => u128::MAX,
}
}
}

/// Type of the float literal based on provided suffix.
#[derive(Clone, Copy, Encodable, Decodable, Debug, Hash, Eq, PartialEq)]
#[derive(HashStable_Generic)]
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ fn inline_literals(mut fmt: Cow<'_, FormatArgs>) -> Cow<'_, FormatArgs> {
{
literal = Some(s);
} else if let token::LitKind::Integer = lit.kind
&& let Ok(LitKind::Int(n, _)) = LitKind::from_token_lit(lit)
&& let Ok(LitKind::Int(n, ty)) = LitKind::from_token_lit(lit)
{
literal = Some(Symbol::intern(&n.to_string()));
// Check if n fits in the type of the argument. If it doesn't,
// simply don't inline the literal here, the error will be emitted at a later stage.
if n <= ty.max_literal_value() {
literal = Some(Symbol::intern(&n.to_string()));
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions tests/ui/fmt/issue-116631.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
format_args!("{}\n", 0xffff_ffff_u8); //~ ERROR literal out of range for `u8`
}
11 changes: 11 additions & 0 deletions tests/ui/fmt/issue-116631.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error: literal out of range for `u8`
--> $DIR/issue-116631.rs:2:26
|
LL | format_args!("{}\n", 0xffff_ffff_u8);
| ^^^^^^^^^^^^^^ help: consider using the type `u32` instead: `0xffff_ffff_u32`
|
= note: the literal `0xffff_ffff_u8` (decimal `4294967295`) does not fit into the type `u8` and will become `255u8`
= note: `#[deny(overflowing_literals)]` on by default

error: aborting due to previous error

0 comments on commit b67bddc

Please sign in to comment.