diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 684e60304eb..d61029a2d2d 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -474,14 +474,26 @@ pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, cx.commit_if_ok(|_| cx.eq_types(a_is_expected, origin, a, b)) } -pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, +pub fn mk_eq_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a_is_expected: bool, origin: TypeOrigin, - a: ty::PolyTraitRef<'tcx>, - b: ty::PolyTraitRef<'tcx>) + a: ty::TraitRef<'tcx>, + b: ty::TraitRef<'tcx>) -> UnitResult<'tcx> { - debug!("mk_sub_trait_refs({:?} <: {:?})", + debug!("mk_eq_trait_refs({:?} <: {:?})", + a, b); + cx.commit_if_ok(|_| cx.eq_trait_refs(a_is_expected, origin, a.clone(), b.clone())) +} + +pub fn mk_sub_poly_trait_refs<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, + a_is_expected: bool, + origin: TypeOrigin, + a: ty::PolyTraitRef<'tcx>, + b: ty::PolyTraitRef<'tcx>) + -> UnitResult<'tcx> +{ + debug!("mk_sub_poly_trait_refs({:?} <: {:?})", a, b); cx.commit_if_ok(|_| cx.sub_poly_trait_refs(a_is_expected, origin, a.clone(), b.clone())) } @@ -857,14 +869,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }) } - pub fn sub_trait_refs(&self, + pub fn eq_trait_refs(&self, a_is_expected: bool, origin: TypeOrigin, a: ty::TraitRef<'tcx>, b: ty::TraitRef<'tcx>) -> UnitResult<'tcx> { - debug!("sub_trait_refs({:?} <: {:?})", + debug!("eq_trait_refs({:?} <: {:?})", a, b); self.commit_if_ok(|_| { @@ -872,7 +884,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { origin: origin, values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone())) }; - self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ()) + self.equate(a_is_expected, trace).relate(&a, &b).map(|_| ()) }) } diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index a3795a32afc..bf950ff6dc9 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -20,7 +20,7 @@ use super::util; use metadata::cstore::LOCAL_CRATE; use middle::def_id::DefId; use middle::subst::{Subst, Substs, TypeSpace}; -use middle::ty::{self, ToPolyTraitRef, Ty}; +use middle::ty::{self, Ty}; use middle::infer::{self, InferCtxt}; use syntax::codemap::{DUMMY_SP, Span}; @@ -41,12 +41,11 @@ pub fn overlapping_impls(infcx: &InferCtxt, let selcx = &mut SelectionContext::intercrate(infcx); infcx.probe(|_| { - overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id) + overlap(selcx, impl1_def_id, impl2_def_id) }) } -/// Can the types from impl `a` be used to satisfy impl `b`? -/// (Including all conditions) +/// Can both impl `a` and impl `b` be satisfied by a common type (including `where` clauses)? fn overlap(selcx: &mut SelectionContext, a_def_id: DefId, b_def_id: DefId) @@ -68,16 +67,16 @@ fn overlap(selcx: &mut SelectionContext, debug!("overlap: b_trait_ref={:?}", b_trait_ref); - // Does `a <: b` hold? If not, no overlap. - if let Err(_) = infer::mk_sub_poly_trait_refs(selcx.infcx(), - true, - infer::Misc(DUMMY_SP), - a_trait_ref.to_poly_trait_ref(), - b_trait_ref.to_poly_trait_ref()) { + // Do `a` and `b` unify? If not, no overlap. + if let Err(_) = infer::mk_eq_trait_refs(selcx.infcx(), + true, + infer::Misc(DUMMY_SP), + a_trait_ref, + b_trait_ref) { return false; } - debug!("overlap: subtraitref check succeeded"); + debug!("overlap: unification check succeeded"); // Are any of the obligations unsatisfiable? If so, no overlap. let infcx = selcx.infcx(); diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs index c1ff0f985cb..f49202eb6c8 100644 --- a/src/librustc/middle/traits/project.rs +++ b/src/librustc/middle/traits/project.rs @@ -902,10 +902,10 @@ fn confirm_param_env_candidate<'cx,'tcx>( obligation.predicate.item_name); let origin = infer::RelateOutputImplTypes(obligation.cause.span); - match infcx.sub_trait_refs(false, - origin, - obligation.predicate.trait_ref.clone(), - projection.projection_ty.trait_ref.clone()) { + match infcx.eq_trait_refs(false, + origin, + obligation.predicate.trait_ref.clone(), + projection.projection_ty.trait_ref.clone()) { Ok(()) => { } Err(e) => { selcx.tcx().sess.span_bug( diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index ba69632fde1..cd08c4feb8d 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -2695,11 +2695,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { skol_obligation_trait_ref); let origin = infer::RelateOutputImplTypes(obligation.cause.span); - if let Err(e) = self.infcx.sub_trait_refs(false, - origin, - impl_trait_ref.value.clone(), - skol_obligation_trait_ref) { - debug!("match_impl: failed sub_trait_refs due to `{}`", e); + if let Err(e) = self.infcx.eq_trait_refs(false, + origin, + impl_trait_ref.value.clone(), + skol_obligation_trait_ref) { + debug!("match_impl: failed eq_trait_refs due to `{}`", e); return Err(()); }