Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c2a0fa8

Browse files
committed
diagnostics :3
1 parent 8365ad1 commit c2a0fa8

10 files changed

+71
-59
lines changed

‎compiler/rustc_borrowck/src/diagnostics/opaque_types.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
244244

245245
// Find a path between the borrow region and our opaque capture.
246246
if let Some((path, _)) =
247-
self.regioncx.find_constraint_paths_between_regions(self.borrow_region, |r| {
247+
self.regioncx.find_constraint_path_between_regions(self.borrow_region, |r| {
248248
r == opaque_region_vid
249249
})
250250
{

‎compiler/rustc_borrowck/src/region_infer/mod.rs‎

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1405,18 +1405,39 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14051405
}
14061406

14071407
/// Walks the graph of constraints (where `'a: 'b` is considered
1408-
/// an edge `'a -> 'b`) to find all paths from `from_region` to
1409-
/// `to_region`. The paths are accumulated into the vector
1410-
/// `results`. The paths are stored as a series of
1411-
/// `ConstraintIndex` values -- in other words, a list of *edges*.
1408+
/// an edge `'a -> 'b`) to find a path from `from_region` to
1409+
/// `to_region`.
14121410
///
14131411
/// Returns: a series of constraints as well as the region `R`
14141412
/// that passed the target test.
14151413
#[instrument(skip(self, target_test), ret)]
1416-
pub(crate) fn find_constraint_paths_between_regions(
1414+
pub(crate) fn find_constraint_path_between_regions(
14171415
&self,
14181416
from_region: RegionVid,
14191417
target_test: impl Fn(RegionVid) -> bool,
1418+
) -> Option<(Vec<OutlivesConstraint<'tcx>>, RegionVid)> {
1419+
self.find_constraint_path_between_regions_inner(true, from_region, &target_test).or_else(
1420+
|| self.find_constraint_path_between_regions_inner(false, from_region, &target_test),
1421+
)
1422+
}
1423+
1424+
/// The constraints we get from equating the hidden type of each use of an opaque
1425+
/// with its final concrete type may end up getting preferred over other, potentially
1426+
/// longer constraint paths.
1427+
///
1428+
/// Given that we compute the final concrete type by relying on this existing constraint
1429+
/// path, this can easily end up hiding the actual reason for why we require these regions
1430+
/// to be equal.
1431+
///
1432+
/// To handle this, we first look at the path while ignoring these constraints and then
1433+
/// retry while considering them. This is not perfect, as the `from_region` may have already
1434+
/// been partially related to its argument region, so while we rely on a member constraint
1435+
/// to get a complete path, the most relevant step of that path already existed before then.
1436+
fn find_constraint_path_between_regions_inner(
1437+
&self,
1438+
ignore_opaque_type_constraints: bool,
1439+
from_region: RegionVid,
1440+
target_test: impl Fn(RegionVid) -> bool,
14201441
) -> Option<(Vec<OutlivesConstraint<'tcx>>, RegionVid)> {
14211442
let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions);
14221443
context[from_region] = Trace::StartRegion;
@@ -1431,7 +1452,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
14311452

14321453
while let Some(r) = deque.pop_front() {
14331454
debug!(
1434-
"find_constraint_paths_between_regions: from_region={:?} r={:?} value={}",
1455+
"find_constraint_path_between_regions: from_region={:?} r={:?} value={}",
14351456
from_region,
14361457
r,
14371458
self.region_value_str(r),
@@ -1503,9 +1524,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15031524
let edges = self.constraint_graph.outgoing_edges_from_graph(r, &self.constraints);
15041525
// This loop can be hot.
15051526
for constraint in edges {
1506-
if matches!(constraint.category, ConstraintCategory::IllegalUniverse) {
1507-
debug!("Ignoring illegal universe constraint: {constraint:?}");
1508-
continue;
1527+
match constraint.category {
1528+
ConstraintCategory::IllegalUniverse => {
1529+
debug!("Ignoring illegal universe constraint: {constraint:?}");
1530+
continue;
1531+
}
1532+
ConstraintCategory::OpaqueType if ignore_opaque_type_constraints => {
1533+
debug!("Ignoring member constraint: {constraint:?}");
1534+
continue;
1535+
}
1536+
_ => {}
15091537
}
15101538
debug_assert_eq!(constraint.sup, r);
15111539
handle_trace(constraint.sub, Trace::FromGraph(constraint));
@@ -1521,7 +1549,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15211549
pub(crate) fn find_sub_region_live_at(&self, fr1: RegionVid, location: Location) -> RegionVid {
15221550
trace!(scc = ?self.constraint_sccs.scc(fr1));
15231551
trace!(universe = ?self.max_nameable_universe(self.constraint_sccs.scc(fr1)));
1524-
self.find_constraint_paths_between_regions(fr1, |r| {
1552+
self.find_constraint_path_between_regions(fr1, |r| {
15251553
// First look for some `r` such that `fr1: r` and `r` is live at `location`
15261554
trace!(?r, liveness_constraints=?self.liveness_constraints.pretty_print_live_points(r));
15271555
self.liveness_constraints.is_live_at(r, location)
@@ -1531,9 +1559,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15311559
// `fr1: r` and `r` is a placeholder from some universe
15321560
// `fr1` cannot name. This would force `fr1` to be
15331561
// `'static`.
1534-
self.find_constraint_paths_between_regions(fr1, |r| {
1535-
self.cannot_name_placeholder(fr1, r)
1536-
})
1562+
self.find_constraint_path_between_regions(fr1, |r| self.cannot_name_placeholder(fr1, r))
15371563
})
15381564
.or_else(|| {
15391565
// If we fail to find THAT, it may be that `fr1` is a
@@ -1546,9 +1572,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
15461572
// must be able to name the universe of R2, because R2 will
15471573
// be at least `'empty(Universe(R2))`, and `R1` must be at
15481574
// larger than that.
1549-
self.find_constraint_paths_between_regions(fr1, |r| {
1550-
self.cannot_name_placeholder(r, fr1)
1551-
})
1575+
self.find_constraint_path_between_regions(fr1, |r| self.cannot_name_placeholder(r, fr1))
15521576
})
15531577
.map(|(_path, r)| r)
15541578
.unwrap()
@@ -1604,9 +1628,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16041628
) -> (BlameConstraint<'tcx>, Vec<OutlivesConstraint<'tcx>>) {
16051629
// Find all paths
16061630
let (path, target_region) = self
1607-
.find_constraint_paths_between_regions(from_region, target_test)
1631+
.find_constraint_path_between_regions(from_region, target_test)
16081632
.or_else(|| {
1609-
self.find_constraint_paths_between_regions(from_region, |r| {
1633+
self.find_constraint_path_between_regions(from_region, |r| {
16101634
self.cannot_name_placeholder(from_region, r)
16111635
})
16121636
})

‎tests/ui/async-await/issue-74072-lifetime-name-annotations.stderr‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ LL | || let y = &*x;
5353
LL | || *x += 1;
5454
LL | || y
5555
LL | || })()
56-
| ||______^_- opaque type requires that borrow lasts for `'1`
56+
| ||______^_- argument requires that borrow lasts for `'1`
5757
| |_______|
5858
| creates a temporary value which is freed while still in use
5959
LL | }
@@ -102,7 +102,7 @@ LL | || let y = &*x;
102102
LL | || *x += 1;
103103
LL | || y
104104
LL | || })()
105-
| ||______^_- opaque type requires that borrow lasts for `'1`
105+
| ||______^_- argument requires that borrow lasts for `'1`
106106
| |_______|
107107
| creates a temporary value which is freed while still in use
108108
LL | }

‎tests/ui/async-await/issue-76547.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ impl<'a> Future for ListFut<'a> {
1717
}
1818

1919
async fn fut(bufs: &mut [&mut [u8]]) {
20-
//~^ ERROR lifetime may not live long enough
2120
ListFut(bufs).await
21+
//~^ ERROR lifetime may not live long enough
2222
}
2323

2424
pub struct ListFut2<'a>(&'a mut [&'a mut [u8]]);
@@ -31,8 +31,8 @@ impl<'a> Future for ListFut2<'a> {
3131
}
3232

3333
async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
34-
//~^ ERROR lifetime may not live long enough
3534
ListFut2(bufs).await
35+
//~^ ERROR lifetime may not live long enough
3636
}
3737

3838
fn main() {}

‎tests/ui/async-await/issue-76547.stderr‎

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
11
error: lifetime may not live long enough
2-
--> $DIR/issue-76547.rs:19:38
2+
--> $DIR/issue-76547.rs:20:13
33
|
4-
LL | async fn fut(bufs: &mut [&mut [u8]]) {
5-
| ____________________-_____-___________^
6-
| | | |
7-
| | | let's call the lifetime of this reference `'2`
8-
| | let's call the lifetime of this reference `'1`
9-
LL | |
10-
LL | | ListFut(bufs).await
11-
LL | | }
12-
| |_^ opaque type requires that `'1` must outlive `'2`
4+
LL | async fn fut(bufs: &mut [&mut [u8]]) {
5+
| - - let's call the lifetime of this reference `'2`
6+
| |
7+
| let's call the lifetime of this reference `'1`
8+
LL | ListFut(bufs).await
9+
| ^^^^ this usage requires that `'1` must outlive `'2`
1310
|
1411
help: consider introducing a named lifetime parameter
1512
|
1613
LL | async fn fut<'a>(bufs: &'a mut [&'a mut [u8]]) {
1714
| ++++ ++ ++
1815

1916
error: lifetime may not live long enough
20-
--> $DIR/issue-76547.rs:33:46
17+
--> $DIR/issue-76547.rs:34:14
2118
|
22-
LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
23-
| _____________________-_____-__________________^
24-
| | | |
25-
| | | let's call the lifetime of this reference `'2`
26-
| | let's call the lifetime of this reference `'1`
27-
LL | |
28-
LL | | ListFut2(bufs).await
29-
LL | | }
30-
| |_^ opaque type requires that `'1` must outlive `'2`
19+
LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
20+
| - - let's call the lifetime of this reference `'2`
21+
| |
22+
| let's call the lifetime of this reference `'1`
23+
LL | ListFut2(bufs).await
24+
| ^^^^ this usage requires that `'1` must outlive `'2`
3125
|
3226
help: consider introducing a named lifetime parameter
3327
|

‎tests/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trai
99
LL | |
1010
LL | | (a, b)
1111
LL | | }
12-
| |_^ opaque type requires that `'a` must outlive `'b`
12+
| |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
1313
|
1414
= help: consider adding the following bound: `'a: 'b`
1515

‎tests/ui/impl-trait/wf-check-hidden-type.stderr‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ LL | fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
66
| |
77
| lifetime `'a` defined here
88
LL | None::<&'_ &'_ ()>
9-
| ^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'b`
9+
| ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
1010
|
1111
= help: consider adding the following bound: `'a: 'b`
1212

‎tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod bav {
1818
impl Bar for i32 {}
1919

2020
fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
21-
val.use_self() //~ ERROR `val` does not live long enough
21+
val.use_self() //~ ERROR cannot return value referencing function parameter `val`
2222
}
2323
}
2424

‎tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr‎

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
1-
error[E0597]: `val` does not live long enough
1+
error[E0515]: cannot return value referencing function parameter `val`
22
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:21:9
33
|
4-
LL | fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32>>) -> impl OtherTrait<'a> {
5-
| -- --- binding `val` declared here
6-
| |
7-
| lifetime `'a` defined here
84
LL | val.use_self()
9-
| ^^^-----------
5+
| ---^^^^^^^^^^^
106
| |
11-
| borrowed value does not live long enough
12-
| opaque type requires that `val` is borrowed for `'a`
13-
LL | }
14-
| - `val` dropped here while still borrowed
7+
| returns a value referencing data owned by the current function
8+
| `val` is borrowed here
159

1610
error[E0515]: cannot return value referencing function parameter `val`
1711
--> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:43:9
@@ -76,5 +70,5 @@ LL | val.use_self()
7670

7771
error: aborting due to 6 previous errors
7872

79-
Some errors have detailed explanations: E0515, E0521, E0597.
73+
Some errors have detailed explanations: E0515, E0521.
8074
For more information about an error, try `rustc --explain E0515`.

‎tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ LL | |
88
LL | | current: None,
99
LL | | remaining: self.0.iter(),
1010
LL | | }
11-
| |_________^ opaque type requires that `'1` must outlive `'static`
11+
| |_________^ returning this value requires that `'1` must outlive `'static`
1212
|
1313
help: to declare that `impl Iterator<Item = Box<(dyn Foo + 'static)>>` captures data from argument `self`, you can add an explicit `'_` lifetime bound
1414
|
@@ -63,7 +63,7 @@ LL | |
6363
LL | | current: None,
6464
LL | | remaining: self.0.iter(),
6565
LL | | }
66-
| |_________^ opaque type requires that `'a` must outlive `'static`
66+
| |_________^ returning this value requires that `'a` must outlive `'static`
6767
|
6868
help: to declare that `impl Iterator<Item = Box<(dyn Foo + 'static)>>` captures data from argument `self`, you can add an explicit `'a` lifetime bound
6969
|

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /