Skip to content

Const guard macro does not work in specialization scenarios #4

@WalterSmuts

Description

@WalterSmuts

The example implements a predicate that checks if the length of an array is larger than two. The twist being that the function is actually evaluated at compile time based on the type of the array. The compiler is not clever enough to realise that SIZE > 2 and SIZE <= 2 covers all cases so we use a specialization trick described in this post.

I came across your crate and loved it. It improves the ergonomics of writing these constraints a ton! Thanks! Unfortunately it does not work in this example.

Manually implementing the work const guard does (AFAICT) works:

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(specialization)]

pub struct ConstCheck<const CHECK: bool>;

pub trait True {}
impl True for ConstCheck<true> {}

fn main() {
    dbg!([0].is_bigger_than_two());
    dbg!([0, 1, 2].is_bigger_than_two());
}

trait Foo {
    fn is_bigger_than_two(&self) -> bool;
}

impl<T, const SIZE: usize> Foo for [T; SIZE]
where
    ConstCheck<{ SIZE < 2 }>: True,
{
    fn is_bigger_than_two(&self) -> bool {
        true
    }
}

impl<T, const SIZE: usize> Foo for [T; SIZE] {
    default fn is_bigger_than_two(&self) -> bool {
        false
    }
}

But switching to const guard does not:

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
#![feature(specialization)]

use const_guards::guard;

fn main() {
    dbg!([0].is_bigger_than_two());
    dbg!([0, 1, 2].is_bigger_than_two());
}

trait Foo {
    fn is_bigger_than_two(&self) -> bool;
}

#[guard(SIZE < 2)]
impl<T, const SIZE: usize> Foo for [T; SIZE] {
    fn is_bigger_than_two(&self) -> bool {
        true
    }
}

impl<T, const SIZE: usize> Foo for [T; SIZE] {
    default fn is_bigger_than_two(&self) -> bool {
        false
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions