From 6e6d8a14da9d7157ff9bf32fbe278608e86f2094 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 6 Feb 2024 19:48:16 +0000 Subject: [PATCH] Add a helpful suggestion --- compiler/rustc_ast_lowering/messages.ftl | 1 + compiler/rustc_ast_lowering/src/errors.rs | 2 + compiler/rustc_ast_lowering/src/lib.rs | 71 ++++++++++++------- .../assoc-type-eq-with-dyn-atb-fail.stderr | 5 ++ .../dyn-impl-trait-type.stderr | 12 ---- .../dyn-rpit-and-let.stderr | 12 ---- .../ui/associated-type-bounds/elision.stderr | 5 ++ 7 files changed, 58 insertions(+), 50 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr delete mode 100644 tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 9c151ec80eefe..e87cf05713cd3 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -10,6 +10,7 @@ ast_lowering_argument = argument ast_lowering_assoc_ty_binding_in_dyn = associated type bounds are not allowed in `dyn` types + .suggestion = use `impl Trait` to introduce a type instead ast_lowering_assoc_ty_parentheses = parenthesized generic arguments cannot be used in associated type constraints diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index fba8ea206f140..274e6b7458c61 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -98,6 +98,8 @@ pub struct MisplacedImplTrait<'a> { pub struct MisplacedAssocTyBinding { #[primary_span] pub span: Span, + #[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")] + pub suggestion: Option, } #[derive(Diagnostic, Clone, Copy)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9292fa5b6f374..345e6412dec93 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1088,32 +1088,50 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AssocConstraintKind::Bound { bounds } => { enum DesugarKind { ImplTrait, - Error, + Error(Option), Bound, } // Piggy-back on the `impl Trait` context to figure out the correct behavior. - let desugar_kind = match itctx { - _ if self.is_in_dyn_type => DesugarKind::Error, - - // We are in the return position: - // - // fn foo() -> impl Iterator - // - // so desugar to - // - // fn foo() -> impl Iterator - ImplTraitContext::ReturnPositionOpaqueTy { .. } - | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait, - - // We are in the parameter position, but not within a dyn type: - // - // fn foo(x: impl Iterator) - // - // so we leave it as is and this gets expanded in astconv to a bound like - // `::Item: Debug` where `T` is the type parameter for the - // `impl Iterator`. - _ => DesugarKind::Bound, + let desugar_kind = if self.is_in_dyn_type { + match itctx { + ImplTraitContext::ReturnPositionOpaqueTy { .. } + | ImplTraitContext::TypeAliasesOpaqueTy { .. } + | ImplTraitContext::Universal => { + let bound_end_span = constraint + .gen_args + .as_ref() + .map_or(constraint.ident.span, |args| args.span()); + let colon_span = if bound_end_span.eq_ctxt(constraint.span) { + Some(self.tcx.sess.source_map().next_point(bound_end_span)) + } else { + None + }; + DesugarKind::Error(colon_span) + } + _ => DesugarKind::Error(None), + } + } else { + match itctx { + // We are in the return position: + // + // fn foo() -> impl Iterator + // + // so desugar to + // + // fn foo() -> impl Iterator + ImplTraitContext::ReturnPositionOpaqueTy { .. } + | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait, + + // We are in the parameter position, but not within a dyn type: + // + // fn foo(x: impl Iterator) + // + // so we leave it as is and this gets expanded in astconv to a bound like + // `::Item: Debug` where `T` is the type parameter for the + // `impl Iterator`. + _ => DesugarKind::Bound, + } }; match desugar_kind { @@ -1150,10 +1168,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Constraint { bounds } } - DesugarKind::Error => { - let guar = self - .dcx() - .emit_err(errors::MisplacedAssocTyBinding { span: constraint.span }); + DesugarKind::Error(suggestion) => { + let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding { + span: constraint.span, + suggestion, + }); let err_ty = &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); hir::TypeBindingKind::Equality { term: err_ty.into() } diff --git a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 2d38bbd8c923e..ad5409094118d 100644 --- a/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/tests/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -3,6 +3,11 @@ error: associated type bounds are not allowed in `dyn` types | LL | type Out = Box>; | ^^^^^^^^^^^ + | +help: use `impl Trait` to introduce a type instead + | +LL | type Out = Box>; + | ~~~~~~ error: aborting due to 1 previous error diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr b/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr deleted file mode 100644 index 2e26a434f5d34..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: method `tr2` is never used - --> $DIR/dyn-impl-trait-type.rs:8:20 - | -LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; } - | --- ^^^ - | | - | method in this trait - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr b/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr deleted file mode 100644 index 9eddbe462847d..0000000000000 --- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr +++ /dev/null @@ -1,12 +0,0 @@ -warning: method `tr2` is never used - --> $DIR/dyn-rpit-and-let.rs:10:20 - | -LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; } - | --- ^^^ - | | - | method in this trait - | - = note: `#[warn(dead_code)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/elision.stderr b/tests/ui/associated-type-bounds/elision.stderr index 70302d25b2b45..749dffdc4d318 100644 --- a/tests/ui/associated-type-bounds/elision.stderr +++ b/tests/ui/associated-type-bounds/elision.stderr @@ -15,6 +15,11 @@ error: associated type bounds are not allowed in `dyn` types | LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `impl Trait` to introduce a type instead + | +LL | fn f(x: &mut dyn Iterator>) -> Option<&'_ ()> { x.next() } + | ~~~~~~ error: aborting due to 2 previous errors