Skip to content

Commit 0a79683

Browse files
committed
turn rustc_box into an intrinsic
1 parent bf6f8a4 commit 0a79683

File tree

13 files changed

+137
-138
lines changed

13 files changed

+137
-138
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 0 additions & 5 deletions
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

Lines changed: 3 additions & 0 deletions
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/src/errors.rs

Lines changed: 0 additions & 19 deletions
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

Lines changed: 18 additions & 39 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

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

236+
/// Magic intrinsic to synthesize a `box <expr>` expression.
237+
/// Ends up calling the `exchange_malloc` lang item and then moves the argument
238+
/// into the newly allocated memory.
239+
#[cfg(not(bootstrap))]
240+
#[rustc_intrinsic]
241+
#[rustc_intrinsic_must_be_overridden]
242+
#[unstable(feature = "liballoc_internals", issue = "none")]
243+
pub fn box_new<T>(_x: T) -> Box<T> {
244+
unreachable!()
245+
}
246+
247+
/// Transition function for the next bootstrap bump.
248+
#[cfg(bootstrap)]
249+
#[unstable(feature = "liballoc_internals", issue = "none")]
250+
#[inline(always)]
251+
pub fn box_new<T>(x: T) -> Box<T> {
252+
#[rustc_box]
253+
Box::new(x)
254+
}
255+
236256
impl<T> Box<T> {
237257
/// Allocates memory on the heap and then places `x` into it.
238258
///
@@ -250,8 +270,7 @@ impl<T> Box<T> {
250270
#[rustc_diagnostic_item = "box_new"]
251271
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
252272
pub fn new(x: T) -> Self {
253-
#[rustc_box]
254-
Box::new(x)
273+
return box_new(x);
255274
}
256275

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

library/alloc/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
#![feature(staged_api)]
181181
#![feature(stmt_expr_attributes)]
182182
#![feature(strict_provenance_lints)]
183+
#![feature(intrinsics)]
183184
#![feature(unboxed_closures)]
184185
#![feature(unsized_fn_params)]
185186
#![feature(with_negative_coherence)]

library/alloc/src/macros.rs

Lines changed: 2 additions & 3 deletions
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

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)