-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiler not realizing an impl is more specific than another when using const generic bounds #138308
Comments
You got two conflicting implementations. Both implementations can be used for |
But 0 doesn't respect the bound This example seem to be the same thing but just with types use std::marker::PhantomData;
struct S1<N> {
_b: PhantomData<N>,
}
trait Bound {}
struct RespectsBound;
impl Bound for RespectsBound {}
struct DoesNot;
trait T {
fn res(&self);
}
impl<S> T for S1<S> where S: Bound {
fn res(&self) {
println!("Respects bound");
}
}
impl T for S1<DoesNot> {
fn res(&self) {
println!("Does not respect bound");
}
}
fn main() {
let respects = S1::<RespectsBound> { _b: PhantomData };
let does_not = S1::<DoesNot> { _b: PhantomData };
respects.res();
does_not.res();
}
|
A trait bound not being satisfied is not an error, the trait solver will simply backtrack. I believe a const expr failing to evaluate is a hard error however without any chance of backtracking. |
Is it a feature ? I feel like they should work the same for |
You probably meant to use specialization (#31844), which isn't yet implemented for associated constants. For now, you may want to use struct R(usize);
impl R {
const fn dec_or(self, default: R) -> R {
match self.0 {
0 => default,
n => R(n - 1),
}
}
}
struct R1<const N: usize>;
const X: R1<{ R(12).dec_or(R(5)).0 }> = R1;
const Y: R1<{ R(0).dec_or(R(5)).0 }> = R1;
fn main() {
fn print<const N: usize>(_: R1<N>) {
println!("{N}");
}
print(X); // 11
print(Y); // 5
} |
Oh okay, there is a tracking issue. Thanks it's exactly that ! |
Closing as the discussion seems to have concluded. |
I tried this code which creates a register and an operation to decrease it's value by one or change it's value to another register. All of that at compile time.
I expected it to work with no errors.
Instead, this happened:
It looks like the compiler evaluates the second
impl
with all values of N instead of realizing there is a more specific one forN=0
. Also the error message is duplicated ?It may be related to #112341. Maybe other issues but I didn't find them.
Obviously related to #76560 too
Meta
rustc --version --verbose
:I kind of expect this issue to get no answer so I might try to solve it myself. It will make for a nice project to plunge into.
The text was updated successfully, but these errors were encountered: