-
Notifications
You must be signed in to change notification settings - Fork 13.3k
New problem with const_trait_impl #88424
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
Comments
You need #![feature(const_trait_impl, const_fn_trait_bound, const_panic)]
pub trait Foo {
fn bar(self) -> usize;
const MAX: Self;
}
impl const Foo for usize {
fn bar(self) -> usize { self }
const MAX: Self = Self::MAX;
}
const fn spam<T: ~const Foo>(n: usize) {
assert!(n <= T::MAX.bar());
}
fn main() {} |
I see. Thank you. So do I convert this into a diagnostic enhancement request asking for a helpful error message (or help message), or do I close this issue down and open another one for that? |
Here I have a problem: #![feature(const_fn_trait_bound, const_trait_impl)]
#![allow(dead_code)]
const fn foo<T: ~const Default + Copy>() -> T {
T::default()
}
fn main() {
const X1: u64 = foo(); // OK
const X2: (u8, u64) = foo(); // Err
} That gives me: error[E0277]: the trait bound `(u8, u64): Default` is not satisfied
--> ...\test1.rs:10:27
|
10 | const X2: (u8, u64) = foo(); // Err
| ^^^ the trait `Default` is not implemented for `(u8, u64)`
|
note: required by a bound in `foo`
--> ...\test1.rs:4:17
|
4 | const fn foo<T: ~const Default + Copy>() -> T {
| ^^^^^^^^^^^^^^ required by this bound in `foo`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
8 | fn main() where (u8, u64): Default {
| ++++++++++++++++++++++++ A little more complex situation: #![feature(
const_evaluatable_checked,
const_fn_trait_bound,
const_generics,
const_panic,
const_trait_impl,
)]
#![allow(incomplete_features)]
pub trait ToFromUsize {
fn to_usize(self) -> usize;
fn from_usize(x: usize) -> Self;
const MAX: Self;
}
impl const ToFromUsize for usize {
fn to_usize(self) -> usize { self }
fn from_usize(x: usize) -> Self { x }
const MAX: Self = Self::MAX;
}
pub const fn assert_nonzero(n: usize) -> usize {
assert!(n > 0);
n
}
pub const fn is_contained(n: usize, m: usize) -> usize {
assert!(n <= m);
n
}
pub const fn is_representable<Ti: ~const ToFromUsize>(n: usize) -> usize {
assert!(n <= Ti::MAX.to_usize());
n
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
#[repr(transparent)]
pub struct Foo<Ti: ToFromUsize + Copy, const N: usize>(Ti)
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]:;
impl<Ti: ToFromUsize + Copy, const N: usize> Foo<Ti, N>
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]: {
pub const fn new(i: Ti) -> Option<Self> {
if i.to_usize() < N {
Some(Self(i))
} else {
None
}
}
}
fn main() {} That gives: error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
--> ...\test2.rs:47:12
|
47 | if i.to_usize() < N {
| ^^^^^^^^^^^^ |
I think you can just move the bound to the const fn's where clause.
|
Unfortunately it gives me a "error: |
Hmmm, looks like I will have to allow const fns in inherent impls having |
The latest Nightly solves most of my problems, but I have two further problems. (Tell me if you prefer me to move them to new issues). #![feature(
const_fn_trait_bound,
const_panic,
const_trait_impl,
generic_const_exprs,
)]
#![allow(incomplete_features)]
pub trait ToFromUsize {
fn to_usize(self) -> usize;
fn from_usize(x: usize) -> Self;
const MAX: Self;
}
impl const ToFromUsize for usize {
fn to_usize(self) -> usize { self }
fn from_usize(x: usize) -> Self { x }
const MAX: Self = Self::MAX;
}
pub const fn assert_nonzero(n: usize) -> usize {
assert!(n > 0);
n
}
pub const fn is_contained(n: usize, m: usize) -> usize {
assert!(n <= m);
n
}
pub const fn is_representable<Ti: ~const ToFromUsize>(n: usize) -> usize {
assert!(n <= Ti::MAX.to_usize());
n
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
#[repr(transparent)]
pub struct Foo<Ti: ToFromUsize + Copy, const N: usize>(Ti)
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]:;
impl<Ti: ToFromUsize + Copy, const N: usize> Foo<Ti, N>
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]: {
pub const unsafe fn new_unchecked(i: Ti) -> Self where Ti: ~const ToFromUsize {
Self(i)
}
pub const FIRST: Self = unsafe { Self::new_unchecked(Ti::from_usize(0)) };
pub const LAST: Self = unsafe { Self::new_unchecked(Ti::from_usize(N - 1)) };
}
fn main() {} It gives me: error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> ...\test.rs:50:58
|
50 | pub const FIRST: Self = unsafe { Self::new_unchecked(Ti::from_usize(0)) };
| ^^^^^^^^^^^^^^^^^
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> ...\test.rs:51:57
|
51 | pub const LAST: Self = unsafe { Self::new_unchecked(Ti::from_usize(N - 1)) };
| ^^^^^^^^^^^^^^^^^^^^^ The other problem is an enhancement request. If I remove a "const" from the signature of new_unchecked the compiler doesn't give me much help to see the problem: #![feature(
const_fn_trait_bound,
const_panic,
const_trait_impl,
generic_const_exprs,
)]
#![allow(incomplete_features)]
pub trait ToFromUsize {
fn to_usize(self) -> usize;
fn from_usize(x: usize) -> Self;
const MAX: Self;
}
impl const ToFromUsize for usize {
fn to_usize(self) -> usize { self }
fn from_usize(x: usize) -> Self { x }
const MAX: Self = Self::MAX;
}
pub const fn assert_nonzero(n: usize) -> usize {
assert!(n > 0);
n
}
pub const fn is_contained(n: usize, m: usize) -> usize {
assert!(n <= m);
n
}
pub const fn is_representable<Ti: ~const ToFromUsize>(n: usize) -> usize {
assert!(n <= Ti::MAX.to_usize());
n
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
#[repr(transparent)]
pub struct Foo<Ti: ToFromUsize + Copy, const N: usize>(Ti)
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]:;
impl<Ti: ToFromUsize + Copy, const N: usize> Foo<Ti, N>
where [(); assert_nonzero(N)]:,
[(); is_representable::<Ti>(N - 1)]: {
pub unsafe fn new_unchecked(i: Ti) -> Self where Ti: ~const ToFromUsize {
Self(i)
}
}
fn main() {} It gives: error: `~const` is not allowed here
--> ...\test2.rs:46:58
|
46 | pub unsafe fn new_unchecked(i: Ti) -> Self where Ti: ~const ToFromUsize {
| ^^^^^^^^^^^^^^^^^^
|
= note: only allowed on bounds on traits' associated types and functions, const fns, const impls and its associated functions |
|
Thank you :) |
This code:
Using:
Gives:
I think this used to compile up to the precedent Nightly.
The text was updated successfully, but these errors were encountered: