about summary refs log tree commit diff
path: root/compiler/rustc_borrowck
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-09-28 21:13:53 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-09-28 21:13:53 +0000
commitc5313fed76a99942edb4c7f94607fa3d2d6da21c (patch)
tree85da949e5e0de1d094bb20c8b2911d0da1691385 /compiler/rustc_borrowck
parent58f5260b960004090bfa9e7ef5068d6554ac9f33 (diff)
downloadrust-c5313fed76a99942edb4c7f94607fa3d2d6da21c.tar.gz
rust-c5313fed76a99942edb4c7f94607fa3d2d6da21c.zip
Point at multiple outlives requirements instead of just the first one
```
error[E0716]: temporary value dropped while borrowed
  --> $DIR/multiple-sources-for-outlives-requirement.rs:5:38
   |
LL | fn foo<'b>() {
   |        -- lifetime `'b` defined here
LL |     outlives_indir::<'_, 'b, _>(&mut 1u32);
   |     ---------------------------------^^^^-- temporary value is freed at the end of this statement
   |     |                                |
   |     |                                creates a temporary value which is freed while still in use
   |     argument requires that borrow lasts for `'b`
   |
note: requirements that the value outlives `'b` introduced here
  --> $DIR/multiple-sources-for-outlives-requirement.rs:1:23
   |
LL | fn outlives_indir<'a: 'b, 'b, T: 'a>(_x: T) {}
   |                       ^^         ^^
```
Diffstat (limited to 'compiler/rustc_borrowck')
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs13
1 files changed, 8 insertions, 5 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 67e33b37416..638d89f5bcb 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -417,18 +417,21 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     self.add_object_lifetime_default_note(tcx, err, unsize_ty);
                 }
 
-                if let Some(pred) = path
+                let mut preds = path
                     .iter()
                     .filter_map(|constraint| match constraint.category {
                         ConstraintCategory::Predicate(pred) if !pred.is_dummy() => Some(pred),
                         _ => None,
                     })
-                    .next()
-                {
+                    .collect::<Vec<Span>>();
+                preds.sort();
+                preds.dedup();
+                if !preds.is_empty() {
+                    let s = if preds.len() == 1 { "" } else { "s" };
                     err.span_note(
-                        pred,
+                        preds,
                         format!(
-                            "requirement that the value outlives `{region_name}` introduced here"
+                            "requirement{s} that the value outlives `{region_name}` introduced here"
                         ),
                     );
                 }