summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/auto_trait.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/auto_trait.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs100
1 files changed, 54 insertions, 46 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index ed34ab95a..8e04da4f9 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -10,9 +10,9 @@ use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable;
-use rustc_middle::ty::{PolyTraitRef, Region, RegionVid};
+use rustc_middle::ty::{ImplPolarity, Region, RegionVid};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use std::collections::hash_map::Entry;
use std::collections::VecDeque;
@@ -27,8 +27,8 @@ pub enum RegionTarget<'tcx> {
#[derive(Default, Debug, Clone)]
pub struct RegionDeps<'tcx> {
- larger: FxHashSet<RegionTarget<'tcx>>,
- smaller: FxHashSet<RegionTarget<'tcx>>,
+ larger: FxIndexSet<RegionTarget<'tcx>>,
+ smaller: FxIndexSet<RegionTarget<'tcx>>,
}
pub enum AutoTraitResult<A> {
@@ -86,18 +86,25 @@ impl<'tcx> AutoTraitFinder<'tcx> {
) -> AutoTraitResult<A> {
let tcx = self.tcx;
- let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) };
-
- let trait_pred = ty::Binder::dummy(trait_ref);
+ let trait_ref = tcx.mk_trait_ref(trait_did, [ty]);
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
- for f in [
- PolyTraitRef::to_poly_trait_predicate,
- PolyTraitRef::to_poly_trait_predicate_negative_polarity,
- ] {
- let result =
- selcx.select(&Obligation::new(ObligationCause::dummy(), orig_env, f(&trait_pred)));
+ for polarity in [true, false] {
+ let result = selcx.select(&Obligation::new(
+ tcx,
+ ObligationCause::dummy(),
+ orig_env,
+ ty::Binder::dummy(ty::TraitPredicate {
+ trait_ref,
+ constness: ty::BoundConstness::NotConst,
+ polarity: if polarity {
+ ImplPolarity::Positive
+ } else {
+ ImplPolarity::Negative
+ },
+ }),
+ ));
if let Ok(Some(ImplSource::UserDefined(_))) = result {
debug!(
"find_auto_trait_generics({:?}): \
@@ -256,17 +263,15 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let mut already_visited = FxHashSet::default();
let mut predicates = VecDeque::new();
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
- trait_ref: ty::TraitRef {
- def_id: trait_did,
- substs: infcx.tcx.mk_substs_trait(ty, &[]),
- },
+ trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]),
+
constness: ty::BoundConstness::NotConst,
// Auto traits are positive
polarity: ty::ImplPolarity::Positive,
}));
let computed_preds = param_env.caller_bounds().iter();
- let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect();
+ let mut user_computed_preds: FxIndexSet<_> = user_env.caller_bounds().iter().collect();
let mut new_env = param_env;
let dummy_cause = ObligationCause::dummy();
@@ -280,8 +285,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// Call `infcx.resolve_vars_if_possible` to see if we can
// get rid of any inference variables.
- let obligation =
- infcx.resolve_vars_if_possible(Obligation::new(dummy_cause.clone(), new_env, pred));
+ let obligation = infcx.resolve_vars_if_possible(Obligation::new(
+ tcx,
+ dummy_cause.clone(),
+ new_env,
+ pred,
+ ));
let result = select.select(&obligation);
match result {
@@ -389,13 +398,15 @@ impl<'tcx> AutoTraitFinder<'tcx> {
/// not just one specific lifetime (e.g., `'static`).
fn add_user_pred(
&self,
- user_computed_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
+ user_computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>,
new_pred: ty::Predicate<'tcx>,
) {
let mut should_add_new = true;
user_computed_preds.retain(|&old_pred| {
- if let (ty::PredicateKind::Trait(new_trait), ty::PredicateKind::Trait(old_trait)) =
- (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
+ if let (
+ ty::PredicateKind::Clause(ty::Clause::Trait(new_trait)),
+ ty::PredicateKind::Clause(ty::Clause::Trait(old_trait)),
+ ) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
{
if new_trait.def_id() == old_trait.def_id() {
let new_substs = new_trait.trait_ref.substs;
@@ -585,20 +596,20 @@ impl<'tcx> AutoTraitFinder<'tcx> {
&self,
ty: Ty<'_>,
nested: impl Iterator<Item = Obligation<'tcx, ty::Predicate<'tcx>>>,
- computed_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
+ computed_preds: &mut FxIndexSet<ty::Predicate<'tcx>>,
fresh_preds: &mut FxHashSet<ty::Predicate<'tcx>>,
predicates: &mut VecDeque<ty::PolyTraitPredicate<'tcx>>,
- select: &mut SelectionContext<'_, 'tcx>,
+ selcx: &mut SelectionContext<'_, 'tcx>,
only_projections: bool,
) -> bool {
let dummy_cause = ObligationCause::dummy();
for obligation in nested {
let is_new_pred =
- fresh_preds.insert(self.clean_pred(select.infcx(), obligation.predicate));
+ fresh_preds.insert(self.clean_pred(selcx.infcx, obligation.predicate));
// Resolve any inference variables that we can, to help selection succeed
- let predicate = select.infcx().resolve_vars_if_possible(obligation.predicate);
+ let predicate = selcx.infcx.resolve_vars_if_possible(obligation.predicate);
// We only add a predicate as a user-displayable bound if
// it involves a generic parameter, and doesn't contain
@@ -615,14 +626,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(p) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(p)) => {
// Add this to `predicates` so that we end up calling `select`
// with it. If this predicate ends up being unimplemented,
// then `evaluate_predicates` will handle adding it the `ParamEnv`
// if possible.
predicates.push_back(bound_predicate.rebind(p));
}
- ty::PredicateKind::Projection(p) => {
+ ty::PredicateKind::Clause(ty::Clause::Projection(p)) => {
let p = bound_predicate.rebind(p);
debug!(
"evaluate_nested_obligations: examining projection predicate {:?}",
@@ -706,7 +717,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// and turn them into an explicit negative impl for our type.
debug!("Projecting and unifying projection predicate {:?}", predicate);
- match project::poly_project_and_unify_type(select, &obligation.with(p)) {
+ match project::poly_project_and_unify_type(selcx, &obligation.with(self.tcx, p))
+ {
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
debug!(
"evaluate_nested_obligations: Unable to unify predicate \
@@ -731,7 +743,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
computed_preds,
fresh_preds,
predicates,
- select,
+ selcx,
only_projections,
) {
return false;
@@ -752,25 +764,25 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
}
}
- ty::PredicateKind::RegionOutlives(binder) => {
+ ty::PredicateKind::Clause(ty::Clause::RegionOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
- select.infcx().region_outlives_predicate(&dummy_cause, binder)
+ selcx.infcx.region_outlives_predicate(&dummy_cause, binder)
}
- ty::PredicateKind::TypeOutlives(binder) => {
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
match (
binder.no_bound_vars(),
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
) {
(None, Some(t_a)) => {
- select.infcx().register_region_obligation_with_cause(
+ selcx.infcx.register_region_obligation_with_cause(
t_a,
- select.infcx().tcx.lifetimes.re_static,
+ selcx.infcx.tcx.lifetimes.re_static,
&dummy_cause,
);
}
(Some(ty::OutlivesPredicate(t_a, r_b)), _) => {
- select.infcx().register_region_obligation_with_cause(
+ selcx.infcx.register_region_obligation_with_cause(
t_a,
r_b,
&dummy_cause,
@@ -782,14 +794,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
ty::PredicateKind::ConstEquate(c1, c2) => {
let evaluate = |c: ty::Const<'tcx>| {
if let ty::ConstKind::Unevaluated(unevaluated) = c.kind() {
- match select.infcx().const_eval_resolve(
+ match selcx.infcx.const_eval_resolve(
obligation.param_env,
unevaluated,
Some(obligation.cause.span),
) {
- Ok(Some(valtree)) => {
- Ok(ty::Const::from_value(select.tcx(), valtree, c.ty()))
- }
+ Ok(Some(valtree)) => Ok(selcx.tcx().mk_const(valtree, c.ty())),
Ok(None) => {
let tcx = self.tcx;
let def_id = unevaluated.def.did;
@@ -809,10 +819,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
match (evaluate(c1), evaluate(c2)) {
(Ok(c1), Ok(c2)) => {
- match select
- .infcx()
- .at(&obligation.cause, obligation.param_env)
- .eq(c1, c2)
+ match selcx.infcx.at(&obligation.cause, obligation.param_env).eq(c1, c2)
{
Ok(_) => (),
Err(_) => return false,
@@ -832,6 +839,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
+ ty::PredicateKind::Ambiguous => return false,
};
}
true
@@ -846,7 +854,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
}
-// Replaces all ReVars in a type with ty::Region's, using the provided map
+/// Replaces all ReVars in a type with ty::Region's, using the provided map
pub struct RegionReplacer<'a, 'tcx> {
vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
tcx: TyCtxt<'tcx>,