Skip to content

Commit 108cad1

Browse files
committed
auto_trait: dedup obligation predicates after elaboration
1 parent 70fd012 commit 108cad1

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::errors::UnableToConstructConstantValue;
77
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
88
use crate::infer::InferCtxt;
99
use crate::traits::project::ProjectAndUnifyResult;
10+
use rustc_infer::traits::util::PredicateSet;
1011
use rustc_middle::mir::interpret::ErrorHandled;
1112
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
1213
use rustc_middle::ty::visit::TypeVisitableExt;
@@ -344,13 +345,24 @@ impl<'tcx> AutoTraitFinder<'tcx> {
344345
_ => panic!("Unexpected error for '{:?}': {:?}", ty, result),
345346
};
346347

347-
let normalized_preds = elaborate_predicates(
348+
let elaborated_preds = elaborate_predicates(
348349
tcx,
349350
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
350351
)
351-
.map(|o| o.predicate);
352+
.map(|obligation| obligation.predicate);
353+
354+
// FIXME(generic_const_exprs):
355+
// This deduplication is required only when generic_const_exprs is not active
356+
// see #108397 for more information.
357+
let mut seen_preds = PredicateSet::new(tcx);
358+
let obctx = ObligationCtxt::new(infcx);
359+
let deduped_preds = elaborated_preds
360+
.into_iter()
361+
.map(|pred| obctx.normalize(&dummy_cause, param_env, pred))
362+
.filter(|normalized_pred| seen_preds.insert(*normalized_pred));
363+
352364
new_env = ty::ParamEnv::new(
353-
tcx.mk_predicates_from_iter(normalized_preds),
365+
tcx.mk_predicates_from_iter(deduped_preds),
354366
param_env.reveal(),
355367
param_env.constness(),
356368
);

tests/rustdoc-ui/issue_107715.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// check-pass
2+
#![crate_type = "lib"]
3+
4+
const N: usize = 1;
5+
6+
trait Supertrait<V> {
7+
type AssociatedType;
8+
}
9+
10+
trait Subtrait: Supertrait<[u8; N]> {}
11+
12+
struct MapType<K: Supertrait<V>, V> {
13+
map: K::AssociatedType,
14+
}
15+
16+
struct Container<S: Subtrait> {
17+
_x: MapType<S, [u8; N]>,
18+
}

0 commit comments

Comments
 (0)