about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs14
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr2
4 files changed, 21 insertions, 2 deletions
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 3aff04f78fb..04d88282862 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -41,7 +41,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Tup(ref elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
                 ExprKind::Call(ref f, ref args) => {
-                    if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
+                    if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) {
+                        if let [inner] = &args[..] {
+                            hir::ExprKind::Box(self.lower_expr(&inner))
+                        } else {
+                            self.sess
+                                .struct_span_err(
+                                    e.span,
+                                    "rustc_box requires precisely one argument",
+                                )
+                                .emit();
+                            hir::ExprKind::Err
+                        }
+                    } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
                         self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args)
                     } else {
                         let f = self.lower_expr(f);
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 8155e65a6db..5eb2be97f8b 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -675,6 +675,12 @@ 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,
+        "#[rustc_box] allows creating boxes \
+        and it is only intended to be used in `alloc`."
+    ),
+
     BuiltinAttribute {
         name: sym::rustc_diagnostic_item,
         // FIXME: This can be `true` once we always use `tcx.is_diagnostic_item`.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 16162f1cc89..1954cdc0bff 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1173,6 +1173,7 @@ symbols! {
         rustc_allow_const_fn_unstable,
         rustc_allow_incoherent_impl,
         rustc_attrs,
+        rustc_box,
         rustc_builtin_macro,
         rustc_capture_analysis,
         rustc_clean,
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index 59b35292726..b59a73af9f9 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -1,4 +1,4 @@
-error: expected type, found `<[_]>::into_vec(box [0, 1])`
+error: expected type, found `<[_]>::into_vec(#[rustc_box] ::alloc::boxed::Box::new([0, 1]))`
   --> $DIR/issue-47666.rs:3:25
    |
 LL |     let _ = Option:Some(vec![0, 1]);