mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Auto merge of #69469 - matthewjasper:type-flags, r=cramertj
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
This commit is contained in:
commit
6af4fd385e
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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(_) => {}
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -221,10 +214,10 @@ 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),
|
||||
@ -232,11 +225,9 @@ impl FlagComputation {
|
||||
}
|
||||
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(_) => {}
|
||||
|
@ -85,11 +85,14 @@ 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)
|
||||
}
|
||||
@ -97,9 +100,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
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(
|
||||
@ -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 {
|
||||
|
@ -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.
|
||||
@ -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)) {
|
||||
|
@ -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 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;
|
||||
|
||||
/// 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;
|
||||
const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits
|
||||
| TypeFlags::HAS_RE_PARAM.bits
|
||||
| TypeFlags::HAS_CT_PARAM.bits;
|
||||
|
||||
/// Does this have any region that "appears free" in the type?
|
||||
/// Basically anything but `ReLateBound` and `ReErased`.
|
||||
const HAS_FREE_REGIONS = 1 << 5;
|
||||
/// 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;
|
||||
|
||||
/// Is an error type reachable?
|
||||
const HAS_TY_ERR = 1 << 6;
|
||||
const HAS_PROJECTION = 1 << 7;
|
||||
/// 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;
|
||||
|
||||
// FIXME: Rename this to the actual property since it's used for generators too
|
||||
const HAS_TY_CLOSURE = 1 << 8;
|
||||
/// 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;
|
||||
/// Set for placeholders and inference variables that are not "Fresh".
|
||||
const KEEP_IN_LOCAL_TCX = 1 << 12;
|
||||
|
||||
/// Does this have any `ReLateBound` regions? Used to check
|
||||
/// Is an error type reachable?
|
||||
const HAS_TY_ERR = 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;
|
||||
|
||||
/// Does this have any [ReLateBound] regions? Used to check
|
||||
/// if a global bound is safe to evaluate.
|
||||
const HAS_RE_LATE_BOUND = 1 << 11;
|
||||
const HAS_RE_LATE_BOUND = 1 << 15;
|
||||
|
||||
/// Does this have any `ReErased` regions?
|
||||
const HAS_RE_ERASED = 1 << 12;
|
||||
|
||||
const HAS_TY_PLACEHOLDER = 1 << 13;
|
||||
|
||||
const HAS_CT_INFER = 1 << 14;
|
||||
const HAS_CT_PLACEHOLDER = 1 << 15;
|
||||
/// Does this have any [Opaque] types.
|
||||
const HAS_TY_OPAQUE = 1 << 16;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
@ -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);
|
||||
|
@ -647,7 +647,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Try to report a help message
|
||||
if !trait_ref.has_infer_types()
|
||||
if !trait_ref.has_infer_types_or_consts()
|
||||
&& self.predicate_can_apply(obligation.param_env, trait_ref)
|
||||
{
|
||||
// If a where-clause may be useful, remind the
|
||||
|
@ -471,7 +471,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
let trait_ref = self.resolve_vars_if_possible(trait_ref);
|
||||
if trait_ref.has_infer_types() {
|
||||
if trait_ref.has_infer_types_or_consts() {
|
||||
// Do not ICE while trying to find if a reborrow would succeed on a trait with
|
||||
// unresolved bindings.
|
||||
return;
|
||||
|
@ -299,7 +299,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||
|
||||
let obligation = &mut pending_obligation.obligation;
|
||||
|
||||
if obligation.predicate.has_infer_types() {
|
||||
if obligation.predicate.has_infer_types_or_consts() {
|
||||
obligation.predicate =
|
||||
self.selcx.infcx().resolve_vars_if_possible(&obligation.predicate);
|
||||
}
|
||||
@ -346,16 +346,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
||||
// This is a bit subtle: for the most part, the
|
||||
// only reason we can fail to make progress on
|
||||
// trait selection is because we don't have enough
|
||||
// information about the types in the trait. One
|
||||
// exception is that we sometimes haven't decided
|
||||
// what kind of closure a closure is. *But*, in
|
||||
// that case, it turns out, the type of the
|
||||
// closure will also change, because the closure
|
||||
// also includes references to its upvars as part
|
||||
// of its type, and those types are resolved at
|
||||
// the same time.
|
||||
//
|
||||
// FIXME(#32286) logic seems false if no upvars
|
||||
// information about the types in the trait.
|
||||
pending_obligation.stalled_on =
|
||||
trait_ref_type_vars(self.selcx, data.to_poly_trait_ref());
|
||||
|
||||
|
@ -213,7 +213,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
|
||||
result
|
||||
);
|
||||
|
||||
if result && (ty.has_infer_types() || ty.has_closure_types()) {
|
||||
if result && ty.has_infer_types_or_consts() {
|
||||
// Because of inference "guessing", selection can sometimes claim
|
||||
// to succeed while the success requires a guess. To ensure
|
||||
// this function's result remains infallible, we must confirm
|
||||
|
@ -490,22 +490,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
match cache_result {
|
||||
Ok(()) => {}
|
||||
Err(ProjectionCacheEntry::Ambiguous) => {
|
||||
// If we found ambiguity the last time, that generally
|
||||
// means we will continue to do so until some type in the
|
||||
// key changes (and we know it hasn't, because we just
|
||||
// fully resolved it). One exception though is closure
|
||||
// types, which can transition from having a fixed kind to
|
||||
// no kind with no visible change in the key.
|
||||
//
|
||||
// FIXME(#32286) refactor this so that closure type
|
||||
// changes
|
||||
// If we found ambiguity the last time, that means we will continue
|
||||
// to do so until some type in the key changes (and we know it
|
||||
// hasn't, because we just fully resolved it).
|
||||
debug!(
|
||||
"opt_normalize_projection_type: \
|
||||
found cache entry: ambiguous"
|
||||
);
|
||||
if !projection_ty.has_closure_types() {
|
||||
return None;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
Err(ProjectionCacheEntry::InProgress) => {
|
||||
// If while normalized A::B, we are asked to normalize
|
||||
|
@ -84,7 +84,7 @@ fn compute_implied_outlives_bounds<'tcx>(
|
||||
// to avoids duplicate errors that otherwise show up.
|
||||
fulfill_cx.register_predicate_obligations(
|
||||
infcx,
|
||||
obligations.iter().filter(|o| o.predicate.has_infer_types()).cloned(),
|
||||
obligations.iter().filter(|o| o.predicate.has_infer_types_or_consts()).cloned(),
|
||||
);
|
||||
|
||||
// From the full set of obligations, just filter down to the
|
||||
|
@ -2900,14 +2900,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
debug!("resolve_vars_with_obligations(ty={:?})", ty);
|
||||
|
||||
// No Infer()? Nothing needs doing.
|
||||
if !ty.has_infer_types() && !ty.has_infer_consts() {
|
||||
if !ty.has_infer_types_or_consts() {
|
||||
debug!("resolve_vars_with_obligations: ty={:?}", ty);
|
||||
return ty;
|
||||
}
|
||||
|
||||
// If `ty` is a type variable, see whether we already know what it is.
|
||||
ty = self.resolve_vars_if_possible(&ty);
|
||||
if !ty.has_infer_types() && !ty.has_infer_consts() {
|
||||
if !ty.has_infer_types_or_consts() {
|
||||
debug!("resolve_vars_with_obligations: ty={:?}", ty);
|
||||
return ty;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:12:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:12:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -19,10 +19,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:18:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:18:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -39,10 +39,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:24:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:24:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -59,10 +59,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:30:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:30:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -79,10 +79,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:36:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:36:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -99,10 +99,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:42:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:42:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
@ -119,10 +119,10 @@ LL | IntoIter::new([0i32; 33])
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0277]: arrays only have std trait implementations for lengths 0..=32
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:48:5
|
||||
--> $DIR/into-iter-no-impls-length-33.rs:48:19
|
||||
|
|
||||
LL | IntoIter::new([0i32; 33])
|
||||
| ^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
| ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]`
|
||||
|
|
||||
= note: required by `std::array::IntoIter::<T, N>::new`
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user