diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-02-20 10:37:35 -0500 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2018-03-13 11:21:31 -0400 |
| commit | 80b4c45ee47833338164c6eb015f421890712863 (patch) | |
| tree | 74cdb96ed797789d78ed7cc6aaef20d7c63b18e4 /src | |
| parent | 64d4ed300b52834954179284a0d0a6eb5084d39e (diff) | |
| download | rust-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.rs | 49 |
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, + } + } } } } |
