From be2900c33b043ca2002bdb11870e8d26c3e410f3 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Tue, 15 May 2018 21:48:35 +0100 Subject: [PATCH] Make is_global true for latebound regions --- src/librustc/traits/fulfill.rs | 2 +- src/librustc/ty/flags.rs | 8 ++++---- src/librustc/ty/fold.rs | 10 +++++++--- src/librustc/ty/mod.rs | 11 ++++++++--- src/librustc/ty/sty.rs | 8 +++++--- src/librustc_lint/builtin.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 4 ++-- 7 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 6e20150718110..94ee39470772f 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -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) { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 01de848e0f076..e913f8f568ada 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -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(_) | diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 1793b5e1edba8..a1f9fd76b02dc 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -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) } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index eede7bd2ea619..01dbef06792cf 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -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; } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f0a7ce5497166..b0eb8ecab2506 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -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); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 912d5c37ca3cd..0b1e9081a725e 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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, diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 1a1076f74b2b2..21f6f62517ba6 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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,