mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +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 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
|
||||
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
trait_: DefId,
|
||||
trait_def_id: 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(_, receiver, args, ..) = expr.kind {
|
||||
assert_eq!(args.len(), 0);
|
||||
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(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 sm = self.tcx.sess.source_map();
|
||||
let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return; };
|
||||
if num_assoc_fn_excess_args != num_trait_generics_except_self {
|
||||
return;
|
||||
}
|
||||
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):
|
||||
|
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 New Issue
Block a user