about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAaron Turon <aturon@mozilla.com>2016-02-17 09:04:26 -0800
committerAaron Turon <aturon@mozilla.com>2016-03-14 15:04:40 -0700
commit8f20cbf03088c8fa89a343de9e97e7608cd701b6 (patch)
treeb21999c61f868698a9475a9b13962bc2b752b130
parent940adda2aef63ac820cf331ebb7f6f0699c12045 (diff)
downloadrust-8f20cbf03088c8fa89a343de9e97e7608cd701b6.tar.gz
rust-8f20cbf03088c8fa89a343de9e97e7608cd701b6.zip
Add more commentary for subst translation
-rw-r--r--src/librustc/middle/traits/specialize/mod.rs32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/librustc/middle/traits/specialize/mod.rs b/src/librustc/middle/traits/specialize/mod.rs
index 2dc4926736e..93505987633 100644
--- a/src/librustc/middle/traits/specialize/mod.rs
+++ b/src/librustc/middle/traits/specialize/mod.rs
@@ -64,9 +64,35 @@ pub fn translate_substs<'tcx>(tcx: &ty::ctxt<'tcx>,
 /// When we have selected one impl, but are actually using item definitions from
 /// a parent impl providing a default, we need a way to translate between the
 /// type parameters of the two impls. Here the `source_impl` is the one we've
-/// selected, and `source_substs` is a substitution of its generics (and possibly
-/// some relevant `FnSpace` variables as well). And `target_impl` is the impl
-/// we're actually going to get the definition from.
+/// selected, and `source_substs` is a substitution of its generics (and
+/// possibly some relevant `FnSpace` variables as well). And `target_impl` is
+/// the impl we're actually going to get the definition from. The resulting
+/// substitution will map from `target_impl`'s generics to `source_impl`'s
+/// generics as instantiated by `source_subst`.
+///
+/// For example, consider the following scenario:
+///
+/// ```rust
+/// trait Foo { ... }
+/// impl<T, U> Foo for (T, U) { ... }  // target impl
+/// impl<V> Foo for (V, V) { ... }     // source impl
+/// ```
+///
+/// Suppose we have selected "source impl" with `V` instantiated with `u32`.
+/// This function will produce a substitution with `T` and `U` both mapping to `u32`.
+///
+/// Where clauses add some trickiness here, because they can be used to "define"
+/// an argument indirectly:
+///
+/// ```rust
+/// impl<'a, I, T: 'a> Iterator for Cloned<I>
+///    where I: Iterator<Item=&'a T>, T: Clone
+/// ```
+///
+/// In a case like this, the substitution for `T` is determined indirectly,
+/// through associated type projection. We deal with such cases by using
+/// *fulfillment* to relate the two impls, requiring that all projections are
+/// resolved.
 fn translate_substs_between_impls<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         source_impl: DefId,
                                         source_substs: Substs<'tcx>,