Skip to content

Const qualification #53819

Open
Open
@oli-obk

Description

@oli-obk

cc @eddyb @RalfJung

Let's figure out what exactly we need, because I'm very confused about it.

So, currently const qualification is doing a few things at once:

  1. figure out all the feature gates and forbid things not allowed in constants/statics/const_fn at all or without the feature gates
  2. figure out what things are promotable by ruling out values containing Drop or UnsafeCell types (None is always ok, even if Some(value) would not be due to the type, even if Option<T> would technically propagate said type.
  3. In order to guarantee this for promotion we also check the bodies of const fn and const for Drop and UnsafeCell value creations, even if it is ignored for the constant itself and only checked when the constant is used in a value checked for promotion

Why I want to stop looking at bodies, and instead just check the final value of constants:

  • This analysis is imperfect. E.g. (UnsafeCell::new(42), 42).1 is treated as if you end up with an UnsafeCell value
  • If we keep looking at the body, we're essentially saying that a const fn's body is not allowed to change, even for changes which would not change the final value for any input, because such a change might subtly lead to the analysis suddenly thinking there's an UnsafeCell in the final value

Why we cannot just look at the final value right now:

  • when promoting associated constants inside a generic function we might not have enough information to actually compute the final value. We'd need to wait for monomorphization to tell us whether the value is problematic. This is obviously not something we want. All the analyses should run before monomophization

Solution brainstorm:

  1. don't promote calls to const fn if its return type may contain UnsafeCell or Drop. So Option::<String> is not promoted, even if the actual value is None. (not a breaking change, since there are no stable const fn for which this could break any code)
  2. Always assume the worst with associated constants (already the case https://play.rust-lang.org/?gist=36546b7a589178413e28ba09f1cd0201&version=stable&mode=debug&edition=2015 ) So we don't promote associated constant uses unless monomorphized.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions