diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-06-04 00:42:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-06-04 00:42:50 +0200 |
| commit | 401be78f2c6fa3ded6b529765ccfe160636a6285 (patch) | |
| tree | fd855a26f4fa61c8b044addfd9890c6473a8078c | |
| parent | e33c6edfc04d0ba5f4e0d996100263ee9d2fef79 (diff) | |
| parent | cd03fe18d8a24434c1510d08c88231fbe9d6b8bf (diff) | |
| download | rust-401be78f2c6fa3ded6b529765ccfe160636a6285.tar.gz rust-401be78f2c6fa3ded6b529765ccfe160636a6285.zip | |
Rollup merge of #97656 - EdwinRy:error_ast_low_type_contraint_parentheses, r=cjgillot
Add a suggestion to replace parentheses with angle brackets on associated trait constraint This implements a requested suggestion FIXME in [`compiler/rustc_ast_lowering/src/lib.rs` ](https://github.com/rust-lang/rust/blob/9598b4b594c97dff66feb93522e22db500deea07/compiler/rustc_ast_lowering/src/lib.rs#L921) The suggestion asks for the parentheses to either be replaced with angle brackets or removed completely depending on whether there are arguments provided within.   r? `@oli-obk`
3 files changed, 73 insertions, 9 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index d1ea76b3922..12fc1dbc4da 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, Applicability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID}; @@ -857,7 +857,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { itctx: ImplTraitContext, ) -> hir::TypeBinding<'hir> { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx); - // lower generic arguments of identifier in constraint let gen_args = if let Some(ref gen_args) = constraint.gen_args { let gen_args_ctor = match gen_args { @@ -865,12 +864,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } GenericArgs::Parenthesized(ref data) => { - let mut err = self.sess.struct_span_err( - gen_args.span(), - "parenthesized generic arguments cannot be used in associated type constraints" - ); - // FIXME: try to write a suggestion here - err.emit(); + self.assoc_ty_contraint_param_error_emit(data); self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), ParamMode::Explicit, @@ -984,6 +978,42 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } + fn assoc_ty_contraint_param_error_emit(&self, data: &ParenthesizedArgs) -> () { + let mut err = self.sess.struct_span_err( + data.span, + "parenthesized generic arguments cannot be used in associated type constraints", + ); + // Suggest removing empty parentheses: "Trait()" -> "Trait" + if data.inputs.is_empty() { + let parentheses_span = + data.inputs_span.shrink_to_lo().to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + "remove these parentheses", + vec![(parentheses_span, String::new())], + Applicability::MaybeIncorrect, + ); + } + // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` + else { + // Start of parameters to the 1st argument + let open_param = data.inputs_span.shrink_to_lo().to(data + .inputs + .first() + .unwrap() + .span + .shrink_to_lo()); + // End of last argument to end of parameters + let close_param = + data.inputs.last().unwrap().span.shrink_to_hi().to(data.inputs_span.shrink_to_hi()); + err.multipart_suggestion( + &format!("use angle brackets instead",), + vec![(open_param, String::from("<")), (close_param, String::from(">"))], + Applicability::MaybeIncorrect, + ); + } + err.emit(); + } + fn lower_generic_arg( &mut self, arg: &ast::GenericArg, diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index f01da8c61ed..c55b0530c9d 100644 --- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -10,4 +10,9 @@ fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} //~| ERROR this associated type takes 0 generic arguments but 1 generic argument //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments + +fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} + //~^ ERROR: parenthesized generic arguments cannot be used + //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments + fn main() {} diff --git a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index 6014a02c4d9..162214063e7 100644 --- a/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/src/test/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -9,6 +9,19 @@ error: parenthesized generic arguments cannot be used in associated type constra | LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} | ^^^^^ + | +help: use angle brackets instead + | +LL | fn foo<'a>(arg: Box<dyn X<Y<'a> = &'a ()>>) {} + | ~ ~ + +error: parenthesized generic arguments cannot be used in associated type constraints + --> $DIR/gat-trait-path-parenthesised-args.rs:14:27 + | +LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} + | ^-- + | | + | help: remove these parentheses error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/gat-trait-path-parenthesised-args.rs:7:27 @@ -40,6 +53,22 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error: aborting due to 4 previous errors +error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/gat-trait-path-parenthesised-args.rs:14:27 + | +LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/gat-trait-path-parenthesised-args.rs:4:8 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn bar<'a>(arg: Box<dyn X<Y('a) = ()>>) {} + | ++ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0107`. |
