Skip to content

Commit 80b4c45

Browse files
committed
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.
1 parent 64d4ed3 commit 80b4c45

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

src/librustc/ty/mod.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,31 +1439,38 @@ impl<'tcx> ParamEnv<'tcx> {
14391439
}
14401440

14411441
/// Creates a suitable environment in which to perform trait
1442-
/// queries on the given value. This will either be `self` *or*
1443-
/// the empty environment, depending on whether `value` references
1444-
/// type parameters that are in scope. (If it doesn't, then any
1445-
/// judgements should be completely independent of the context,
1446-
/// and hence we can safely use the empty environment so as to
1447-
/// enable more sharing across functions.)
1442+
/// queries on the given value. When type-checking, this is simply
1443+
/// the pair of the environment plus value. But when reveal is set to
1444+
/// All, then if `value` does not reference any type parameters, we will
1445+
/// pair it with the empty environment. This improves caching and is generally
1446+
/// invisible.
14481447
///
1449-
/// NB: This is a mildly dubious thing to do, in that a function
1450-
/// (or other environment) might have wacky where-clauses like
1448+
/// NB: We preserve the environment when type-checking because it
1449+
/// is possible for the user to have wacky where-clauses like
14511450
/// `where Box<u32>: Copy`, which are clearly never
1452-
/// satisfiable. The code will at present ignore these,
1453-
/// effectively, when type-checking the body of said
1454-
/// function. This preserves existing behavior in any
1455-
/// case. --nmatsakis
1451+
/// satisfiable. We generally want to behave as if they were true,
1452+
/// although the surrounding function is never reachable.
14561453
pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
1457-
assert!(!value.needs_infer());
1458-
if value.has_param_types() || value.has_self_ty() {
1459-
ParamEnvAnd {
1460-
param_env: self,
1461-
value,
1454+
match self.reveal {
1455+
Reveal::UserFacing => {
1456+
ParamEnvAnd {
1457+
param_env: self,
1458+
value,
1459+
}
14621460
}
1463-
} else {
1464-
ParamEnvAnd {
1465-
param_env: self.without_caller_bounds(),
1466-
value,
1461+
1462+
Reveal::All => {
1463+
if value.needs_infer() || value.has_param_types() || value.has_self_ty() {
1464+
ParamEnvAnd {
1465+
param_env: self,
1466+
value,
1467+
}
1468+
} else {
1469+
ParamEnvAnd {
1470+
param_env: self.without_caller_bounds(),
1471+
value,
1472+
}
1473+
}
14671474
}
14681475
}
14691476
}

0 commit comments

Comments
 (0)