about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-08-26 15:56:30 -0700
committerGitHub <noreply@github.com>2022-08-26 15:56:30 -0700
commit96ceadde76e204a269252b1252b916278ecc4ea7 (patch)
tree1bf54b2c1b9b15bbf1e7d4726d50101901b2aed6 /compiler
parente7d870b1883f6861e825abf3896110e2a795ccf9 (diff)
parent622217da59ae7b4d1d5128255c9517aeb2174ea6 (diff)
downloadrust-96ceadde76e204a269252b1252b916278ecc4ea7.tar.gz
rust-96ceadde76e204a269252b1252b916278ecc4ea7.zip
Rollup merge of #100900 - AndyJado:diag-migrate, r=davidtwco
on `region_errors.rs`

`@rustbot` label +A-translation
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs93
-rw-r--r--compiler/rustc_borrowck/src/lib.rs18
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs17
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs117
-rw-r--r--compiler/rustc_error_messages/locales/en-US/borrowck.ftl42
5 files changed, 211 insertions, 76 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 0dce5be953e..00fdf331ca6 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1,3 +1,5 @@
+#![deny(rustc::untranslatable_diagnostic)]
+#![deny(rustc::diagnostic_outside_of_impl)]
 //! Error reporting machinery for lifetime errors.
 
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +25,10 @@ use rustc_span::symbol::{kw, sym, Ident};
 use rustc_span::Span;
 
 use crate::borrowck_errors;
-use crate::session_diagnostics::GenericDoesNotLiveLongEnough;
+use crate::session_diagnostics::{
+    FnMutError, FnMutReturnTypeErr, GenericDoesNotLiveLongEnough, LifetimeOutliveErr,
+    LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
+};
 
 use super::{OutlivesSuggestionBuilder, RegionName};
 use crate::region_infer::BlameConstraint;
@@ -488,12 +493,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
 
-        let mut diag = self
-            .infcx
-            .tcx
-            .sess
-            .struct_span_err(*span, "captured variable cannot escape `FnMut` closure body");
-
         let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
         if let ty::Opaque(def_id, _) = *output_ty.kind() {
             output_ty = self.infcx.tcx.type_of(def_id)
@@ -501,19 +500,20 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
         debug!("report_fnmut_error: output_ty={:?}", output_ty);
 
-        let message = match output_ty.kind() {
-            ty::Closure(_, _) => {
-                "returns a closure that contains a reference to a captured variable, which then \
-                 escapes the closure body"
-            }
-            ty::Adt(def, _) if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) => {
-                "returns an `async` block that contains a reference to a captured variable, which then \
-                 escapes the closure body"
-            }
-            _ => "returns a reference to a captured variable which escapes the closure body",
+        let err = FnMutError {
+            span: *span,
+            ty_err: match output_ty.kind() {
+                ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
+                ty::Adt(def, _)
+                    if self.infcx.tcx.is_diagnostic_item(sym::gen_future, def.did()) =>
+                {
+                    FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
+                }
+                _ => FnMutReturnTypeErr::ReturnRef { span: *span },
+            },
         };
 
-        diag.span_label(*span, message);
+        let mut diag = self.infcx.tcx.sess.create_err(err);
 
         if let ReturnConstraint::ClosureUpvar(upvar_field) = kind {
             let def_id = match self.regioncx.universal_regions().defining_ty {
@@ -532,20 +532,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 let upvars_map = self.infcx.tcx.upvars_mentioned(def_id).unwrap();
                 let upvar_def_span = self.infcx.tcx.hir().span(def_hir);
                 let upvar_span = upvars_map.get(&def_hir).unwrap().span;
-                diag.span_label(upvar_def_span, "variable defined here");
-                diag.span_label(upvar_span, "variable captured here");
+                diag.subdiagnostic(VarHereDenote::Defined { span: upvar_def_span });
+                diag.subdiagnostic(VarHereDenote::Captured { span: upvar_span });
             }
         }
 
         if let Some(fr_span) = self.give_region_a_name(*outlived_fr).unwrap().span() {
-            diag.span_label(fr_span, "inferred to be a `FnMut` closure");
+            diag.subdiagnostic(VarHereDenote::FnMutInferred { span: fr_span });
         }
 
-        diag.note(
-            "`FnMut` closures only have access to their captured variables while they are \
-             executing...",
-        );
-        diag.note("...therefore, they cannot allow references to captured variables to escape");
         self.suggest_move_on_borrowing_closure(&mut diag);
 
         diag
@@ -681,39 +676,33 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             ..
         } = errci;
 
-        let mut diag =
-            self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough");
-
         let (_, mir_def_name) =
             self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id());
 
+        let err = LifetimeOutliveErr { span: *span };
+        let mut diag = self.infcx.tcx.sess.create_err(err);
+
         let fr_name = self.give_region_a_name(*fr).unwrap();
         fr_name.highlight_region_name(&mut diag);
         let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap();
         outlived_fr_name.highlight_region_name(&mut diag);
 
-        match (category, outlived_fr_is_local, fr_is_local) {
-            (ConstraintCategory::Return(_), true, _) => {
-                diag.span_label(
-                    *span,
-                    format!(
-                        "{mir_def_name} was supposed to return data with lifetime `{outlived_fr_name}` but it is returning \
-                         data with lifetime `{fr_name}`",
-                    ),
-                );
-            }
-            _ => {
-                diag.span_label(
-                    *span,
-                    format!(
-                        "{}requires that `{}` must outlive `{}`",
-                        category.description(),
-                        fr_name,
-                        outlived_fr_name,
-                    ),
-                );
-            }
-        }
+        let err_category = match (category, outlived_fr_is_local, fr_is_local) {
+            (ConstraintCategory::Return(_), true, _) => LifetimeReturnCategoryErr::WrongReturn {
+                span: *span,
+                mir_def_name,
+                outlived_fr_name,
+                fr_name: &fr_name,
+            },
+            _ => LifetimeReturnCategoryErr::ShortReturn {
+                span: *span,
+                category_desc: category.description(),
+                free_region_name: &fr_name,
+                outlived_fr_name,
+            },
+        };
+
+        diag.subdiagnostic(err_category);
 
         self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
         self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr);
@@ -862,7 +851,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     ident.span,
                     "calling this method introduces the `impl`'s 'static` requirement",
                 );
-                err.span_note(multi_span, "the used `impl` has a `'static` requirement");
+                err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
                 err.span_suggestion_verbose(
                     span.shrink_to_hi(),
                     "consider relaxing the implicit `'static` requirement",
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 4ad9a970bc1..0f8afb038f4 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -18,7 +18,7 @@ extern crate tracing;
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::graph::dominators::Dominators;
-use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::ChunkedBitSet;
@@ -50,6 +50,8 @@ use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult, MoveData, MoveE
 use rustc_mir_dataflow::Analysis;
 use rustc_mir_dataflow::MoveDataParamEnv;
 
+use crate::session_diagnostics::VarNeedNotMut;
+
 use self::diagnostics::{AccessKind, RegionName};
 use self::location::LocationTable;
 use self::prefixes::PrefixSet;
@@ -424,17 +426,9 @@ fn do_mir_borrowck<'a, 'tcx>(
             continue;
         }
 
-        tcx.struct_span_lint_hir(UNUSED_MUT, lint_root, span, |lint| {
-            let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
-            lint.build("variable does not need to be mutable")
-                .span_suggestion_short(
-                    mut_span,
-                    "remove this `mut`",
-                    "",
-                    Applicability::MachineApplicable,
-                )
-                .emit();
-        })
+        let mut_span = tcx.sess.source_map().span_until_non_whitespace(span);
+
+        tcx.emit_spanned_lint(UNUSED_MUT, lint_root, span, VarNeedNotMut { span: mut_span })
     }
 
     let tainted_by_errors = mbcx.emit_errors();
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index d6712b6a479..127cb4e4083 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -16,6 +16,8 @@ use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 use rustc_trait_selection::traits::TraitEngineExt as _;
 
+use crate::session_diagnostics::ConstNotUsedTraitAlias;
+
 use super::RegionInferenceContext;
 
 impl<'tcx> RegionInferenceContext<'tcx> {
@@ -639,17 +641,10 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> {
                     Some(GenericArgKind::Const(c1)) => c1,
                     Some(u) => panic!("const mapped to unexpected kind: {:?}", u),
                     None => {
-                        self.tcx
-                            .sess
-                            .struct_span_err(
-                                self.span,
-                                &format!(
-                                    "const parameter `{}` is part of concrete type but not \
-                                          used in parameter list for the `impl Trait` type alias",
-                                    ct
-                                ),
-                            )
-                            .emit();
+                        self.tcx.sess.emit_err(ConstNotUsedTraitAlias {
+                            ct: ct.to_string(),
+                            span: self.span,
+                        });
 
                         self.tcx().const_error(ct.ty())
                     }
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 8c9676e4bfa..5d750c6ca8c 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -1,7 +1,10 @@
-use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
+use rustc_errors::{IntoDiagnosticArg, MultiSpan};
+use rustc_macros::{LintDiagnostic, SessionDiagnostic, SessionSubdiagnostic};
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
+use crate::diagnostics::RegionName;
+
 #[derive(SessionDiagnostic)]
 #[diag(borrowck::move_unsized, code = "E0161")]
 pub(crate) struct MoveUnsized<'tcx> {
@@ -42,3 +45,115 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(borrowck::var_does_not_need_mut)]
+pub(crate) struct VarNeedNotMut {
+    #[suggestion_short(applicability = "machine-applicable", code = "")]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::const_not_used_in_type_alias)]
+pub(crate) struct ConstNotUsedTraitAlias {
+    pub ct: String,
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::var_cannot_escape_closure)]
+#[note]
+#[note(borrowck::cannot_escape)]
+pub(crate) struct FnMutError {
+    #[primary_span]
+    pub span: Span,
+    #[subdiagnostic]
+    pub ty_err: FnMutReturnTypeErr,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum VarHereDenote {
+    #[label(borrowck::var_here_captured)]
+    Captured {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(borrowck::var_here_defined)]
+    Defined {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(borrowck::closure_inferred_mut)]
+    FnMutInferred {
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum FnMutReturnTypeErr {
+    #[label(borrowck::returned_closure_escaped)]
+    ReturnClosure {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(borrowck::returned_async_block_escaped)]
+    ReturnAsyncBlock {
+        #[primary_span]
+        span: Span,
+    },
+    #[label(borrowck::returned_ref_escaped)]
+    ReturnRef {
+        #[primary_span]
+        span: Span,
+    },
+}
+
+#[derive(SessionDiagnostic)]
+#[diag(borrowck::lifetime_constraints_error)]
+pub(crate) struct LifetimeOutliveErr {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum LifetimeReturnCategoryErr<'a> {
+    #[label(borrowck::returned_lifetime_wrong)]
+    WrongReturn {
+        #[primary_span]
+        span: Span,
+        mir_def_name: &'a str,
+        outlived_fr_name: RegionName,
+        fr_name: &'a RegionName,
+    },
+    #[label(borrowck::returned_lifetime_short)]
+    ShortReturn {
+        #[primary_span]
+        span: Span,
+        category_desc: &'static str,
+        free_region_name: &'a RegionName,
+        outlived_fr_name: RegionName,
+    },
+}
+
+impl IntoDiagnosticArg for &RegionName {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        format!("{}", self).into_diagnostic_arg()
+    }
+}
+
+impl IntoDiagnosticArg for RegionName {
+    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
+        format!("{}", self).into_diagnostic_arg()
+    }
+}
+
+#[derive(SessionSubdiagnostic)]
+pub(crate) enum RequireStaticErr {
+    #[note(borrowck::used_impl_require_static)]
+    UsedImpl {
+        #[primary_span]
+        multi_span: MultiSpan,
+    },
+}
diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
index a96fe7c8a05..67f2156f32e 100644
--- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl
@@ -16,3 +16,45 @@ borrowck_higher_ranked_subtype_error =
 
 borrowck_generic_does_not_live_long_enough =
     `{$kind}` does not live long enough
+
+borrowck_move_borrowed =
+    cannot move out of `{$desc}` beacause it is borrowed
+
+borrowck_var_does_not_need_mut =
+    variable does not need to be mutable
+    .suggestion = remove this `mut`
+
+borrowck_const_not_used_in_type_alias =
+    const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+
+borrowck_var_cannot_escape_closure =
+    captured variable cannot escape `FnMut` closure body
+    .note = `FnMut` closures only have access to their captured variables while they are executing...
+    .cannot_escape = ...therefore, they cannot allow references to captured variables to escape
+
+borrowck_var_here_defined = variable defined here
+
+borrowck_var_here_captured = variable captured here
+
+borrowck_closure_inferred_mut =  inferred to be a `FnMut` closure
+
+borrowck_returned_closure_escaped =
+    returns a closure that contains a reference to a captured variable, which then escapes the closure body
+
+borrowck_returned_async_block_escaped =
+    returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
+
+borrowck_returned_ref_escaped =
+    returns a reference to a captured variable which escapes the closure body
+
+borrowck_lifetime_constraints_error =
+    lifetime may not live long enough
+
+borrowck_returned_lifetime_wrong =
+    {$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`
+
+borrowck_returned_lifetime_short =
+    {$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`
+
+borrowck_used_impl_require_static =
+    the used `impl` has a `'static` requirement