Skip to content

type aliases dont propagate implied ConstEvaluatable bounds of rhs #86259

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
crlf0710 opened this issue Jun 13, 2021 · 4 comments
Open

type aliases dont propagate implied ConstEvaluatable bounds of rhs #86259

crlf0710 opened this issue Jun 13, 2021 · 4 comments
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]`

Comments

@crlf0710
Copy link
Member

In an attempt to implement array default with const generics, I tried this code:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=700737e7598eca3dc58921f4530627f5

The code seems overall ok, but the compilation failed. After some try, it seems i can workaround this by add another usage of the "complex expression", and this second code snippet compiles:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d3b02c12306c7e0754020951c84f0cbe

However when the usage code is generic, it still doesn't work:

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=d3b02c12306c7e0754020951c84f0cbe

With this third piece of code, I did some debugging, and it seems in the is_const_evaluatable<'cx, 'tcx> function, there's a call like this:

[compiler\rustc_trait_selection\src\traits\const_evaluatable.rs:44] &def = WithOptConstParam {
    did: DefId(0:46 ~ array_default_extern_generic_doesnt_work[317d]::{impl#0}::{constant#0}),
    const_param_did: None,
}
[compiler\rustc_trait_selection\src\traits\const_evaluatable.rs:45] &substs = [
    R,
    Const {
        ty: usize,
        val: Unevaluated(
            Unevaluated {
                def: WithOptConstParam {
                    did: DefId(0:79 ~ array_default_extern_generic_doesnt_work[317d]::impl_test::UnwindContext::stack_storage::{constant#0}),
                    const_param_did: None,
                },
                substs: [
                    R,
                ],
                promoted: None,
            },
        ),
    },
]
[compiler\rustc_trait_selection\src\traits\const_evaluatable.rs:46] param_env.caller_bounds() = [
    Binder(TraitPredicate(<R as std::default::Default>), []),
    Binder(TraitPredicate(<R as std::marker::Sized>), []),
]

And there's no corresponding ConstEvaluatable bound in it. So it seems the evaluatable analysis is using a wrong or unpopulated "environment bounds"?

This and the const_evaluatable_checked feature itself is the single blocker for array defaults implementation using const generics. So it would be nice if this can get fixed.

cc @rust-lang/wg-const-eval

@crlf0710 crlf0710 added C-bug Category: This is a bug. A-const-generics Area: const generics (parameters and arguments) F-const_generics `#![feature(const_generics)]` F-generic_const_exprs `#![feature(generic_const_exprs)]` labels Jun 13, 2021
@BoxyUwU
Copy link
Member

BoxyUwU commented Jun 13, 2021

if you write ArrayDefaultImplDispatch<T, LEN, { LEN == 0 }> instead of Dispatcher<T, LEN> it also compiles

@crlf0710
Copy link
Member Author

Mmmm, what's the difference here? @BoxyUwU

@BoxyUwU
Copy link
Member

BoxyUwU commented Jun 13, 2021

The reason your code doesn't compile is because Dispatcher<T, LEN>: ArrayDefaultImpl<Output = Self> doesnt have the { LEN == 0 } expression anywhere so we dont implicitly add a ConstEvaluatable bound.

your // AnyBool<{LEN == 0}>:, line does the same thing. const_evaluatable_checked requires generic expressions to be considered "evaluatable" (doesn't panic) and the way to do that currently is a bit hacky. Ideally we'd have something liek where evaluatable { LEN == 0 }but for now you just have to write { LEN == 0 } somewhere in the impl block and rustc implicitly adds a ConstEvaluatable bound.

in this case LEN == 0 can never fail to evaluate, but right now const_evaluatable_checked is not smart enough to work that out

@BoxyUwU
Copy link
Member

BoxyUwU commented Jun 13, 2021

I don't know what the correct behaviour should be here with regards to type aliases + the implied ConstEvaluatable bounds

@BoxyUwU BoxyUwU removed the F-const_generics `#![feature(const_generics)]` label Jun 24, 2022
@BoxyUwU BoxyUwU changed the title Strange behavior related to const_evaluatable_checked type aliases dont propagate implied ConstEvaluatable bounds of rhs Jun 24, 2022
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. F-generic_const_exprs `#![feature(generic_const_exprs)]`
Projects
None yet
Development

No branches or pull requests

2 participants