Skip to content

Commit

Permalink
Introduce DeepRejectCtxt::substs_refs_may_unify.
Browse files Browse the repository at this point in the history
It factors out a repeated code pattern.
  • Loading branch information
nnethercote committed Mar 28, 2023
1 parent 478cbb4 commit 47225e8
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 17 deletions.
15 changes: 11 additions & 4 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::mir::Mutability;
use crate::ty::subst::GenericArgKind;
use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt};
use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitableExt};
use rustc_hir::def_id::DefId;
use std::fmt::Debug;
use std::hash::Hash;
Expand Down Expand Up @@ -188,6 +188,15 @@ pub struct DeepRejectCtxt {
}

impl DeepRejectCtxt {
pub fn substs_refs_may_unify<'tcx>(
self,
obligation_substs: SubstsRef<'tcx>,
impl_substs: SubstsRef<'tcx>,
) -> bool {
iter::zip(obligation_substs, impl_substs)
.all(|(obl, imp)| self.generic_args_may_unify(obl, imp))
}

pub fn generic_args_may_unify<'tcx>(
self,
obligation_arg: ty::GenericArg<'tcx>,
Expand Down Expand Up @@ -258,9 +267,7 @@ impl DeepRejectCtxt {
},
ty::Adt(obl_def, obl_substs) => match k {
&ty::Adt(impl_def, impl_substs) => {
obl_def == impl_def
&& iter::zip(obl_substs, impl_substs)
.all(|(obl, imp)| self.generic_args_may_unify(obl, imp))
obl_def == impl_def && self.substs_refs_may_unify(obl_substs, impl_substs)
}
_ => false,
},
Expand Down
5 changes: 1 addition & 4 deletions compiler/rustc_trait_selection/src/solve/project_goals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use rustc_middle::ty::ProjectionPredicate;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
use rustc_span::{sym, DUMMY_SP};
use std::iter;

impl<'tcx> EvalCtxt<'_, 'tcx> {
#[instrument(level = "debug", skip(self), ret)]
Expand Down Expand Up @@ -144,9 +143,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx);
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
if iter::zip(goal_trait_ref.substs, impl_trait_ref.skip_binder().substs)
.any(|(goal, imp)| !drcx.generic_args_may_unify(goal, imp))
{
if !drcx.substs_refs_may_unify(goal_trait_ref.substs, impl_trait_ref.skip_binder().substs) {
return Err(NoSolution);
}

Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_trait_selection/src/solve/trait_goals.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
use std::iter;

use super::{assembly, EvalCtxt, SolverMode};
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
Expand Down Expand Up @@ -41,9 +39,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {

let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
if iter::zip(goal.predicate.trait_ref.substs, impl_trait_ref.skip_binder().substs)
.any(|(goal, imp)| !drcx.generic_args_may_unify(goal, imp))
{
if !drcx.substs_refs_may_unify(
goal.predicate.trait_ref.substs,
impl_trait_ref.skip_binder().substs,
) {
return Err(NoSolution);
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ pub fn overlapping_impls(
let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
let may_overlap = match (impl1_ref, impl2_ref) {
(Some(a), Some(b)) => iter::zip(a.skip_binder().substs, b.skip_binder().substs)
.all(|(arg1, arg2)| drcx.generic_args_may_unify(arg1, arg2)),
(Some(a), Some(b)) => {
drcx.substs_refs_may_unify(a.skip_binder().substs, b.skip_binder().substs)
}
(None, None) => {
let self_ty1 = tcx.type_of(impl1_def_id).skip_binder();
let self_ty2 = tcx.type_of(impl2_def_id).skip_binder();
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2542,8 +2542,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// substitution if we find that any of the input types, when
// simplified, do not match.
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
iter::zip(obligation.predicate.skip_binder().trait_ref.substs, impl_trait_ref.substs)
.any(|(obl, imp)| !drcx.generic_args_may_unify(obl, imp))
!drcx.substs_refs_may_unify(
obligation.predicate.skip_binder().trait_ref.substs,
impl_trait_ref.substs,
)
}

/// Normalize `where_clause_trait_ref` and try to match it against
Expand Down

0 comments on commit 47225e8

Please sign in to comment.