Not sure how to report a compiler issue so posting it here:
Consider the following code where I am validating a template const
value at compile time... which results in [E0599] when:
- expression in the
where
clause has a local function (i.e.{ const fn _local(C) {...}; _local()}
. - And the
struct
implements 1 or moretrait
in addition to its ownimpl
- The error is misleading as the
trait
and itswhere
is already satisfied but the expression is complex.
It works when the expression in where
calls a global const fn
or has a simple expression.
An ideal/expected behaviour would be:
- It works with complex
const
expressions - but of course, an acceptable/helpful behaviour would be if the error message indicated that the
where
clause is too complex
(p.s. this is related to my previous post: ( Help with [E0599] when implementing trait - The Rust Programming Language Forum
Minimal sample to reproduce the issues:
#![allow(incomplete_features)]
#![allow(internal_features)]
#![feature(generic_const_exprs)]
use std::ops::Index;
struct Guard<const U: bool>;
trait Protect {}
impl Protect for Guard<true> {}
enum Nucleotide {
A,
C,
}
struct NucleotideCount<const C: usize> {
a: usize,
c: usize,
}
const fn a_global_const_fn(c: usize) -> bool {
c <= 100
}
impl <const C: usize> NucleotideCount<C>
where
Guard<{
// BEGIN => causes E0599
const fn _a_local_const_fn<const C: usize>() -> bool {
C <= 100
}
_a_local_const_fn::<C>()
// END
// C <= 100 // <== uncomment me and comment above to get it working
// a_global_const_fn(C) // <=== OR uncumment me.. also works!!
}>: Protect,
{
pub fn get(&self, nucleotide: Nucleotide) -> Option<&usize> {
match nucleotide {
Nucleotide::A => Some(&self.a),
Nucleotide::C => Some(&self.c),
}
}
}
impl <const C: usize> Index<Nucleotide> for NucleotideCount<C>
where
Guard<{
// BEGIN => causes E0599
const fn _a_local_const_fn<const C: usize>() -> bool {
C <= 100
}
_a_local_const_fn::<C>()
// END
// C <= 100 // <== uncomment me and comment above to get it working
// a_global_const_fn(C) // <=== OR uncumment me.. also works!!
}>: Protect,
{
type Output = usize;
fn index(&self, nucleotide: Nucleotide) -> &Self::Output {
self.get(nucleotide).unwrap()
}
}
fn main() {
let nucleotide_count: NucleotideCount<10> = NucleotideCount {a: 14, c: 9};
assert_eq!(nucleotide_count[Nucleotide::A], 14);
assert_eq!(nucleotide_count[Nucleotide::C], 9);
println!("SUCCESS!")
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `get` found for reference `&NucleotideCount<C>` in the current scope
--> src/main.rs:64:14
|
64 | self.get(nucleotide).unwrap()
| ^^^ method cannot be called on `&NucleotideCount<C>` due to unsatisfied trait bounds
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `get`, perhaps you need to implement it:
candidate #1: `SliceIndex`
For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (bin "playground") due to 1 previous error