about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/locales/en-US.ftl3
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs3
-rw-r--r--compiler/rustc_mir_build/locales/en-US.ftl6
-rw-r--r--compiler/rustc_mir_build/src/errors.rs19
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs32
8 files changed, 65 insertions, 23 deletions
diff --git a/compiler/rustc_ast_lowering/locales/en-US.ftl b/compiler/rustc_ast_lowering/locales/en-US.ftl
index a2837deafde..3ccd84398ec 100644
--- a/compiler/rustc_ast_lowering/locales/en-US.ftl
+++ b/compiler/rustc_ast_lowering/locales/en-US.ftl
@@ -22,9 +22,6 @@ ast_lowering_misplaced_impl_trait =
 ast_lowering_misplaced_assoc_ty_binding =
     associated type bounds are only allowed in where clauses and function signatures, not in {$position}
 
-ast_lowering_rustc_box_attribute_error =
-    #[rustc_box] requires precisely one argument and no other attributes are allowed
-
 ast_lowering_underscore_expr_lhs_assign =
     in expressions, `_` can only be used on the left-hand side of an assignment
     .label = `_` not allowed here
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index def74c2adee..5e6b6050bc0 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -88,13 +88,6 @@ pub struct MisplacedAssocTyBinding<'a> {
 }
 
 #[derive(Diagnostic, Clone, Copy)]
-#[diag(ast_lowering_rustc_box_attribute_error)]
-pub struct RustcBoxAttributeError {
-    #[primary_span]
-    pub span: Span,
-}
-
-#[derive(Diagnostic, Clone, Copy)]
 #[diag(ast_lowering_underscore_expr_lhs_assign)]
 pub struct UnderscoreExprLhsAssign {
     #[primary_span]
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index d4fafe38638..ffb30b1b391 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -2,7 +2,7 @@ use super::errors::{
     AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
     BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignemnt,
     GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure,
-    RustcBoxAttributeError, UnderscoreExprLhsAssign,
+    UnderscoreExprLhsAssign,
 };
 use super::ResolverAstLoweringExt;
 use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
@@ -83,15 +83,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 }
                 ExprKind::Tup(elts) => hir::ExprKind::Tup(self.lower_exprs(elts)),
                 ExprKind::Call(f, args) => {
-                    if e.attrs.get(0).map_or(false, |a| a.has_name(sym::rustc_box)) {
-                        if let [inner] = &args[..] && e.attrs.len() == 1 {
-                            let kind = hir::ExprKind::Box(self.lower_expr(&inner));
-                            return hir::Expr { hir_id, kind, span: self.lower_span(e.span) };
-                        } else {
-                            let guar = self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span });
-                            hir::ExprKind::Err(guar)
-                        }
-                    } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) {
+                    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_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 25c467bfd2b..f5ce02c9e61 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -2399,8 +2399,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                 infcx
                                     .can_eq(
                                         ty::ParamEnv::empty(),
-                                        tcx.erase_regions(impl_.self_ty()),
-                                        tcx.erase_regions(qself_ty),
+                                        impl_.self_ty(),
+                                        // Must fold past escaping bound vars too,
+                                        // since we have those at this point in astconv.
+                                        tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased),
                                     )
                             })
                             && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 47a4d4e72df..60d56263d2e 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -333,6 +333,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             rcvr_ty.prefix_string(self.tcx),
             ty_str_reported,
         );
+        if tcx.sess.source_map().is_multiline(sugg_span) {
+            err.span_label(sugg_span.with_hi(span.lo()), "");
+        }
         let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 {
             short_ty_str
         } else {
diff --git a/compiler/rustc_mir_build/locales/en-US.ftl b/compiler/rustc_mir_build/locales/en-US.ftl
index f9bda721df3..93e7fb330e0 100644
--- a/compiler/rustc_mir_build/locales/en-US.ftl
+++ b/compiler/rustc_mir_build/locales/en-US.ftl
@@ -374,3 +374,9 @@ mir_build_suggest_let_else = you might want to use `let else` to handle the {$co
     } matched
 
 mir_build_suggest_attempted_int_lit = alternatively, you could prepend the pattern with an underscore to define a new named variable; identifiers cannot begin with digits
+
+
+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
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index c1f6b8b59ce..dc4d2276e4a 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -888,3 +888,22 @@ pub enum MiscPatternSuggestion {
         start_span: Span,
     },
 }
+
+#[derive(Diagnostic)]
+#[diag(mir_build_rustc_box_attribute_error)]
+pub struct RustcBoxAttributeError {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub reason: RustcBoxAttrReason,
+}
+
+#[derive(Subdiagnostic)]
+pub enum RustcBoxAttrReason {
+    #[note(mir_build_attributes)]
+    Attributes,
+    #[note(mir_build_not_box)]
+    NotBoxNew,
+    #[note(mir_build_missing_box)]
+    MissingBox,
+}
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index d510a5fc76f..a937ec24741 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -1,3 +1,4 @@
+use crate::errors;
 use crate::thir::cx::region::Scope;
 use crate::thir::cx::Cx;
 use crate::thir::util::UserAnnotatedTyHelpers;
@@ -18,7 +19,7 @@ use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{
     self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType,
 };
-use rustc_span::Span;
+use rustc_span::{sym, Span};
 use rustc_target::abi::VariantIdx;
 
 impl<'tcx> Cx<'tcx> {
@@ -262,6 +263,7 @@ impl<'tcx> Cx<'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn make_mirror_unadjusted(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Expr<'tcx> {
         let tcx = self.tcx;
         let expr_ty = self.typeck_results().expr_ty(expr);
@@ -322,6 +324,34 @@ impl<'tcx> Cx<'tcx> {
                         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.sess.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().map_or(false, |did| did == box_item)
+                                && fn_path.ident.name == sym::new
+                                && let [value] = args
+                            {
+                                return Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind: ExprKind::Box { value: self.mirror_expr(value) } }
+                            } else {
+                                tcx.sess.emit_err(errors::RustcBoxAttributeError {
+                                    span: expr.span,
+                                    reason: errors::RustcBoxAttrReason::NotBoxNew
+                                });
+                            }
+                        } else {
+                            tcx.sess.emit_err(errors::RustcBoxAttributeError {
+                                span: attrs[0].span,
+                                reason: errors::RustcBoxAttrReason::MissingBox,
+                            });
+                        }
+                    }
                     let adt_data =
                         if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = fun.kind {
                             // Tuple-like ADTs are represented as ExprKind::Call. We convert them here.