about summary refs log tree commit diff
path: root/compiler/rustc_ast_lowering/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-02-06 19:48:16 +0000
committerMichael Goulet <michael@errs.io>2024-02-10 03:31:34 +0000
commitfde695a2d19fc13a5773b8e9168341c67a21912e (patch)
tree551d9a53ee5d8bf059ad2fc8b2161d020fc43775 /compiler/rustc_ast_lowering/src
parent973bbfbd23df736dd3a257e42c6cd7e3fe5b0281 (diff)
downloadrust-fde695a2d19fc13a5773b8e9168341c67a21912e.tar.gz
rust-fde695a2d19fc13a5773b8e9168341c67a21912e.zip
Add a helpful suggestion
Diffstat (limited to 'compiler/rustc_ast_lowering/src')
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs63
2 files changed, 32 insertions, 33 deletions
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index fba8ea206f1..274e6b7458c 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<Span>,
 }
 
 #[derive(Diagnostic, Clone, Copy)]
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 48cc301219a..7c89600fa28 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1084,41 +1084,38 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::TypeBindingKind::Equality { term }
             }
             AssocConstraintKind::Bound { bounds } => {
-                enum DesugarKind {
-                    Error,
-                    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 parameter position, but not within a dyn type:
-                    //
-                    //     fn foo(x: impl Iterator<Item: Debug>)
-                    //
-                    // so we leave it as is and this gets expanded in astconv to a bound like
-                    // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the
-                    // `impl Iterator`.
-                    _ => DesugarKind::Bound,
-                };
+                // Disallow ATB in dyn types
+                if self.is_in_dyn_type {
+                    let suggestion = 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());
+                            if bound_end_span.eq_ctxt(constraint.span) {
+                                Some(self.tcx.sess.source_map().next_point(bound_end_span))
+                            } else {
+                                None
+                            }
+                        }
+                        _ => None,
+                    };
 
-                match desugar_kind {
-                    DesugarKind::Bound => {
-                        // Desugar `AssocTy: Bounds` into a type binding where the
-                        // later desugars into a trait predicate.
-                        let bounds = self.lower_param_bounds(bounds, itctx);
+                    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() }
+                } else {
+                    // Desugar `AssocTy: Bounds` into a type binding where the
+                    // later desugars into a trait predicate.
+                    let bounds = self.lower_param_bounds(bounds, itctx);
 
-                        hir::TypeBindingKind::Constraint { bounds }
-                    }
-                    DesugarKind::Error => {
-                        let guar = self
-                            .dcx()
-                            .emit_err(errors::MisplacedAssocTyBinding { span: constraint.span });
-                        let err_ty =
-                            &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
-                        hir::TypeBindingKind::Equality { term: err_ty.into() }
-                    }
+                    hir::TypeBindingKind::Constraint { bounds }
                 }
             }
         };