Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

type aliases dont propagate implied ConstEvaluatable bounds of rhs #86259

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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