Skip to content

Commit 0f249f5

Browse files
committed
Tweak E0478
``` error[E0478]: lifetime bound not satisfied --> $DIR/point-at-lifetime-obligation-from-trait-in-trait-object.rs:4:27 | LL | broken: Box<dyn Any + 'a> | --- ^^ lifetime bound not satisfied | | | this requires `'static` | note: lifetime parameter instantiated with the lifetime `'a` as defined here --> $DIR/point-at-lifetime-obligation-from-trait-in-trait-object.rs:3:18 | LL | struct Something<'a> { | ^^ = note: but lifetime parameter must outlive the static lifetime note: `'static` requirement introduced here --> $SRC_DIR/core/src/any.rs:LL:COL ```
1 parent b163ee0 commit 0f249f5

File tree

6 files changed

+39
-20
lines changed

6 files changed

+39
-20
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ use crate::traits::{
5959
PredicateObligation,
6060
};
6161

62-
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
62+
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
6363
use rustc_errors::{
6464
codes::*, pluralize, struct_span_code_err, Applicability, Diag, DiagCtxt, DiagStyledString,
6565
ErrorGuaranteed, IntoDiagnosticArg, MultiSpan,
@@ -2698,7 +2698,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
26982698
pub struct HirTraitObjectVisitor<'tcx> {
26992699
pub expected_region: ty::Region<'tcx>,
27002700
pub found_region: ty::Region<'tcx>,
2701-
pub lifetime_spans: FxHashSet<Span>,
2701+
pub primary_spans: Vec<Span>,
2702+
pub secondary_spans: Vec<Span>,
27022703
pub pred_spans: Vec<Span>,
27032704
pub tcx: TyCtxt<'tcx>,
27042705
}
@@ -2716,7 +2717,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27162717
_ => false,
27172718
} {
27182719
// We want to keep a span to the lifetime bound on the trait object.
2719-
self.lifetime_spans.insert(lt.ident.span);
2720+
self.primary_spans.push(lt.ident.span);
27202721
}
27212722
}
27222723
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
@@ -2742,18 +2743,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27422743
.filter_map(filter_predicates(self.found_region, |_| true))
27432744
.collect();
27442745
if !bindings.is_empty() {
2745-
self.lifetime_spans.insert(ptr.span);
2746+
self.secondary_spans.push(ptr.span);
27462747
self.pred_spans.extend(bindings);
27472748
}
27482749
}
27492750
}
27502751
}
27512752
// Detect when an associated item is given a lifetime restriction that the
27522753
// definition of that associated item couldn't meet.
2753-
hir::TyKind::Path(hir::QPath::Resolved(Some(_), path)) => {
2754-
self.pred_spans = elaborate_predicates_of(self.tcx, path.res.def_id())
2755-
.filter_map(filter_predicates(self.found_region, |_| true))
2756-
.collect();
2754+
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
2755+
self.pred_spans.extend(
2756+
elaborate_predicates_of(self.tcx, path.res.def_id())
2757+
.filter_map(filter_predicates(self.found_region, |_| true))
2758+
.collect::<Vec<_>>(),
2759+
);
27572760
}
27582761
_ => {}
27592762
}
@@ -2763,7 +2766,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27632766
let mut visitor = HirTraitObjectVisitor {
27642767
expected_region: sup,
27652768
found_region: sub,
2766-
lifetime_spans: Default::default(),
2769+
primary_spans: vec![],
2770+
secondary_spans: vec![],
27672771
pred_spans: vec![],
27682772
tcx: self.tcx,
27692773
};
@@ -2775,9 +2779,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
27752779
}
27762780
}
27772781

2778-
#[allow(rustc::potential_query_instability)]
2779-
let primary_spans: Vec<Span> = visitor.lifetime_spans.into_iter().collect();
2780-
Some((primary_spans.into(), visitor.pred_spans.into()))
2782+
visitor.primary_spans.sort();
2783+
let mut primary_span: MultiSpan = visitor.primary_spans.clone().into();
2784+
if let Some(last) = visitor.primary_spans.iter().rev().next() {
2785+
primary_span.push_span_label(
2786+
*last,
2787+
format!(
2788+
"lifetime bound{s} not satisfied",
2789+
s = pluralize!(visitor.primary_spans.len())
2790+
),
2791+
);
2792+
}
2793+
2794+
for span in visitor.secondary_spans {
2795+
primary_span.push_span_label(span, format!("this requires `{sub}`"));
2796+
}
2797+
Some((primary_span, visitor.pred_spans.into()))
27812798
}
27822799

27832800
/// Determine whether an error associated with the given span and definition

tests/ui/error-codes/E0478.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0478]: lifetime bound not satisfied
22
--> $DIR/E0478.rs:4:37
33
|
44
LL | child: Box<dyn Wedding<'kiss> + 'SnowWhite>,
5-
| ^^^^^^^^^^
5+
| ^^^^^^^^^^ lifetime bound not satisfied
66
|
77
note: lifetime parameter instantiated with the lifetime `'SnowWhite` as defined here
88
--> $DIR/E0478.rs:3:22

tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ error[E0478]: lifetime bound not satisfied
3535
--> $DIR/unsatisfied-item-lifetime-bound.rs:14:20
3636
|
3737
LL | f: <T as X>::Y<'a>,
38-
| ^^
38+
| ^^ lifetime bound not satisfied
3939
|
4040
note: lifetime parameter instantiated with the lifetime `'a` as defined here
4141
--> $DIR/unsatisfied-item-lifetime-bound.rs:13:10
@@ -53,7 +53,7 @@ error[E0478]: lifetime bound not satisfied
5353
--> $DIR/unsatisfied-item-lifetime-bound.rs:19:20
5454
|
5555
LL | f: <T as X>::Y<'a>,
56-
| ^^
56+
| ^^ lifetime bound not satisfied
5757
|
5858
note: lifetime parameter instantiated with the lifetime `'a` as defined here
5959
--> $DIR/unsatisfied-item-lifetime-bound.rs:18:10
@@ -71,7 +71,7 @@ error[E0478]: lifetime bound not satisfied
7171
--> $DIR/unsatisfied-item-lifetime-bound.rs:24:21
7272
|
7373
LL | f: <() as X>::Y<'a>,
74-
| ^^
74+
| ^^ lifetime bound not satisfied
7575
|
7676
note: lifetime parameter instantiated with the lifetime `'a` as defined here
7777
--> $DIR/unsatisfied-item-lifetime-bound.rs:23:10

tests/ui/lifetimes/point-at-lifetime-obligation-from-trait-in-trait-object.stderr

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
error[E0478]: lifetime bound not satisfied
2-
--> $DIR/point-at-lifetime-obligation-from-trait-in-trait-object.rs:4:21
2+
--> $DIR/point-at-lifetime-obligation-from-trait-in-trait-object.rs:4:27
33
|
44
LL | broken: Box<dyn Any + 'a>
5-
| ^^^ ^^
5+
| --- ^^ lifetime bound not satisfied
6+
| |
7+
| this requires `'static`
68
|
79
note: lifetime parameter instantiated with the lifetime `'a` as defined here
810
--> $DIR/point-at-lifetime-obligation-from-trait-in-trait-object.rs:3:18

tests/ui/regions/region-bounds-on-objects-and-type-parameters.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ error[E0478]: lifetime bound not satisfied
88
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:21:23
99
|
1010
LL | z: Box<dyn Is<'a>+'b+'c>,
11-
| ^^
11+
| ^^ lifetime bound not satisfied
1212
|
1313
note: lifetime parameter instantiated with the lifetime `'b` as defined here
1414
--> $DIR/region-bounds-on-objects-and-type-parameters.rs:11:15

tests/ui/regions/regions-wf-trait-object.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0478]: lifetime bound not satisfied
22
--> $DIR/regions-wf-trait-object.rs:7:29
33
|
44
LL | x: Box<dyn TheTrait<'a>+'b>
5-
| ^^
5+
| ^^ lifetime bound not satisfied
66
|
77
note: lifetime parameter instantiated with the lifetime `'b` as defined here
88
--> $DIR/regions-wf-trait-object.rs:6:15

0 commit comments

Comments
 (0)