From d8f5d5e9cbb6a3f910becdbc725623425e8af186 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 16 May 2021 18:33:32 +0200 Subject: [PATCH 1/2] Consider edge cases in missing lifetime diagnostics --- .../wrong_number_of_generic_args.rs | 49 ++++++------------- 1 file changed, 14 insertions(+), 35 deletions(-) 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 56f288ff051..aed36b12f3a 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 @@ fn suggest_adding_lifetime_args(&self, err: &mut DiagnosticBuilder<'_>) { } 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(); + 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(); - if let Ok(first_gen_arg) = source_map.span_to_snippet(first_arg_span) { - let sugg = format!("{}, {}", suggested_args, first_gen_arg); + let sugg_prefix = if is_first { "" } else { ", " }; + let sugg_suffix = + if is_first && (has_non_lt_args || has_bindings) { ", " } else { "" }; - err.span_suggestion_verbose( - first_arg_span, - &msg, - sugg, - Applicability::HasPlaceholders, - ); - } - } + 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 From 363eacd8d336e273f234d320dba26e67f7399616 Mon Sep 17 00:00:00 2001 From: Giacomo Stevanato Date: Sun, 16 May 2021 18:33:41 +0200 Subject: [PATCH 2/2] Add regression test --- src/test/ui/suggestions/issue-85347.rs | 10 ++++++++++ src/test/ui/suggestions/issue-85347.stderr | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/test/ui/suggestions/issue-85347.rs create mode 100644 src/test/ui/suggestions/issue-85347.stderr diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs new file mode 100644 index 00000000000..f08e38689d6 --- /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 00000000000..60594baa29c --- /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`.