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 13, 2024
1 parent deb0d0f commit 7638733
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 27 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
1 change: 0 additions & 1 deletion tests/ui/borrowck/issue-64453.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ struct Value;

static settings_dir: String = format!("");
//~^ ERROR cannot call non-const fn
//~| ERROR is not yet stable as a const

fn from_string(_: String) -> Value {
Value
Expand Down
13 changes: 2 additions & 11 deletions tests/ui/borrowck/issue-64453.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
error: `Arguments::<'a>::new_const` is not yet stable as a const fn
--> $DIR/issue-64453.rs:4:31
|
LL | static settings_dir: String = format!("");
| ^^^^^^^^^^^
|
= help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0015]: cannot call non-const fn `format` in statics
--> $DIR/issue-64453.rs:4:31
|
Expand All @@ -18,7 +9,7 @@ LL | static settings_dir: String = format!("");
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0507]: cannot move out of static item `settings_dir`
--> $DIR/issue-64453.rs:14:37
--> $DIR/issue-64453.rs:13:37
|
LL | let settings_data = from_string(settings_dir);
| ^^^^^^^^^^^^ move occurs because `settings_dir` has type `String`, which does not implement the `Copy` trait
Expand All @@ -28,7 +19,7 @@ help: consider cloning the value if the performance cost is acceptable
LL | let settings_data = from_string(settings_dir.clone());
| ++++++++

error: aborting due to 3 previous errors
error: aborting due to 2 previous errors

Some errors have detailed explanations: E0015, E0507.
For more information about an error, try `rustc --explain E0015`.
2 changes: 1 addition & 1 deletion tests/ui/consts/const-format-arguments.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

pub fn main() {
const A: std::fmt::Arguments = std::fmt::Arguments::new_const(&[&"hola"]);
//~^ use of unstable library feature
//~| temporary value dropped while borrowed
}
15 changes: 9 additions & 6 deletions tests/ui/consts/const-format-arguments.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ LL | const A: std::fmt::Arguments = std::fmt::Arguments::new_const(&[&"hola"
= help: add `#![feature(fmt_internals)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date

error: `Arguments::<'a>::new_const` is not yet stable as a const fn
--> $DIR/const-format-arguments.rs:3:36
error[E0716]: temporary value dropped while borrowed
--> $DIR/const-format-arguments.rs:3:68
|
LL | const A: std::fmt::Arguments = std::fmt::Arguments::new_const(&[&"hola"]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
| --------------------------------^^^^^^^^^-
| | | |
| | | temporary value is freed at the end of this statement
| | creates a temporary value which is freed while still in use
| using this value as a constant requires that borrow lasts for `'static`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0658`.
Some errors have detailed explanations: E0658, E0716.
For more information about an error, try `rustc --explain E0658`.
1 change: 0 additions & 1 deletion tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ compile-flags: -Znext-solver
#![allow(incomplete_features)]
#![feature(const_fmt_arguments_new)]
#![feature(const_trait_impl, effects)]

#[const_trait]
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0015]: cannot call non-const fn `_print` in constant functions
--> $DIR/issue-79450.rs:11:9
--> $DIR/issue-79450.rs:10:9
|
LL | println!("lul");
| ^^^^^^^^^^^^^^^
Expand Down

0 comments on commit 7638733

Please sign in to comment.