Skip to content

Commit 5fdfc09

Browse files
authored
Rollup merge of rust-lang#82370 - 0yoyoyo:update-issue-81650-point-anonymous-lifetime, r=estebank
Improve anonymous lifetime note to indicate the target span Improvement for rust-lang#81650 Cc rust-lang#81995 Message after this improvement: (Improve note in the middle) ``` error[E0311]: the parameter type `T` may not live long enough --> src/main.rs:25:11 | 24 | fn play_with<T: Animal + Send>(scope: &Scope, animal: T) { | -- help: consider adding an explicit lifetime bound...: `T: 'a +` 25 | scope.spawn(move |_| { | ^^^^^ | note: the parameter type `T` must be valid for the anonymous lifetime defined on the function body at 24:40... --> src/main.rs:24:40 | 24 | fn play_with<T: Animal + Send>(scope: &Scope, animal: T) { | ^^^^^ note: ...so that the type `[closure@src/main.rs:25:17: 27:6]` will meet its required lifetime bounds --> src/main.rs:25:11 | 25 | scope.spawn(move |_| { | ^^^^^ ``` r? ``@estebank``
2 parents b0458bc + 75d1e30 commit 5fdfc09

20 files changed

+158
-167
lines changed

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use super::region_constraints::GenericKind;
5050
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};
5151

5252
use crate::infer;
53+
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
5354
use crate::traits::error_reporting::report_object_safety_error;
5455
use crate::traits::{
5556
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
@@ -179,7 +180,14 @@ fn msg_span_from_early_bound_and_free_regions(
179180
}
180181
ty::ReFree(ref fr) => match fr.bound_region {
181182
ty::BrAnon(idx) => {
182-
(format!("the anonymous lifetime #{} defined on", idx + 1), tcx.hir().span(node))
183+
if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) {
184+
("the anonymous lifetime defined on".to_string(), ty.span)
185+
} else {
186+
(
187+
format!("the anonymous lifetime #{} defined on", idx + 1),
188+
tcx.hir().span(node),
189+
)
190+
}
183191
}
184192
_ => (
185193
format!("the lifetime `{}` as defined on", region),

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Error Reporting for Anonymous Region Lifetime Errors
22
//! where both the regions are anonymous.
33
4+
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
45
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
56
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
67
use crate::infer::lexical_region_resolve::RegionResolutionError;
@@ -66,9 +67,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
6667
let scope_def_id_sub = anon_reg_sub.def_id;
6768
let bregion_sub = anon_reg_sub.boundregion;
6869

69-
let ty_sup = self.find_anon_type(sup, &bregion_sup)?;
70+
let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?;
7071

71-
let ty_sub = self.find_anon_type(sub, &bregion_sub)?;
72+
let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?;
7273

7374
debug!(
7475
"try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs

+55-59
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,68 @@
1-
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
21
use rustc_hir as hir;
32
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
43
use rustc_hir::Node;
54
use rustc_middle::hir::map::Map;
65
use rustc_middle::middle::resolve_lifetime as rl;
76
use rustc_middle::ty::{self, Region, TyCtxt};
87

9-
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
10-
/// This function calls the `visit_ty` method for the parameters
11-
/// corresponding to the anonymous regions. The `nested_visitor.found_type`
12-
/// contains the anonymous type.
13-
///
14-
/// # Arguments
15-
/// region - the anonymous region corresponding to the anon_anon conflict
16-
/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
17-
///
18-
/// # Example
19-
/// ```
20-
/// fn foo(x: &mut Vec<&u8>, y: &u8)
21-
/// { x.push(y); }
22-
/// ```
23-
/// The function returns the nested type corresponding to the anonymous region
24-
/// for e.g., `&u8` and Vec<`&u8`.
25-
pub(super) fn find_anon_type(
26-
&self,
27-
region: Region<'tcx>,
28-
br: &ty::BoundRegionKind,
29-
) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> {
30-
if let Some(anon_reg) = self.tcx().is_suitable_region(region) {
31-
let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
32-
let fndecl = match self.tcx().hir().get(hir_id) {
33-
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
34-
| Node::TraitItem(&hir::TraitItem {
35-
kind: hir::TraitItemKind::Fn(ref m, ..),
36-
..
37-
})
38-
| Node::ImplItem(&hir::ImplItem {
39-
kind: hir::ImplItemKind::Fn(ref m, ..), ..
40-
}) => &m.decl,
41-
_ => return None,
42-
};
8+
/// This function calls the `visit_ty` method for the parameters
9+
/// corresponding to the anonymous regions. The `nested_visitor.found_type`
10+
/// contains the anonymous type.
11+
///
12+
/// # Arguments
13+
/// region - the anonymous region corresponding to the anon_anon conflict
14+
/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
15+
///
16+
/// # Example
17+
/// ```
18+
/// fn foo(x: &mut Vec<&u8>, y: &u8)
19+
/// { x.push(y); }
20+
/// ```
21+
/// The function returns the nested type corresponding to the anonymous region
22+
/// for e.g., `&u8` and Vec<`&u8`.
23+
pub(crate) fn find_anon_type(
24+
tcx: TyCtxt<'tcx>,
25+
region: Region<'tcx>,
26+
br: &ty::BoundRegionKind,
27+
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> {
28+
if let Some(anon_reg) = tcx.is_suitable_region(region) {
29+
let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
30+
let fndecl = match tcx.hir().get(hir_id) {
31+
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
32+
| Node::TraitItem(&hir::TraitItem {
33+
kind: hir::TraitItemKind::Fn(ref m, ..), ..
34+
})
35+
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => {
36+
&m.decl
37+
}
38+
_ => return None,
39+
};
4340

44-
fndecl
45-
.inputs
46-
.iter()
47-
.find_map(|arg| self.find_component_for_bound_region(arg, br))
48-
.map(|ty| (ty, &**fndecl))
49-
} else {
50-
None
51-
}
41+
fndecl
42+
.inputs
43+
.iter()
44+
.find_map(|arg| find_component_for_bound_region(tcx, arg, br))
45+
.map(|ty| (ty, &**fndecl))
46+
} else {
47+
None
5248
}
49+
}
5350

54-
// This method creates a FindNestedTypeVisitor which returns the type corresponding
55-
// to the anonymous region.
56-
fn find_component_for_bound_region(
57-
&self,
58-
arg: &'tcx hir::Ty<'tcx>,
59-
br: &ty::BoundRegionKind,
60-
) -> Option<&'tcx hir::Ty<'tcx>> {
61-
let mut nested_visitor = FindNestedTypeVisitor {
62-
tcx: self.tcx(),
63-
bound_region: *br,
64-
found_type: None,
65-
current_index: ty::INNERMOST,
66-
};
67-
nested_visitor.visit_ty(arg);
68-
nested_visitor.found_type
69-
}
51+
// This method creates a FindNestedTypeVisitor which returns the type corresponding
52+
// to the anonymous region.
53+
fn find_component_for_bound_region(
54+
tcx: TyCtxt<'tcx>,
55+
arg: &'tcx hir::Ty<'tcx>,
56+
br: &ty::BoundRegionKind,
57+
) -> Option<&'tcx hir::Ty<'tcx>> {
58+
let mut nested_visitor = FindNestedTypeVisitor {
59+
tcx,
60+
bound_region: *br,
61+
found_type: None,
62+
current_index: ty::INNERMOST,
63+
};
64+
nested_visitor.visit_ty(arg);
65+
nested_visitor.found_type
7066
}
7167

7268
// The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_middle::ty::{self, TyCtxt};
66
use rustc_span::source_map::Span;
77

88
mod different_lifetimes;
9-
mod find_anon_type;
9+
pub mod find_anon_type;
1010
mod named_anon_conflict;
1111
mod placeholder_error;
1212
mod static_impl_trait;

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Error Reporting for Anonymous Region Lifetime Errors
22
//! where one region is named and the other is anonymous.
3+
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
34
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
45
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
56
use rustc_hir::intravisit::Visitor;
@@ -74,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
7475
return None;
7576
}
7677

77-
if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
78+
if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
7879
if self.is_self_anon(is_first, scope_def_id) {
7980
return None;
8081
}

src/test/ui/issues/issue-16683.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
44
LL | self.a();
55
| ^
66
|
7-
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 3:5...
8-
--> $DIR/issue-16683.rs:3:5
7+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 3:10...
8+
--> $DIR/issue-16683.rs:3:10
99
|
1010
LL | fn b(&self) {
11-
| ^^^^^^^^^^^
11+
| ^^^^^
1212
note: ...so that reference does not outlive borrowed content
1313
--> $DIR/issue-16683.rs:4:9
1414
|

src/test/ui/issues/issue-17740.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | fn bar(self: &mut Foo) {
66
|
77
= note: expected struct `Foo<'a>`
88
found struct `Foo<'_>`
9-
note: the anonymous lifetime #2 defined on the method body at 6:5...
10-
--> $DIR/issue-17740.rs:6:5
9+
note: the anonymous lifetime defined on the method body at 6:23...
10+
--> $DIR/issue-17740.rs:6:23
1111
|
1212
LL | fn bar(self: &mut Foo) {
13-
| ^^^^^^^^^^^^^^^^^^^^^^
13+
| ^^^
1414
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 5:7
1515
--> $DIR/issue-17740.rs:5:7
1616
|
@@ -30,11 +30,11 @@ note: the lifetime `'a` as defined on the impl at 5:7...
3030
|
3131
LL | impl <'a> Foo<'a>{
3232
| ^^
33-
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the method body at 6:5
34-
--> $DIR/issue-17740.rs:6:5
33+
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 6:23
34+
--> $DIR/issue-17740.rs:6:23
3535
|
3636
LL | fn bar(self: &mut Foo) {
37-
| ^^^^^^^^^^^^^^^^^^^^^^
37+
| ^^^
3838

3939
error: aborting due to 2 previous errors
4040

src/test/ui/issues/issue-17758.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
44
LL | self.foo();
55
| ^^^
66
|
7-
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
8-
--> $DIR/issue-17758.rs:6:5
7+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 6:12...
8+
--> $DIR/issue-17758.rs:6:12
99
|
1010
LL | fn bar(&self) {
11-
| ^^^^^^^^^^^^^
11+
| ^^^^^
1212
note: ...so that reference does not outlive borrowed content
1313
--> $DIR/issue-17758.rs:7:9
1414
|

src/test/ui/issues/issue-17905-2.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | fn say(self: &Pair<&str, isize>) {
66
|
77
= note: expected struct `Pair<&str, _>`
88
found struct `Pair<&str, _>`
9-
note: the anonymous lifetime #2 defined on the method body at 8:5...
10-
--> $DIR/issue-17905-2.rs:8:5
9+
note: the anonymous lifetime defined on the method body at 8:24...
10+
--> $DIR/issue-17905-2.rs:8:24
1111
|
1212
LL | fn say(self: &Pair<&str, isize>) {
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
| ^^^^
1414
note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 5:5
1515
--> $DIR/issue-17905-2.rs:5:5
1616
|
@@ -30,11 +30,11 @@ note: the lifetime `'_` as defined on the impl at 5:5...
3030
|
3131
LL | &str,
3232
| ^
33-
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the method body at 8:5
34-
--> $DIR/issue-17905-2.rs:8:5
33+
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 8:24
34+
--> $DIR/issue-17905-2.rs:8:24
3535
|
3636
LL | fn say(self: &Pair<&str, isize>) {
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
| ^^^^
3838

3939
error: aborting due to 2 previous errors
4040

src/test/ui/issues/issue-20831-debruijn.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
44
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
7-
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5...
8-
--> $DIR/issue-20831-debruijn.rs:28:5
7+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 28:58...
8+
--> $DIR/issue-20831-debruijn.rs:28:58
99
|
1010
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
1212
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6...
1313
--> $DIR/issue-20831-debruijn.rs:26:6
1414
|

src/test/ui/issues/issue-27942.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | fn select(&self) -> BufferViewHandle<R>;
66
|
77
= note: expected type `Resources<'_>`
88
found type `Resources<'a>`
9-
note: the anonymous lifetime #1 defined on the method body at 5:5...
10-
--> $DIR/issue-27942.rs:5:5
9+
note: the anonymous lifetime defined on the method body at 5:15...
10+
--> $DIR/issue-27942.rs:5:15
1111
|
1212
LL | fn select(&self) -> BufferViewHandle<R>;
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
| ^^^^^
1414
note: ...does not necessarily outlive the lifetime `'a` as defined on the trait at 3:18
1515
--> $DIR/issue-27942.rs:3:18
1616
|
@@ -30,11 +30,11 @@ note: the lifetime `'a` as defined on the trait at 3:18...
3030
|
3131
LL | pub trait Buffer<'a, R: Resources<'a>> {
3232
| ^^
33-
note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 5:5
34-
--> $DIR/issue-27942.rs:5:5
33+
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 5:15
34+
--> $DIR/issue-27942.rs:5:15
3535
|
3636
LL | fn select(&self) -> BufferViewHandle<R>;
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
| ^^^^^
3838

3939
error: aborting due to 2 previous errors
4040

src/test/ui/nll/issue-52742.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ note: ...the reference is valid for the lifetime `'_` as defined on the impl at
99
|
1010
LL | impl Foo<'_, '_> {
1111
| ^^
12-
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 13:5
13-
--> $DIR/issue-52742.rs:13:5
12+
note: ...but the borrowed content is only valid for the anonymous lifetime defined on the method body at 13:31
13+
--> $DIR/issue-52742.rs:13:31
1414
|
1515
LL | fn take_bar(&mut self, b: Bar<'_>) {
16-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
| ^^^^^^^
1717

1818
error: aborting due to previous error
1919

src/test/ui/nll/issue-55394.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'s` d
44
LL | Foo { bar }
55
| ^^^
66
|
7-
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
8-
--> $DIR/issue-55394.rs:8:5
7+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 8:17...
8+
--> $DIR/issue-55394.rs:8:17
99
|
1010
LL | fn new(bar: &mut Bar) -> Self {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^^^^^^^^
1212
note: ...so that reference does not outlive borrowed content
1313
--> $DIR/issue-55394.rs:9:15
1414
|

src/test/ui/nll/type-alias-free-regions.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
44
LL | C { f: b }
55
| ^
66
|
7-
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
8-
--> $DIR/type-alias-free-regions.rs:16:5
7+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 16:24...
8+
--> $DIR/type-alias-free-regions.rs:16:24
99
|
1010
LL | fn from_box(b: Box<B>) -> Self {
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11+
| ^
1212
note: ...so that the expression is assignable
1313
--> $DIR/type-alias-free-regions.rs:17:16
1414
|
@@ -35,11 +35,11 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
3535
LL | C { f: Box::new(b.0) }
3636
| ^^^^^^^^^^^^^
3737
|
38-
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 26:5...
39-
--> $DIR/type-alias-free-regions.rs:26:5
38+
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 26:23...
39+
--> $DIR/type-alias-free-regions.rs:26:23
4040
|
4141
LL | fn from_tuple(b: (B,)) -> Self {
42-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42+
| ^
4343
note: ...so that the expression is assignable
4444
--> $DIR/type-alias-free-regions.rs:27:25
4545
|

0 commit comments

Comments
 (0)