Skip to content

Commit

Permalink
Added some comments to lowering code.
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis authored and Alexander Regueiro committed Jun 5, 2019
1 parent a71d557 commit 0f4a5ca
Showing 1 changed file with 50 additions and 3 deletions.
53 changes: 50 additions & 3 deletions src/librustc/hir/lowering.rs
Expand Up @@ -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;
Expand Down

0 comments on commit 0f4a5ca

Please sign in to comment.