diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index b7120ab31f0..f3682f8d35d 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -126,7 +126,7 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>, } pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - trait_ref: &ty::TraitRef<'tcx>) -> bool + trait_ref: ty::TraitRef<'tcx>) -> bool { debug!("trait_ref_is_knowable(trait_ref={:?})", trait_ref); @@ -140,10 +140,7 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, // if the trait is not marked fundamental, then it's always possible that // an ancestor crate will impl this in the future, if they haven't // already - if - trait_ref.def_id.krate != LOCAL_CRATE && - !tcx.has_attr(trait_ref.def_id, "fundamental") - { + if !trait_ref_is_local_or_fundamental(tcx, trait_ref) { debug!("trait_ref_is_knowable: trait is neither local nor fundamental"); return false; } @@ -157,6 +154,12 @@ pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, orphan_check_trait_ref(tcx, trait_ref, InferIsLocal(true)).is_err() } +pub fn trait_ref_is_local_or_fundamental<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + trait_ref: ty::TraitRef<'tcx>) + -> bool { + trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, "fundamental") +} + pub enum OrphanCheckErr<'tcx> { NoLocalInputType, UncoveredTy(Ty<'tcx>), @@ -186,11 +189,11 @@ pub fn orphan_check<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, return Ok(()); } - orphan_check_trait_ref(tcx, &trait_ref, InferIsLocal(false)) + orphan_check_trait_ref(tcx, trait_ref, InferIsLocal(false)) } fn orphan_check_trait_ref<'tcx>(tcx: TyCtxt, - trait_ref: &ty::TraitRef<'tcx>, + trait_ref: ty::TraitRef<'tcx>, infer_is_local: InferIsLocal) -> Result<(), OrphanCheckErr<'tcx>> { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 07b64e3c221..cd259fc2528 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -31,7 +31,7 @@ use super::{VtableImplData, VtableObjectData, VtableBuiltinData, VtableGenerator use super::util; use dep_graph::{DepNodeIndex, DepKind}; -use hir::def_id::{DefId, LOCAL_CRATE}; +use hir::def_id::DefId; use infer; use infer::{InferCtxt, InferOk, TypeFreshener}; use ty::subst::{Kind, Subst, Substs}; @@ -1075,9 +1075,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } else { None }; - let cause = if - trait_ref.def_id.krate != LOCAL_CRATE && - !self.tcx().has_attr(trait_ref.def_id, "fundamental") { + let cause = if !coherence::trait_ref_is_local_or_fundamental(self.tcx(), + trait_ref) { IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } } else { IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } @@ -1205,7 +1204,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { // ok to skip binder because of the nature of the // trait-ref-is-knowable check, which does not care about // bound regions - let trait_ref = &predicate.skip_binder().trait_ref; + let trait_ref = predicate.skip_binder().trait_ref; coherence::trait_ref_is_knowable(self.tcx(), trait_ref) }