Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Addressed points raised in review.
  • Loading branch information
nikomatsakis authored and Alexander Regueiro committed Jun 5, 2019
1 parent 5bf5994 commit f472cd9
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 69 deletions.
12 changes: 8 additions & 4 deletions src/librustc/hir/intravisit.rs
Expand Up @@ -626,9 +626,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
TyKind::CVarArgs(ref lt) => {
visitor.visit_lifetime(lt)
}
TyKind::AssocTyExistential(ref bounds) => {
walk_list!(visitor, visit_param_bound, bounds);
}
TyKind::Infer | TyKind::Err => {}
}
}
Expand Down Expand Up @@ -677,7 +674,14 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V,
type_binding: &'v TypeBinding) {
visitor.visit_id(type_binding.hir_id);
visitor.visit_ident(type_binding.ident);
visitor.visit_ty(&type_binding.ty);
match type_binding.kind {
TypeBindingKind::Equality { ref ty } => {
visitor.visit_ty(ty);
}
TypeBindingKind::Constraint { ref bounds } => {
walk_list!(visitor, visit_param_bound, bounds);
}
}
}

pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
Expand Down
52 changes: 31 additions & 21 deletions src/librustc/hir/lowering.rs
Expand Up @@ -1377,9 +1377,10 @@ impl<'a> LoweringContext<'a> {
-> 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),
let kind = match c.kind {
AssocTyConstraintKind::Equality { ref ty } => hir::TypeBindingKind::Equality {
ty: self.lower_ty(ty, itctx)
},
AssocTyConstraintKind::Bound { ref bounds } => {
// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let (desugar_to_impl_trait, itctx) = match itctx {
Expand Down Expand Up @@ -1422,7 +1423,7 @@ impl<'a> LoweringContext<'a> {

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.
// 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 All @@ -1436,35 +1437,35 @@ impl<'a> LoweringContext<'a> {
);

self.with_dyn_type_scope(false, |this| {
this.lower_ty(
let ty = this.lower_ty(
&Ty {
id: this.sess.next_node_id(),
node: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
span: DUMMY_SP,
},
itctx,
)
);

hir::TypeBindingKind::Equality {
ty
}
})
} else {
// Desugar `AssocTy: Bounds` into `AssocTy = ∃ T (T: Bounds)`, where the
// "false existential" later desugars into a trait predicate.

// Desugar `AssocTy: Bounds` into a type binding where the
// later desugars into a trait predicate.
let bounds = self.lower_param_bounds(bounds, itctx);

let id = self.sess.next_node_id();
P(hir::Ty {
hir_id: self.lower_node_id(id),
node: hir::TyKind::AssocTyExistential(bounds),
span: DUMMY_SP,
})
hir::TypeBindingKind::Constraint {
bounds
}
}
}
};

hir::TypeBinding {
hir_id: self.lower_node_id(c.id),
ident: c.ident,
ty,
kind,
span: c.span,
}
}
Expand Down Expand Up @@ -2359,10 +2360,17 @@ impl<'a> LoweringContext<'a> {
hir::TypeBinding {
hir_id: this.next_id(),
ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
ty: output
.as_ref()
.map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed()))
.unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))),
kind: hir::TypeBindingKind::Equality {
ty: output
.as_ref()
.map(|ty| this.lower_ty(
&ty,
ImplTraitContext::disallowed()
))
.unwrap_or_else(||
P(mk_tup(this, hir::HirVec::new(), span))
),
},
span: output.as_ref().map_or(span, |ty| ty.span),
}
],
Expand Down Expand Up @@ -2666,7 +2674,9 @@ impl<'a> LoweringContext<'a> {
args: hir_vec![],
bindings: hir_vec![hir::TypeBinding {
ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME),
ty: output_ty,
kind: hir::TypeBindingKind::Equality {
ty: output_ty,
},
hir_id: self.next_id(),
span,
}],
Expand Down
53 changes: 43 additions & 10 deletions src/librustc/hir/mod.rs
Expand Up @@ -1780,7 +1780,7 @@ pub struct ImplItem {
pub span: Span,
}

/// Represents different contents within `impl`s.
/// Represents various kinds of content within an `impl`.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum ImplItemKind {
/// An associated constant of the given type, set to the constant result
Expand All @@ -1794,16 +1794,51 @@ pub enum ImplItemKind {
Existential(GenericBounds),
}

// Bind a type to an associated type (`A = Foo`).
/// Bind a type to an associated type (i.e., `A = Foo`).
///
/// Bindings like `A: Debug` are represented as a special type `A =
/// $::Debug` that is understood by the astconv code.
///
/// FIXME(alexreg) -- why have a separate type for the binding case,
/// wouldn't it be better to make the `ty` field an enum like:
///
/// ```
/// enum TypeBindingKind {
/// Equals(...),
/// Binding(...),
/// }
/// ```
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct TypeBinding {
pub hir_id: HirId,
#[stable_hasher(project(name))]
pub ident: Ident,
pub ty: P<Ty>,
pub kind: TypeBindingKind,
pub span: Span,
}

// Represents the two kinds of type bindings.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum TypeBindingKind {
/// E.g., `Foo<Bar: Send>`.
Constraint {
bounds: HirVec<GenericBound>,
},
/// E.g., `Foo<Bar = ()>`.
Equality {
ty: P<Ty>,
},
}

impl TypeBinding {
pub fn ty(&self) -> &Ty {
match self.kind {
TypeBindingKind::Equality { ref ty } => ty,
_ => bug!("expected equality type binding for parenthesized generic args"),
}
}
}

#[derive(Clone, RustcEncodable, RustcDecodable)]
pub struct Ty {
pub hir_id: HirId,
Expand Down Expand Up @@ -1898,8 +1933,6 @@ pub enum TyKind {
/// Placeholder for C-variadic arguments. We "spoof" the `VaList` created
/// from the variadic arguments. This type is only valid up to typeck.
CVarArgs(Lifetime),
/// The existential type (i.e., `impl Trait`) that constrains an associated type.
AssocTyExistential(HirVec<GenericBound>),
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
Expand Down Expand Up @@ -2236,18 +2269,18 @@ impl StructField {
}
}

/// Fields and constructor ids of enum variants and structs
/// Fields and constructor IDs of enum variants and structs.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
pub enum VariantData {
/// Struct variant.
/// A struct variant.
///
/// e.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
/// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`.
Struct(HirVec<StructField>, /* recovered */ bool),
/// Tuple variant.
/// A tuple variant.
///
/// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`.
Tuple(HirVec<StructField>, HirId),
/// Unit variant.
/// A unit variant.
///
/// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`.
Unit(HirId),
Expand Down
16 changes: 10 additions & 6 deletions src/librustc/hir/print.rs
Expand Up @@ -409,9 +409,6 @@ impl<'a> State<'a> {
hir::TyKind::CVarArgs(_) => {
self.s.word("...")?;
}
hir::TyKind::AssocTyExistential(ref bounds) => {
self.print_bounds(":", bounds)?;
}
}
self.end()
}
Expand Down Expand Up @@ -1648,7 +1645,7 @@ impl<'a> State<'a> {

self.space_if_not_bol()?;
self.word_space("->")?;
self.print_type(&generic_args.bindings[0].ty)?;
self.print_type(generic_args.bindings[0].ty())?;
} else {
let start = if colons_before_params { "::<" } else { "<" };
let empty = Cell::new(true);
Expand Down Expand Up @@ -1693,8 +1690,15 @@ impl<'a> State<'a> {
start_or_comma(self)?;
self.print_ident(binding.ident)?;
self.s.space()?;
self.word_space("=")?;
self.print_type(&binding.ty)?;
match generic_args.bindings[0].kind {
hir::TypeBindingKind::Equality { ref ty } => {
self.word_space("=")?;
self.print_type(ty)?;
}
hir::TypeBindingKind::Constraint { ref bounds } => {
self.print_bounds(":", bounds)?;
}
}
}

if !empty.get() {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/middle/resolve_lifetime.rs
Expand Up @@ -923,7 +923,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) {
let output = match fd.output {
hir::DefaultReturn(_) => None,
hir::Return(ref ty) => Some(ty),
hir::Return(ref ty) => Some(&**ty),
};
self.visit_fn_like_elision(&fd.inputs, output);
}
Expand Down Expand Up @@ -1884,7 +1884,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
if generic_args.parenthesized {
let was_in_fn_syntax = self.is_in_fn_syntax;
self.is_in_fn_syntax = true;
self.visit_fn_like_elision(generic_args.inputs(), Some(&generic_args.bindings[0].ty));
self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty()));
self.is_in_fn_syntax = was_in_fn_syntax;
return;
}
Expand Down Expand Up @@ -2020,7 +2020,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
}
}

fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tcx P<hir::Ty>>) {
fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tcx hir::Ty>) {
debug!("visit_fn_like_elision: enter");
let mut arg_elide = Elide::FreshLateAnon(Cell::new(0));
let arg_scope = Scope::Elision {
Expand Down
13 changes: 5 additions & 8 deletions src/librustc_typeck/astconv.rs
Expand Up @@ -710,10 +710,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
// back separately.
let assoc_bindings = generic_args.bindings.iter()
.map(|binding| {
let kind = if let hir::TyKind::AssocTyExistential(ref bounds) = binding.ty.node {
ConvertedBindingKind::Constraint(bounds.clone())
} else {
ConvertedBindingKind::Equality(self.ast_ty_to_ty(&binding.ty))
let kind = match binding.kind {
hir::TypeBindingKind::Equality { ref ty } =>
ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)),
hir::TypeBindingKind::Constraint { ref bounds } =>
ConvertedBindingKind::Constraint(bounds.clone()),
};
ConvertedBinding {
item_name: binding.ident,
Expand Down Expand Up @@ -2060,10 +2061,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
let region = self.ast_region_to_region(&lt, None);
tcx.type_of(va_list_did).subst(tcx, &[region.into()])
}
hir::TyKind::AssocTyExistential(..) => {
// Type is never actually used.
tcx.types.err
}
hir::TyKind::Err => {
tcx.types.err
}
Expand Down
4 changes: 3 additions & 1 deletion src/librustdoc/clean/auto_trait.rs
Expand Up @@ -626,7 +626,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
} => {
bindings.push(TypeBinding {
name: left_name.clone(),
ty: rhs,
kind: TypeBindingKind::Equality {
ty: rhs,
},
});
}
&mut GenericArgs::Parenthesized { .. } => {
Expand Down

0 comments on commit f472cd9

Please sign in to comment.