Make is_global true for latebound regions
This commit is contained in:
parent
dc8ce4c139
commit
be2900c33b
@ -330,7 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
let trait_obligation = obligation.with(data.clone());
|
||||
|
||||
if data.is_global() {
|
||||
if data.is_global() && !data.has_late_bound_regions() {
|
||||
// no type variables present, can use evaluation for better caching.
|
||||
// FIXME: consider caching errors too.
|
||||
if selcx.infcx().predicate_must_hold(&obligation) {
|
||||
|
@ -79,7 +79,7 @@ impl FlagComputation {
|
||||
}
|
||||
|
||||
&ty::TyParam(ref p) => {
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
|
||||
if p.is_self() {
|
||||
self.add_flags(TypeFlags::HAS_SELF);
|
||||
} else {
|
||||
@ -89,7 +89,7 @@ impl FlagComputation {
|
||||
|
||||
&ty::TyGenerator(_, ref substs, _) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
|
||||
self.add_substs(&substs.substs);
|
||||
}
|
||||
|
||||
@ -101,12 +101,12 @@ impl FlagComputation {
|
||||
|
||||
&ty::TyClosure(_, ref substs) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
|
||||
self.add_substs(&substs.substs);
|
||||
}
|
||||
|
||||
&ty::TyInfer(infer) => {
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES); // it might, right?
|
||||
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES); // it might, right?
|
||||
self.add_flags(TypeFlags::HAS_TY_INFER);
|
||||
match infer {
|
||||
ty::FreshTy(_) |
|
||||
|
@ -116,10 +116,14 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
|
||||
|
||||
/// Indicates whether this value references only 'global'
|
||||
/// types/lifetimes that are the same regardless of what fn we are
|
||||
/// in. This is used for caching. Errs on the side of returning
|
||||
/// false.
|
||||
/// in. This is used for caching.
|
||||
fn is_global(&self) -> bool {
|
||||
!self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
|
||||
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
|
||||
}
|
||||
|
||||
/// True if there are any late-bound regions
|
||||
fn has_late_bound_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -441,7 +441,7 @@ bitflags! {
|
||||
|
||||
// true if there are "names" of types and regions and so forth
|
||||
// that are local to a particular fn
|
||||
const HAS_LOCAL_NAMES = 1 << 10;
|
||||
const HAS_FREE_LOCAL_NAMES = 1 << 10;
|
||||
|
||||
// Present if the type belongs in a local type context.
|
||||
// Only set for TyInfer other than Fresh.
|
||||
@ -455,6 +455,10 @@ bitflags! {
|
||||
// ought to be true only for the results of canonicalization.
|
||||
const HAS_CANONICAL_VARS = 1 << 13;
|
||||
|
||||
/// Does this have any `ReLateBound` regions? Used to check
|
||||
/// if a global bound is safe to evaluate.
|
||||
const HAS_RE_LATE_BOUND = 1 << 14;
|
||||
|
||||
const NEEDS_SUBST = TypeFlags::HAS_PARAMS.bits |
|
||||
TypeFlags::HAS_SELF.bits |
|
||||
TypeFlags::HAS_RE_EARLY_BOUND.bits;
|
||||
@ -472,9 +476,10 @@ bitflags! {
|
||||
TypeFlags::HAS_TY_ERR.bits |
|
||||
TypeFlags::HAS_PROJECTION.bits |
|
||||
TypeFlags::HAS_TY_CLOSURE.bits |
|
||||
TypeFlags::HAS_LOCAL_NAMES.bits |
|
||||
TypeFlags::HAS_FREE_LOCAL_NAMES.bits |
|
||||
TypeFlags::KEEP_IN_LOCAL_TCX.bits |
|
||||
TypeFlags::HAS_CANONICAL_VARS.bits;
|
||||
TypeFlags::HAS_CANONICAL_VARS.bits |
|
||||
TypeFlags::HAS_RE_LATE_BOUND.bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1268,7 +1268,9 @@ impl RegionKind {
|
||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||
flags = flags | TypeFlags::HAS_RE_SKOL;
|
||||
}
|
||||
ty::ReLateBound(..) => { }
|
||||
ty::ReLateBound(..) => {
|
||||
flags = flags | TypeFlags::HAS_RE_LATE_BOUND;
|
||||
}
|
||||
ty::ReEarlyBound(..) => {
|
||||
flags = flags | TypeFlags::HAS_FREE_REGIONS;
|
||||
flags = flags | TypeFlags::HAS_RE_EARLY_BOUND;
|
||||
@ -1291,8 +1293,8 @@ impl RegionKind {
|
||||
}
|
||||
|
||||
match *self {
|
||||
ty::ReStatic | ty::ReEmpty | ty::ReErased => (),
|
||||
_ => flags = flags | TypeFlags::HAS_LOCAL_NAMES,
|
||||
ty::ReStatic | ty::ReEmpty | ty::ReErased | ty::ReLateBound(..) => (),
|
||||
_ => flags = flags | TypeFlags::HAS_FREE_LOCAL_NAMES,
|
||||
}
|
||||
|
||||
debug!("type_flags({:?}) = {:?}", self, flags);
|
||||
|
@ -1637,7 +1637,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints {
|
||||
Subtype(..) |
|
||||
ConstEvaluatable(..) => continue,
|
||||
};
|
||||
if !predicate.is_global() {
|
||||
if predicate.is_global() {
|
||||
cx.span_lint(
|
||||
TRIVIAL_BOUNDS,
|
||||
item.span,
|
||||
|
@ -683,8 +683,8 @@ fn check_false_global_bounds<'a, 'gcx, 'tcx>(
|
||||
let implied_obligations = traits::elaborate_predicates(fcx.tcx, predicates);
|
||||
|
||||
for pred in implied_obligations {
|
||||
// HAS_LOCAL_NAMES is used to match the existing behvaiour.
|
||||
if !pred.has_type_flags(ty::TypeFlags::HAS_LOCAL_NAMES) {
|
||||
// Match the existing behavior.
|
||||
if pred.is_global() && !pred.has_late_bound_regions() {
|
||||
let obligation = traits::Obligation::new(
|
||||
traits::ObligationCause::new(
|
||||
span,
|
||||
|
Loading…
Reference in New Issue
Block a user