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.
This commit is contained in:
parent
64d4ed300b
commit
80b4c45ee4
1 changed files with 28 additions and 21 deletions
|
@ -1439,31 +1439,38 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a suitable environment in which to perform trait
|
/// Creates a suitable environment in which to perform trait
|
||||||
/// queries on the given value. This will either be `self` *or*
|
/// queries on the given value. When type-checking, this is simply
|
||||||
/// the empty environment, depending on whether `value` references
|
/// the pair of the environment plus value. But when reveal is set to
|
||||||
/// type parameters that are in scope. (If it doesn't, then any
|
/// All, then if `value` does not reference any type parameters, we will
|
||||||
/// judgements should be completely independent of the context,
|
/// pair it with the empty environment. This improves caching and is generally
|
||||||
/// and hence we can safely use the empty environment so as to
|
/// invisible.
|
||||||
/// enable more sharing across functions.)
|
|
||||||
///
|
///
|
||||||
/// NB: This is a mildly dubious thing to do, in that a function
|
/// NB: We preserve the environment when type-checking because it
|
||||||
/// (or other environment) might have wacky where-clauses like
|
/// is possible for the user to have wacky where-clauses like
|
||||||
/// `where Box<u32>: Copy`, which are clearly never
|
/// `where Box<u32>: Copy`, which are clearly never
|
||||||
/// satisfiable. The code will at present ignore these,
|
/// satisfiable. We generally want to behave as if they were true,
|
||||||
/// effectively, when type-checking the body of said
|
/// although the surrounding function is never reachable.
|
||||||
/// function. This preserves existing behavior in any
|
|
||||||
/// case. --nmatsakis
|
|
||||||
pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
|
pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
|
||||||
assert!(!value.needs_infer());
|
match self.reveal {
|
||||||
if value.has_param_types() || value.has_self_ty() {
|
Reveal::UserFacing => {
|
||||||
ParamEnvAnd {
|
ParamEnvAnd {
|
||||||
param_env: self,
|
param_env: self,
|
||||||
value,
|
value,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
ParamEnvAnd {
|
Reveal::All => {
|
||||||
param_env: self.without_caller_bounds(),
|
if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
|
||||||
value,
|
ParamEnvAnd {
|
||||||
|
param_env: self,
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ParamEnvAnd {
|
||||||
|
param_env: self.without_caller_bounds(),
|
||||||
|
value,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue