mirror of
https://github.com/rust-lang/rust
synced 2024-10-01 22:34:35 +00:00
Fix ICE, generalize 'move generics to trait' suggestion for >0 non-rcvr arguments
This commit is contained in:
parent
b44197abb0
commit
bee48e3fdc
|
@ -749,23 +749,45 @@ fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
|
||||||
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||||
&self,
|
&self,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
trait_: DefId,
|
trait_def_id: DefId,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
msg: String,
|
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,
|
||||||
) {
|
) {
|
||||||
if let hir::ExprKind::MethodCall(_, receiver, args, ..) = expr.kind {
|
let sm = self.tcx.sess.source_map();
|
||||||
assert_eq!(args.len(), 0);
|
let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return; };
|
||||||
if num_assoc_fn_excess_args == num_trait_generics_except_self {
|
if num_assoc_fn_excess_args != num_trait_generics_except_self {
|
||||||
if let Some(gen_args) = self.gen_args.span_ext()
|
return;
|
||||||
&& let Ok(gen_args) = self.tcx.sess.source_map().span_to_snippet(gen_args)
|
|
||||||
&& let Ok(receiver) = self.tcx.sess.source_map().span_to_snippet(receiver.span) {
|
|
||||||
let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), receiver);
|
|
||||||
err.span_suggestion(expr.span, msg, sugg, Applicability::MaybeIncorrect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
let Some(gen_args) = self.gen_args.span_ext() else { return; };
|
||||||
|
let Ok(generics) = sm.span_to_snippet(gen_args) else { return; };
|
||||||
|
let Ok(rcvr) = sm.span_to_snippet(
|
||||||
|
rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span)
|
||||||
|
) else { return; };
|
||||||
|
let Ok(rest) =
|
||||||
|
(match args {
|
||||||
|
[] => Ok(String::new()),
|
||||||
|
[arg] => sm.span_to_snippet(
|
||||||
|
arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span),
|
||||||
|
),
|
||||||
|
[first, .., last] => {
|
||||||
|
let first_span =
|
||||||
|
first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
|
||||||
|
let last_span =
|
||||||
|
last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
|
||||||
|
sm.span_to_snippet(first_span.to(last_span))
|
||||||
|
}
|
||||||
|
}) else { return; };
|
||||||
|
let comma = if args.len() > 0 { ", " } else { "" };
|
||||||
|
let trait_path = self.tcx.def_path_str(trait_def_id);
|
||||||
|
let method_name = self.tcx.item_name(self.def_id);
|
||||||
|
err.span_suggestion(
|
||||||
|
expr.span,
|
||||||
|
msg,
|
||||||
|
format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Suggests to remove redundant argument(s):
|
/// Suggests to remove redundant argument(s):
|
||||||
|
|
12
src/test/ui/suggestions/issue-101421.rs
Normal file
12
src/test/ui/suggestions/issue-101421.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
pub trait Ice {
|
||||||
|
fn f(&self, _: ());
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ice for () {
|
||||||
|
fn f(&self, _: ()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
().f::<()>(());
|
||||||
|
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
}
|
17
src/test/ui/suggestions/issue-101421.stderr
Normal file
17
src/test/ui/suggestions/issue-101421.stderr
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
--> $DIR/issue-101421.rs:10:8
|
||||||
|
|
|
||||||
|
LL | ().f::<()>(());
|
||||||
|
| ^------ help: remove these generics
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
||||||
|
note: associated function defined here, with 0 generic parameters
|
||||||
|
--> $DIR/issue-101421.rs:2:8
|
||||||
|
|
|
||||||
|
LL | fn f(&self, _: ());
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0107`.
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Generalizes the suggestion introduced in #100838
|
||||||
|
|
||||||
|
trait Foo<T> {
|
||||||
|
fn bar(&self, _: T);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo<i32> for i32 {
|
||||||
|
fn bar(&self, x: i32) {
|
||||||
|
println!("{}", self + x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
1.bar::<i32>(0);
|
||||||
|
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
//~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
|
||||||
|
//~| HELP remove these generics
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
|
--> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7
|
||||||
|
|
|
||||||
|
LL | 1.bar::<i32>(0);
|
||||||
|
| ^^^ expected 0 generic arguments
|
||||||
|
|
|
||||||
|
note: associated function defined here, with 0 generic parameters
|
||||||
|
--> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8
|
||||||
|
|
|
||||||
|
LL | fn bar(&self, _: T);
|
||||||
|
| ^^^
|
||||||
|
help: consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
|
||||||
|
|
|
||||||
|
LL | Foo::<i32>::bar(1, 0);
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
help: remove these generics
|
||||||
|
|
|
||||||
|
LL - 1.bar::<i32>(0);
|
||||||
|
LL + 1.bar(0);
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0107`.
|
Loading…
Reference in a new issue