1
Fork 0

Change how suggested lifetime args are computed.

This commit is contained in:
Camille GILLOT 2022-11-06 09:45:34 +00:00
parent 5f5e7a8eec
commit 41090346d8
11 changed files with 83 additions and 55 deletions

View file

@ -296,25 +296,35 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
) -> String { ) -> String {
debug!(?path_hir_id); debug!(?path_hir_id);
// If there was already a lifetime among the arguments, just replicate that one.
if let Some(lt) = self.gen_args.args.iter().find_map(|arg| match arg {
hir::GenericArg::Lifetime(lt) => Some(lt),
_ => None,
}) {
return std::iter::repeat(lt.to_string())
.take(num_params_to_take)
.collect::<Vec<_>>()
.join(", ");
}
let mut ret = Vec::new(); let mut ret = Vec::new();
let mut ty_id = None;
for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
debug!(?id); debug!(?id);
let params = if let Some(generics) = node.generics() { if let hir::Node::Ty(_) = node {
generics.params ty_id = Some(id);
} else if let hir::Node::Ty(ty) = node }
&& let hir::TyKind::BareFn(bare_fn) = ty.kind
{ // Suggest `'_` when in function parameter or elided function return.
bare_fn.generic_params if let Some(fn_decl) = node.fn_decl() && let Some(ty_id) = ty_id {
} else { let in_arg = fn_decl.inputs.iter().any(|t| t.hir_id == ty_id);
&[] let in_ret = matches!(fn_decl.output, hir::FnRetTy::Return(ty) if ty.hir_id == ty_id);
};
ret.extend(params.iter().filter_map(|p| { if in_arg || (in_ret && fn_decl.lifetime_elision_allowed) {
let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } return std::iter::repeat("'_".to_owned()).take(num_params_to_take).collect::<Vec<_>>().join(", ");
= p.kind }
else { return None }; }
let hir::ParamName::Plain(name) = p.name else { return None };
Some(name.to_string())
}));
// Suggest `'static` when in const/static item-like. // Suggest `'static` when in const/static item-like.
if let hir::Node::Item(hir::Item { if let hir::Node::Item(hir::Item {
kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. }, kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
@ -334,11 +344,29 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
}) })
| hir::Node::AnonConst(..) = node | hir::Node::AnonConst(..) = node
{ {
ret.extend( return std::iter::repeat("'static".to_owned())
std::iter::repeat("'static".to_owned()) .take(num_params_to_take.saturating_sub(ret.len()))
.take(num_params_to_take.saturating_sub(ret.len())), .collect::<Vec<_>>()
); .join(", ");
} }
let params = if let Some(generics) = node.generics() {
generics.params
} else if let hir::Node::Ty(ty) = node
&& let hir::TyKind::BareFn(bare_fn) = ty.kind
{
bare_fn.generic_params
} else {
&[]
};
ret.extend(params.iter().filter_map(|p| {
let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
= p.kind
else { return None };
let hir::ParamName::Plain(name) = p.name else { return None };
Some(name.to_string())
}));
if ret.len() >= num_params_to_take { if ret.len() >= num_params_to_take {
return ret[..num_params_to_take].join(", "); return ret[..num_params_to_take].join(", ");
} }

View file

@ -11,7 +11,7 @@ LL | type Y<'a>;
| ^ -- | ^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn f2<'a>(arg: Box<dyn X<Y<'a, 1> = &'a ()>>) {} LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++ | +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied

View file

@ -13,8 +13,8 @@ LL | struct S<'a, 'b>(&'a u8, &'b u8);
| ^ -- -- | ^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | S::<'static, 'b>(&0, &0); LL | S::<'static, 'static>(&0, &0);
| ++++ | +++++++++
error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/constructor-lifetime-args.rs:19:5 --> $DIR/constructor-lifetime-args.rs:19:5
@ -45,8 +45,8 @@ LL | enum E<'a, 'b> {
| ^ -- -- | ^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | E::V::<'static, 'b>(&0); LL | E::V::<'static, 'static>(&0);
| ++++ | +++++++++
error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/constructor-lifetime-args.rs:24:8 --> $DIR/constructor-lifetime-args.rs:24:8

View file

@ -11,7 +11,7 @@ LL | type Assoc<'a> where Self: 'a;
| ^^^^^ -- | ^^^^^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn g(&self) -> Self::Assoc<'a>; LL | fn g(&self) -> Self::Assoc<'_>;
| ~~~~~~~~~ | ~~~~~~~~~
error[E0107]: missing generics for associated type `Trait::Assoc` error[E0107]: missing generics for associated type `Trait::Assoc`
@ -27,7 +27,7 @@ LL | type Assoc<'a> where Self: 'a;
| ^^^^^ -- | ^^^^^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn g(&self) -> Self::Assoc<'a> { LL | fn g(&self) -> Self::Assoc<'_> {
| ~~~~~~~~~ | ~~~~~~~~~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -36,7 +36,7 @@ LL | type Y<'a>;
| ^ -- | ^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn foo<'a>(arg: Box<dyn X<Y('a, 'a) = &'a ()>>) {} LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {}
| +++ | +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied
@ -66,7 +66,7 @@ LL | type Y<'a>;
| ^ -- | ^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn bar<'a>(arg: Box<dyn X<Y('a) = ()>>) {} LL | fn bar<'a>(arg: Box<dyn X<Y('_) = ()>>) {}
| ++ | ++
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -11,7 +11,7 @@ LL | type Item<'a>;
| ^^^^ -- | ^^^^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn next(&mut self) -> Option<Self::Item<'a>>; LL | fn next(&mut self) -> Option<Self::Item<'_>>;
| ~~~~~~~~ | ~~~~~~~~
error: aborting due to previous error error: aborting due to previous error

View file

@ -11,7 +11,7 @@ LL | type Y<'a, 'b>;
| ^ -- -- | ^ -- --
help: add missing lifetime arguments help: add missing lifetime arguments
| |
LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'c, 'd> = (&'c u32, &'d u32)>>) {} LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {}
| ~~~~~~~~~ | ~~~~~~~~~
error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied
@ -47,7 +47,7 @@ LL | struct Foo<'a, 'b, 'c> {
| ^^^ -- -- -- | ^^^ -- -- --
help: add missing lifetime arguments help: add missing lifetime arguments
| |
LL | fn f<'a>(_arg: Foo<'a, 'b, 'c>) {} LL | fn f<'a>(_arg: Foo<'a, 'a, 'a>) {}
| ++++++++ | ++++++++
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View file

@ -11,7 +11,7 @@ LL | type Y<'a>;
| ^ -- | ^ --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | fn f2<'a>(arg : Box<dyn X<Y<'a, 1> = &'a ()>>) {} LL | fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {}
| +++ | +++
error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied

View file

@ -812,8 +812,8 @@ LL | trait GenericLifetimeLifetimeAT<'a, 'b> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ -- -- | ^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'b, AssocTy=()>>; LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'static, AssocTy=()>>;
| ++++ | +++++++++
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:287:26 --> $DIR/wrong-number-of-args.rs:287:26
@ -846,8 +846,8 @@ LL | trait GenericLifetimeLifetimeTypeAT<'a, 'b, A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- -- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'b, AssocTy=()>>; LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, AssocTy=()>>;
| ++++ | +++++++++
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/wrong-number-of-args.rs:294:26 --> $DIR/wrong-number-of-args.rs:294:26
@ -880,8 +880,8 @@ LL | trait GenericLifetimeLifetimeTypeAT<'a, 'b, A> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- -- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'b, (), AssocTy=()>>; LL | type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, (), AssocTy=()>>;
| ++++ | +++++++++
error[E0107]: missing generics for struct `HashMap` error[E0107]: missing generics for struct `HashMap`
--> $DIR/wrong-number-of-args.rs:310:18 --> $DIR/wrong-number-of-args.rs:310:18

View file

@ -13,8 +13,8 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
| ^^^^^ -- -- | ^^^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | S.early::<'static, 'b>(); LL | S.early::<'static, 'static>();
| ++++ | +++++++++
error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/method-call-lifetime-args-fail.rs:18:7 --> $DIR/method-call-lifetime-args-fail.rs:18:7
@ -213,8 +213,8 @@ LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} }
| ^^^^^ -- -- | ^^^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | S::early::<'static, 'b>(S); LL | S::early::<'static, 'static>(S);
| ++++ | +++++++++
error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied
--> $DIR/method-call-lifetime-args-fail.rs:65:8 --> $DIR/method-call-lifetime-args-fail.rs:65:8

View file

@ -166,8 +166,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44 --> $DIR/missing-lifetime-specifier.rs:39:44
@ -184,8 +184,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44 --> $DIR/missing-lifetime-specifier.rs:39:44
@ -202,8 +202,8 @@ LL | pub union Qux<'t, 'k, I> {
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:39:44 --> $DIR/missing-lifetime-specifier.rs:39:44
@ -256,8 +256,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45 --> $DIR/missing-lifetime-specifier.rs:47:45
@ -274,8 +274,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45 --> $DIR/missing-lifetime-specifier.rs:47:45
@ -292,8 +292,8 @@ LL | trait Tar<'t, 'k, I> {}
| ^^^ -- -- | ^^^ -- --
help: add missing lifetime argument help: add missing lifetime argument
| |
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'k, i32>>>>> = RefCell::new(HashMap::new()); LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ++++ | +++++++++
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
--> $DIR/missing-lifetime-specifier.rs:47:45 --> $DIR/missing-lifetime-specifier.rs:47:45