Skip to content

Commit 2ba6a5f

Browse files
committed
turn rustc_box into an intrinsic
1 parent bf6f8a4 commit 2ba6a5f

File tree

20 files changed

+181
-174
lines changed

20 files changed

+181
-174
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

-5
Original file line numberDiff line numberDiff line change
@@ -933,11 +933,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
933933
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
934934
the given type by annotating all impl items with #[rustc_allow_incoherent_impl]."
935935
),
936-
rustc_attr!(
937-
rustc_box, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
938-
"#[rustc_box] allows creating boxes \
939-
and it is only intended to be used in `alloc`."
940-
),
941936

942937
BuiltinAttribute {
943938
name: sym::rustc_diagnostic_item,

compiler/rustc_hir_analysis/src/check/intrinsic.rs

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
8686
| sym::assert_inhabited
8787
| sym::assert_zero_valid
8888
| sym::assert_mem_uninitialized_valid
89+
| sym::box_new
8990
| sym::breakpoint
9091
| sym::size_of
9192
| sym::min_align_of
@@ -606,6 +607,8 @@ pub fn check_intrinsic_type(
606607

607608
sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool),
608609

610+
sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))),
611+
609612
sym::simd_eq
610613
| sym::simd_ne
611614
| sym::simd_lt

compiler/rustc_mir_build/messages.ftl

-5
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,6 @@ mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabite
287287
288288
mir_build_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024
289289
290-
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
291-
.attributes = no other attributes may be applied
292-
.not_box = `#[rustc_box]` may only be applied to a `Box::new()` call
293-
.missing_box = `#[rustc_box]` requires the `owned_box` lang item
294-
295290
mir_build_static_in_pattern = statics cannot be referenced in patterns
296291
.label = can't be used in patterns
297292
mir_build_static_in_pattern_def = `static` defined here

compiler/rustc_mir_build/src/errors.rs

-19
Original file line numberDiff line numberDiff line change
@@ -1067,25 +1067,6 @@ pub(crate) enum MiscPatternSuggestion {
10671067
},
10681068
}
10691069

1070-
#[derive(Diagnostic)]
1071-
#[diag(mir_build_rustc_box_attribute_error)]
1072-
pub(crate) struct RustcBoxAttributeError {
1073-
#[primary_span]
1074-
pub(crate) span: Span,
1075-
#[subdiagnostic]
1076-
pub(crate) reason: RustcBoxAttrReason,
1077-
}
1078-
1079-
#[derive(Subdiagnostic)]
1080-
pub(crate) enum RustcBoxAttrReason {
1081-
#[note(mir_build_attributes)]
1082-
Attributes,
1083-
#[note(mir_build_not_box)]
1084-
NotBoxNew,
1085-
#[note(mir_build_missing_box)]
1086-
MissingBox,
1087-
}
1088-
10891070
#[derive(LintDiagnostic)]
10901071
#[diag(mir_build_rust_2024_incompatible_pat)]
10911072
pub(crate) struct Rust2024IncompatiblePat<'a> {

compiler/rustc_mir_build/src/thir/cx/expr.rs

+18-39
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use rustc_middle::{bug, span_bug};
2020
use rustc_span::{Span, sym};
2121
use tracing::{debug, info, instrument, trace};
2222

23-
use crate::errors;
2423
use crate::thir::cx::Cx;
2524
use crate::thir::util::UserAnnotatedTyHelpers;
2625

@@ -380,45 +379,25 @@ impl<'tcx> Cx<'tcx> {
380379
from_hir_call: true,
381380
fn_span: expr.span,
382381
}
383-
} else {
384-
let attrs = tcx.hir().attrs(expr.hir_id);
385-
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_box) {
386-
if attrs.len() != 1 {
387-
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
388-
span: attrs[0].span,
389-
reason: errors::RustcBoxAttrReason::Attributes,
390-
});
391-
} else if let Some(box_item) = tcx.lang_items().owned_box() {
392-
if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) =
393-
fun.kind
394-
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
395-
&& path.res.opt_def_id().is_some_and(|did| did == box_item)
396-
&& fn_path.ident.name == sym::new
397-
&& let [value] = args
398-
{
399-
return Expr {
400-
temp_lifetime: TempLifetime {
401-
temp_lifetime,
402-
backwards_incompatible,
403-
},
404-
ty: expr_ty,
405-
span: expr.span,
406-
kind: ExprKind::Box { value: self.mirror_expr(value) },
407-
};
408-
} else {
409-
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
410-
span: expr.span,
411-
reason: errors::RustcBoxAttrReason::NotBoxNew,
412-
});
413-
}
414-
} else {
415-
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
416-
span: attrs[0].span,
417-
reason: errors::RustcBoxAttrReason::MissingBox,
418-
});
419-
}
382+
} else if let ty::FnDef(def_id, _) = self.typeck_results().expr_ty(fun).kind()
383+
&& let Some(intrinsic) = self.tcx.intrinsic(def_id)
384+
&& intrinsic.name == sym::box_new
385+
{
386+
// We don't actually evaluate `fun` here, so make sure that doesn't miss any side-effects.
387+
if !matches!(fun.kind, hir::ExprKind::Path(_)) {
388+
span_bug!(
389+
expr.span,
390+
"`box_new` intrinsic can only be called via path expression"
391+
);
420392
}
421-
393+
let value = &args[0];
394+
return Expr {
395+
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
396+
ty: expr_ty,
397+
span: expr.span,
398+
kind: ExprKind::Box { value: self.mirror_expr(value) },
399+
};
400+
} else {
422401
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
423402
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
424403
&& let Some(adt_def) = expr_ty.ty_adt_def()

compiler/rustc_span/src/symbol.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,6 @@ symbols! {
16961696
rustc_as_ptr,
16971697
rustc_attrs,
16981698
rustc_autodiff,
1699-
rustc_box,
17001699
rustc_builtin_macro,
17011700
rustc_capture_analysis,
17021701
rustc_clean,

library/alloc/src/alloc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ unsafe impl Allocator for Global {
339339
}
340340
}
341341

342-
/// The allocator for unique pointers.
342+
/// The allocator for `Box`.
343343
#[cfg(all(not(no_global_oom_handling), not(test)))]
344344
#[lang = "exchange_malloc"]
345345
#[inline]

library/alloc/src/boxed.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,27 @@ pub struct Box<
233233
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
234234
>(Unique<T>, A);
235235

236+
/// Constructs a `Box<T>` by calling the `exchange_malloc` lang item and moving the argument into
237+
/// the newly allocated memory.
238+
///
239+
/// This is the surface syntax for `box <expr>` expressions.
240+
#[cfg(not(bootstrap))]
241+
#[rustc_intrinsic]
242+
#[rustc_intrinsic_must_be_overridden]
243+
#[unstable(feature = "liballoc_internals", issue = "none")]
244+
pub fn box_new<T>(_x: T) -> Box<T> {
245+
unreachable!()
246+
}
247+
248+
/// Transition function for the next bootstrap bump.
249+
#[cfg(bootstrap)]
250+
#[unstable(feature = "liballoc_internals", issue = "none")]
251+
#[inline(always)]
252+
pub fn box_new<T>(x: T) -> Box<T> {
253+
#[rustc_box]
254+
Box::new(x)
255+
}
256+
236257
impl<T> Box<T> {
237258
/// Allocates memory on the heap and then places `x` into it.
238259
///
@@ -250,8 +271,7 @@ impl<T> Box<T> {
250271
#[rustc_diagnostic_item = "box_new"]
251272
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
252273
pub fn new(x: T) -> Self {
253-
#[rustc_box]
254-
Box::new(x)
274+
return box_new(x);
255275
}
256276

257277
/// Constructs a new box with uninitialized contents.

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
#![feature(dropck_eyepatch)]
169169
#![feature(fundamental)]
170170
#![feature(hashmap_internals)]
171+
#![feature(intrinsics)]
171172
#![feature(lang_items)]
172173
#![feature(min_specialization)]
173174
#![feature(multiple_supertrait_upcastable)]

library/alloc/src/macros.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,9 @@ macro_rules! vec {
4848
);
4949
($($x:expr),+ $(,)?) => (
5050
<[_]>::into_vec(
51-
// This rustc_box is not required, but it produces a dramatic improvement in compile
51+
// Using the intrinsic produces a dramatic improvement in compile
5252
// time when constructing arrays with many elements.
53-
#[rustc_box]
54-
$crate::boxed::Box::new([$($x),+])
53+
$crate::boxed::box_new([$($x),+])
5554
)
5655
);
5756
}

tests/ui/attributes/rustc-box.rs

-18
This file was deleted.

tests/ui/attributes/rustc-box.stderr

-34
This file was deleted.

tests/ui/coroutine/issue-105084.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#![feature(coroutines)]
33
#![feature(coroutine_clone)]
44
#![feature(coroutine_trait)]
5-
#![feature(rustc_attrs, stmt_expr_attributes)]
5+
#![feature(rustc_attrs, stmt_expr_attributes, liballoc_internals)]
66

77
use std::ops::Coroutine;
88
use std::pin::Pin;
@@ -19,8 +19,7 @@ fn main() {
1919
// - create a Box that is ignored for trait computations;
2020
// - compute fields (and yields);
2121
// - assign to `t`.
22-
let t = #[rustc_box]
23-
Box::new((5, yield));
22+
let t = std::boxed::box_new((5, yield));
2423
drop(t);
2524
};
2625

tests/ui/coroutine/issue-105084.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0382]: borrow of moved value: `g`
2-
--> $DIR/issue-105084.rs:39:14
2+
--> $DIR/issue-105084.rs:38:14
33
|
44
LL | let mut g = #[coroutine]
55
| ----- move occurs because `g` has type `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, which does not implement the `Copy` trait
@@ -23,7 +23,7 @@ LL | let mut h = copy(g.clone());
2323
| ++++++++
2424

2525
error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
26-
--> $DIR/issue-105084.rs:33:17
26+
--> $DIR/issue-105084.rs:32:17
2727
|
2828
LL | || {
2929
| -- within this `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`
@@ -32,13 +32,13 @@ LL | let mut h = copy(g);
3232
| ^^^^^^^ within `{coroutine@$DIR/issue-105084.rs:16:5: 16:7}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
3333
|
3434
note: coroutine does not implement `Copy` as this value is used across a yield
35-
--> $DIR/issue-105084.rs:23:22
35+
--> $DIR/issue-105084.rs:22:41
3636
|
37-
LL | Box::new((5, yield));
38-
| -------------^^^^^--
39-
| | |
40-
| | yield occurs here, with `Box::new((5, yield))` maybe used later
41-
| has type `Box<(i32, ())>` which does not implement `Copy`
37+
LL | let t = std::boxed::box_new((5, yield));
38+
| ------------------------^^^^^--
39+
| | |
40+
| | yield occurs here, with `std::boxed::box_new((5, yield))` maybe used later
41+
| has type `Box<(i32, ())>` which does not implement `Copy`
4242
note: required by a bound in `copy`
4343
--> $DIR/issue-105084.rs:10:12
4444
|
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
#![feature(rustc_attrs, stmt_expr_attributes)]
21
#![deny(unused_allocation)]
32

43
fn main() {
5-
_ = (#[rustc_box] Box::new([1])).len(); //~ error: unnecessary allocation, use `&` instead
64
_ = Box::new([1]).len(); //~ error: unnecessary allocation, use `&` instead
75
}
+5-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
error: unnecessary allocation, use `&` instead
2-
--> $DIR/unused-allocation.rs:5:9
2+
--> $DIR/unused-allocation.rs:4:9
33
|
4-
LL | _ = (#[rustc_box] Box::new([1])).len();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
LL | _ = Box::new([1]).len();
5+
| ^^^^^^^^^^^^^
66
|
77
note: the lint level is defined here
8-
--> $DIR/unused-allocation.rs:2:9
8+
--> $DIR/unused-allocation.rs:1:9
99
|
1010
LL | #![deny(unused_allocation)]
1111
| ^^^^^^^^^^^^^^^^^
1212

13-
error: unnecessary allocation, use `&` instead
14-
--> $DIR/unused-allocation.rs:6:9
15-
|
16-
LL | _ = Box::new([1]).len();
17-
| ^^^^^^^^^^^^^
18-
19-
error: aborting due to 2 previous errors
13+
error: aborting due to 1 previous error
2014

tests/ui/macros/vec-macro-in-pattern.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
fn main() {
66
match Some(vec![42]) {
7-
Some(vec![43]) => {} //~ ERROR expected pattern, found `#`
7+
Some(vec![43]) => {} //~ ERROR expected a pattern, found a function call
8+
//~| ERROR found associated function
9+
//~| ERROR usage of qualified paths in this context is experimental
810
_ => {}
911
}
1012
}

0 commit comments

Comments
 (0)