about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-02-20 10:37:35 -0500
committerNiko Matsakis <niko@alum.mit.edu>2018-03-13 11:21:31 -0400
commit80b4c45ee47833338164c6eb015f421890712863 (patch)
tree74cdb96ed797789d78ed7cc6aaef20d7c63b18e4 /src
parent64d4ed300b52834954179284a0d0a6eb5084d39e (diff)
downloadrust-80b4c45ee47833338164c6eb015f421890712863.tar.gz
rust-80b4c45ee47833338164c6eb015f421890712863.zip
change `ParamEnv::and` to sometimes keep the environment [VIC]
In general, we've been moving towards a semantics where you can have
contradictory where-clauses, and we try to honor them.  There are
already existing run-pass tests where we take that philosophy as
well (e.g., `compile-fail/issue-36839.rs`). The current behavior of
`and`, where it strips the environment, breaks that code.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/mod.rs49
1 files changed, 28 insertions, 21 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index f81a2b9750a..e3405e0c3b3 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1439,31 +1439,38 @@ impl<'tcx> ParamEnv<'tcx> {
     }
 
     /// Creates a suitable environment in which to perform trait
-    /// queries on the given value. This will either be `self` *or*
-    /// the empty environment, depending on whether `value` references
-    /// type parameters that are in scope. (If it doesn't, then any
-    /// judgements should be completely independent of the context,
-    /// and hence we can safely use the empty environment so as to
-    /// enable more sharing across functions.)
+    /// queries on the given value. When type-checking, this is simply
+    /// the pair of the environment plus value. But when reveal is set to
+    /// All, then if `value` does not reference any type parameters, we will
+    /// pair it with the empty environment. This improves caching and is generally
+    /// invisible.
     ///
-    /// NB: This is a mildly dubious thing to do, in that a function
-    /// (or other environment) might have wacky where-clauses like
+    /// NB: We preserve the environment when type-checking because it
+    /// is possible for the user to have wacky where-clauses like
     /// `where Box<u32>: Copy`, which are clearly never
-    /// satisfiable. The code will at present ignore these,
-    /// effectively, when type-checking the body of said
-    /// function. This preserves existing behavior in any
-    /// case. --nmatsakis
+    /// satisfiable. We generally want to behave as if they were true,
+    /// although the surrounding function is never reachable.
     pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
-        assert!(!value.needs_infer());
-        if value.has_param_types() || value.has_self_ty() {
-            ParamEnvAnd {
-                param_env: self,
-                value,
+        match self.reveal {
+            Reveal::UserFacing => {
+                ParamEnvAnd {
+                    param_env: self,
+                    value,
+                }
             }
-        } else {
-            ParamEnvAnd {
-                param_env: self.without_caller_bounds(),
-                value,
+
+            Reveal::All => {
+                if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
+                    ParamEnvAnd {
+                        param_env: self,
+                        value,
+                    }
+                } else {
+                    ParamEnvAnd {
+                        param_env: self.without_caller_bounds(),
+                        value,
+                    }
+                }
             }
         }
     }