# Trait rustc_const_eval::check_consts::qualifs::Qualif

source ·

    pub trait Qualif {
        const ANALYSIS_NAME: &'static str;
        const IS_CLEARED_ON_MOVE: bool = false;
        const ALLOW_PROMOTED: bool = false;

        // Required methods
        fn in_qualifs(qualifs: &ConstQualifs) -> bool;
        fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool;
        fn in_adt_inherently<'tcx>(
            cx: &ConstCx<'_, 'tcx>,
            adt: AdtDef<'tcx>,
            args: GenericArgsRef<'tcx>,
        ) -> bool;
        fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool;
    }

Expand description

A “qualif”(-ication) is a way to look for something “bad” in the MIR that would disqualify some code for promotion or prevent it from evaluating at compile time.

Normally, we would determine what qualifications apply to each type and error when an illegal operation is performed on such a type. However, this was found to be too imprecise, especially in the presence of `enum`s. If only a single variant of an enum has a certain qualification, we needn’t reject code unless it actually constructs and operates on the qualified variant.

To accomplish this, const-checking and promotion use a value-based analysis (as opposed to a type-based one). Qualifications propagate structurally across variables: If a local (or a projection of a local) is assigned a qualified value, that local itself becomes qualified.

## Required Associated Constants§

source

#### const ANALYSIS_NAME: &'static str

The name of the file used to debug the dataflow analysis that computes this qualif.

## Provided Associated Constants§

source

#### const IS_CLEARED_ON_MOVE: bool = false

Whether this `Qualif` is cleared when a local is moved from.

source

#### const ALLOW_PROMOTED: bool = false

Whether this `Qualif` might be evaluated after the promotion and can encounter a promoted.

## Required Methods§

source

#### fn in_qualifs(qualifs: &ConstQualifs) -> bool

Extracts the field of `ConstQualifs` that corresponds to this `Qualif`.

source

#### fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool

Returns `true` if any value of the given type could possibly have this `Qualif`.

This function determines `Qualif`s when we cannot do a value-based analysis. Since qualif propagation is context-insensitive, this includes function arguments and values returned from a call to another function.

It also determines the `Qualif`s for primitive types.

source

#### fn in_adt_inherently<'tcx>( cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>, args: GenericArgsRef<'tcx>, ) -> bool

Returns `true` if this `Qualif` is inherent to the given struct or enum.

By default, `Qualif`s propagate into ADTs in a structural way: An ADT only becomes qualified if part of it is assigned a value with that `Qualif`. However, some ADTs always have a certain `Qualif`, regardless of whether their fields have it. For example, a type with a custom `Drop` impl is inherently `NeedsDrop`.

Returning `true` for `in_adt_inherently` but `false` for `in_any_value_of_ty` is unsound.

source

#### fn deref_structural<'tcx>(cx: &ConstCx<'_, 'tcx>) -> bool

Returns `true` if this `Qualif` behaves sructurally for pointers and references: the pointer/reference qualifies if and only if the pointee qualifies.

(This is currently `false` for all our instances, but that may change in the future. Also, by keeping it abstract, the handling of `Deref` in `in_place` becomes more clear.)

## Object Safety§

This trait is not object safe.

## Implementors§

source§

### impl Qualif for HasMutInterior

source§

#### const ANALYSIS_NAME: &'static str = "flow_has_mut_interior"

source§

### impl Qualif for NeedsDrop

source§

#### const ANALYSIS_NAME: &'static str = "flow_needs_drop"

source§

#### const IS_CLEARED_ON_MOVE: bool = true

source§

### impl Qualif for NeedsNonConstDrop

source§

#### const ANALYSIS_NAME: &'static str = "flow_needs_nonconst_drop"

source§

#### const IS_CLEARED_ON_MOVE: bool = true

source§

#### const ALLOW_PROMOTED: bool = true