Skip to content

Commit

Permalink
Auto merge of #69469 - matthewjasper:type-flags, r=cramertj
Browse files Browse the repository at this point in the history
Clean up TypeFlags

* Add a new method `has_infer_types_or_consts` that's used instead of `has_infer_types` most of the time, since there's generally no reason to only consider types.
*  Remove `has_closure_types`/`HAS_TY_CLOSURE`, because closures are no longer implicitly linked to the `InferCtxt`.
* Reorder flags to group similar ones together
* Make some flags more granular
* Compute `HAS_FREE_LOCAL_NAMES` from the other flags
* Add some more doc comments
  • Loading branch information
bors committed Mar 2, 2020
2 parents e86c9e6 + 1617ec4 commit 6af4fd3
Show file tree
Hide file tree
Showing 17 changed files with 136 additions and 148 deletions.
23 changes: 7 additions & 16 deletions src/librustc/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,10 @@ impl FlagComputation {
&ty::Error => self.add_flags(TypeFlags::HAS_TY_ERR),

&ty::Param(_) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_PARAMS);
self.add_flags(TypeFlags::HAS_TY_PARAM);
}

&ty::Generator(_, ref substs, _) => {
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_substs(substs);
}

Expand All @@ -97,8 +94,6 @@ impl FlagComputation {
}

&ty::Closure(_, ref substs) => {
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_substs(substs);
}

Expand All @@ -107,12 +102,10 @@ impl FlagComputation {
}

&ty::Placeholder(..) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
}

&ty::Infer(infer) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
self.add_flags(TypeFlags::HAS_TY_INFER);
match infer {
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
Expand All @@ -128,17 +121,17 @@ impl FlagComputation {
}

&ty::Projection(ref data) => {
self.add_flags(TypeFlags::HAS_PROJECTION);
self.add_flags(TypeFlags::HAS_TY_PROJECTION);
self.add_projection_ty(data);
}

&ty::UnnormalizedProjection(ref data) => {
self.add_flags(TypeFlags::HAS_PROJECTION);
self.add_flags(TypeFlags::HAS_TY_PROJECTION);
self.add_projection_ty(data);
}

&ty::Opaque(_, substs) => {
self.add_flags(TypeFlags::HAS_PROJECTION | TypeFlags::HAS_TY_OPAQUE);
self.add_flags(TypeFlags::HAS_TY_OPAQUE);
self.add_substs(substs);
}

Expand Down Expand Up @@ -221,22 +214,20 @@ impl FlagComputation {
match c.val {
ty::ConstKind::Unevaluated(_, substs, _) => {
self.add_substs(substs);
self.add_flags(TypeFlags::HAS_PROJECTION);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
}
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
self.add_flags(TypeFlags::HAS_CT_INFER);
match infer {
InferConst::Fresh(_) => {}
InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
}
}
ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn),
ty::ConstKind::Param(_) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_PARAMS);
self.add_flags(TypeFlags::HAS_CT_PARAM);
}
ty::ConstKind::Placeholder(_) => {
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
}
ty::ConstKind::Value(_) => {}
Expand Down
12 changes: 5 additions & 7 deletions src/librustc/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,21 +85,22 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
self.has_type_flags(TypeFlags::HAS_TY_ERR)
}
fn has_param_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAMS)
self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM)
}
fn has_infer_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
fn has_infer_types_or_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_CT_INFER)
}
fn has_infer_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_CT_INFER)
}
fn has_local_value(&self) -> bool {
self.has_type_flags(TypeFlags::KEEP_IN_LOCAL_TCX)
}
fn needs_infer(&self) -> bool {
self.has_type_flags(
TypeFlags::HAS_TY_INFER | TypeFlags::HAS_RE_INFER | TypeFlags::HAS_CT_INFER,
)
self.has_type_flags(TypeFlags::NEEDS_INFER)
}
fn has_placeholders(&self) -> bool {
self.has_type_flags(
Expand All @@ -114,9 +115,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn has_re_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER)
}
fn has_closure_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_CLOSURE)
}
/// "Free" regions in this context means that it has any region
/// that is not (a) erased or (b) late-bound.
fn has_free_regions(&self) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
let univariant = |fields: &[TyLayout<'_>], repr: &ReprOptions, kind| {
Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?))
};
debug_assert!(!ty.has_infer_types());
debug_assert!(!ty.has_infer_types_or_consts());

Ok(match ty.kind {
// Basic scalars.
Expand Down Expand Up @@ -1752,7 +1752,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> {
debug_assert!(!ty.has_infer_types());
debug_assert!(!ty.has_infer_types_or_consts());

// First try computing a static layout.
let err = match tcx.layout_of(param_env.and(ty)) {
Expand Down
150 changes: 89 additions & 61 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,79 +515,107 @@ pub struct CReaderCacheKey {
pub pos: usize,
}

// Flags that we track on types. These flags are propagated upwards
// through the type during type construction, so that we can quickly
// check whether the type has various kinds of types in it without
// recursing over the type itself.
bitflags! {
/// Flags that we track on types. These flags are propagated upwards
/// through the type during type construction, so that we can quickly check
/// whether the type has various kinds of types in it without recursing
/// over the type itself.
pub struct TypeFlags: u32 {
const HAS_PARAMS = 1 << 0;
const HAS_TY_INFER = 1 << 1;
const HAS_RE_INFER = 1 << 2;
const HAS_RE_PLACEHOLDER = 1 << 3;

/// Does this have any `ReEarlyBound` regions? Used to
/// determine whether substitition is required, since those
/// represent regions that are bound in a `ty::Generics` and
/// hence may be substituted.
const HAS_RE_EARLY_BOUND = 1 << 4;

/// Does this have any region that "appears free" in the type?
/// Basically anything but `ReLateBound` and `ReErased`.
const HAS_FREE_REGIONS = 1 << 5;

/// Is an error type reachable?
const HAS_TY_ERR = 1 << 6;
const HAS_PROJECTION = 1 << 7;

// FIXME: Rename this to the actual property since it's used for generators too
const HAS_TY_CLOSURE = 1 << 8;
// Does this have parameters? Used to determine whether substitution is
// required.
/// Does this have [Param]?
const HAS_TY_PARAM = 1 << 0;
/// Does this have [ReEarlyBound]?
const HAS_RE_PARAM = 1 << 1;
/// Does this have [ConstKind::Param]?
const HAS_CT_PARAM = 1 << 2;

const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits
| TypeFlags::HAS_RE_PARAM.bits
| TypeFlags::HAS_CT_PARAM.bits;

/// Does this have [Infer]?
const HAS_TY_INFER = 1 << 3;
/// Does this have [ReVar]?
const HAS_RE_INFER = 1 << 4;
/// Does this have [ConstKind::Infer]?
const HAS_CT_INFER = 1 << 5;

/// Does this have inference variables? Used to determine whether
/// inference is required.
const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits
| TypeFlags::HAS_RE_INFER.bits
| TypeFlags::HAS_CT_INFER.bits;

/// Does this have [Placeholder]?
const HAS_TY_PLACEHOLDER = 1 << 6;
/// Does this have [RePlaceholder]?
const HAS_RE_PLACEHOLDER = 1 << 7;
/// Does this have [ConstKind::Placeholder]?
const HAS_CT_PLACEHOLDER = 1 << 8;

/// `true` if there are "names" of types and regions and so forth
/// that are local to a particular fn
const HAS_FREE_LOCAL_NAMES = 1 << 9;
const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits
| TypeFlags::HAS_RE_PARAM.bits
| TypeFlags::HAS_CT_PARAM.bits
| TypeFlags::HAS_TY_INFER.bits
| TypeFlags::HAS_RE_INFER.bits
| TypeFlags::HAS_CT_INFER.bits
| TypeFlags::HAS_TY_PLACEHOLDER.bits
| TypeFlags::HAS_RE_PLACEHOLDER.bits
| TypeFlags::HAS_CT_PLACEHOLDER.bits;

/// Does this have [Projection] or [UnnormalizedProjection]?
const HAS_TY_PROJECTION = 1 << 9;
/// Does this have [Opaque]?
const HAS_TY_OPAQUE = 1 << 10;
/// Does this have [ConstKind::Unevaluated]?
const HAS_CT_PROJECTION = 1 << 11;

/// Could this type be normalized further?
const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
| TypeFlags::HAS_TY_OPAQUE.bits
| TypeFlags::HAS_CT_PROJECTION.bits;

/// Present if the type belongs in a local type context.
/// Only set for Infer other than Fresh.
const KEEP_IN_LOCAL_TCX = 1 << 10;

/// Does this have any `ReLateBound` regions? Used to check
/// if a global bound is safe to evaluate.
const HAS_RE_LATE_BOUND = 1 << 11;
/// Set for placeholders and inference variables that are not "Fresh".
const KEEP_IN_LOCAL_TCX = 1 << 12;

/// Does this have any `ReErased` regions?
const HAS_RE_ERASED = 1 << 12;
/// Is an error type reachable?
const HAS_TY_ERR = 1 << 13;

const HAS_TY_PLACEHOLDER = 1 << 13;
/// Does this have any region that "appears free" in the type?
/// Basically anything but [ReLateBound] and [ReErased].
const HAS_FREE_REGIONS = 1 << 14;

const HAS_CT_INFER = 1 << 14;
const HAS_CT_PLACEHOLDER = 1 << 15;
/// Does this have any [Opaque] types.
const HAS_TY_OPAQUE = 1 << 16;
/// Does this have any [ReLateBound] regions? Used to check
/// if a global bound is safe to evaluate.
const HAS_RE_LATE_BOUND = 1 << 15;

const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
TypeFlags::HAS_RE_EARLY_BOUND.bits;
/// Does this have any [ReErased] regions?
const HAS_RE_ERASED = 1 << 16;

/// Flags representing the nominal content of a type,
/// computed by FlagsComputation. If you add a new nominal
/// flag, it should be added here too.
const NOMINAL_FLAGS = TypeFlags::HAS_PARAMS.bits |
TypeFlags::HAS_TY_INFER.bits |
TypeFlags::HAS_RE_INFER.bits |
TypeFlags::HAS_RE_PLACEHOLDER.bits |
TypeFlags::HAS_RE_EARLY_BOUND.bits |
TypeFlags::HAS_FREE_REGIONS.bits |
TypeFlags::HAS_TY_ERR.bits |
TypeFlags::HAS_PROJECTION.bits |
TypeFlags::HAS_TY_CLOSURE.bits |
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
TypeFlags::HAS_RE_LATE_BOUND.bits |
TypeFlags::HAS_RE_ERASED.bits |
TypeFlags::HAS_TY_PLACEHOLDER.bits |
TypeFlags::HAS_CT_INFER.bits |
TypeFlags::HAS_CT_PLACEHOLDER.bits |
TypeFlags::HAS_TY_OPAQUE.bits;
const NOMINAL_FLAGS = TypeFlags::HAS_TY_PARAM.bits
| TypeFlags::HAS_RE_PARAM.bits
| TypeFlags::HAS_CT_PARAM.bits
| TypeFlags::HAS_TY_INFER.bits
| TypeFlags::HAS_RE_INFER.bits
| TypeFlags::HAS_CT_INFER.bits
| TypeFlags::HAS_TY_PLACEHOLDER.bits
| TypeFlags::HAS_RE_PLACEHOLDER.bits
| TypeFlags::HAS_CT_PLACEHOLDER.bits
| TypeFlags::HAS_TY_PROJECTION.bits
| TypeFlags::HAS_TY_OPAQUE.bits
| TypeFlags::HAS_CT_PROJECTION.bits
| TypeFlags::KEEP_IN_LOCAL_TCX.bits
| TypeFlags::HAS_TY_ERR.bits
| TypeFlags::HAS_FREE_REGIONS.bits
| TypeFlags::HAS_RE_LATE_BOUND.bits
| TypeFlags::HAS_RE_ERASED.bits;
}
}

Expand Down Expand Up @@ -1816,10 +1844,10 @@ impl<'tcx> ParamEnv<'tcx> {
Reveal::UserFacing => ParamEnvAnd { param_env: self, value },

Reveal::All => {
if value.has_placeholders() || value.needs_infer() || value.has_param_types() {
ParamEnvAnd { param_env: self, value }
} else {
if value.is_global() {
ParamEnvAnd { param_env: self.without_caller_bounds(), value }
} else {
ParamEnvAnd { param_env: self, value }
}
}
}
Expand Down
7 changes: 1 addition & 6 deletions src/librustc/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,7 @@ impl RegionKind {
}
ty::ReEarlyBound(..) => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
flags = flags | TypeFlags::HAS_RE_EARLY_BOUND;
flags = flags | TypeFlags::HAS_RE_PARAM;
}
ty::ReEmpty(_) | ty::ReStatic | ty::ReFree { .. } | ty::ReScope { .. } => {
flags = flags | TypeFlags::HAS_FREE_REGIONS;
Expand All @@ -1781,11 +1781,6 @@ impl RegionKind {
}
}

match *self {
ty::ReStatic | ty::ReEmpty(_) | ty::ReErased | ty::ReLateBound(..) => (),
_ => flags = flags | TypeFlags::HAS_FREE_LOCAL_NAMES,
}

debug!("type_flags({:?}) = {:?}", self, flags);

flags
Expand Down
5 changes: 1 addition & 4 deletions src/librustc_infer/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> {
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if !(t.needs_infer()
|| t.has_erasable_regions()
|| (t.has_closure_types() && self.infcx.in_progress_tables.is_some()))
{
if !t.needs_infer() && !t.has_erasable_regions() {
return t;
}

Expand Down
8 changes: 2 additions & 6 deletions src/librustc_infer/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1482,12 +1482,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
) -> bool {
let ty = self.resolve_vars_if_possible(&ty);

// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.
if self.in_progress_tables.is_none() || !ty.has_closure_types() {
if !(param_env, ty).has_local_value() {
return ty.is_copy_modulo_regions(self.tcx, param_env, span);
}
if !(param_env, ty).has_local_value() {
return ty.is_copy_modulo_regions(self.tcx, param_env, span);
}

let copy_def_id = self.tcx.require_lang_item(lang_items::CopyTraitLangItem, None);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ where
// In NLL, we don't have type inference variables
// floating around, so we can do this rather imprecise
// variant of the occurs-check.
assert!(!generalized_ty.has_infer_types());
assert!(!generalized_ty.has_infer_types_or_consts());
}

self.infcx.inner.borrow_mut().type_variables.instantiate(vid, generalized_ty);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_infer/infer/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if !t.has_infer_types() && !t.has_infer_consts() {
if !t.has_infer_types_or_consts() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
let t = self.infcx.shallow_resolve(t);
Expand All @@ -37,7 +37,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> {
}

fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
if !ct.has_infer_consts() {
if !ct.has_infer_types_or_consts() {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
let ct = self.infcx.shallow_resolve(ct);
Expand Down
Loading

0 comments on commit 6af4fd3

Please sign in to comment.