Skip to content

Commit 8588f79

Browse files
Do not use ParamEnv::and to cache param-env with candidate
1 parent 551b4fa commit 8588f79

File tree

3 files changed

+20
-12
lines changed
  • compiler
    • rustc_middle/src/traits
    • rustc_trait_selection/src/traits/select
  • src/test/ui/higher-rank-trait-bounds/normalize-under-binder

3 files changed

+20
-12
lines changed

compiler/rustc_middle/src/traits/select.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,19 @@ use rustc_hir::def_id::DefId;
1313
use rustc_query_system::cache::Cache;
1414

1515
pub type SelectionCache<'tcx> = Cache<
16-
ty::ParamEnvAnd<'tcx, ty::TraitPredicate<'tcx>>,
16+
// This cache does not use `ParamEnvAnd` in its keys because `ParamEnv::and` can replace
17+
// caller bounds with an empty list if the `TraitPredicate` looks global, which may happen
18+
// after erasing lifetimes from the predicate.
19+
(ty::ParamEnv<'tcx>, ty::TraitPredicate<'tcx>),
1720
SelectionResult<'tcx, SelectionCandidate<'tcx>>,
1821
>;
1922

20-
pub type EvaluationCache<'tcx> =
21-
Cache<ty::ParamEnvAnd<'tcx, ty::PolyTraitPredicate<'tcx>>, EvaluationResult>;
23+
pub type EvaluationCache<'tcx> = Cache<
24+
// See above: this cache does not use `ParamEnvAnd` in its keys due to sometimes incorrectly
25+
// caching with the wrong `ParamEnv`.
26+
(ty::ParamEnv<'tcx>, ty::PolyTraitPredicate<'tcx>),
27+
EvaluationResult,
28+
>;
2229

2330
/// The selection process begins by considering all impls, where
2431
/// clauses, and so forth that might resolve an obligation. Sometimes

compiler/rustc_trait_selection/src/traits/select/mod.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -1046,11 +1046,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10461046

10471047
let tcx = self.tcx();
10481048
if self.can_use_global_caches(param_env) {
1049-
if let Some(res) = tcx.evaluation_cache.get(&param_env.and(trait_pred), tcx) {
1049+
if let Some(res) = tcx.evaluation_cache.get(&(param_env, trait_pred), tcx) {
10501050
return Some(res);
10511051
}
10521052
}
1053-
self.infcx.evaluation_cache.get(&param_env.and(trait_pred), tcx)
1053+
self.infcx.evaluation_cache.get(&(param_env, trait_pred), tcx)
10541054
}
10551055

10561056
fn insert_evaluation_cache(
@@ -1081,13 +1081,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10811081
// FIXME: Due to #50507 this overwrites the different values
10821082
// This should be changed to use HashMapExt::insert_same
10831083
// when that is fixed
1084-
self.tcx().evaluation_cache.insert(param_env.and(trait_pred), dep_node, result);
1084+
self.tcx().evaluation_cache.insert((param_env, trait_pred), dep_node, result);
10851085
return;
10861086
}
10871087
}
10881088

10891089
debug!(?trait_pred, ?result, "insert_evaluation_cache");
1090-
self.infcx.evaluation_cache.insert(param_env.and(trait_pred), dep_node, result);
1090+
self.infcx.evaluation_cache.insert((param_env, trait_pred), dep_node, result);
10911091
}
10921092

10931093
/// For various reasons, it's possible for a subobligation
@@ -1297,11 +1297,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12971297
pred.remap_constness(tcx, &mut param_env);
12981298

12991299
if self.can_use_global_caches(param_env) {
1300-
if let Some(res) = tcx.selection_cache.get(&param_env.and(pred), tcx) {
1300+
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
13011301
return Some(res);
13021302
}
13031303
}
1304-
self.infcx.selection_cache.get(&param_env.and(pred), tcx)
1304+
self.infcx.selection_cache.get(&(param_env, pred), tcx)
13051305
}
13061306

13071307
/// Determines whether can we safely cache the result
@@ -1361,14 +1361,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13611361
if !candidate.needs_infer() {
13621362
debug!(?pred, ?candidate, "insert_candidate_cache global");
13631363
// This may overwrite the cache with the same value.
1364-
tcx.selection_cache.insert(param_env.and(pred), dep_node, candidate);
1364+
tcx.selection_cache.insert((param_env, pred), dep_node, candidate);
13651365
return;
13661366
}
13671367
}
13681368
}
13691369

13701370
debug!(?pred, ?candidate, "insert_candidate_cache local");
1371-
self.infcx.selection_cache.insert(param_env.and(pred), dep_node, candidate);
1371+
self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
13721372
}
13731373

13741374
/// Matches a predicate against the bounds of its self type.

src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-80706.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// check-pass
1+
// build-pass
22
// edition:2018
33

44
type BoxFuture<T> = std::pin::Pin<Box<dyn std::future::Future<Output=T>>>;
@@ -65,6 +65,7 @@ async fn run<S>(dep: &str)
6565
where
6666
S: Storage,
6767
for<'a> SaveUser<'a>: StorageRequest<S>,
68+
for<'a> SaveUser<'a>: StorageRequestReturnType,
6869
{
6970
User { dep }.save().await;
7071
}

0 commit comments

Comments
 (0)