Skip to content

Commit

Permalink
Evaluate std::fmt::Arguments::new_const() During Compile Time
Browse files Browse the repository at this point in the history
  • Loading branch information
veera-sivarajan committed Oct 14, 2024
1 parent deb0d0f commit 558d241
Show file tree
Hide file tree
Showing 19 changed files with 112 additions and 126 deletions.
27 changes: 25 additions & 2 deletions compiler/rustc_ast_lowering/src/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_ast::visit::Visitor;
use rustc_ast::*;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_session::config::FmtDebug;
use rustc_span::symbol::{Ident, kw};
use rustc_span::{Span, Symbol, sym};
Expand All @@ -24,6 +25,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
expand_format_args(self, sp, &fmt, allow_const)
}

/// Wraps given `ExprKind` in an inline const block.
///
/// Caller must ensure it's safe and sound to do so.
fn wrap_in_const_context(
&mut self,
sp: Span,
kind: hir::ExprKind<'hir>,
) -> hir::ExprKind<'hir> {
let expr = hir::Expr { hir_id: self.next_id(), kind, span: self.lower_span(sp) };
let const_node_id = self.next_node_id();
let parent_def_id = self.current_def_id_parent;
let def_id =
self.create_def(parent_def_id, const_node_id, kw::Empty, DefKind::InlineConst, sp);
let hir_id = self.lower_node_id(const_node_id);
let const_block = self.with_new_scopes(sp, |this| hir::ConstBlock {
def_id,
hir_id,
body: this.with_def_id_parent(def_id, |this| this.lower_body(|_| (&[], expr))),
});
hir::ExprKind::ConstBlock(const_block)
}

/// Try to convert a literal into an interned string
fn try_inline_lit(&self, lit: token::Lit) -> Option<Symbol> {
match LitKind::from_token_lit(lit) {
Expand Down Expand Up @@ -464,14 +487,14 @@ fn expand_format_args<'hir>(

if allow_const && arguments.is_empty() && argmap.is_empty() {
// Generate:
// <core::fmt::Arguments>::new_const(lit_pieces)
// const { <core::fmt::Arguments>::new_const(lit_pieces) }
let new = ctx.arena.alloc(ctx.expr_lang_item_type_relative(
macsp,
hir::LangItem::FormatArguments,
sym::new_const,
));
let new_args = ctx.arena.alloc_from_iter([lit_pieces]);
return hir::ExprKind::Call(new, new_args);
return ctx.wrap_in_const_context(macsp, hir::ExprKind::Call(new, new_args));
}

// If the args array contains exactly all the original arguments once,
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ pub struct Arguments<'a> {
#[unstable(feature = "fmt_internals", issue = "none")]
impl<'a> Arguments<'a> {
#[inline]
#[rustc_const_unstable(feature = "const_fmt_arguments_new", issue = "none")]
#[rustc_const_stable(feature = "const_fmt_arguments_new", since = "CURRENT_RUSTC_VERSION")]
pub const fn new_const<const N: usize>(pieces: &'a [&'static str; N]) -> Self {
const { assert!(N <= 1) };
Arguments { pieces, fmt: None, args: &[] }
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@
#![feature(const_char_encode_utf16)]
#![feature(const_eval_select)]
#![feature(const_exact_div)]
#![feature(const_fmt_arguments_new)]
#![feature(const_hash)]
#![feature(const_heap)]
#![feature(const_index_range_slice_index)]
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1038,7 +1038,7 @@ pub(crate) mod builtin {
///
/// This macro will be removed once `format_args` is allowed in const contexts.
#[unstable(feature = "const_format_args", issue = "none")]
#[allow_internal_unstable(fmt_internals, const_fmt_arguments_new)]
#[allow_internal_unstable(fmt_internals)]
#[rustc_builtin_macro]
#[macro_export]
macro_rules! const_format_args {
Expand Down
2 changes: 1 addition & 1 deletion tests/codegen/issues/issue-128709-format-without-args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![crate_type = "lib"]

// String formating macros without any arguments should compile
// to a `memcpy` followed by a call to `std::io::stdio::_print`.
// to a `memcpy` followed by a call to a library function.

#[no_mangle]
pub fn code() {
Expand Down
13 changes: 5 additions & 8 deletions tests/coverage/assert.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,12 @@ Number of file 0 mappings: 9
Highest counter ID seen: c4

Function name: assert::might_fail_assert
Raw bytes (21): 0x[01, 01, 01, 01, 05, 03, 01, 04, 01, 02, 0f, 02, 02, 25, 00, 3d, 05, 01, 01, 00, 02]
Raw bytes (14): 0x[01, 01, 00, 02, 01, 04, 01, 02, 3e, 05, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
Number of file 0 mappings: 3
- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 15)
- Code(Expression(0, Sub)) at (prev + 2, 37) to (start + 0, 61)
= (c0 - c1)
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 4, 1) to (start + 2, 62)
- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c1

42 changes: 18 additions & 24 deletions tests/coverage/bad_counter_ids.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,13 @@ Number of file 0 mappings: 2
Highest counter ID seen: c0

Function name: bad_counter_ids::eq_bad_message
Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 29, 01, 02, 0f, 02, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
Raw bytes (14): 0x[01, 01, 00, 02, 01, 29, 01, 02, 2c, 00, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Zero
Number of file 0 mappings: 3
- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 15)
- Code(Expression(0, Sub)) at (prev + 2, 32) to (start + 0, 43)
= (c0 - Zero)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Number of expressions: 0
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 41, 1) to (start + 2, 44)
- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c0

Function name: bad_counter_ids::eq_good
Expand All @@ -32,14 +29,13 @@ Number of file 0 mappings: 2
Highest counter ID seen: c1

Function name: bad_counter_ids::eq_good_message
Raw bytes (19): 0x[01, 01, 00, 03, 01, 15, 01, 02, 0f, 00, 02, 20, 00, 2b, 05, 01, 01, 00, 02]
Raw bytes (14): 0x[01, 01, 00, 02, 01, 15, 01, 02, 2c, 05, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 3
- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 15)
- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 21, 1) to (start + 2, 44)
- Code(Counter(1)) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c1

Function name: bad_counter_ids::ne_bad
Expand All @@ -53,15 +49,14 @@ Number of file 0 mappings: 2
Highest counter ID seen: c0

Function name: bad_counter_ids::ne_bad_message
Raw bytes (19): 0x[01, 01, 00, 03, 01, 33, 01, 02, 0f, 05, 02, 20, 00, 2b, 00, 01, 01, 00, 02]
Raw bytes (14): 0x[01, 01, 00, 02, 01, 33, 01, 02, 2c, 00, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 0
Number of file 0 mappings: 3
- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 15)
- Code(Counter(1)) at (prev + 2, 32) to (start + 0, 43)
- Code(Zero) at (prev + 1, 1) to (start + 0, 2)
Highest counter ID seen: c1
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 51, 1) to (start + 2, 44)
- Code(Zero) at (prev + 3, 1) to (start + 0, 2)
Highest counter ID seen: c0

Function name: bad_counter_ids::ne_good
Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 1a, 01, 02, 1f, 02, 03, 01, 00, 02]
Expand All @@ -76,15 +71,14 @@ Number of file 0 mappings: 2
Highest counter ID seen: c0

Function name: bad_counter_ids::ne_good_message
Raw bytes (21): 0x[01, 01, 01, 01, 00, 03, 01, 1f, 01, 02, 0f, 00, 02, 20, 00, 2b, 02, 01, 01, 00, 02]
Raw bytes (16): 0x[01, 01, 01, 01, 00, 02, 01, 1f, 01, 02, 2c, 02, 03, 01, 00, 02]
Number of files: 1
- file 0 => global file 1
Number of expressions: 1
- expression 0 operands: lhs = Counter(0), rhs = Zero
Number of file 0 mappings: 3
- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 15)
- Code(Zero) at (prev + 2, 32) to (start + 0, 43)
- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
Number of file 0 mappings: 2
- Code(Counter(0)) at (prev + 31, 1) to (start + 2, 44)
- Code(Expression(0, Sub)) at (prev + 3, 1) to (start + 0, 2)
= (c0 - Zero)
Highest counter ID seen: c0

9 changes: 4 additions & 5 deletions tests/coverage/closure_macro.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,19 @@ Number of file 0 mappings: 6
Highest counter ID seen: c1

Function name: closure_macro::main::{closure#0}
Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
Raw bytes (30): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 04, 01, 10, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 1f, 07, 02, 09, 00, 0a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
Number of file 0 mappings: 5
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 16, 28) to (start + 3, 33)
- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 31)
= (c0 - c1)
- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
- Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10)
= (c1 + (c2 + c3))
Highest counter ID seen: c3
Highest counter ID seen: c1

9 changes: 4 additions & 5 deletions tests/coverage/closure_macro_async.cov-map
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,19 @@ Number of file 0 mappings: 6
Highest counter ID seen: c1

Function name: closure_macro_async::test::{closure#0}::{closure#0}
Raw bytes (35): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 05, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 16, 0d, 00, 17, 00, 1e, 07, 02, 09, 00, 0a]
Raw bytes (30): 0x[01, 01, 03, 01, 05, 05, 0b, 09, 0d, 04, 01, 15, 1c, 03, 21, 05, 04, 11, 01, 27, 02, 03, 11, 00, 1f, 07, 02, 09, 00, 0a]
Number of files: 1
- file 0 => global file 1
Number of expressions: 3
- expression 0 operands: lhs = Counter(0), rhs = Counter(1)
- expression 1 operands: lhs = Counter(1), rhs = Expression(2, Add)
- expression 2 operands: lhs = Counter(2), rhs = Counter(3)
Number of file 0 mappings: 5
Number of file 0 mappings: 4
- Code(Counter(0)) at (prev + 21, 28) to (start + 3, 33)
- Code(Counter(1)) at (prev + 4, 17) to (start + 1, 39)
- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 22)
- Code(Expression(0, Sub)) at (prev + 3, 17) to (start + 0, 31)
= (c0 - c1)
- Code(Counter(3)) at (prev + 0, 23) to (start + 0, 30)
- Code(Expression(1, Add)) at (prev + 2, 9) to (start + 0, 10)
= (c1 + (c2 + c3))
Highest counter ID seen: c3
Highest counter ID seen: c1

Loading

0 comments on commit 558d241

Please sign in to comment.