Repository navigation
Closed
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`Area: Suggestions generated by the compiler applied by `cargo fix`C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-papercutDiagnostics: An error or lint that needs small tweaks.Diagnostics: An error or lint that needs small tweaks.P-lowLow priorityLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Repro:
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 = 4;
}This caused E0277 "the trait bound is not satisfied" error:
error[E0277]: the trait bound `C: std::marker::Sized` is not satisfied
--> src/main.rs:11:5
|
11 | const N: C::M = 4;
| ^^^^^^^^^^^^^^^^^^ `C` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `C`
= help: consider adding a `where C: std::marker::Sized` bound
= note: required because of the requirements on the impl of `O` for `C`
The error doesn't make sense because C is obviously Sized. It seems the associated const type is evaluated before the generic bounds are added, causing this error.
Changing both A::M and C::M to u8 makes the error go away.
Reproducible on all 3 versions on playground (1.23.0, 1.24.0-beta, 1.25.0-nightly).
Reacted by Bergi, Michael Bradshaw, phimuemue and Robin Freyler
Metadata
Metadata
Assignees
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`Area: Suggestions generated by the compiler applied by `cargo fix`C-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-papercutDiagnostics: An error or lint that needs small tweaks.Diagnostics: An error or lint that needs small tweaks.P-lowLow priorityLow priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
oberien commentedon Mar 10, 2018
This exact issue just occured to @CryZe 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: playground). A minimized examples is this (playground):
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: playground
bgeron commentedon May 19, 2018
I ran into the same problem. It's also in 1.26 stable.
Here's a further minimized example (play):
We can also use the type parameter in the trait rather than the type (play):
Both code fragments give an error saying that in the blanket impl, Rust cannot figure out that
UimplementsEmptyTraitandSized:Note that in both cases, if you remove the
EmptyTraitconstraint on the quantified typeU, the error aboutEmptyTraitgoes away! This is very strange. However, like in #50824, theSizederror message stays.The problem goes away if you declare the type of
VALinConstto beu32, 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:
const VAL: Self::T = 5;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:
[u8; ::std::mem::size_of::<T>()]. This fails. The error message shows that Rust cannot decide thatT : Sized, even thoughT : Sizedwas in the where clause. Same in Array lengths don't support generic parameters. #43408, where they get a warning (!) about a "constant evaluation error".CAD97 commentedon Sep 2, 2018
Copying over my minimal example from #53908 as another data point (playground):
Here I've added a
Sizedsupertrait to my trait to get rid of theSizedissue but it still can't determine the required trait implementation (of my trait in this case) to make this work.pest@1 doesn't emit eoi, remove handling
Handle EOI by adding a way to discard trailing pairs
estebank commentedon Apr 29, 2019
All of these cases now compile, except for the original report, 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
<C as O>::Mtou8" 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 theC: Oconstraint towhere, for example (although that's not needed, just nicer stylistically).Suggest constraining assoc types in more cases
Suggest constraining assoc types in more cases
Rollup merge of rust-lang#116865 - estebank:issue-46969, r=compiler-e…
Unrolled build for rust-lang#116865