Help for the new const trait checks

Recently some const-related holes have being fixed:

This code used to work because it wrongly used those holes:


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);

pub const fn is_contained(n: usize, m: usize) -> usize {
    assert!(n <= m);

pub const fn is_representable<Ti: ~const ToFromUsize>(n: usize) -> usize {
    assert!(n <= Ti::MAX.to_usize());

#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
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 {
        } else {

fn main() {}

Currently it gives the error message:

error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
  --> ...\
46 |         if i.to_usize() < N {
   |            ^^^^^^^^^^^^

Do you have suggestions regarding how to to fix code like this?

For now I've solved the problem pulling new() out of the impl, making it a free function, so now I can add ~const to its ToFromUsize. I hope in future the ~const will be allowed in impls too.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.