How does Box::new() compile into exchange_malloc?

I dig down the compiler to know how the Box::<T>::new() compile to the exchange_malloc call.
I found some code snippets on compiler/rustc_mir_build/src/build/expr/as_rvalue.rs:130:

ExprKind::Box { value } => {
    let value = &this.thir[value];
    let tcx = this.tcx;

    // `exchange_malloc` is unsafe but box is safe, so need a new scope.
    let synth_scope = this.new_source_scope(
        expr_span,
        LintLevel::Inherited,
        Some(Safety::BuiltinUnsafe),
    );
    let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
...

But it only seems to work when I use the box expression, not the Box::new() call.
Can you guys tell me where the Box::new() call terminator translates into the exchange_malloc call?

Because the library code, library/alloc/src/boxed.rs, the Box::new() definition is so confused:

impl<T> Box<T> {
    #[cfg(all(not(no_global_oom_handling)))]
    #[inline(always)]
    #[stable(feature = "rust1", since = "1.0.0")]
    #[must_use]
    #[rustc_diagnostic_item = "box_new"]
    pub fn new(x: T) -> Self {
        #[rustc_box]
        Box::new(x)
    }

Thus, I want to know how the Box::new() compiles into the raw code.

This SO answer looks like it gives the answer you are looking for:

4 Likes

The SO answer also said the Box::new() is translated into a box expression, and the code in my original question, the as_rvalue() in compiler/rustc_mir_build/src/build/expr/as_rvalue.rs handles the expression.

However, I wrote the simple Rust code as follows:

fn main(){
    let b = Box::new(122344);
}

and compile it with RUSTC_LOG=debug rustc test.rs 2>&1 | grep expr_as_rvalue, the debug message never printed, even the function as_rvalue has the debug print at the entry of the function. Do I confused something?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.