From 45f4bf112a422fe62b9152ecf557f8550eb9c7ca Mon Sep 17 00:00:00 2001 From: Aaron Turon Date: Wed, 30 Dec 2015 13:47:23 -0800 Subject: [PATCH] Refactor `impl_trait_ref_and_oblig`, making it generally available as a utility --- src/librustc/middle/traits/coherence.rs | 4 +-- src/librustc/middle/traits/util.rs | 36 +++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 6005d36ff4eb..454698c1b3a8 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -10,8 +10,8 @@ //! See `README.md` for high-level documentation -use super::{SelectionContext}; -use super::{Obligation, ObligationCause}; +use super::{SelectionContext, Obligation, ObligationCause}; +use super::util; use middle::cstore::LOCAL_CRATE; use middle::def_id::DefId; diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs index 08d504143c7c..3289d5877829 100644 --- a/src/librustc/middle/traits/util.rs +++ b/src/librustc/middle/traits/util.rs @@ -10,13 +10,13 @@ use middle::def_id::DefId; use middle::infer::InferCtxt; -use middle::subst::Substs; +use middle::subst::{Subst, Substs}; use middle::ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; use syntax::codemap::Span; use util::common::ErrorReported; use util::nodemap::FnvHashSet; -use super::{Obligation, ObligationCause, PredicateObligation}; +use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext, Normalized}; struct PredicateSet<'a,'tcx:'a> { tcx: &'a TyCtxt<'tcx>, @@ -299,6 +299,38 @@ impl<'tcx,I:Iterator>> Iterator for FilterToTraits { // Other /////////////////////////////////////////////////////////////////////////// +/// Instantiate all bound parameters of the impl with the given substs, +/// returning the resulting trait ref and all obligations that arise. +/// The obligations are closed under normalization. +pub fn impl_trait_ref_and_oblig<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, + impl_def_id: DefId, + impl_substs: &Substs<'tcx>) + -> (ty::TraitRef<'tcx>, + Vec>) +{ + let impl_trait_ref = + selcx.tcx().impl_trait_ref(impl_def_id).unwrap(); + let impl_trait_ref = + impl_trait_ref.subst(selcx.tcx(), impl_substs); + let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } = + super::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref); + + let predicates = selcx.tcx().lookup_predicates(impl_def_id); + let predicates = predicates.instantiate(selcx.tcx(), impl_substs); + let Normalized { value: predicates, obligations: normalization_obligations2 } = + super::normalize(selcx, ObligationCause::dummy(), &predicates); + let impl_obligations = + predicates_for_generics(ObligationCause::dummy(), 0, &predicates); + + let impl_obligations: Vec<_> = + impl_obligations.into_iter() + .chain(normalization_obligations1) + .chain(normalization_obligations2) + .collect(); + + (impl_trait_ref, impl_obligations) +} + // determine the `self` type, using fresh variables for all variables // declared on the impl declaration e.g., `impl for Box<[(A,B)]>` // would return ($0, $1) where $0 and $1 are freshly instantiated type