about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2018-05-15 21:48:35 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2018-05-15 21:48:35 +0100
commitbe2900c33b043ca2002bdb11870e8d26c3e410f3 (patch)
tree340c980121a7073060ea49a7020fddfb897c09d4
parentdc8ce4c139d9f75557fdccad0795d0a149f29d68 (diff)
downloadrust-be2900c33b043ca2002bdb11870e8d26c3e410f3.tar.gz
rust-be2900c33b043ca2002bdb11870e8d26c3e410f3.zip
Make is_global true for latebound regions
-rw-r--r--src/librustc/traits/fulfill.rs2
-rw-r--r--src/librustc/ty/flags.rs8
-rw-r--r--src/librustc/ty/fold.rs10
-rw-r--r--src/librustc/ty/mod.rs11
-rw-r--r--src/librustc/ty/sty.rs8
-rw-r--r--src/librustc_lint/builtin.rs2
-rw-r--r--src/librustc_typeck/check/wfcheck.rs4
7 files changed, 28 insertions, 17 deletions
diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs
index 6e201507181..94ee3947077 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 01de848e0f0..e913f8f568a 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 1793b5e1edb..a1f9fd76b02 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 eede7bd2ea6..01dbef06792 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 f0a7ce54971..b0eb8ecab25 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 912d5c37ca3..0b1e9081a72 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 1a1076f74b2..21f6f62517b 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,