Skip to content

Commit 8936211

Browse files
authored
Rollup merge of #101427 - compiler-errors:issue-101421, r=cjgillot
Fix ICE, generalize 'move generics to trait' suggestion for >0 non-rcvr arguments Fixes #101421 cc #100838
2 parents 00db13f + bee48e3 commit 8936211

File tree

5 files changed

+104
-11
lines changed

5 files changed

+104
-11
lines changed

compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs

+33-11
Original file line numberDiff line numberDiff line change
@@ -749,23 +749,45 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
749749
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
750750
&self,
751751
err: &mut Diagnostic,
752-
trait_: DefId,
752+
trait_def_id: DefId,
753753
expr: &'tcx hir::Expr<'tcx>,
754754
msg: String,
755755
num_assoc_fn_excess_args: usize,
756756
num_trait_generics_except_self: usize,
757757
) {
758-
if let hir::ExprKind::MethodCall(_, receiver, args, ..) = expr.kind {
759-
assert_eq!(args.len(), 0);
760-
if num_assoc_fn_excess_args == num_trait_generics_except_self {
761-
if let Some(gen_args) = self.gen_args.span_ext()
762-
&& let Ok(gen_args) = self.tcx.sess.source_map().span_to_snippet(gen_args)
763-
&& let Ok(receiver) = self.tcx.sess.source_map().span_to_snippet(receiver.span) {
764-
let sugg = format!("{}::{}::{}({})", self.tcx.item_name(trait_), gen_args, self.tcx.item_name(self.def_id), receiver);
765-
err.span_suggestion(expr.span, msg, sugg, Applicability::MaybeIncorrect);
766-
}
767-
}
758+
let sm = self.tcx.sess.source_map();
759+
let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return; };
760+
if num_assoc_fn_excess_args != num_trait_generics_except_self {
761+
return;
768762
}
763+
let Some(gen_args) = self.gen_args.span_ext() else { return; };
764+
let Ok(generics) = sm.span_to_snippet(gen_args) else { return; };
765+
let Ok(rcvr) = sm.span_to_snippet(
766+
rcvr.span.find_ancestor_inside(expr.span).unwrap_or(rcvr.span)
767+
) else { return; };
768+
let Ok(rest) =
769+
(match args {
770+
[] => Ok(String::new()),
771+
[arg] => sm.span_to_snippet(
772+
arg.span.find_ancestor_inside(expr.span).unwrap_or(arg.span),
773+
),
774+
[first, .., last] => {
775+
let first_span =
776+
first.span.find_ancestor_inside(expr.span).unwrap_or(first.span);
777+
let last_span =
778+
last.span.find_ancestor_inside(expr.span).unwrap_or(last.span);
779+
sm.span_to_snippet(first_span.to(last_span))
780+
}
781+
}) else { return; };
782+
let comma = if args.len() > 0 { ", " } else { "" };
783+
let trait_path = self.tcx.def_path_str(trait_def_id);
784+
let method_name = self.tcx.item_name(self.def_id);
785+
err.span_suggestion(
786+
expr.span,
787+
msg,
788+
format!("{trait_path}::{generics}::{method_name}({rcvr}{comma}{rest})"),
789+
Applicability::MaybeIncorrect,
790+
);
769791
}
770792

771793
/// Suggests to remove redundant argument(s):
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
pub trait Ice {
2+
fn f(&self, _: ());
3+
}
4+
5+
impl Ice for () {
6+
fn f(&self, _: ()) {}
7+
}
8+
9+
fn main() {
10+
().f::<()>(());
11+
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
2+
--> $DIR/issue-101421.rs:10:8
3+
|
4+
LL | ().f::<()>(());
5+
| ^------ help: remove these generics
6+
| |
7+
| expected 0 generic arguments
8+
|
9+
note: associated function defined here, with 0 generic parameters
10+
--> $DIR/issue-101421.rs:2:8
11+
|
12+
LL | fn f(&self, _: ());
13+
| ^
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0107`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Generalizes the suggestion introduced in #100838
2+
3+
trait Foo<T> {
4+
fn bar(&self, _: T);
5+
}
6+
7+
impl Foo<i32> for i32 {
8+
fn bar(&self, x: i32) {
9+
println!("{}", self + x);
10+
}
11+
}
12+
13+
fn main() {
14+
1.bar::<i32>(0);
15+
//~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied
16+
//~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
17+
//~| HELP remove these generics
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied
2+
--> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7
3+
|
4+
LL | 1.bar::<i32>(0);
5+
| ^^^ expected 0 generic arguments
6+
|
7+
note: associated function defined here, with 0 generic parameters
8+
--> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8
9+
|
10+
LL | fn bar(&self, _: T);
11+
| ^^^
12+
help: consider moving this generic argument to the `Foo` trait, which takes up to 1 argument
13+
|
14+
LL | Foo::<i32>::bar(1, 0);
15+
| ~~~~~~~~~~~~~~~~~~~~~
16+
help: remove these generics
17+
|
18+
LL - 1.bar::<i32>(0);
19+
LL + 1.bar(0);
20+
|
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)