constcat icon indicating copy to clipboard operation
constcat copied to clipboard

Can this crate work with Associated Constants ?

Open DontBreakAlex opened this issue 2 years ago • 6 comments

Currently it produces this error when attempting to use Associated Constants:

error[E0401]: can't use generic parameters from outer function
   --> src/sync.rs:284:47
    |
282 | pub fn get_updated<T: Uploadable>(db: &rusqlite::Connection) -> Result<Vec<T>> {
    |                    - type parameter from outer function
283 |     let mut stmt =
284 |         db.prepare_cached(concat!("SELECT * FROM ", T::SQLITE_TABLE_NAME, " INNER JOIN actions a on ", T::SQLITE_TABLE_NAME, ".uuid = a.u...
    |                                                     ^^^^^^^^^^^^^^^^^^^^ use of generic parameter from outer function

I'm not sure what is going on, can this be supported ?

DontBreakAlex avatar Jun 27 '23 15:06 DontBreakAlex

I'm not sure this can be supported. But if there is some way to get this working I'd love to add it.

Both generics and const items are evaluated at compile time but I think const items are evaluated before the actual exact type T is known.

Minimal example:

trait Foo {
    const BAR: &'static str;
}

fn takes_foo<T: Foo>() {
    const TEST: &str = T::BAR;
}

rossmacarthur avatar Jun 28 '23 06:06 rossmacarthur

@DontBreakAlex I ran into the same. This would save users of my crate (zvariant and zbus in turn) so many allocations as I can then turn one the main/central trait to use associated constants.

zeenix avatar Dec 22 '23 16:12 zeenix

@rossmacarthur This can be fixed by using inline const blocks instead of const items. Inline const blocks can capture generic parameters from their scope and don't require type annotations. This is a recently stabilized feature that requires Rust 1.79.0 or later. This would likely be a MSRV increase for this crate, so you might want to put it behind a feature flag.

Esper89 avatar Aug 30 '24 06:08 Esper89

After several attempts to implement this using inline const blocks, I don't think it's actually possible today without basic generic_const_exprs support, because the length of the underlying array would depend on generic parameters.

Esper89 avatar Aug 30 '24 09:08 Esper89

@DontBreakAlex I ran into the same. This would save users of my crate (zvariant and zbus in turn) so many allocations as I can then turn one the main/central trait to use associated constants.

Just for the record here, I went for a completely different approach and no longer require concatenating strings in const context.

zeenix avatar Aug 30 '24 11:08 zeenix

I attempted this when const inlining was first introduced, but was unable to get things to work. I think its mainly due to this section in the RFC: https://rust-lang.github.io/rfcs/2920-inline-const.html#generic-parameters

It also has a pretty good explanation why it isn't supported yet.

airblast-dev avatar Aug 30 '24 15:08 airblast-dev