Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve anonymous lifetime note to indicate the target span #82370

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ use super::region_constraints::GenericKind;
use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePairs};

use crate::infer;
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::traits::error_reporting::report_object_safety_error;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
Expand Down Expand Up @@ -179,7 +180,14 @@ fn msg_span_from_early_bound_and_free_regions(
}
ty::ReFree(ref fr) => match fr.bound_region {
ty::BrAnon(idx) => {
(format!("the anonymous lifetime #{} defined on", idx + 1), tcx.hir().span(node))
if let Some((ty, _)) = find_anon_type(tcx, region, &fr.bound_region) {
("the anonymous lifetime defined on".to_string(), ty.span)
} else {
(
format!("the anonymous lifetime #{} defined on", idx + 1),
tcx.hir().span(node),
)
}
}
_ => (
format!("the lifetime `{}` as defined on", region),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Error Reporting for Anonymous Region Lifetime Errors
//! where both the regions are anonymous.

use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use crate::infer::lexical_region_resolve::RegionResolutionError;
Expand Down Expand Up @@ -66,9 +67,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let scope_def_id_sub = anon_reg_sub.def_id;
let bregion_sub = anon_reg_sub.boundregion;

let ty_sup = self.find_anon_type(sup, &bregion_sup)?;
let ty_sup = find_anon_type(self.tcx(), sup, &bregion_sup)?;

let ty_sub = self.find_anon_type(sub, &bregion_sub)?;
let ty_sub = find_anon_type(self.tcx(), sub, &bregion_sub)?;

debug!(
"try_report_anon_anon_conflict: found_param1={:?} sup={:?} br1={:?}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,72 +1,68 @@
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_hir as hir;
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::Node;
use rustc_middle::hir::map::Map;
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::ty::{self, Region, TyCtxt};

impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// This function calls the `visit_ty` method for the parameters
/// corresponding to the anonymous regions. The `nested_visitor.found_type`
/// contains the anonymous type.
///
/// # Arguments
/// region - the anonymous region corresponding to the anon_anon conflict
/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
///
/// # Example
/// ```
/// fn foo(x: &mut Vec<&u8>, y: &u8)
/// { x.push(y); }
/// ```
/// The function returns the nested type corresponding to the anonymous region
/// for e.g., `&u8` and Vec<`&u8`.
pub(super) fn find_anon_type(
&self,
region: Region<'tcx>,
br: &ty::BoundRegionKind,
) -> Option<(&hir::Ty<'tcx>, &hir::FnDecl<'tcx>)> {
if let Some(anon_reg) = self.tcx().is_suitable_region(region) {
let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
let fndecl = match self.tcx().hir().get(hir_id) {
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
| Node::TraitItem(&hir::TraitItem {
kind: hir::TraitItemKind::Fn(ref m, ..),
..
})
| Node::ImplItem(&hir::ImplItem {
kind: hir::ImplItemKind::Fn(ref m, ..), ..
}) => &m.decl,
_ => return None,
};
/// This function calls the `visit_ty` method for the parameters
/// corresponding to the anonymous regions. The `nested_visitor.found_type`
/// contains the anonymous type.
///
/// # Arguments
/// region - the anonymous region corresponding to the anon_anon conflict
/// br - the bound region corresponding to the above region which is of type `BrAnon(_)`
///
/// # Example
/// ```
/// fn foo(x: &mut Vec<&u8>, y: &u8)
/// { x.push(y); }
/// ```
/// The function returns the nested type corresponding to the anonymous region
/// for e.g., `&u8` and Vec<`&u8`.
pub(crate) fn find_anon_type(
tcx: TyCtxt<'tcx>,
region: Region<'tcx>,
br: &ty::BoundRegionKind,
) -> Option<(&'tcx hir::Ty<'tcx>, &'tcx hir::FnDecl<'tcx>)> {
if let Some(anon_reg) = tcx.is_suitable_region(region) {
let hir_id = tcx.hir().local_def_id_to_hir_id(anon_reg.def_id);
let fndecl = match tcx.hir().get(hir_id) {
Node::Item(&hir::Item { kind: hir::ItemKind::Fn(ref m, ..), .. })
| Node::TraitItem(&hir::TraitItem {
kind: hir::TraitItemKind::Fn(ref m, ..), ..
})
| Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Fn(ref m, ..), .. }) => {
&m.decl
}
_ => return None,
};

fndecl
.inputs
.iter()
.find_map(|arg| self.find_component_for_bound_region(arg, br))
.map(|ty| (ty, &**fndecl))
} else {
None
}
fndecl
.inputs
.iter()
.find_map(|arg| find_component_for_bound_region(tcx, arg, br))
.map(|ty| (ty, &**fndecl))
} else {
None
}
}

// This method creates a FindNestedTypeVisitor which returns the type corresponding
// to the anonymous region.
fn find_component_for_bound_region(
&self,
arg: &'tcx hir::Ty<'tcx>,
br: &ty::BoundRegionKind,
) -> Option<&'tcx hir::Ty<'tcx>> {
let mut nested_visitor = FindNestedTypeVisitor {
tcx: self.tcx(),
bound_region: *br,
found_type: None,
current_index: ty::INNERMOST,
};
nested_visitor.visit_ty(arg);
nested_visitor.found_type
}
// This method creates a FindNestedTypeVisitor which returns the type corresponding
// to the anonymous region.
fn find_component_for_bound_region(
tcx: TyCtxt<'tcx>,
arg: &'tcx hir::Ty<'tcx>,
br: &ty::BoundRegionKind,
) -> Option<&'tcx hir::Ty<'tcx>> {
let mut nested_visitor = FindNestedTypeVisitor {
tcx,
bound_region: *br,
found_type: None,
current_index: ty::INNERMOST,
};
nested_visitor.visit_ty(arg);
nested_visitor.found_type
}

// The FindNestedTypeVisitor captures the corresponding `hir::Ty` of the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_span::source_map::Span;

mod different_lifetimes;
mod find_anon_type;
pub mod find_anon_type;
mod named_anon_conflict;
mod placeholder_error;
mod static_impl_trait;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Error Reporting for Anonymous Region Lifetime Errors
//! where one region is named and the other is anonymous.
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir::intravisit::Visitor;
Expand Down Expand Up @@ -74,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
return None;
}

if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
if self.is_self_anon(is_first, scope_def_id) {
return None;
}
Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-16683.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
LL | self.a();
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 3:5...
--> $DIR/issue-16683.rs:3:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 3:10...
--> $DIR/issue-16683.rs:3:10
|
LL | fn b(&self) {
| ^^^^^^^^^^^
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> $DIR/issue-16683.rs:4:9
|
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-17740.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ LL | fn bar(self: &mut Foo) {
|
= note: expected struct `Foo<'a>`
found struct `Foo<'_>`
note: the anonymous lifetime #2 defined on the method body at 6:5...
--> $DIR/issue-17740.rs:6:5
note: the anonymous lifetime defined on the method body at 6:23...
--> $DIR/issue-17740.rs:6:23
|
LL | fn bar(self: &mut Foo) {
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^
note: ...does not necessarily outlive the lifetime `'a` as defined on the impl at 5:7
--> $DIR/issue-17740.rs:5:7
|
Expand All @@ -30,11 +30,11 @@ note: the lifetime `'a` as defined on the impl at 5:7...
|
LL | impl <'a> Foo<'a>{
| ^^
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the method body at 6:5
--> $DIR/issue-17740.rs:6:5
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 6:23
--> $DIR/issue-17740.rs:6:23
|
LL | fn bar(self: &mut Foo) {
| ^^^^^^^^^^^^^^^^^^^^^^
| ^^^

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-17758.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflictin
LL | self.foo();
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> $DIR/issue-17758.rs:6:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 6:12...
--> $DIR/issue-17758.rs:6:12
|
LL | fn bar(&self) {
| ^^^^^^^^^^^^^
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> $DIR/issue-17758.rs:7:9
|
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-17905-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ LL | fn say(self: &Pair<&str, isize>) {
|
= note: expected struct `Pair<&str, _>`
found struct `Pair<&str, _>`
note: the anonymous lifetime #2 defined on the method body at 8:5...
--> $DIR/issue-17905-2.rs:8:5
note: the anonymous lifetime defined on the method body at 8:24...
--> $DIR/issue-17905-2.rs:8:24
|
LL | fn say(self: &Pair<&str, isize>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^
note: ...does not necessarily outlive the lifetime `'_` as defined on the impl at 5:5
--> $DIR/issue-17905-2.rs:5:5
|
Expand All @@ -30,11 +30,11 @@ note: the lifetime `'_` as defined on the impl at 5:5...
|
LL | &str,
| ^
note: ...does not necessarily outlive the anonymous lifetime #2 defined on the method body at 8:5
--> $DIR/issue-17905-2.rs:8:5
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 8:24
--> $DIR/issue-17905-2.rs:8:24
|
LL | fn say(self: &Pair<&str, isize>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/issues/issue-20831-debruijn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 28:5...
--> $DIR/issue-20831-debruijn.rs:28:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 28:58...
--> $DIR/issue-20831-debruijn.rs:28:58
|
LL | fn subscribe(&mut self, t : Box<dyn Subscriber<Input=<Self as Publisher>::Output> + 'a>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the impl at 26:6...
--> $DIR/issue-20831-debruijn.rs:26:6
|
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/issues/issue-27942.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ LL | fn select(&self) -> BufferViewHandle<R>;
|
= note: expected type `Resources<'_>`
found type `Resources<'a>`
note: the anonymous lifetime #1 defined on the method body at 5:5...
--> $DIR/issue-27942.rs:5:5
note: the anonymous lifetime defined on the method body at 5:15...
--> $DIR/issue-27942.rs:5:15
|
LL | fn select(&self) -> BufferViewHandle<R>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^
note: ...does not necessarily outlive the lifetime `'a` as defined on the trait at 3:18
--> $DIR/issue-27942.rs:3:18
|
Expand All @@ -30,11 +30,11 @@ note: the lifetime `'a` as defined on the trait at 3:18...
|
LL | pub trait Buffer<'a, R: Resources<'a>> {
| ^^
note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 5:5
--> $DIR/issue-27942.rs:5:5
note: ...does not necessarily outlive the anonymous lifetime defined on the method body at 5:15
--> $DIR/issue-27942.rs:5:15
|
LL | fn select(&self) -> BufferViewHandle<R>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^

error: aborting due to 2 previous errors

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/nll/issue-52742.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ note: ...the reference is valid for the lifetime `'_` as defined on the impl at
|
LL | impl Foo<'_, '_> {
| ^^
note: ...but the borrowed content is only valid for the anonymous lifetime #2 defined on the method body at 13:5
--> $DIR/issue-52742.rs:13:5
note: ...but the borrowed content is only valid for the anonymous lifetime defined on the method body at 13:31
--> $DIR/issue-52742.rs:13:31
|
LL | fn take_bar(&mut self, b: Bar<'_>) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^

error: aborting due to previous error

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/nll/issue-55394.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'s` d
LL | Foo { bar }
| ^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 8:5...
--> $DIR/issue-55394.rs:8:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 8:17...
--> $DIR/issue-55394.rs:8:17
|
LL | fn new(bar: &mut Bar) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> $DIR/issue-55394.rs:9:15
|
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/nll/type-alias-free-regions.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` d
LL | C { f: b }
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 16:5...
--> $DIR/type-alias-free-regions.rs:16:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 16:24...
--> $DIR/type-alias-free-regions.rs:16:24
|
LL | fn from_box(b: Box<B>) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
note: ...so that the expression is assignable
--> $DIR/type-alias-free-regions.rs:17:16
|
Expand All @@ -35,11 +35,11 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requiremen
LL | C { f: Box::new(b.0) }
| ^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 26:5...
--> $DIR/type-alias-free-regions.rs:26:5
note: first, the lifetime cannot outlive the anonymous lifetime defined on the method body at 26:23...
--> $DIR/type-alias-free-regions.rs:26:23
|
LL | fn from_tuple(b: (B,)) -> Self {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| ^
note: ...so that the expression is assignable
--> $DIR/type-alias-free-regions.rs:27:25
|
Expand Down
Loading