Change:
Repro: This caused E0277 "the trait bound is not satisfied" error: The error doesn't make sense because is obviously . It seems the associated const type is evaluated before the generic bounds are , causing this error. Changing both and to makes the error go away. Reproducible on all 3 versions on playground (1.23.0, 1.24.0-beta, 1.25.0-nightly).
This exact issue just occured to and me when trying to use associated constants to create a constant struct in a library with user-provided data (without const fns) (actual use case: ). A minimized examples is this (): Error: The interesting thing is that even though both bounds are specified, the compiler doesn't seem to take them into account. Edit: The issue is not using a trait with an associated type and const as generic bound. Instead the problem is implementing a trait with an associated type and const in general:
I ran into the same problem. It's also in 1.26 stable. Here's a further minimized example (): We can also use the type parameter in the trait rather than the type (): Both code fragments give an error saying that in the blanket impl, Rust cannot figure out that implements and : Note that in both cases, if you remove the constraint on the quantified type , the error about goes away! This is very strange. However, like in , the error message stays. The problem goes away if you declare the type of in to be , rather than some type that is computed potentially based on parameters. I'm not familiar with the compiler internals, but my hypothesis is that associated types and constants depending on a type parameter are not evaluated properly in the constant expression evaluator. In this case, it's associated types that do not reduce well: forces Rust to do some fancy type of computation at compile time in order to type check, but there's a bug in the code for such computations. I feel there are a couple of different issues in the same spirit: In , Rust is trying to check two types against each other, which forces it to simplify the type . This fails. The error message shows that Rust cannot decide that , even though was in the where clause. Same in , where they get a warning (!) about a "constant evaluation error". In , the same happens but with a consteval that uses a different trait fn.
Copying over my minimal example from as another data point (): Here I've a supertrait to my trait to get rid of the issue but it still can't determine the required trait implementation (of my trait in this case) to make this work.
All of these cases now compile, except for , which has a type error: Current output: The correct code would be The outstanding work would be providing a suggestion explaining what "consider constraining the associated type to " means. This will be hard to do given the different cases that need to be accounted for, for the case above you need to move the constraint to , for example (although that's not needed, just nicer stylistically).

Discussion:
let tcx = self.tcx; let assoc = tcx.associated_item(proj_ty.def_id); let (trait_ref, assoc_args) = proj_ty.trait_ref_and_own_args(tcx); <del> if let Some(item) = tcx.hir().get_if_local(body_owner_def_id) { if let Some(hir_generics) = item.generics() { // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`. // This will also work for `impl Trait`. let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() { let generics = tcx.generics_of(body_owner_def_id); generics.type_param(param_ty, tcx).def_id } else { return false; }; let Some(def_id) = def_id.as_local() else { return false; }; // First look in the `where` clause, as this might be // `fn foo<T>(x: T) where T: Trait`. for pred in hir_generics.bounds_for_param(def_id) { if self.constrain_generic_bound_associated_type_structured_suggestion( diag, &trait_ref, pred.bounds, assoc, assoc_args, ty, &msg, false, ) { return true; } } </del> <ins> let Some(item) = tcx.hir().get_if_local(body_owner_def_id) else { return false; }; let Some(hir_generics) = item.generics() else { return false; }; // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`. // This will also work for `impl Trait`. let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() { let generics = tcx.generics_of(body_owner_def_id); generics.type_param(param_ty, tcx).def_id } else { return false; }; let Some(def_id) = def_id.as_local() else { return false; }; // First look in the `where` clause, as this might be // `fn foo<T>(x: T) where T: Trait`. for pred in hir_generics.bounds_for_param(def_id) { if self.constrain_generic_bound_associated_type_structured_suggestion( diag, &trait_ref, pred.bounds, assoc, assoc_args, ty, &msg, false, ) { return true; </ins> } } <del> false </del> <ins> // If associated item, look to constrain the params of the trait/impl. let hir_id = match item { hir::Node::ImplItem(item) => item.hir_id(), hir::Node::TraitItem(item) => item.hir_id(), _ => return false, }; let parent = tcx.hir().get_parent_item(hir_id).def_id; self.suggest_constraint(diag, msg, parent.into(), proj_ty, ty) </ins> } /// An associated type was expected and a different type was found.

let impl_comparison = matches!(cause_code, ObligationCauseCode::CompareImplItemObligation { .. }); let assoc = tcx.associated_item(proj_ty.def_id); <del> if !callable_scope || impl_comparison { </del> <ins> if impl_comparison { </ins> // We do not want to suggest calling functions when the reason of the <del> // type error is a comparison of an `impl` with its `trait` or when the // scope is outside of a `Body`. </del> <ins> // type error is a comparison of an `impl` with its `trait`. </ins> } else { <del> // If we find a suitable associated function that returns the expected type, we don't // want the more general suggestion later in this method about "consider constraining // the associated type or calling a method that returns the associated type". let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type( diag, assoc.container_id(tcx), current_method_ident, proj_ty.def_id, values.expected, ); </del> <ins> let point_at_assoc_fn = if callable_scope && self.point_at_methods_that_satisfy_associated_type( diag, assoc.container_id(tcx), current_method_ident, proj_ty.def_id, values.expected, ) { // If we find a suitable associated function that returns the expected type, we // don't want the more general suggestion later in this method about "consider // constraining the associated type or calling a method that returns the associated // type". true } else { false }; </ins> // Possibly suggest constraining the associated type to conform to the // found type. if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found)

<ins> // run-rustfix trait O { type M; } trait U<A: O> { const N: A::M; } impl<D> O for D { type M = u8; } impl<C: O<M = u8>> U<C> for u16 { const N: C::M = 4u8; //~ ERROR mismatched types } fn main() {} </ins>

<ins> // run-rustfix trait O { type M; } trait U<A: O> { const N: A::M; } impl<D> O for D { type M = u8; } impl<C: O> U<C> for u16 { const N: C::M = 4u8; //~ ERROR mismatched types } fn main() {} </ins>

<ins> error[E0308]: mismatched types --> $DIR/suggest-contraining-assoc-type-because-of-assoc-const.rs:12:21 | LL |     const N: C::M = 4u8; |                     ^^^ expected associated type, found `u8` | = note: expected associated type `<C as O>::M` found type `u8` help: consider constraining the associated type `<C as O>::M` to `u8` | LL | impl<C: O<M = u8>> U<C> for u16 { |          ++++++++ error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. </ins>