diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index 56f288ff051c2..aed36b12f3a22 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -509,44 +509,23 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } AngleBrackets::Available => { - // angle brackets exist, so we insert missing arguments after the existing args - - assert!(!self.gen_args.args.is_empty()); - - if self.num_provided_lifetime_args() > 0 { - let last_lt_arg_span = self.gen_args.args - [self.num_provided_lifetime_args() - 1] - .span() - .shrink_to_hi(); - let source_map = self.tcx.sess.source_map(); - - if let Ok(last_gen_arg) = source_map.span_to_snippet(last_lt_arg_span) { - let sugg = format!("{}, {}", last_gen_arg, suggested_args); - - err.span_suggestion_verbose( - last_lt_arg_span, - &msg, - sugg, - Applicability::HasPlaceholders, - ); - } + let (sugg_span, is_first) = if self.num_provided_lifetime_args() == 0 { + (self.gen_args.span().unwrap().shrink_to_lo(), true) } else { - // Non-lifetime arguments included in `gen_args` -> insert missing lifetimes before - // existing arguments - let first_arg_span = self.gen_args.args[0].span().shrink_to_lo(); - let source_map = self.tcx.sess.source_map(); - - if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) { - let sugg = format!("{}, {}", suggested_args, first_gen_arg); - - err.span_suggestion_verbose( - first_arg_span, - &msg, - sugg, - Applicability::HasPlaceholders, - ); - } - } + let last_lt = &self.gen_args.args[self.num_provided_lifetime_args() - 1]; + (last_lt.span().shrink_to_hi(), false) + }; + let has_non_lt_args = self.num_provided_type_or_const_args() != 0; + let has_bindings = !self.gen_args.bindings.is_empty(); + + let sugg_prefix = if is_first { "" } else { ", " }; + let sugg_suffix = + if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" }; + + let sugg = format!("{}{}{}", sugg_prefix, suggested_args, sugg_suffix); + debug!("sugg: {:?}", sugg); + + err.span_suggestion_verbose(sugg_span, &msg, sugg, Applicability::HasPlaceholders); } AngleBrackets::Implied => { // We never encounter missing lifetimes in situations in which lifetimes are elided diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs new file mode 100644 index 0000000000000..f08e38689d6af --- /dev/null +++ b/src/test/ui/suggestions/issue-85347.rs @@ -0,0 +1,10 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] +use std::ops::Deref; +trait Foo { + type Bar<'a>: Deref::Bar>; + //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + //~| HELP add missing +} + +fn main() {} diff --git a/src/test/ui/suggestions/issue-85347.stderr b/src/test/ui/suggestions/issue-85347.stderr new file mode 100644 index 0000000000000..60594baa29cb6 --- /dev/null +++ b/src/test/ui/suggestions/issue-85347.stderr @@ -0,0 +1,19 @@ +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/issue-85347.rs:5:42 + | +LL | type Bar<'a>: Deref::Bar>; + | ^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-85347.rs:5:10 + | +LL | type Bar<'a>: Deref::Bar>; + | ^^^ -- +help: add missing lifetime argument + | +LL | type Bar<'a>: Deref::Bar<'a, Target = Self>>; + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`.