Skip to content

Commit 8ad3c1d

Browse files
committed
Auto merge of rust-lang#92149 - fee1-dead:cache-fix, r=oli-obk
Fix bad caching of `~const Drop` bounds Fixes rust-lang#92111.
2 parents 3d57c61 + aaaad5b commit 8ad3c1d

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

Diff for: compiler/rustc_middle/src/ty/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,15 @@ pub struct TraitPredicate<'tcx> {
734734
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
735735

736736
impl<'tcx> TraitPredicate<'tcx> {
737+
pub fn remap_constness(&mut self, tcx: TyCtxt<'tcx>, param_env: &mut ParamEnv<'tcx>) {
738+
if unlikely!(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
739+
// remap without changing constness of this predicate.
740+
// this is because `T: ~const Drop` has a different meaning to `T: Drop`
741+
param_env.remap_constness_with(self.constness)
742+
} else {
743+
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
744+
}
745+
}
737746
pub fn def_id(self) -> DefId {
738747
self.trait_ref.def_id
739748
}

Diff for: compiler/rustc_trait_selection/src/traits/select/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
730730
let mut param_env = obligation.param_env;
731731

732732
fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| {
733-
param_env = param_env.with_constness(pred.constness.and(param_env.constness()));
733+
pred.remap_constness(self.tcx(), &mut param_env);
734734
pred
735735
});
736736

@@ -1269,7 +1269,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12691269
}
12701270
let tcx = self.tcx();
12711271
let mut pred = cache_fresh_trait_pred.skip_binder();
1272-
param_env = param_env.with_constness(pred.constness.and(param_env.constness()));
1272+
pred.remap_constness(tcx, &mut param_env);
12731273

12741274
if self.can_use_global_caches(param_env) {
12751275
if let Some(res) = tcx.selection_cache.get(&param_env.and(pred), tcx) {
@@ -1322,7 +1322,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13221322
let tcx = self.tcx();
13231323
let mut pred = cache_fresh_trait_pred.skip_binder();
13241324

1325-
param_env = param_env.with_constness(pred.constness.and(param_env.constness()));
1325+
pred.remap_constness(tcx, &mut param_env);
13261326

13271327
if !self.can_cache_candidate(&candidate) {
13281328
debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");

Diff for: src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Regression test for #92111.
2+
//
3+
// The issue was that we normalize trait bounds before caching
4+
// results of selection. Checking that `impl NoDrop for S` requires
5+
// checking `S: !Drop` because it cannot overlap with the blanket
6+
// impl. Then we save the (unsatisfied) result from checking `S: Drop`.
7+
// Then the call to `a` checks whether `S: ~const Drop` but we normalize
8+
// it to `S: Drop` which the cache claims to be unsatisfied.
9+
//
10+
// check-pass
11+
12+
#![feature(const_trait_impl)]
13+
#![feature(const_fn_trait_bound)]
14+
15+
pub trait Tr {}
16+
17+
#[allow(drop_bounds)]
18+
impl<T: Drop> Tr for T {}
19+
20+
#[derive(Debug)]
21+
pub struct S(i32);
22+
23+
impl Tr for S {}
24+
25+
const fn a<T: ~const Drop>(t: T) {}
26+
27+
fn main() {
28+
a(S(0));
29+
}

0 commit comments

Comments
 (0)