diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 3848f3b778298..3e58570767d70 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1254,11 +1254,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
         coroutine_kind: Option<CoroutineKind>,
     ) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
         let header = self.lower_fn_header(sig.header);
+        // Don't pass along the user-provided constness of trait associated functions; we don't want to
+        // synthesize a host effect param for them. We reject `const` on them during AST validation.
+        let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
         let itctx = ImplTraitContext::Universal;
-        let (generics, decl) =
-            self.lower_generics(generics, sig.header.constness, id, &itctx, |this| {
-                this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
-            });
+        let (generics, decl) = self.lower_generics(generics, constness, id, &itctx, |this| {
+            this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
+        });
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
     }
 
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index b5612c1820d0c..feea02c679ce1 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -233,8 +233,21 @@ ast_passes_tilde_const_disallowed = `~const` is not allowed here
     .item = this item cannot have `~const` trait bounds
 
 ast_passes_trait_fn_const =
-    functions in traits cannot be declared const
-    .label = functions in traits cannot be const
+    functions in {$in_impl ->
+        [true] trait impls
+        *[false] traits
+    } cannot be declared const
+    .label = functions in {$in_impl ->
+        [true] trait impls
+        *[false] traits
+    } cannot be const
+    .const_context_label = this declares all associated functions implicitly const
+    .remove_const_sugg = remove the `const`{$requires_multiple_changes ->
+        [true] {" ..."}
+        *[false] {""}
+    }
+    .make_impl_const_sugg = ... and declare the impl to be const instead
+    .make_trait_const_sugg = ... and declare the trait to be a `#[const_trait]` instead
 
 ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
 
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index bc5cf463f1204..b69d4cccaf04f 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -46,6 +46,21 @@ enum DisallowTildeConstContext<'a> {
     Item,
 }
 
+enum TraitOrTraitImpl<'a> {
+    Trait { span: Span, constness: Option<Span> },
+    TraitImpl { constness: Const, polarity: ImplPolarity, trait_ref: &'a TraitRef },
+}
+
+impl<'a> TraitOrTraitImpl<'a> {
+    fn constness(&self) -> Option<Span> {
+        match self {
+            Self::Trait { constness: Some(span), .. }
+            | Self::TraitImpl { constness: Const::Yes(span), .. } => Some(*span),
+            _ => None,
+        }
+    }
+}
+
 struct AstValidator<'a> {
     session: &'a Session,
     features: &'a Features,
@@ -53,11 +68,7 @@ struct AstValidator<'a> {
     /// The span of the `extern` in an `extern { ... }` block, if any.
     extern_mod: Option<&'a Item>,
 
-    /// Are we inside a trait impl?
-    in_trait_impl: bool,
-
-    /// Are we inside a const trait defn or impl?
-    in_const_trait_or_impl: bool,
+    outer_trait_or_trait_impl: Option<TraitOrTraitImpl<'a>>,
 
     has_proc_macro_decls: bool,
 
@@ -78,24 +89,28 @@ struct AstValidator<'a> {
 impl<'a> AstValidator<'a> {
     fn with_in_trait_impl(
         &mut self,
-        is_in: bool,
-        constness: Option<Const>,
+        trait_: Option<(Const, ImplPolarity, &'a TraitRef)>,
         f: impl FnOnce(&mut Self),
     ) {
-        let old = mem::replace(&mut self.in_trait_impl, is_in);
-        let old_const = mem::replace(
-            &mut self.in_const_trait_or_impl,
-            matches!(constness, Some(Const::Yes(_))),
+        let old = mem::replace(
+            &mut self.outer_trait_or_trait_impl,
+            trait_.map(|(constness, polarity, trait_ref)| TraitOrTraitImpl::TraitImpl {
+                constness,
+                polarity,
+                trait_ref,
+            }),
         );
         f(self);
-        self.in_trait_impl = old;
-        self.in_const_trait_or_impl = old_const;
+        self.outer_trait_or_trait_impl = old;
     }
 
-    fn with_in_trait(&mut self, is_const: bool, f: impl FnOnce(&mut Self)) {
-        let old = mem::replace(&mut self.in_const_trait_or_impl, is_const);
+    fn with_in_trait(&mut self, span: Span, constness: Option<Span>, f: impl FnOnce(&mut Self)) {
+        let old = mem::replace(
+            &mut self.outer_trait_or_trait_impl,
+            Some(TraitOrTraitImpl::Trait { span, constness }),
+        );
         f(self);
-        self.in_const_trait_or_impl = old;
+        self.outer_trait_or_trait_impl = old;
     }
 
     fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
@@ -291,10 +306,48 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn check_trait_fn_not_const(&self, constness: Const) {
-        if let Const::Yes(span) = constness {
-            self.dcx().emit_err(errors::TraitFnConst { span });
-        }
+    fn check_trait_fn_not_const(&self, constness: Const, parent: &TraitOrTraitImpl<'a>) {
+        let Const::Yes(span) = constness else {
+            return;
+        };
+
+        let make_impl_const_sugg = if self.features.const_trait_impl
+            && let TraitOrTraitImpl::TraitImpl {
+                constness: Const::No,
+                polarity: ImplPolarity::Positive,
+                trait_ref,
+            } = parent
+        {
+            Some(trait_ref.path.span.shrink_to_lo())
+        } else {
+            None
+        };
+
+        let make_trait_const_sugg = if self.features.const_trait_impl
+            && let TraitOrTraitImpl::Trait { span, constness: None } = parent
+        {
+            Some(span.shrink_to_lo())
+        } else {
+            None
+        };
+
+        let parent_constness = parent.constness();
+        self.dcx().emit_err(errors::TraitFnConst {
+            span,
+            in_impl: matches!(parent, TraitOrTraitImpl::TraitImpl { .. }),
+            const_context_label: parent_constness,
+            remove_const_sugg: (
+                self.session.source_map().span_extend_while(span, |c| c == ' ').unwrap_or(span),
+                match parent_constness {
+                    Some(_) => rustc_errors::Applicability::MachineApplicable,
+                    None => rustc_errors::Applicability::MaybeIncorrect,
+                },
+            ),
+            requires_multiple_changes: make_impl_const_sugg.is_some()
+                || make_trait_const_sugg.is_some(),
+            make_impl_const_sugg,
+            make_trait_const_sugg,
+        });
     }
 
     fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
@@ -817,7 +870,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 self_ty,
                 items,
             }) => {
-                self.with_in_trait_impl(true, Some(*constness), |this| {
+                self.with_in_trait_impl(Some((*constness, *polarity, t)), |this| {
                     this.visibility_not_permitted(
                         &item.vis,
                         errors::VisibilityNotPermittedNote::TraitImpl,
@@ -963,8 +1016,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
             }
             ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => {
-                let is_const_trait = attr::contains_name(&item.attrs, sym::const_trait);
-                self.with_in_trait(is_const_trait, |this| {
+                let is_const_trait =
+                    attr::find_by_name(&item.attrs, sym::const_trait).map(|attr| attr.span);
+                self.with_in_trait(item.span, is_const_trait, |this| {
                     if *is_auto == IsAuto::Yes {
                         // Auto traits cannot have generics, super traits nor contain items.
                         this.deny_generic_params(generics, item.ident.span);
@@ -977,8 +1031,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     // context for the supertraits.
                     this.visit_vis(&item.vis);
                     this.visit_ident(item.ident);
-                    let disallowed =
-                        (!is_const_trait).then(|| DisallowTildeConstContext::Trait(item.span));
+                    let disallowed = is_const_trait
+                        .is_none()
+                        .then(|| DisallowTildeConstContext::Trait(item.span));
                     this.with_tilde_const(disallowed, |this| {
                         this.visit_generics(generics);
                         walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
@@ -1342,7 +1397,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
         let tilde_const_allowed =
             matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
-                || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)) if self.in_const_trait_or_impl);
+                || matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)))
+                    && self
+                        .outer_trait_or_trait_impl
+                        .as_ref()
+                        .and_then(TraitOrTraitImpl::constness)
+                        .is_some();
 
         let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
         self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
@@ -1353,7 +1413,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             self.check_nomangle_item_asciionly(item.ident, item.span);
         }
 
-        if ctxt == AssocCtxt::Trait || !self.in_trait_impl {
+        if ctxt == AssocCtxt::Trait || self.outer_trait_or_trait_impl.is_none() {
             self.check_defaultness(item.span, item.kind.defaultness());
         }
 
@@ -1401,10 +1461,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             );
         }
 
-        if ctxt == AssocCtxt::Trait || self.in_trait_impl {
+        if let Some(parent) = &self.outer_trait_or_trait_impl {
             self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
             if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
-                self.check_trait_fn_not_const(sig.header.constness);
+                self.check_trait_fn_not_const(sig.header.constness, parent);
             }
         }
 
@@ -1414,7 +1474,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
 
         match &item.kind {
             AssocItemKind::Fn(box Fn { sig, generics, body, .. })
-                if self.in_const_trait_or_impl
+                if self
+                    .outer_trait_or_trait_impl
+                    .as_ref()
+                    .and_then(TraitOrTraitImpl::constness)
+                    .is_some()
                     || ctxt == AssocCtxt::Trait
                     || matches!(sig.header.constness, Const::Yes(_)) =>
             {
@@ -1430,8 +1494,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 );
                 self.visit_fn(kind, item.span, item.id);
             }
-            _ => self
-                .with_in_trait_impl(false, None, |this| visit::walk_assoc_item(this, item, ctxt)),
+            _ => self.with_in_trait_impl(None, |this| visit::walk_assoc_item(this, item, ctxt)),
         }
     }
 }
@@ -1547,8 +1610,7 @@ pub fn check_crate(
         session,
         features,
         extern_mod: None,
-        in_trait_impl: false,
-        in_const_trait_or_impl: false,
+        outer_trait_or_trait_impl: None,
         has_proc_macro_decls: false,
         outer_impl_trait: None,
         disallow_tilde_const: Some(DisallowTildeConstContext::Item),
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 0cec4374be2ee..42ada39f51589 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,7 +1,7 @@
 //! Errors emitted by ast_passes.
 
 use rustc_ast::ParamKindOrd;
-use rustc_errors::AddToDiagnostic;
+use rustc_errors::{AddToDiagnostic, Applicability};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
@@ -49,6 +49,24 @@ pub struct TraitFnConst {
     #[primary_span]
     #[label]
     pub span: Span,
+    pub in_impl: bool,
+    #[label(ast_passes_const_context_label)]
+    pub const_context_label: Option<Span>,
+    #[suggestion(ast_passes_remove_const_sugg, code = "")]
+    pub remove_const_sugg: (Span, Applicability),
+    pub requires_multiple_changes: bool,
+    #[suggestion(
+        ast_passes_make_impl_const_sugg,
+        code = "const ",
+        applicability = "maybe-incorrect"
+    )]
+    pub make_impl_const_sugg: Option<Span>,
+    #[suggestion(
+        ast_passes_make_trait_const_sugg,
+        code = "#[const_trait]\n",
+        applicability = "maybe-incorrect"
+    )]
+    pub make_trait_const_sugg: Option<Span>,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_error_codes/src/error_codes/E0379.md b/compiler/rustc_error_codes/src/error_codes/E0379.md
index ab438e4144712..35f546cfdb737 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0379.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0379.md
@@ -6,6 +6,10 @@ Erroneous code example:
 trait Foo {
     const fn bar() -> u32; // error!
 }
+
+impl Foo for () {
+    const fn bar() -> u32 { 0 } // error!
+}
 ```
 
 Trait methods cannot be declared `const` by design. For more information, see
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 5abc752309ad5..b44b2eefabbc6 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -315,7 +315,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
 
             if is_host_effect {
                 if let Some(idx) = host_effect_index {
-                    bug!("parent also has host effect param? index: {idx}, def: {def_id:?}");
+                    tcx.dcx().span_delayed_bug(
+                        param.span,
+                        format!("parent also has host effect param? index: {idx}, def: {def_id:?}"),
+                    );
                 }
 
                 host_effect_index = Some(index as usize);
diff --git a/tests/ui/consts/const-fn-mismatch.rs b/tests/ui/consts/const-fn-mismatch.rs
index 3107b8128e602..b17e4cedd3ff6 100644
--- a/tests/ui/consts/const-fn-mismatch.rs
+++ b/tests/ui/consts/const-fn-mismatch.rs
@@ -9,7 +9,7 @@ trait Foo {
 
 impl Foo for u32 {
     const fn f() -> u32 {
-        //~^ ERROR functions in traits cannot be declared const
+        //~^ ERROR functions in trait impls cannot be declared const
         22
     }
 }
diff --git a/tests/ui/consts/const-fn-mismatch.stderr b/tests/ui/consts/const-fn-mismatch.stderr
index beaf52c0cfb36..9e7d93b0c97bb 100644
--- a/tests/ui/consts/const-fn-mismatch.stderr
+++ b/tests/ui/consts/const-fn-mismatch.stderr
@@ -1,8 +1,11 @@
-error[E0379]: functions in traits cannot be declared const
+error[E0379]: functions in trait impls cannot be declared const
   --> $DIR/const-fn-mismatch.rs:11:5
    |
 LL |     const fn f() -> u32 {
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in trait impls cannot be const
+   |     help: remove the `const`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/consts/const-fn-not-in-trait.stderr b/tests/ui/consts/const-fn-not-in-trait.stderr
index 5d364eb882dba..04430610ad00c 100644
--- a/tests/ui/consts/const-fn-not-in-trait.stderr
+++ b/tests/ui/consts/const-fn-not-in-trait.stderr
@@ -2,13 +2,19 @@ error[E0379]: functions in traits cannot be declared const
   --> $DIR/const-fn-not-in-trait.rs:5:5
    |
 LL |     const fn f() -> u32;
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
 error[E0379]: functions in traits cannot be declared const
   --> $DIR/const-fn-not-in-trait.rs:7:5
    |
 LL |     const fn g() -> u32 {
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr
index b0701bab793c5..03c47030c0e3f 100644
--- a/tests/ui/consts/issue-54954.stderr
+++ b/tests/ui/consts/issue-54954.stderr
@@ -2,7 +2,10 @@ error[E0379]: functions in traits cannot be declared const
   --> $DIR/issue-54954.rs:5:5
    |
 LL |     const fn const_val<T: Sized>() -> usize {
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
 error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
   --> $DIR/issue-54954.rs:1:24
diff --git a/tests/ui/feature-gates/feature-gate-min_const_fn.rs b/tests/ui/feature-gates/feature-gate-min_const_fn.rs
index 8f9b433009d3c..3d61a9eb93777 100644
--- a/tests/ui/feature-gates/feature-gate-min_const_fn.rs
+++ b/tests/ui/feature-gates/feature-gate-min_const_fn.rs
@@ -8,7 +8,7 @@ trait Foo {
 }
 
 impl Foo for u32 {
-    const fn foo() -> u32 { 0 } //~ ERROR functions in traits cannot be declared const
+    const fn foo() -> u32 { 0 } //~ ERROR functions in trait impls cannot be declared const
 }
 
 trait Bar {}
diff --git a/tests/ui/feature-gates/feature-gate-min_const_fn.stderr b/tests/ui/feature-gates/feature-gate-min_const_fn.stderr
index d7a58591364ed..0b16f9abb7071 100644
--- a/tests/ui/feature-gates/feature-gate-min_const_fn.stderr
+++ b/tests/ui/feature-gates/feature-gate-min_const_fn.stderr
@@ -2,19 +2,28 @@ error[E0379]: functions in traits cannot be declared const
   --> $DIR/feature-gate-min_const_fn.rs:6:5
    |
 LL |     const fn foo() -> u32;
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
 error[E0379]: functions in traits cannot be declared const
   --> $DIR/feature-gate-min_const_fn.rs:7:5
    |
 LL |     const fn bar() -> u32 { 0 }
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
-error[E0379]: functions in traits cannot be declared const
+error[E0379]: functions in trait impls cannot be declared const
   --> $DIR/feature-gate-min_const_fn.rs:11:5
    |
 LL |     const fn foo() -> u32 { 0 }
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in trait impls cannot be const
+   |     help: remove the `const`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/mismatched_types/const-fn-in-trait.stderr b/tests/ui/mismatched_types/const-fn-in-trait.stderr
index 7d1fbe45c5302..06976933b2f94 100644
--- a/tests/ui/mismatched_types/const-fn-in-trait.stderr
+++ b/tests/ui/mismatched_types/const-fn-in-trait.stderr
@@ -2,13 +2,19 @@ error[E0379]: functions in traits cannot be declared const
   --> $DIR/const-fn-in-trait.rs:3:5
    |
 LL |     const fn g();
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
 
-error[E0379]: functions in traits cannot be declared const
+error[E0379]: functions in trait impls cannot be declared const
   --> $DIR/const-fn-in-trait.rs:7:5
    |
 LL |     const fn f() -> u32 { 22 }
-   |     ^^^^^ functions in traits cannot be const
+   |     ^^^^^-
+   |     |
+   |     functions in trait impls cannot be const
+   |     help: remove the `const`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs
index f8b58cad7c144..f01e1c2277c6f 100644
--- a/tests/ui/parser/fn-header-semantic-fail.rs
+++ b/tests/ui/parser/fn-header-semantic-fail.rs
@@ -26,10 +26,10 @@ fn main() {
     impl X for Y {
         async fn ft1() {} // OK.
         unsafe fn ft2() {} // OK.
-        const fn ft3() {} //~ ERROR functions in traits cannot be declared const
+        const fn ft3() {} //~ ERROR functions in trait impls cannot be declared const
         extern "C" fn ft4() {}
         const async unsafe extern "C" fn ft5() {}
-        //~^ ERROR functions in traits cannot be declared const
+        //~^ ERROR functions in trait impls cannot be declared const
         //~| ERROR functions cannot be both `const` and `async`
     }
 
diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr
index cdf01e0c5df64..696d8e01b6387 100644
--- a/tests/ui/parser/fn-header-semantic-fail.stderr
+++ b/tests/ui/parser/fn-header-semantic-fail.stderr
@@ -11,13 +11,19 @@ error[E0379]: functions in traits cannot be declared const
   --> $DIR/fn-header-semantic-fail.rs:18:9
    |
 LL |         const fn ft3();
-   |         ^^^^^ functions in traits cannot be const
+   |         ^^^^^-
+   |         |
+   |         functions in traits cannot be const
+   |         help: remove the `const`
 
 error[E0379]: functions in traits cannot be declared const
   --> $DIR/fn-header-semantic-fail.rs:20:9
    |
 LL |         const async unsafe extern "C" fn ft5();
-   |         ^^^^^ functions in traits cannot be const
+   |         ^^^^^-
+   |         |
+   |         functions in traits cannot be const
+   |         help: remove the `const`
 
 error: functions cannot be both `const` and `async`
   --> $DIR/fn-header-semantic-fail.rs:20:9
@@ -28,17 +34,23 @@ LL |         const async unsafe extern "C" fn ft5();
    |         |     `async` because of this
    |         `const` because of this
 
-error[E0379]: functions in traits cannot be declared const
+error[E0379]: functions in trait impls cannot be declared const
   --> $DIR/fn-header-semantic-fail.rs:29:9
    |
 LL |         const fn ft3() {}
-   |         ^^^^^ functions in traits cannot be const
+   |         ^^^^^-
+   |         |
+   |         functions in trait impls cannot be const
+   |         help: remove the `const`
 
-error[E0379]: functions in traits cannot be declared const
+error[E0379]: functions in trait impls cannot be declared const
   --> $DIR/fn-header-semantic-fail.rs:31:9
    |
 LL |         const async unsafe extern "C" fn ft5() {}
-   |         ^^^^^ functions in traits cannot be const
+   |         ^^^^^-
+   |         |
+   |         functions in trait impls cannot be const
+   |         help: remove the `const`
 
 error: functions cannot be both `const` and `async`
   --> $DIR/fn-header-semantic-fail.rs:31:9
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs
new file mode 100644
index 0000000000000..891e87d3b97d4
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.rs
@@ -0,0 +1,21 @@
+// Regression test for issue #113378.
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    const fn fun(); //~ ERROR functions in traits cannot be declared const
+}
+
+impl const Trait for () {
+    const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
+}
+
+impl Trait for u32 {
+    const fn fun() {} //~ ERROR functions in trait impls cannot be declared const
+}
+
+trait NonConst {
+    const fn fun(); //~ ERROR functions in traits cannot be declared const
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr
new file mode 100644
index 0000000000000..4d0b03046d27d
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/trait-fn-const.stderr
@@ -0,0 +1,59 @@
+error[E0379]: functions in traits cannot be declared const
+  --> $DIR/trait-fn-const.rs:6:5
+   |
+LL | #[const_trait]
+   | -------------- this declares all associated functions implicitly const
+LL | trait Trait {
+LL |     const fn fun();
+   |     ^^^^^-
+   |     |
+   |     functions in traits cannot be const
+   |     help: remove the `const`
+
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/trait-fn-const.rs:10:5
+   |
+LL | impl const Trait for () {
+   |      ----- this declares all associated functions implicitly const
+LL |     const fn fun() {}
+   |     ^^^^^-
+   |     |
+   |     functions in trait impls cannot be const
+   |     help: remove the `const`
+
+error[E0379]: functions in trait impls cannot be declared const
+  --> $DIR/trait-fn-const.rs:14:5
+   |
+LL |     const fn fun() {}
+   |     ^^^^^ functions in trait impls cannot be const
+   |
+help: remove the `const` ...
+   |
+LL -     const fn fun() {}
+LL +     fn fun() {}
+   |
+help: ... and declare the impl to be const instead
+   |
+LL | impl const Trait for u32 {
+   |      +++++
+
+error[E0379]: functions in traits cannot be declared const
+  --> $DIR/trait-fn-const.rs:18:5
+   |
+LL |     const fn fun();
+   |     ^^^^^ functions in traits cannot be const
+   |
+help: remove the `const` ...
+   |
+LL -     const fn fun();
+LL +     fn fun();
+   |
+help: ... and declare the trait to be a `#[const_trait]` instead
+   |
+LL + #[const_trait]
+LL | trait NonConst {
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0379`.