Support method calls
This commit is contained in:
parent
75ed56f0cb
commit
152913767a
@ -683,6 +683,14 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||||||
let num_trait_generics_except_self =
|
let num_trait_generics_except_self =
|
||||||
trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };
|
trait_generics.count() - if trait_generics.has_self { 1 } else { 0 };
|
||||||
|
|
||||||
|
let msg = format!(
|
||||||
|
"consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
|
||||||
|
these = pluralize!("this", num_assoc_fn_excess_args),
|
||||||
|
s = pluralize!(num_assoc_fn_excess_args),
|
||||||
|
name = self.tcx.item_name(trait_),
|
||||||
|
num = num_trait_generics_except_self,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(hir_id) = self.path_segment.hir_id
|
if let Some(hir_id) = self.path_segment.hir_id
|
||||||
&& let Some(parent_node) = self.tcx.hir().find_parent_node(hir_id)
|
&& let Some(parent_node) = self.tcx.hir().find_parent_node(hir_id)
|
||||||
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
|
&& let Some(parent_node) = self.tcx.hir().find(parent_node)
|
||||||
@ -691,14 +699,22 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||||||
hir::ExprKind::Path(ref qpath) => {
|
hir::ExprKind::Path(ref qpath) => {
|
||||||
self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
self.suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||||
err,
|
err,
|
||||||
trait_,
|
|
||||||
qpath,
|
qpath,
|
||||||
|
msg,
|
||||||
|
num_assoc_fn_excess_args,
|
||||||
|
num_trait_generics_except_self
|
||||||
|
)
|
||||||
|
},
|
||||||
|
hir::ExprKind::MethodCall(..) => {
|
||||||
|
self.suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||||
|
err,
|
||||||
|
trait_,
|
||||||
|
expr,
|
||||||
|
msg,
|
||||||
num_assoc_fn_excess_args,
|
num_assoc_fn_excess_args,
|
||||||
num_trait_generics_except_self
|
num_trait_generics_except_self
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
// FIXME(hkmatsumoto): Emit similar suggestion for "x.<assoc fn>()"
|
|
||||||
hir::ExprKind::MethodCall(..) => return,
|
|
||||||
_ => return,
|
_ => return,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -707,8 +723,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||||||
fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
trait_: DefId,
|
|
||||||
qpath: &'tcx hir::QPath<'tcx>,
|
qpath: &'tcx hir::QPath<'tcx>,
|
||||||
|
msg: String,
|
||||||
num_assoc_fn_excess_args: usize,
|
num_assoc_fn_excess_args: usize,
|
||||||
num_trait_generics_except_self: usize,
|
num_trait_generics_except_self: usize,
|
||||||
) {
|
) {
|
||||||
@ -719,13 +735,6 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||||||
if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
|
if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
|
||||||
if let Some(span) = self.gen_args.span_ext()
|
if let Some(span) = self.gen_args.span_ext()
|
||||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||||
let msg = format!(
|
|
||||||
"consider moving {these} generic argument{s} to the `{name}` trait, which takes up to {num} argument{s}",
|
|
||||||
these = pluralize!("this", num_assoc_fn_excess_args),
|
|
||||||
s = pluralize!(num_assoc_fn_excess_args),
|
|
||||||
name = self.tcx.item_name(trait_),
|
|
||||||
num = num_trait_generics_except_self,
|
|
||||||
);
|
|
||||||
let sugg = vec![
|
let sugg = vec![
|
||||||
(self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)),
|
(self.path_segment.ident.span, format!("{}::{}", snippet, self.path_segment.ident)),
|
||||||
(span.with_lo(self.path_segment.ident.span.hi()), "".to_owned())
|
(span.with_lo(self.path_segment.ident.span.hi()), "".to_owned())
|
||||||
@ -741,6 +750,28 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||||
|
&self,
|
||||||
|
err: &mut Diagnostic,
|
||||||
|
trait_: DefId,
|
||||||
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
msg: String,
|
||||||
|
num_assoc_fn_excess_args: usize,
|
||||||
|
num_trait_generics_except_self: usize,
|
||||||
|
) {
|
||||||
|
if let hir::ExprKind::MethodCall(_, args, _) = expr.kind {
|
||||||
|
assert_eq!(args.len(), 1);
|
||||||
|
if num_assoc_fn_excess_args == num_trait_generics_except_self {
|
||||||
|
if let Some(gen_args) = self.gen_args.span_ext()
|
||||||
|
&& let Ok(gen_args) = self.tcx.sess.source_map().span_to_snippet(gen_args)
|
||||||
|
&& let Ok(args) = self.tcx.sess.source_map().span_to_snippet(args[0].span) {
|
||||||
|
let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), args);
|
||||||
|
err.span_suggestion(expr.span, msg, sugg, Applicability::MaybeIncorrect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Suggests to remove redundant argument(s):
|
/// Suggests to remove redundant argument(s):
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
|
@ -2,15 +2,22 @@ error[E0107]: this associated function takes 0 generic arguments but 1 generic a
|
|||||||
--> $DIR/invalid-const-arg-for-type-param.rs:6:23
|
--> $DIR/invalid-const-arg-for-type-param.rs:6:23
|
||||||
|
|
|
|
||||||
LL | let _: u32 = 5i32.try_into::<32>().unwrap();
|
LL | let _: u32 = 5i32.try_into::<32>().unwrap();
|
||||||
| ^^^^^^^^------ help: remove these generics
|
| ^^^^^^^^ expected 0 generic arguments
|
||||||
| |
|
|
||||||
| expected 0 generic arguments
|
|
||||||
|
|
|
|
||||||
note: associated function defined here, with 0 generic parameters
|
note: associated function defined here, with 0 generic parameters
|
||||||
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | fn try_into(self) -> Result<T, Self::Error>;
|
LL | fn try_into(self) -> Result<T, Self::Error>;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
help: consider moving this generic argument to the `TryInto` trait, which takes up to 1 argument
|
||||||
|
|
|
||||||
|
LL | let _: u32 = TryInto::<32>::try_into(5i32).unwrap();
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
help: remove these generics
|
||||||
|
|
|
||||||
|
LL - let _: u32 = 5i32.try_into::<32>().unwrap();
|
||||||
|
LL + let _: u32 = 5i32.try_into().unwrap();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0599]: no method named `f` found for struct `S` in the current scope
|
error[E0599]: no method named `f` found for struct `S` in the current scope
|
||||||
--> $DIR/invalid-const-arg-for-type-param.rs:9:7
|
--> $DIR/invalid-const-arg-for-type-param.rs:9:7
|
||||||
|
@ -27,4 +27,9 @@ fn main() {
|
|||||||
let _ = A::<S>::foo::<S>();
|
let _ = A::<S>::foo::<S>();
|
||||||
//~^ ERROR
|
//~^ ERROR
|
||||||
//~| HELP remove these generics
|
//~| HELP remove these generics
|
||||||
|
|
||||||
|
let _ = 42.into::<Option<_>>();
|
||||||
|
//~^ ERROR
|
||||||
|
//~| HELP remove these generics
|
||||||
|
//~| HELP consider moving this generic argument
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,16 @@ note: associated function defined here, with 0 generic parameters
|
|||||||
|
|
|
|
||||||
LL | fn foo() {}
|
LL | fn foo() {}
|
||||||
| ^^^
|
| ^^^
|
||||||
help: remove these generics
|
|
||||||
|
|
|
||||||
LL - let _ = A::foo::<S>();
|
|
||||||
LL + let _ = A::foo();
|
|
||||||
|
|
|
||||||
help: consider moving this generic argument to the `A` trait, which takes up to 1 argument
|
help: consider moving this generic argument to the `A` trait, which takes up to 1 argument
|
||||||
|
|
|
|
||||||
LL - let _ = A::foo::<S>();
|
LL - let _ = A::foo::<S>();
|
||||||
LL + let _ = A::<S>::foo();
|
LL + let _ = A::<S>::foo();
|
||||||
|
|
|
|
||||||
|
help: remove these generics
|
||||||
|
|
|
||||||
|
LL - let _ = A::foo::<S>();
|
||||||
|
LL + let _ = A::foo();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied
|
error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied
|
||||||
--> $DIR/issue-89064.rs:22:16
|
--> $DIR/issue-89064.rs:22:16
|
||||||
@ -31,16 +31,16 @@ note: associated function defined here, with 0 generic parameters
|
|||||||
|
|
|
|
||||||
LL | fn bar() {}
|
LL | fn bar() {}
|
||||||
| ^^^
|
| ^^^
|
||||||
help: remove these generics
|
|
||||||
|
|
|
||||||
LL - let _ = B::bar::<S, S>();
|
|
||||||
LL + let _ = B::bar();
|
|
||||||
|
|
|
||||||
help: consider moving these generic arguments to the `B` trait, which takes up to 2 arguments
|
help: consider moving these generic arguments to the `B` trait, which takes up to 2 arguments
|
||||||
|
|
|
|
||||||
LL - let _ = B::bar::<S, S>();
|
LL - let _ = B::bar::<S, S>();
|
||||||
LL + let _ = B::<S, S>::bar();
|
LL + let _ = B::<S, S>::bar();
|
||||||
|
|
|
|
||||||
|
help: remove these generics
|
||||||
|
|
|
||||||
|
LL - let _ = B::bar::<S, S>();
|
||||||
|
LL + let _ = B::bar();
|
||||||
|
|
|
||||||
|
|
||||||
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
--> $DIR/issue-89064.rs:27:21
|
--> $DIR/issue-89064.rs:27:21
|
||||||
@ -56,6 +56,27 @@ note: associated function defined here, with 0 generic parameters
|
|||||||
LL | fn foo() {}
|
LL | fn foo() {}
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
--> $DIR/issue-89064.rs:31:16
|
||||||
|
|
|
||||||
|
LL | let _ = 42.into::<Option<_>>();
|
||||||
|
| ^^^^ expected 0 generic arguments
|
||||||
|
|
|
||||||
|
note: associated function defined here, with 0 generic parameters
|
||||||
|
--> $SRC_DIR/core/src/convert/mod.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into(self) -> T;
|
||||||
|
| ^^^^
|
||||||
|
help: consider moving this generic argument to the `Into` trait, which takes up to 1 argument
|
||||||
|
|
|
||||||
|
LL | let _ = Into::<Option<_>>::into(42);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
help: remove these generics
|
||||||
|
|
|
||||||
|
LL - let _ = 42.into::<Option<_>>();
|
||||||
|
LL + let _ = 42.into();
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0107`.
|
For more information about this error, try `rustc --explain E0107`.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user