Skip to content

Commit

Permalink
auto_trait: dedup obligation predicates after elaboration
Browse files Browse the repository at this point in the history
  • Loading branch information
megakorre committed Feb 26, 2023
1 parent 70fd012 commit 108cad1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
18 changes: 15 additions & 3 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::errors::UnableToConstructConstantValue;
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::InferCtxt;
use crate::traits::project::ProjectAndUnifyResult;
use rustc_infer::traits::util::PredicateSet;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitableExt;
Expand Down Expand Up @@ -344,13 +345,24 @@ impl<'tcx> AutoTraitFinder<'tcx> {
_ => panic!("Unexpected error for '{:?}': {:?}", ty, result),
};

let normalized_preds = elaborate_predicates(
let elaborated_preds = elaborate_predicates(
tcx,
computed_preds.clone().chain(user_computed_preds.iter().cloned()),
)
.map(|o| o.predicate);
.map(|obligation| obligation.predicate);

// FIXME(generic_const_exprs):
// This deduplication is required only when generic_const_exprs is not active
// see #108397 for more information.
let mut seen_preds = PredicateSet::new(tcx);
let obctx = ObligationCtxt::new(infcx);
let deduped_preds = elaborated_preds
.into_iter()
.map(|pred| obctx.normalize(&dummy_cause, param_env, pred))
.filter(|normalized_pred| seen_preds.insert(*normalized_pred));

new_env = ty::ParamEnv::new(
tcx.mk_predicates_from_iter(normalized_preds),
tcx.mk_predicates_from_iter(deduped_preds),
param_env.reveal(),
param_env.constness(),
);
Expand Down
18 changes: 18 additions & 0 deletions tests/rustdoc-ui/issue_107715.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// check-pass
#![crate_type = "lib"]

const N: usize = 1;

trait Supertrait<V> {
type AssociatedType;
}

trait Subtrait: Supertrait<[u8; N]> {}

struct MapType<K: Supertrait<V>, V> {
map: K::AssociatedType,
}

struct Container<S: Subtrait> {
_x: MapType<S, [u8; N]>,
}

0 comments on commit 108cad1

Please sign in to comment.