Account for owning item lifetimes in suggestion and annotate tests as run-rustfix
``` error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:12:9 | LL | fn ref_self(&self, f: &u32) -> &u32 { | - - let's call the lifetime of this reference `'1` | | | let's call the lifetime of this reference `'2` LL | f | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | LL | fn ref_self<'b>(&'b self, f: &'b u32) -> &'b u32 { | ++++ ++ ++ ++ ```
This commit is contained in:
parent
120049fab4
commit
d1d585d039
27 changed files with 404 additions and 59 deletions
|
@ -1,4 +1,5 @@
|
|||
use hir::GenericParamKind;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{
|
||||
codes::*, Applicability, Diag, DiagMessage, DiagStyledString, EmissionGuarantee, IntoDiagArg,
|
||||
MultiSpan, SubdiagMessageOp, Subdiagnostic,
|
||||
|
@ -362,13 +363,27 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
|
||||
let node = self.tcx.hir_node_by_def_id(anon_reg.def_id);
|
||||
let is_impl = matches!(&node, hir::Node::ImplItem(_));
|
||||
let generics = match node {
|
||||
let (generics, parent_generics) = match node {
|
||||
hir::Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Fn(_, ref generics, ..),
|
||||
..
|
||||
})
|
||||
| hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
|
||||
| hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
|
||||
| hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => (
|
||||
generics,
|
||||
match self.tcx.parent_hir_node(self.tcx.local_def_id_to_hir_id(anon_reg.def_id))
|
||||
{
|
||||
hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Trait(_, _, ref generics, ..),
|
||||
..
|
||||
})
|
||||
| hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Impl(hir::Impl { ref generics, .. }),
|
||||
..
|
||||
}) => Some(generics),
|
||||
_ => None,
|
||||
},
|
||||
),
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
|
@ -379,8 +394,29 @@ impl Subdiagnostic for AddLifetimeParamsSuggestion<'_> {
|
|||
.map(|p| p.name.ident().name)
|
||||
.find(|i| *i != kw::UnderscoreLifetime);
|
||||
let introduce_new = suggestion_param_name.is_none();
|
||||
|
||||
let mut default = "'a".to_string();
|
||||
if let Some(parent_generics) = parent_generics {
|
||||
let used: FxHashSet<_> = parent_generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
|
||||
.map(|p| p.name.ident().name)
|
||||
.filter(|i| *i != kw::UnderscoreLifetime)
|
||||
.map(|l| l.to_string())
|
||||
.collect();
|
||||
if let Some(lt) =
|
||||
('a'..='z').map(|it| format!("'{it}")).find(|it| !used.contains(it))
|
||||
{
|
||||
// We want a lifetime that *isn't* present in the `trait` or `impl` that assoc
|
||||
// `fn` belongs to. We could suggest reusing one of their lifetimes, but it is
|
||||
// likely to be an over-constraining lifetime requirement, so we always add a
|
||||
// lifetime to the `fn`.
|
||||
default = lt;
|
||||
}
|
||||
}
|
||||
let suggestion_param_name =
|
||||
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| "'a".to_owned());
|
||||
suggestion_param_name.map(|n| n.to_string()).unwrap_or_else(|| default);
|
||||
|
||||
struct ImplicitLifetimeFinder {
|
||||
suggestions: Vec<(Span, String)>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue