turn rustc_box into an intrinsic
This commit is contained in:
@@ -933,11 +933,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
||||
"#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \
|
||||
the given type by annotating all impl items with #[rustc_allow_incoherent_impl]."
|
||||
),
|
||||
rustc_attr!(
|
||||
rustc_box, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No,
|
||||
"#[rustc_box] allows creating boxes \
|
||||
and it is only intended to be used in `alloc`."
|
||||
),
|
||||
|
||||
BuiltinAttribute {
|
||||
name: sym::rustc_diagnostic_item,
|
||||
|
||||
@@ -86,6 +86,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
|
||||
| sym::assert_inhabited
|
||||
| sym::assert_zero_valid
|
||||
| sym::assert_mem_uninitialized_valid
|
||||
| sym::box_new
|
||||
| sym::breakpoint
|
||||
| sym::size_of
|
||||
| sym::min_align_of
|
||||
@@ -606,6 +607,8 @@ pub fn check_intrinsic_type(
|
||||
|
||||
sym::ub_checks => (0, 0, Vec::new(), tcx.types.bool),
|
||||
|
||||
sym::box_new => (1, 0, vec![param(0)], Ty::new_box(tcx, param(0))),
|
||||
|
||||
sym::simd_eq
|
||||
| sym::simd_ne
|
||||
| sym::simd_lt
|
||||
|
||||
@@ -287,11 +287,6 @@ mir_build_privately_uninhabited = pattern `{$witness_1}` is currently uninhabite
|
||||
|
||||
mir_build_rust_2024_incompatible_pat = this pattern relies on behavior which may change in edition 2024
|
||||
|
||||
mir_build_rustc_box_attribute_error = `#[rustc_box]` attribute used incorrectly
|
||||
.attributes = no other attributes may be applied
|
||||
.not_box = `#[rustc_box]` may only be applied to a `Box::new()` call
|
||||
.missing_box = `#[rustc_box]` requires the `owned_box` lang item
|
||||
|
||||
mir_build_static_in_pattern = statics cannot be referenced in patterns
|
||||
.label = can't be used in patterns
|
||||
mir_build_static_in_pattern_def = `static` defined here
|
||||
|
||||
@@ -1067,25 +1067,6 @@ pub(crate) enum MiscPatternSuggestion {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(mir_build_rustc_box_attribute_error)]
|
||||
pub(crate) struct RustcBoxAttributeError {
|
||||
#[primary_span]
|
||||
pub(crate) span: Span,
|
||||
#[subdiagnostic]
|
||||
pub(crate) reason: RustcBoxAttrReason,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub(crate) enum RustcBoxAttrReason {
|
||||
#[note(mir_build_attributes)]
|
||||
Attributes,
|
||||
#[note(mir_build_not_box)]
|
||||
NotBoxNew,
|
||||
#[note(mir_build_missing_box)]
|
||||
MissingBox,
|
||||
}
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(mir_build_rust_2024_incompatible_pat)]
|
||||
pub(crate) struct Rust2024IncompatiblePat<'a> {
|
||||
|
||||
@@ -20,7 +20,6 @@ use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::{Span, sym};
|
||||
use tracing::{debug, info, instrument, trace};
|
||||
|
||||
use crate::errors;
|
||||
use crate::thir::cx::Cx;
|
||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
|
||||
@@ -380,45 +379,25 @@ impl<'tcx> Cx<'tcx> {
|
||||
from_hir_call: true,
|
||||
fn_span: expr.span,
|
||||
}
|
||||
} else {
|
||||
let attrs = tcx.hir().attrs(expr.hir_id);
|
||||
if attrs.iter().any(|a| a.name_or_empty() == sym::rustc_box) {
|
||||
if attrs.len() != 1 {
|
||||
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
|
||||
span: attrs[0].span,
|
||||
reason: errors::RustcBoxAttrReason::Attributes,
|
||||
});
|
||||
} else if let Some(box_item) = tcx.lang_items().owned_box() {
|
||||
if let hir::ExprKind::Path(hir::QPath::TypeRelative(ty, fn_path)) =
|
||||
fun.kind
|
||||
&& let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
|
||||
&& path.res.opt_def_id().is_some_and(|did| did == box_item)
|
||||
&& fn_path.ident.name == sym::new
|
||||
&& let [value] = args
|
||||
{
|
||||
return Expr {
|
||||
temp_lifetime: TempLifetime {
|
||||
temp_lifetime,
|
||||
backwards_incompatible,
|
||||
},
|
||||
ty: expr_ty,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Box { value: self.mirror_expr(value) },
|
||||
};
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
|
||||
span: expr.span,
|
||||
reason: errors::RustcBoxAttrReason::NotBoxNew,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
tcx.dcx().emit_err(errors::RustcBoxAttributeError {
|
||||
span: attrs[0].span,
|
||||
reason: errors::RustcBoxAttrReason::MissingBox,
|
||||
});
|
||||
}
|
||||
} else if let ty::FnDef(def_id, _) = self.typeck_results().expr_ty(fun).kind()
|
||||
&& let Some(intrinsic) = self.tcx.intrinsic(def_id)
|
||||
&& intrinsic.name == sym::box_new
|
||||
{
|
||||
// We don't actually evaluate `fun` here, so make sure that doesn't miss any side-effects.
|
||||
if !matches!(fun.kind, hir::ExprKind::Path(_)) {
|
||||
span_bug!(
|
||||
expr.span,
|
||||
"`box_new` intrinsic can only be called via path expression"
|
||||
);
|
||||
}
|
||||
|
||||
let value = &args[0];
|
||||
return Expr {
|
||||
temp_lifetime: TempLifetime { temp_lifetime, backwards_incompatible },
|
||||
ty: expr_ty,
|
||||
span: expr.span,
|
||||
kind: ExprKind::Box { value: self.mirror_expr(value) },
|
||||
};
|
||||
} else {
|
||||
// Tuple-like ADTs are represented as ExprKind::Call. We convert them here.
|
||||
let adt_data = if let hir::ExprKind::Path(ref qpath) = fun.kind
|
||||
&& let Some(adt_def) = expr_ty.ty_adt_def()
|
||||
|
||||
@@ -1696,7 +1696,6 @@ symbols! {
|
||||
rustc_as_ptr,
|
||||
rustc_attrs,
|
||||
rustc_autodiff,
|
||||
rustc_box,
|
||||
rustc_builtin_macro,
|
||||
rustc_capture_analysis,
|
||||
rustc_clean,
|
||||
|
||||
Reference in New Issue
Block a user