diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2019-05-08 15:56:39 -0400 |
|---|---|---|
| committer | Alexander Regueiro <alexreg@me.com> | 2019-06-05 21:09:27 +0100 |
| commit | 0f4a5ca33ceb22edd4f2cd12a03806331a2883ed (patch) | |
| tree | 2de98a1aff550ccef02b597b2717ca24a493df0b | |
| parent | a71d55701e303514f936b862ae5cf0c410d2a785 (diff) | |
| download | rust-0f4a5ca33ceb22edd4f2cd12a03806331a2883ed.tar.gz rust-0f4a5ca33ceb22edd4f2cd12a03806331a2883ed.zip | |
Added some comments to lowering code.
| -rw-r--r-- | src/librustc/hir/lowering.rs | 53 |
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; |
