about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2019-05-08 15:56:39 -0400
committerAlexander Regueiro <alexreg@me.com>2019-06-05 21:09:27 +0100
commit0f4a5ca33ceb22edd4f2cd12a03806331a2883ed (patch)
tree2de98a1aff550ccef02b597b2717ca24a493df0b
parenta71d55701e303514f936b862ae5cf0c410d2a785 (diff)
downloadrust-0f4a5ca33ceb22edd4f2cd12a03806331a2883ed.tar.gz
rust-0f4a5ca33ceb22edd4f2cd12a03806331a2883ed.zip
Added some comments to lowering code.
-rw-r--r--src/librustc/hir/lowering.rs53
1 files changed, 50 insertions, 3 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index a49744aa523..06f9128cd22 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -1361,26 +1361,73 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
+    /// Given an associated type constraint like one of these:
+    ///
+    /// ```
+    /// T: Iterator<Item: Debug>
+    ///             ^^^^^^^^^^^
+    /// T: Iterator<Item = Debug>
+    ///             ^^^^^^^^^^^^
+    /// ```
+    ///
+    /// returns a `hir::TypeBinding` representing `Item`.
     fn lower_assoc_ty_constraint(&mut self,
                                  c: &AssocTyConstraint,
                                  itctx: ImplTraitContext<'_>)
                                  -> hir::TypeBinding {
         debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx);
 
+        // Convert to a type representing the `T::Item` value.
         let ty = match c.kind {
             AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx),
             AssocTyConstraintKind::Bound { ref bounds } => {
-                let (existential_desugaring, itctx) = match itctx {
+                // Piggy-back on the impl trait context to figure out
+                // the correct behavior.
+                let (desugar_to_impl_trait, itctx) = match itctx {
+                    // We are in the return position:
+                    //
+                    // fn foo() -> impl Iterator<Item: Debug>
+                    //
+                    // so desugar to
+                    //
+                    // fn foo() -> impl Iterator<Item = impl Debug>
                     ImplTraitContext::Existential(_) => (true, itctx),
+
+                    // We are in the argument position, but within a dyn type:
+                    //
+                    // fn foo(x: dyn Iterator<Item: Debug>)
+                    //
+                    // so desugar to
+                    //
+                    // fn foo(x: dyn Iterator<Item = impl Debug>)
                     ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx),
+
+                    // In `type Foo = dyn Iterator<Item: Debug>` we
+                    // desugar to `type Foo = dyn Iterator<Item = impl
+                    // Debug>` but we have to override the "impl trait
+                    // context" to permit `impl Debug` in this
+                    // position (it desugars then to an existential
+                    // type).
+                    //
                     // FIXME: this is only needed until `impl Trait` is allowed in type aliases.
                     ImplTraitContext::Disallowed(_) if self.is_in_dyn_type =>
                         (true, ImplTraitContext::Existential(None)),
+
+                    // We are in the argument position, but not within a dyn type:
+                    //
+                    // fn foo(x: impl Iterator<Item: Debug>)
+                    //
+                    // so we leave it as is and this gets expanded in
+                    // astconv to a bound like `<T as Iterator>::Item:
+                    // Debug` where `T` is the type parameter for the
+                    // `impl Iterator`.
                     _ => (false, itctx),
                 };
 
-                if existential_desugaring {
-                    // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`.
+                if desugar_to_impl_trait {
+                    // Desugar `AssocTy: Bounds` into `AssocTy = impl
+                    // Bounds`. We do this by constructing the HIR
+                    // for "impl bounds" and then lowering that.
 
                     let impl_trait_node_id = self.sess.next_node_id();
                     let parent_def_index = self.current_hir_id_owner.last().unwrap().0;