Skip to content

Commit 90b61b5

Browse files
authored
Unrolled build for rust-lang#135046
Rollup merge of rust-lang#135046 - RalfJung:rustc_box_intrinsic, r=compiler-errors turn rustc_box into an intrinsic I am not entirely sure why this was made a special magic attribute, but an intrinsic seems like a more natural way to add magic expressions to the language.
2 parents ead4a8f + ac9cb90 commit 90b61b5

File tree

25 files changed

+198
-208
lines changed

25 files changed

+198
-208
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. This is an intrinsic to avoid unnecessary copies.
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
}

src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
1-
error: use of a disallowed macro `std::vec`
2-
--> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
3-
|
4-
LL | vec![1, 2, 3];
5-
| ^^^^^^^^^^^^^
6-
|
7-
= note: `-D clippy::disallowed-macros` implied by `-D warnings`
8-
= help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
9-
101
error: use of a disallowed macro `serde::Serialize`
112
--> tests/ui-toml/disallowed_macros/disallowed_macros.rs:18:14
123
|
134
LL | #[derive(Serialize)]
145
| ^^^^^^^^^
156
|
167
= note: no serializing
8+
= note: `-D clippy::disallowed-macros` implied by `-D warnings`
9+
= help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
1710

1811
error: use of a disallowed macro `macros::attr`
1912
--> tests/ui-toml/disallowed_macros/disallowed_macros.rs:31:1
@@ -47,6 +40,12 @@ error: use of a disallowed macro `std::cfg`
4740
LL | cfg!(unix);
4841
| ^^^^^^^^^^
4942

43+
error: use of a disallowed macro `std::vec`
44+
--> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
45+
|
46+
LL | vec![1, 2, 3];
47+
| ^^^^^^^^^^^^^
48+
5049
error: use of a disallowed macro `macros::expr`
5150
--> tests/ui-toml/disallowed_macros/disallowed_macros.rs:21:13
5251
|

tests/mir-opt/box_expr.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ test-mir-pass: ElaborateDrops
22
//@ needs-unwind
33

4-
#![feature(rustc_attrs, stmt_expr_attributes)]
4+
#![feature(rustc_attrs, liballoc_internals)]
55

66
// EMIT_MIR box_expr.main.ElaborateDrops.diff
77
fn main() {
@@ -17,8 +17,7 @@ fn main() {
1717
// CHECK: [[boxref:_.*]] = &mut [[box]];
1818
// CHECK: <Box<S> as Drop>::drop(move [[boxref]])
1919

20-
let x = #[rustc_box]
21-
Box::new(S::new());
20+
let x = std::boxed::box_new(S::new());
2221
drop(x);
2322
}
2423

tests/mir-opt/building/uniform_array_move_out.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
// skip-filecheck
2-
#![feature(stmt_expr_attributes, rustc_attrs)]
2+
#![feature(liballoc_internals, rustc_attrs)]
33

44
// EMIT_MIR uniform_array_move_out.move_out_from_end.built.after.mir
55
fn move_out_from_end() {
6-
let a = [
7-
#[rustc_box]
8-
Box::new(1),
9-
#[rustc_box]
10-
Box::new(2),
11-
];
6+
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
127
let [.., _y] = a;
138
}
149

1510
// EMIT_MIR uniform_array_move_out.move_out_by_subslice.built.after.mir
1611
fn move_out_by_subslice() {
17-
let a = [
18-
#[rustc_box]
19-
Box::new(1),
20-
#[rustc_box]
21-
Box::new(2),
22-
];
12+
let a = [std::boxed::box_new(1), std::boxed::box_new(2)];
2313
let [_y @ ..] = a;
2414
}
2515

tests/mir-opt/const_prop/boxes.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//@ compile-flags: -O
33
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
44

5-
#![feature(rustc_attrs, stmt_expr_attributes)]
5+
#![feature(rustc_attrs, liballoc_internals)]
66

77
// Note: this test verifies that we, in fact, do not const prop `#[rustc_box]`
88

@@ -13,7 +13,5 @@ fn main() {
1313
// CHECK: (*{{_.*}}) = const 42_i32;
1414
// CHECK: [[tmp:_.*]] = copy (*{{_.*}});
1515
// CHECK: [[x]] = copy [[tmp]];
16-
let x = *(#[rustc_box]
17-
Box::new(42))
18-
+ 0;
16+
let x = *(std::boxed::box_new(42)) + 0;
1917
}

tests/mir-opt/issue_62289.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,11 @@
33
// initializing it
44
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
55

6-
#![feature(rustc_attrs)]
6+
#![feature(rustc_attrs, liballoc_internals)]
77

88
// EMIT_MIR issue_62289.test.ElaborateDrops.before.mir
99
fn test() -> Option<Box<u32>> {
10-
Some(
11-
#[rustc_box]
12-
Box::new(None?),
13-
)
10+
Some(std::boxed::box_new(None?))
1411
}
1512

1613
fn main() {

tests/ui/attributes/rustc-box.rs

-18
This file was deleted.

tests/ui/attributes/rustc-box.stderr

-34
This file was deleted.

0 commit comments

Comments
 (0)