about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_messages/locales/en-US/infer.ftl6
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs10
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note.rs28
4 files changed, 45 insertions, 7 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_error_messages/locales/en-US/infer.ftl
index 505dd980494..0fcde811740 100644
--- a/compiler/rustc_error_messages/locales/en-US/infer.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/infer.ftl
@@ -142,12 +142,14 @@ infer_region_explanation = {$pref_kind ->
     *[should_not_happen] [{$pref_kind}]
     [ref_valid_for] ...the reference is valid for
     [content_valid_for] ...but the borrowed content is only valid for
-    [type_valid_for] object type is valid for
+    [type_obj_valid_for] object type is valid for
     [source_pointer_valid_for] source pointer is only valid for
     [type_satisfy] type must satisfy
     [type_outlive] type must outlive
     [lf_instantiated_with] lifetime parameter instantiated with
     [lf_must_outlive] but lifetime parameter must outlive
+    [type_valid_for] the type is valid for
+    [borrow_lasts_for] but the borrow lasts for
     [empty] {""}
 }{$pref_kind ->
     [empty] {""}
@@ -156,7 +158,6 @@ infer_region_explanation = {$pref_kind ->
     *[should_not_happen] [{$desc_kind}]
     [restatic] the static lifetime
     [revar] lifetime {$desc_arg}
-
     [as_defined] the lifetime `{$desc_arg}` as defined here
     [as_defined_anon] the anonymous lifetime as defined here
     [defined_here] the anonymous lifetime defined here
@@ -173,6 +174,7 @@ infer_outlives_content = lifetime of reference outlives lifetime of borrowed con
 infer_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
 infer_fullfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
 infer_lf_bound_not_satisfied = lifetime bound not satisfied
+infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long
 
 infer_mismatched_static_lifetime = incompatible lifetime on type
 infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index ae2985d456b..6efe72bfc36 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -970,3 +970,13 @@ pub struct LfBoundNotSatisfied<'a> {
     #[subdiagnostic]
     pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
 }
+
+#[derive(Diagnostic)]
+#[diag(infer_borrowed_too_long, code = "E0490")]
+pub struct BorrowedTooLong<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub ty: Ty<'a>,
+    #[subdiagnostic]
+    pub notes: Vec<note_and_explain::RegionExplanation<'a>>,
+}
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index c60eee60994..e779fdd6e55 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -123,12 +123,14 @@ pub enum PrefixKind {
     Empty,
     RefValidFor,
     ContentValidFor,
-    TypeValidFor,
+    TypeObjValidFor,
     SourcePointerValidFor,
     TypeSatisfy,
     TypeOutlive,
     LfInstantiatedWith,
     LfMustOutlive,
+    TypeValidFor,
+    BorrowLastsFor,
 }
 
 pub enum SuffixKind {
@@ -143,12 +145,14 @@ impl IntoDiagnosticArg for PrefixKind {
             Self::Empty => "empty",
             Self::RefValidFor => "ref_valid_for",
             Self::ContentValidFor => "content_valid_for",
-            Self::TypeValidFor => "type_valid_for",
+            Self::TypeObjValidFor => "type_obj_valid_for",
             Self::SourcePointerValidFor => "source_pointer_valid_for",
             Self::TypeSatisfy => "type_satisfy",
             Self::TypeOutlive => "type_outlive",
             Self::LfInstantiatedWith => "lf_instantiated_with",
             Self::LfMustOutlive => "lf_must_outlive",
+            Self::TypeValidFor => "type_valid_for",
+            Self::BorrowLastsFor => "borrow_lasts_for",
         }
         .into();
         rustc_errors::DiagnosticArgValue::Str(kind)
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs
index c2b936c3402..e470d9d9053 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs
@@ -1,6 +1,6 @@
 use crate::errors::{
-    note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
-    RegionOriginNote,
+    note_and_explain, BorrowedTooLong, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound,
+    OutlivesContent, RegionOriginNote,
 };
 use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
 use crate::infer::{self, SubregionOrigin};
@@ -147,7 +147,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     self.tcx,
                     sub,
                     None,
-                    note_and_explain::PrefixKind::TypeValidFor,
+                    note_and_explain::PrefixKind::TypeObjValidFor,
                     note_and_explain::SuffixKind::Empty,
                 );
                 let pointer_valid = note_and_explain::RegionExplanation::new(
@@ -200,6 +200,28 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
                 .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
             }
+            infer::DataBorrowed(ty, span) => {
+                let type_valid = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    sub,
+                    None,
+                    note_and_explain::PrefixKind::TypeValidFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                let borrow_lasts_for = note_and_explain::RegionExplanation::new(
+                    self.tcx,
+                    sup,
+                    None,
+                    note_and_explain::PrefixKind::BorrowLastsFor,
+                    note_and_explain::SuffixKind::Empty,
+                );
+                BorrowedTooLong {
+                    span,
+                    ty: self.resolve_vars_if_possible(ty),
+                    notes: type_valid.into_iter().chain(borrow_lasts_for).collect(),
+                }
+                .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
+            }
             infer::ReferenceOutlivesReferent(ty, span) => {
                 let mut err = struct_span_err!(
                     self.tcx.sess,