diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-09-01 10:21:12 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-09-20 20:08:00 +0300 |
| commit | 02c4155d2cf0b17f526a126ad1f9dca944d9e85d (patch) | |
| tree | f8585ad384145a44a05da1139eb15e9d9e2d7cea | |
| parent | ed593bed882e1ad6bc7ff6a3b3b6730176b5536b (diff) | |
| download | rust-02c4155d2cf0b17f526a126ad1f9dca944d9e85d.tar.gz rust-02c4155d2cf0b17f526a126ad1f9dca944d9e85d.zip | |
rustc: remove hir::fold.
| -rw-r--r-- | src/librustc/hir/fold.rs | 1131 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc_const_eval/check_match.rs | 105 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 120 | ||||
| -rw-r--r-- | src/librustdoc/core.rs | 36 | ||||
| -rw-r--r-- | src/librustdoc/test.rs | 9 |
6 files changed, 142 insertions, 1260 deletions
diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs deleted file mode 100644 index 57b5599bd1d..00000000000 --- a/src/librustc/hir/fold.rs +++ /dev/null @@ -1,1131 +0,0 @@ -// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or -// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A Folder represents an HIR->HIR fold; it accepts a HIR piece, -//! and returns a piece of the same type. - -use hir::*; -use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_}; -use syntax::ast::{NestedMetaItem, NestedMetaItemKind, MetaItem, MetaItemKind}; -use hir; -use syntax_pos::Span; -use syntax::codemap::{respan, Spanned}; -use syntax::ptr::P; -use syntax::parse::token::keywords; -use syntax::util::move_map::MoveMap; - -pub trait Folder : Sized { - // Any additions to this trait should happen in form - // of a call to a public `noop_*` function that only calls - // out to the folder again, not other `noop_*` functions. - // - // This is a necessary API workaround to the problem of not - // being able to call out to the super default method - // in an overridden default method. - - fn fold_crate(&mut self, c: Crate) -> Crate { - noop_fold_crate(c, self) - } - - fn fold_meta_items(&mut self, meta_items: HirVec<P<MetaItem>>) -> HirVec<P<MetaItem>> { - noop_fold_meta_items(meta_items, self) - } - - fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem { - noop_fold_meta_list_item(list_item, self) - } - - fn fold_meta_item(&mut self, meta_item: P<MetaItem>) -> P<MetaItem> { - noop_fold_meta_item(meta_item, self) - } - - fn fold_view_path(&mut self, view_path: P<ViewPath>) -> P<ViewPath> { - noop_fold_view_path(view_path, self) - } - - fn fold_foreign_item(&mut self, ni: ForeignItem) -> ForeignItem { - noop_fold_foreign_item(ni, self) - } - - fn fold_item(&mut self, i: Item) -> Item { - noop_fold_item(i, self) - } - - fn fold_item_id(&mut self, i: ItemId) -> ItemId { - noop_fold_item_id(i, self) - } - - fn fold_struct_field(&mut self, sf: StructField) -> StructField { - noop_fold_struct_field(sf, self) - } - - fn fold_item_underscore(&mut self, i: Item_) -> Item_ { - noop_fold_item_underscore(i, self) - } - - fn fold_trait_item(&mut self, i: TraitItem) -> TraitItem { - noop_fold_trait_item(i, self) - } - - fn fold_impl_item(&mut self, i: ImplItem) -> ImplItem { - noop_fold_impl_item(i, self) - } - - fn fold_fn_decl(&mut self, d: P<FnDecl>) -> P<FnDecl> { - noop_fold_fn_decl(d, self) - } - - fn fold_block(&mut self, b: P<Block>) -> P<Block> { - noop_fold_block(b, self) - } - - fn fold_stmt(&mut self, s: Stmt) -> Stmt { - noop_fold_stmt(s, self) - } - - fn fold_arm(&mut self, a: Arm) -> Arm { - noop_fold_arm(a, self) - } - - fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> { - noop_fold_pat(p, self) - } - - fn fold_decl(&mut self, d: P<Decl>) -> P<Decl> { - noop_fold_decl(d, self) - } - - fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> { - e.map(|e| noop_fold_expr(e, self)) - } - - fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> { - noop_fold_ty(t, self) - } - - fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding { - noop_fold_ty_binding(t, self) - } - - fn fold_mod(&mut self, m: Mod) -> Mod { - noop_fold_mod(m, self) - } - - fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod { - noop_fold_foreign_mod(nm, self) - } - - fn fold_variant(&mut self, v: Variant) -> Variant { - noop_fold_variant(v, self) - } - - fn fold_name(&mut self, n: Name) -> Name { - noop_fold_name(n, self) - } - - fn fold_usize(&mut self, i: usize) -> usize { - noop_fold_usize(i, self) - } - - fn fold_path(&mut self, p: Path) -> Path { - noop_fold_path(p, self) - } - - fn fold_path_parameters(&mut self, p: PathParameters) -> PathParameters { - noop_fold_path_parameters(p, self) - } - - fn fold_angle_bracketed_parameter_data(&mut self, - p: AngleBracketedParameterData) - -> AngleBracketedParameterData { - noop_fold_angle_bracketed_parameter_data(p, self) - } - - fn fold_parenthesized_parameter_data(&mut self, - p: ParenthesizedParameterData) - -> ParenthesizedParameterData { - noop_fold_parenthesized_parameter_data(p, self) - } - - fn fold_local(&mut self, l: P<Local>) -> P<Local> { - noop_fold_local(l, self) - } - - fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime { - noop_fold_lifetime(l, self) - } - - fn fold_lifetime_def(&mut self, l: LifetimeDef) -> LifetimeDef { - noop_fold_lifetime_def(l, self) - } - - fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> { - noop_fold_attribute(at, self) - } - - fn fold_arg(&mut self, a: Arg) -> Arg { - noop_fold_arg(a, self) - } - - fn fold_generics(&mut self, generics: Generics) -> Generics { - noop_fold_generics(generics, self) - } - - fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef { - noop_fold_trait_ref(p, self) - } - - fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef { - noop_fold_poly_trait_ref(p, self) - } - - fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData { - noop_fold_variant_data(vdata, self) - } - - fn fold_lifetimes(&mut self, lts: HirVec<Lifetime>) -> HirVec<Lifetime> { - noop_fold_lifetimes(lts, self) - } - - fn fold_lifetime_defs(&mut self, lts: HirVec<LifetimeDef>) -> HirVec<LifetimeDef> { - noop_fold_lifetime_defs(lts, self) - } - - fn fold_ty_param(&mut self, tp: TyParam) -> TyParam { - noop_fold_ty_param(tp, self) - } - - fn fold_ty_params(&mut self, tps: HirVec<TyParam>) -> HirVec<TyParam> { - noop_fold_ty_params(tps, self) - } - - fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> { - noop_fold_opt_lifetime(o_lt, self) - } - - fn fold_opt_bounds(&mut self, - b: Option<TyParamBounds>) - -> Option<TyParamBounds> { - noop_fold_opt_bounds(b, self) - } - - fn fold_bounds(&mut self, b: TyParamBounds) -> TyParamBounds { - noop_fold_bounds(b, self) - } - - fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound { - noop_fold_ty_param_bound(tpb, self) - } - - fn fold_mt(&mut self, mt: MutTy) -> MutTy { - noop_fold_mt(mt, self) - } - - fn fold_field(&mut self, field: Field) -> Field { - noop_fold_field(field, self) - } - - fn fold_where_clause(&mut self, where_clause: WhereClause) -> WhereClause { - noop_fold_where_clause(where_clause, self) - } - - fn fold_where_predicate(&mut self, where_predicate: WherePredicate) -> WherePredicate { - noop_fold_where_predicate(where_predicate, self) - } - - /// called for the `id` on each declaration - fn new_id(&mut self, i: NodeId) -> NodeId { - i - } - - /// called for ids that are references (e.g., ItemDef) - fn map_id(&mut self, i: NodeId) -> NodeId { - i - } - - fn new_span(&mut self, sp: Span) -> Span { - sp - } -} - -pub fn noop_fold_meta_items<T: Folder>(meta_items: HirVec<P<MetaItem>>, - fld: &mut T) - -> HirVec<P<MetaItem>> { - meta_items.move_map(|x| fld.fold_meta_item(x)) -} - -pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> { - view_path.map(|Spanned { node, span }| { - Spanned { - node: match node { - ViewPathSimple(name, path) => { - ViewPathSimple(name, fld.fold_path(path)) - } - ViewPathGlob(path) => { - ViewPathGlob(fld.fold_path(path)) - } - ViewPathList(path, path_list_idents) => { - ViewPathList(fld.fold_path(path), - path_list_idents.move_map(|path_list_ident| { - Spanned { - node: PathListItem_ { - id: fld.new_id(path_list_ident.node.id), - name: path_list_ident.node.name, - rename: path_list_ident.node.rename, - }, - span: fld.new_span(path_list_ident.span), - } - })) - } - }, - span: fld.new_span(span), - } - }) -} - -pub fn fold_attrs<T, F>(attrs: T, fld: &mut F) -> T - where T: Into<Vec<Attribute>> + From<Vec<Attribute>>, - F: Folder, -{ - attrs.into().move_flat_map(|x| fld.fold_attribute(x)).into() -} - -pub fn noop_fold_arm<T: Folder>(Arm { attrs, pats, guard, body }: Arm, fld: &mut T) -> Arm { - Arm { - attrs: fold_attrs(attrs, fld), - pats: pats.move_map(|x| fld.fold_pat(x)), - guard: guard.map(|x| fld.fold_expr(x)), - body: fld.fold_expr(body), - } -} - -pub fn noop_fold_decl<T: Folder>(d: P<Decl>, fld: &mut T) -> P<Decl> { - d.map(|Spanned { node, span }| { - match node { - DeclLocal(l) => Spanned { - node: DeclLocal(fld.fold_local(l)), - span: fld.new_span(span), - }, - DeclItem(it) => Spanned { - node: DeclItem(fld.fold_item_id(it)), - span: fld.new_span(span), - }, - } - }) -} - -pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding { - TypeBinding { - id: fld.new_id(b.id), - name: b.name, - ty: fld.fold_ty(b.ty), - span: fld.new_span(b.span), - } -} - -pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> { - t.map(|Ty { id, node, span }| { - Ty { - id: fld.new_id(id), - node: match node { - TyInfer => node, - TyVec(ty) => TyVec(fld.fold_ty(ty)), - TyPtr(mt) => TyPtr(fld.fold_mt(mt)), - TyRptr(region, mt) => { - TyRptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt)) - } - TyBareFn(f) => { - TyBareFn(f.map(|BareFnTy { lifetimes, unsafety, abi, decl }| { - BareFnTy { - lifetimes: fld.fold_lifetime_defs(lifetimes), - unsafety: unsafety, - abi: abi, - decl: fld.fold_fn_decl(decl), - } - })) - } - TyNever => node, - TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))), - TyPath(qself, path) => { - let qself = qself.map(|QSelf { ty, position }| { - QSelf { - ty: fld.fold_ty(ty), - position: position, - } - }); - TyPath(qself, fld.fold_path(path)) - } - TyObjectSum(ty, bounds) => { - TyObjectSum(fld.fold_ty(ty), fld.fold_bounds(bounds)) - } - TyFixedLengthVec(ty, e) => { - TyFixedLengthVec(fld.fold_ty(ty), fld.fold_expr(e)) - } - TyTypeof(expr) => { - TyTypeof(fld.fold_expr(expr)) - } - TyPolyTraitRef(bounds) => { - TyPolyTraitRef(bounds.move_map(|b| fld.fold_ty_param_bound(b))) - } - TyImplTrait(bounds) => { - TyImplTrait(bounds.move_map(|b| fld.fold_ty_param_bound(b))) - } - }, - span: fld.new_span(span), - } - }) -} - -pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod { abi, items }: ForeignMod, - fld: &mut T) - -> ForeignMod { - ForeignMod { - abi: abi, - items: items.move_map(|x| fld.fold_foreign_item(x)), - } -} - -pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant { - Spanned { - node: Variant_ { - name: v.node.name, - attrs: fold_attrs(v.node.attrs, fld), - data: fld.fold_variant_data(v.node.data), - disr_expr: v.node.disr_expr.map(|e| fld.fold_expr(e)), - }, - span: fld.new_span(v.span), - } -} - -pub fn noop_fold_name<T: Folder>(n: Name, _: &mut T) -> Name { - n -} - -pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize { - i -} - -pub fn noop_fold_path<T: Folder>(Path { global, segments, span }: Path, fld: &mut T) -> Path { - Path { - global: global, - segments: segments.move_map(|PathSegment { name, parameters }| { - PathSegment { - name: fld.fold_name(name), - parameters: fld.fold_path_parameters(parameters), - } - }), - span: fld.new_span(span), - } -} - -pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, - fld: &mut T) - -> PathParameters { - match path_parameters { - AngleBracketedParameters(data) => - AngleBracketedParameters(fld.fold_angle_bracketed_parameter_data(data)), - ParenthesizedParameters(data) => - ParenthesizedParameters(fld.fold_parenthesized_parameter_data(data)), - } -} - -pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData, - fld: &mut T) - -> AngleBracketedParameterData { - let AngleBracketedParameterData { lifetimes, types, bindings } = data; - AngleBracketedParameterData { - lifetimes: fld.fold_lifetimes(lifetimes), - types: types.move_map(|ty| fld.fold_ty(ty)), - bindings: bindings.move_map(|b| fld.fold_ty_binding(b)), - } -} - -pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData, - fld: &mut T) - -> ParenthesizedParameterData { - let ParenthesizedParameterData { inputs, output, span } = data; - ParenthesizedParameterData { - inputs: inputs.move_map(|ty| fld.fold_ty(ty)), - output: output.map(|ty| fld.fold_ty(ty)), - span: fld.new_span(span), - } -} - -pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { - l.map(|Local { id, pat, ty, init, span, attrs }| { - Local { - id: fld.new_id(id), - ty: ty.map(|t| fld.fold_ty(t)), - pat: fld.fold_pat(pat), - init: init.map(|e| fld.fold_expr(e)), - span: fld.new_span(span), - attrs: fold_attrs(attrs, fld), - } - }) -} - -pub fn noop_fold_attribute<T: Folder>(at: Attribute, fld: &mut T) -> Option<Attribute> { - let Spanned {node: Attribute_ {id, style, value, is_sugared_doc}, span} = at; - Some(Spanned { - node: Attribute_ { - id: id, - style: style, - value: fld.fold_meta_item(value), - is_sugared_doc: is_sugared_doc, - }, - span: fld.new_span(span), - }) -} - -pub fn noop_fold_meta_list_item<T: Folder>(li: NestedMetaItem, fld: &mut T) - -> NestedMetaItem { - Spanned { - node: match li.node { - NestedMetaItemKind::MetaItem(mi) => { - NestedMetaItemKind::MetaItem(fld.fold_meta_item(mi)) - }, - NestedMetaItemKind::Literal(lit) => NestedMetaItemKind::Literal(lit) - }, - span: fld.new_span(li.span) - } -} - -pub fn noop_fold_meta_item<T: Folder>(mi: P<MetaItem>, fld: &mut T) -> P<MetaItem> { - mi.map(|Spanned { node, span }| { - Spanned { - node: match node { - MetaItemKind::Word(id) => MetaItemKind::Word(id), - MetaItemKind::List(id, mis) => { - MetaItemKind::List(id, mis.move_map(|e| fld.fold_meta_list_item(e))) - } - MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s), - }, - span: fld.new_span(span), - } - }) -} - -pub fn noop_fold_arg<T: Folder>(Arg { id, pat, ty }: Arg, fld: &mut T) -> Arg { - Arg { - id: fld.new_id(id), - pat: fld.fold_pat(pat), - ty: fld.fold_ty(ty), - } -} - -pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> { - decl.map(|FnDecl { inputs, output, variadic }| { - FnDecl { - inputs: inputs.move_map(|x| fld.fold_arg(x)), - output: match output { - Return(ty) => Return(fld.fold_ty(ty)), - DefaultReturn(span) => DefaultReturn(span), - }, - variadic: variadic, - } - }) -} - -pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T) -> TyParamBound - where T: Folder -{ - match tpb { - TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier), - RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)), - } -} - -pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam { - let TyParam {id, name, bounds, default, span} = tp; - TyParam { - id: fld.new_id(id), - name: name, - bounds: fld.fold_bounds(bounds), - default: default.map(|x| fld.fold_ty(x)), - span: span, - } -} - -pub fn noop_fold_ty_params<T: Folder>(tps: HirVec<TyParam>, - fld: &mut T) - -> HirVec<TyParam> { - tps.move_map(|tp| fld.fold_ty_param(tp)) -} - -pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime { - Lifetime { - id: fld.new_id(l.id), - name: l.name, - span: fld.new_span(l.span), - } -} - -pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T) -> LifetimeDef { - LifetimeDef { - lifetime: fld.fold_lifetime(l.lifetime), - bounds: fld.fold_lifetimes(l.bounds), - } -} - -pub fn noop_fold_lifetimes<T: Folder>(lts: HirVec<Lifetime>, fld: &mut T) -> HirVec<Lifetime> { - lts.move_map(|l| fld.fold_lifetime(l)) -} - -pub fn noop_fold_lifetime_defs<T: Folder>(lts: HirVec<LifetimeDef>, - fld: &mut T) - -> HirVec<LifetimeDef> { - lts.move_map(|l| fld.fold_lifetime_def(l)) -} - -pub fn noop_fold_opt_lifetime<T: Folder>(o_lt: Option<Lifetime>, fld: &mut T) -> Option<Lifetime> { - o_lt.map(|lt| fld.fold_lifetime(lt)) -} - -pub fn noop_fold_generics<T: Folder>(Generics {ty_params, lifetimes, where_clause, span}: Generics, - fld: &mut T) - -> Generics { - Generics { - ty_params: fld.fold_ty_params(ty_params), - lifetimes: fld.fold_lifetime_defs(lifetimes), - where_clause: fld.fold_where_clause(where_clause), - span: fld.new_span(span), - } -} - -pub fn noop_fold_where_clause<T: Folder>(WhereClause { id, predicates }: WhereClause, - fld: &mut T) - -> WhereClause { - WhereClause { - id: fld.new_id(id), - predicates: predicates.move_map(|predicate| fld.fold_where_predicate(predicate)), - } -} - -pub fn noop_fold_where_predicate<T: Folder>(pred: WherePredicate, fld: &mut T) -> WherePredicate { - match pred { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{bound_lifetimes, - bounded_ty, - bounds, - span}) => { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: fld.fold_lifetime_defs(bound_lifetimes), - bounded_ty: fld.fold_ty(bounded_ty), - bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)), - span: fld.new_span(span), - }) - } - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{lifetime, - bounds, - span}) => { - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: fld.new_span(span), - lifetime: fld.fold_lifetime(lifetime), - bounds: bounds.move_map(|bound| fld.fold_lifetime(bound)), - }) - } - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{id, - path, - ty, - span}) => { - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - id: fld.new_id(id), - path: fld.fold_path(path), - ty: fld.fold_ty(ty), - span: fld.new_span(span), - }) - } - } -} - -pub fn noop_fold_variant_data<T: Folder>(vdata: VariantData, fld: &mut T) -> VariantData { - match vdata { - VariantData::Struct(fields, id) => { - VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)), - fld.new_id(id)) - } - VariantData::Tuple(fields, id) => { - VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)), - fld.new_id(id)) - } - VariantData::Unit(id) => VariantData::Unit(fld.new_id(id)), - } -} - -pub fn noop_fold_trait_ref<T: Folder>(p: TraitRef, fld: &mut T) -> TraitRef { - let id = fld.new_id(p.ref_id); - let TraitRef { - path, - ref_id: _, - } = p; - hir::TraitRef { - path: fld.fold_path(path), - ref_id: id, - } -} - -pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef { - hir::PolyTraitRef { - bound_lifetimes: fld.fold_lifetime_defs(p.bound_lifetimes), - trait_ref: fld.fold_trait_ref(p.trait_ref), - span: fld.new_span(p.span), - } -} - -pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField { - StructField { - span: fld.new_span(f.span), - id: fld.new_id(f.id), - name: f.name, - vis: f.vis, - ty: fld.fold_ty(f.ty), - attrs: fold_attrs(f.attrs, fld), - } -} - -pub fn noop_fold_field<T: Folder>(Field { name, expr, span }: Field, folder: &mut T) -> Field { - Field { - name: respan(folder.new_span(name.span), folder.fold_name(name.node)), - expr: folder.fold_expr(expr), - span: folder.new_span(span), - } -} - -pub fn noop_fold_mt<T: Folder>(MutTy { ty, mutbl }: MutTy, folder: &mut T) -> MutTy { - MutTy { - ty: folder.fold_ty(ty), - mutbl: mutbl, - } -} - -pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, - folder: &mut T) - -> Option<TyParamBounds> { - b.map(|bounds| folder.fold_bounds(bounds)) -} - -fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T) -> TyParamBounds { - bounds.move_map(|bound| folder.fold_ty_param_bound(bound)) -} - -pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> { - b.map(|Block { id, stmts, expr, rules, span }| { - Block { - id: folder.new_id(id), - stmts: stmts.move_map(|s| folder.fold_stmt(s)), - expr: expr.map(|x| folder.fold_expr(x)), - rules: rules, - span: folder.new_span(span), - } - }) -} - -pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ { - match i { - ItemExternCrate(string) => ItemExternCrate(string), - ItemUse(view_path) => { - ItemUse(folder.fold_view_path(view_path)) - } - ItemStatic(t, m, e) => { - ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e)) - } - ItemConst(t, e) => { - ItemConst(folder.fold_ty(t), folder.fold_expr(e)) - } - ItemFn(decl, unsafety, constness, abi, generics, body) => { - ItemFn(folder.fold_fn_decl(decl), - unsafety, - constness, - abi, - folder.fold_generics(generics), - folder.fold_block(body)) - } - ItemMod(m) => ItemMod(folder.fold_mod(m)), - ItemForeignMod(nm) => ItemForeignMod(folder.fold_foreign_mod(nm)), - ItemTy(t, generics) => { - ItemTy(folder.fold_ty(t), folder.fold_generics(generics)) - } - ItemEnum(enum_definition, generics) => { - ItemEnum(hir::EnumDef { - variants: enum_definition.variants.move_map(|x| folder.fold_variant(x)), - }, - folder.fold_generics(generics)) - } - ItemStruct(struct_def, generics) => { - let struct_def = folder.fold_variant_data(struct_def); - ItemStruct(struct_def, folder.fold_generics(generics)) - } - ItemUnion(struct_def, generics) => { - let struct_def = folder.fold_variant_data(struct_def); - ItemUnion(struct_def, folder.fold_generics(generics)) - } - ItemDefaultImpl(unsafety, ref trait_ref) => { - ItemDefaultImpl(unsafety, folder.fold_trait_ref((*trait_ref).clone())) - } - ItemImpl(unsafety, polarity, generics, ifce, ty, impl_items) => { - let new_impl_items = impl_items - .move_map(|item| folder.fold_impl_item(item)); - let ifce = match ifce { - None => None, - Some(ref trait_ref) => { - Some(folder.fold_trait_ref((*trait_ref).clone())) - } - }; - ItemImpl(unsafety, - polarity, - folder.fold_generics(generics), - ifce, - folder.fold_ty(ty), - new_impl_items) - } - ItemTrait(unsafety, generics, bounds, items) => { - let bounds = folder.fold_bounds(bounds); - let items = items.move_map(|item| folder.fold_trait_item(item)); - ItemTrait(unsafety, folder.fold_generics(generics), bounds, items) - } - } -} - -pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, - folder: &mut T) - -> TraitItem { - TraitItem { - id: folder.new_id(i.id), - name: folder.fold_name(i.name), - attrs: fold_attrs(i.attrs, folder), - node: match i.node { - ConstTraitItem(ty, default) => { - ConstTraitItem(folder.fold_ty(ty), default.map(|x| folder.fold_expr(x))) - } - MethodTraitItem(sig, body) => { - MethodTraitItem(noop_fold_method_sig(sig, folder), - body.map(|x| folder.fold_block(x))) - } - TypeTraitItem(bounds, default) => { - TypeTraitItem(folder.fold_bounds(bounds), - default.map(|x| folder.fold_ty(x))) - } - }, - span: folder.new_span(i.span), - } -} - -pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T) -> ImplItem { - ImplItem { - id: folder.new_id(i.id), - name: folder.fold_name(i.name), - attrs: fold_attrs(i.attrs, folder), - vis: i.vis, - defaultness: i.defaultness, - node: match i.node { - ImplItemKind::Const(ty, expr) => { - ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr)) - } - ImplItemKind::Method(sig, body) => { - ImplItemKind::Method(noop_fold_method_sig(sig, folder), folder.fold_block(body)) - } - ImplItemKind::Type(ty) => ImplItemKind::Type(folder.fold_ty(ty)), - }, - span: folder.new_span(i.span), - } -} - -pub fn noop_fold_mod<T: Folder>(Mod { inner, item_ids }: Mod, folder: &mut T) -> Mod { - Mod { - inner: folder.new_span(inner), - item_ids: item_ids.move_map(|x| folder.fold_item_id(x)), - } -} - -pub fn noop_fold_crate<T: Folder>(Crate { module, attrs, config, span, - exported_macros, items }: Crate, - folder: &mut T) - -> Crate { - let config = folder.fold_meta_items(config); - - let crate_mod = folder.fold_item(hir::Item { - name: keywords::Invalid.name(), - attrs: attrs, - id: DUMMY_NODE_ID, - vis: hir::Public, - span: span, - node: hir::ItemMod(module), - }); - - let (module, attrs, span) = match crate_mod { - hir::Item { attrs, span, node, .. } => { - match node { - hir::ItemMod(m) => (m, attrs, span), - _ => panic!("fold converted a module to not a module"), - } - } - }; - - let items = items.into_iter() - .map(|(id, item)| (id, folder.fold_item(item))) - .collect(); - - Crate { - module: module, - attrs: attrs, - config: config, - span: span, - exported_macros: exported_macros, - items: items, - } -} - -pub fn noop_fold_item_id<T: Folder>(i: ItemId, folder: &mut T) -> ItemId { - let id = folder.map_id(i.id); - ItemId { id: id } -} - -// fold one item into one item -pub fn noop_fold_item<T: Folder>(item: Item, folder: &mut T) -> Item { - let Item { id, name, attrs, node, vis, span } = item; - let id = folder.new_id(id); - let node = folder.fold_item_underscore(node); - - Item { - id: id, - name: folder.fold_name(name), - attrs: fold_attrs(attrs, folder), - node: node, - vis: vis, - span: folder.new_span(span), - } -} - -pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> ForeignItem { - ForeignItem { - id: folder.new_id(ni.id), - name: folder.fold_name(ni.name), - attrs: fold_attrs(ni.attrs, folder), - node: match ni.node { - ForeignItemFn(fdec, generics) => { - ForeignItemFn(folder.fold_fn_decl(fdec), folder.fold_generics(generics)) - } - ForeignItemStatic(t, m) => { - ForeignItemStatic(folder.fold_ty(t), m) - } - }, - vis: ni.vis, - span: folder.new_span(ni.span), - } -} - -pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig { - MethodSig { - generics: folder.fold_generics(sig.generics), - abi: sig.abi, - unsafety: sig.unsafety, - constness: sig.constness, - decl: folder.fold_fn_decl(sig.decl), - } -} - -pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> { - p.map(|Pat { id, node, span }| { - Pat { - id: folder.new_id(id), - node: match node { - PatKind::Wild => PatKind::Wild, - PatKind::Binding(binding_mode, pth1, sub) => { - PatKind::Binding(binding_mode, - Spanned { - span: folder.new_span(pth1.span), - node: folder.fold_name(pth1.node), - }, - sub.map(|x| folder.fold_pat(x))) - } - PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), - PatKind::TupleStruct(pth, pats, ddpos) => { - PatKind::TupleStruct(folder.fold_path(pth), - pats.move_map(|x| folder.fold_pat(x)), ddpos) - } - PatKind::Path(opt_qself, pth) => { - let opt_qself = opt_qself.map(|qself| { - QSelf { ty: folder.fold_ty(qself.ty), position: qself.position } - }); - PatKind::Path(opt_qself, folder.fold_path(pth)) - } - PatKind::Struct(pth, fields, etc) => { - let pth = folder.fold_path(pth); - let fs = fields.move_map(|f| { - Spanned { - span: folder.new_span(f.span), - node: hir::FieldPat { - name: f.node.name, - pat: folder.fold_pat(f.node.pat), - is_shorthand: f.node.is_shorthand, - }, - } - }); - PatKind::Struct(pth, fs, etc) - } - PatKind::Tuple(elts, ddpos) => { - PatKind::Tuple(elts.move_map(|x| folder.fold_pat(x)), ddpos) - } - PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)), - PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl), - PatKind::Range(e1, e2) => { - PatKind::Range(folder.fold_expr(e1), folder.fold_expr(e2)) - } - PatKind::Vec(before, slice, after) => { - PatKind::Vec(before.move_map(|x| folder.fold_pat(x)), - slice.map(|x| folder.fold_pat(x)), - after.move_map(|x| folder.fold_pat(x))) - } - }, - span: folder.new_span(span), - } - }) -} - -pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &mut T) -> Expr { - Expr { - id: folder.new_id(id), - node: match node { - ExprBox(e) => { - ExprBox(folder.fold_expr(e)) - } - ExprVec(exprs) => { - ExprVec(exprs.move_map(|x| folder.fold_expr(x))) - } - ExprRepeat(expr, count) => { - ExprRepeat(folder.fold_expr(expr), folder.fold_expr(count)) - } - ExprTup(elts) => ExprTup(elts.move_map(|x| folder.fold_expr(x))), - ExprCall(f, args) => { - ExprCall(folder.fold_expr(f), args.move_map(|x| folder.fold_expr(x))) - } - ExprMethodCall(name, tps, args) => { - ExprMethodCall(respan(folder.new_span(name.span), folder.fold_name(name.node)), - tps.move_map(|x| folder.fold_ty(x)), - args.move_map(|x| folder.fold_expr(x))) - } - ExprBinary(binop, lhs, rhs) => { - ExprBinary(binop, folder.fold_expr(lhs), folder.fold_expr(rhs)) - } - ExprUnary(binop, ohs) => { - ExprUnary(binop, folder.fold_expr(ohs)) - } - ExprLit(l) => ExprLit(l), - ExprCast(expr, ty) => { - ExprCast(folder.fold_expr(expr), folder.fold_ty(ty)) - } - ExprType(expr, ty) => { - ExprType(folder.fold_expr(expr), folder.fold_ty(ty)) - } - ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)), - ExprIf(cond, tr, fl) => { - ExprIf(folder.fold_expr(cond), - folder.fold_block(tr), - fl.map(|x| folder.fold_expr(x))) - } - ExprWhile(cond, body, opt_name) => { - ExprWhile(folder.fold_expr(cond), - folder.fold_block(body), - opt_name.map(|label| { - respan(folder.new_span(label.span), folder.fold_name(label.node)) - })) - } - ExprLoop(body, opt_name) => { - ExprLoop(folder.fold_block(body), - opt_name.map(|label| { - respan(folder.new_span(label.span), folder.fold_name(label.node)) - })) - } - ExprMatch(expr, arms, source) => { - ExprMatch(folder.fold_expr(expr), - arms.move_map(|x| folder.fold_arm(x)), - source) - } - ExprClosure(capture_clause, decl, body, fn_decl_span) => { - ExprClosure(capture_clause, - folder.fold_fn_decl(decl), - folder.fold_block(body), - folder.new_span(fn_decl_span)) - } - ExprBlock(blk) => ExprBlock(folder.fold_block(blk)), - ExprAssign(el, er) => { - ExprAssign(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprAssignOp(op, el, er) => { - ExprAssignOp(op, folder.fold_expr(el), folder.fold_expr(er)) - } - ExprField(el, name) => { - ExprField(folder.fold_expr(el), - respan(folder.new_span(name.span), folder.fold_name(name.node))) - } - ExprTupField(el, index) => { - ExprTupField(folder.fold_expr(el), - respan(folder.new_span(index.span), folder.fold_usize(index.node))) - } - ExprIndex(el, er) => { - ExprIndex(folder.fold_expr(el), folder.fold_expr(er)) - } - ExprPath(qself, path) => { - let qself = qself.map(|QSelf { ty, position }| { - QSelf { - ty: folder.fold_ty(ty), - position: position, - } - }); - ExprPath(qself, folder.fold_path(path)) - } - ExprBreak(opt_name) => ExprBreak(opt_name.map(|label| { - respan(folder.new_span(label.span), folder.fold_name(label.node)) - })), - ExprAgain(opt_name) => ExprAgain(opt_name.map(|label| { - respan(folder.new_span(label.span), folder.fold_name(label.node)) - })), - ExprRet(e) => ExprRet(e.map(|x| folder.fold_expr(x))), - ExprInlineAsm(asm, outputs, inputs) => { - ExprInlineAsm(asm, - outputs.move_map(|x| folder.fold_expr(x)), - inputs.move_map(|x| folder.fold_expr(x))) - } - ExprStruct(path, fields, maybe_expr) => { - ExprStruct(folder.fold_path(path), - fields.move_map(|x| folder.fold_field(x)), - maybe_expr.map(|x| folder.fold_expr(x))) - } - }, - span: folder.new_span(span), - attrs: fold_attrs(attrs, folder), - } -} - -pub fn noop_fold_stmt<T: Folder>(stmt: Stmt, folder: &mut T) -> Stmt { - let span = folder.new_span(stmt.span); - match stmt.node { - StmtDecl(d, id) => { - let id = folder.new_id(id); - Spanned { - node: StmtDecl(folder.fold_decl(d), id), - span: span - } - } - StmtExpr(e, id) => { - let id = folder.new_id(id); - Spanned { - node: StmtExpr(folder.fold_expr(e), id), - span: span, - } - } - StmtSemi(e, id) => { - let id = folder.new_id(id); - Spanned { - node: StmtSemi(folder.fold_expr(e), id), - span: span, - } - } - } -} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e22c9869ab1..0cfdbae1a50 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -67,7 +67,6 @@ macro_rules! hir_vec { pub mod check_attr; pub mod def; pub mod def_id; -pub mod fold; pub mod intravisit; pub mod lowering; pub mod map; diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 5d2b266ec4b..dda72ce57b4 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -40,11 +40,10 @@ use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; use syntax::codemap::Spanned; use syntax_pos::{Span, DUMMY_SP}; -use rustc::hir::fold::{Folder, noop_fold_pat}; use rustc::hir::print::pat_to_string; use syntax::ptr::P; +use syntax::util::move_map::MoveMap; use rustc::util::common::ErrorReported; -use rustc::util::nodemap::FnvHashMap; pub const DUMMY_WILD_PAT: &'static Pat = &Pat { id: DUMMY_NODE_ID, @@ -182,7 +181,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) { } } - let mut static_inliner = StaticInliner::new(cx.tcx, None); + let mut static_inliner = StaticInliner::new(cx.tcx); let inlined_arms = arms.iter().map(|arm| { (arm.pats.iter().map(|pat| { static_inliner.fold_pat((*pat).clone()) @@ -467,53 +466,30 @@ fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> { }) } -pub struct StaticInliner<'a, 'tcx: 'a> { - pub tcx: TyCtxt<'a, 'tcx, 'tcx>, - pub failed: bool, - pub renaming_map: Option<&'a mut FnvHashMap<(NodeId, Span), NodeId>>, +struct StaticInliner<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + failed: bool } impl<'a, 'tcx> StaticInliner<'a, 'tcx> { - pub fn new<'b>(tcx: TyCtxt<'b, 'tcx, 'tcx>, - renaming_map: Option<&'b mut FnvHashMap<(NodeId, Span), NodeId>>) - -> StaticInliner<'b, 'tcx> { + pub fn new<'b>(tcx: TyCtxt<'b, 'tcx, 'tcx>) -> StaticInliner<'b, 'tcx> { StaticInliner { tcx: tcx, - failed: false, - renaming_map: renaming_map + failed: false } } } -struct RenamingRecorder<'map> { - substituted_node_id: NodeId, - origin_span: Span, - renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId> -} - -impl<'v, 'map> Visitor<'v> for RenamingRecorder<'map> { - fn visit_id(&mut self, node_id: NodeId) { - let key = (node_id, self.origin_span); - self.renaming_map.insert(key, self.substituted_node_id); - } -} - -impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { +impl<'a, 'tcx> StaticInliner<'a, 'tcx> { fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> { - return match pat.node { + match pat.node { PatKind::Path(..) => { match self.tcx.expect_def(pat.id) { Def::AssociatedConst(did) | Def::Const(did) => { let substs = Some(self.tcx.node_id_item_substs(pat.id).substs); if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) { match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) { - Ok(new_pat) => { - if let Some(ref mut map) = self.renaming_map { - // Record any renamings we do here - record_renamings(const_expr, &pat, map); - } - new_pat - } + Ok(new_pat) => return new_pat, Err(def_id) => { self.failed = true; self.tcx.sess.span_err( @@ -521,33 +497,62 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { &format!("constants of the type `{}` \ cannot be used in patterns", self.tcx.item_path_str(def_id))); - pat } } } else { self.failed = true; span_err!(self.tcx.sess, pat.span, E0158, "statics cannot be referenced in patterns"); - pat } } - _ => noop_fold_pat(pat, self) + _ => {} } } - _ => noop_fold_pat(pat, self) - }; + _ => {} + } - fn record_renamings(const_expr: &hir::Expr, - substituted_pat: &hir::Pat, - renaming_map: &mut FnvHashMap<(NodeId, Span), NodeId>) { - let mut renaming_recorder = RenamingRecorder { - substituted_node_id: substituted_pat.id, - origin_span: substituted_pat.span, - renaming_map: renaming_map, + pat.map(|Pat { id, node, span }| { + let node = match node { + PatKind::Binding(binding_mode, pth1, sub) => { + PatKind::Binding(binding_mode, pth1, sub.map(|x| self.fold_pat(x))) + } + PatKind::TupleStruct(pth, pats, ddpos) => { + PatKind::TupleStruct(pth, pats.move_map(|x| self.fold_pat(x)), ddpos) + } + PatKind::Struct(pth, fields, etc) => { + let fs = fields.move_map(|f| { + Spanned { + span: f.span, + node: hir::FieldPat { + name: f.node.name, + pat: self.fold_pat(f.node.pat), + is_shorthand: f.node.is_shorthand, + }, + } + }); + PatKind::Struct(pth, fs, etc) + } + PatKind::Tuple(elts, ddpos) => { + PatKind::Tuple(elts.move_map(|x| self.fold_pat(x)), ddpos) + } + PatKind::Box(inner) => PatKind::Box(self.fold_pat(inner)), + PatKind::Ref(inner, mutbl) => PatKind::Ref(self.fold_pat(inner), mutbl), + PatKind::Vec(before, slice, after) => { + PatKind::Vec(before.move_map(|x| self.fold_pat(x)), + slice.map(|x| self.fold_pat(x)), + after.move_map(|x| self.fold_pat(x))) + } + PatKind::Wild | + PatKind::Lit(_) | + PatKind::Range(..) | + PatKind::Path(..) => node }; - - renaming_recorder.visit_expr(const_expr); - } + Pat { + id: id, + node: node, + span: span + } + }) } } @@ -1047,7 +1052,7 @@ pub fn specialize<'a, 'b, 'tcx>( fn check_local(cx: &mut MatchCheckCtxt, loc: &hir::Local) { intravisit::walk_local(cx, loc); - let pat = StaticInliner::new(cx.tcx, None).fold_pat(loc.pat.clone()); + let pat = StaticInliner::new(cx.tcx).fold_pat(loc.pat.clone()); check_irrefutable(cx, &pat, false); // Check legality of move bindings and `@` patterns. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3983c098f30..7eb7b24015e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -38,7 +38,6 @@ use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime::DefRegion::*; use rustc::hir::def::Def; use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX}; -use rustc::hir::fold::Folder; use rustc::hir::print as pprust; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtKind}; @@ -774,7 +773,20 @@ impl Lifetime { } impl Clean<Lifetime> for hir::Lifetime { - fn clean(&self, _: &DocContext) -> Lifetime { + fn clean(&self, cx: &DocContext) -> Lifetime { + if let Some(tcx) = cx.tcx_opt() { + let def = tcx.named_region_map.defs.get(&self.id).cloned(); + match def { + Some(DefEarlyBoundRegion(_, node_id)) | + Some(DefLateBoundRegion(_, node_id)) | + Some(DefFreeRegion(_, node_id)) => { + if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { + return lt; + } + } + _ => {} + } + } Lifetime(self.name.to_string()) } } @@ -1629,42 +1641,6 @@ impl From<ast::FloatTy> for PrimitiveType { } } -// Poor man's type parameter substitution at HIR level. -// Used to replace private type aliases in public signatures with their aliased types. -struct SubstAlias<'a, 'tcx: 'a> { - tcx: &'a ty::TyCtxt<'a, 'tcx, 'tcx>, - // Table type parameter definition -> substituted type - ty_substs: FnvHashMap<Def, hir::Ty>, - // Table node id of lifetime parameter definition -> substituted lifetime - lt_substs: FnvHashMap<ast::NodeId, hir::Lifetime>, -} - -impl<'a, 'tcx: 'a, 'b: 'tcx> Folder for SubstAlias<'a, 'tcx> { - fn fold_ty(&mut self, ty: P<hir::Ty>) -> P<hir::Ty> { - if let hir::TyPath(..) = ty.node { - let def = self.tcx.expect_def(ty.id); - if let Some(new_ty) = self.ty_substs.get(&def).cloned() { - return P(new_ty); - } - } - hir::fold::noop_fold_ty(ty, self) - } - fn fold_lifetime(&mut self, lt: hir::Lifetime) -> hir::Lifetime { - let def = self.tcx.named_region_map.defs.get(<.id).cloned(); - match def { - Some(DefEarlyBoundRegion(_, node_id)) | - Some(DefLateBoundRegion(_, node_id)) | - Some(DefFreeRegion(_, node_id)) => { - if let Some(lt) = self.lt_substs.get(&node_id).cloned() { - return lt; - } - } - _ => {} - } - hir::fold::noop_fold_lifetime(lt, self) - } -} - impl Clean<Type> for hir::Ty { fn clean(&self, cx: &DocContext) -> Type { use rustc::hir::*; @@ -1696,43 +1672,47 @@ impl Clean<Type> for hir::Ty { }, TyTup(ref tys) => Tuple(tys.clean(cx)), TyPath(None, ref path) => { - if let Some(tcx) = cx.tcx_opt() { - // Substitute private type aliases - let def = tcx.expect_def(self.id); + let tcx_and_def = cx.tcx_opt().map(|tcx| (tcx, tcx.expect_def(self.id))); + if let Some((_, def)) = tcx_and_def { + if let Some(new_ty) = cx.ty_substs.borrow().get(&def).cloned() { + return new_ty; + } + } + + let tcx_and_alias = tcx_and_def.and_then(|(tcx, def)| { if let Def::TyAlias(def_id) = def { - if let Some(node_id) = tcx.map.as_local_node_id(def_id) { + // Substitute private type aliases + tcx.map.as_local_node_id(def_id).and_then(|node_id| { if !cx.access_levels.borrow().is_exported(def_id) { - let item = tcx.map.expect_item(node_id); - if let hir::ItemTy(ref ty, ref generics) = item.node { - let provided_params = &path.segments.last().unwrap().parameters; - let mut ty_substs = FnvHashMap(); - let mut lt_substs = FnvHashMap(); - for (i, ty_param) in generics.ty_params.iter().enumerate() { - let ty_param_def = tcx.expect_def(ty_param.id); - if let Some(ty) = provided_params.types().get(i).cloned() - .cloned() { - ty_substs.insert(ty_param_def, ty.unwrap()); - } else if let Some(default) = ty_param.default.clone() { - ty_substs.insert(ty_param_def, default.unwrap()); - } - } - for (i, lt_param) in generics.lifetimes.iter().enumerate() { - if let Some(lt) = provided_params.lifetimes().get(i) - .cloned() - .cloned() { - lt_substs.insert(lt_param.lifetime.id, lt); - } - } - let mut subst_alias = SubstAlias { - tcx: &tcx, - ty_substs: ty_substs, - lt_substs: lt_substs - }; - return subst_alias.fold_ty(ty.clone()).clean(cx); - } + Some((tcx, &tcx.map.expect_item(node_id).node)) + } else { + None } + }) + } else { + None + } + }); + if let Some((tcx, &hir::ItemTy(ref ty, ref generics))) = tcx_and_alias { + let provided_params = &path.segments.last().unwrap().parameters; + let mut ty_substs = FnvHashMap(); + let mut lt_substs = FnvHashMap(); + for (i, ty_param) in generics.ty_params.iter().enumerate() { + let ty_param_def = tcx.expect_def(ty_param.id); + if let Some(ty) = provided_params.types().get(i).cloned() + .cloned() { + ty_substs.insert(ty_param_def, ty.unwrap().clean(cx)); + } else if let Some(default) = ty_param.default.clone() { + ty_substs.insert(ty_param_def, default.unwrap().clean(cx)); + } + } + for (i, lt_param) in generics.lifetimes.iter().enumerate() { + if let Some(lt) = provided_params.lifetimes().get(i).cloned() + .cloned() { + lt_substs.insert(lt_param.lifetime.id, lt.clean(cx)); } } + return cx.enter_alias(ty_substs, lt_substs, || ty.clean(cx)); } resolve_type(cx, path.clean(cx), self.id) } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index ab6858a0931..399702003ea 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -14,6 +14,7 @@ use rustc_driver::{driver, target_features, abort_on_err}; use rustc::dep_graph::DepGraph; use rustc::session::{self, config}; use rustc::hir::def_id::{CrateNum, DefId}; +use rustc::hir::def::Def; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; use rustc::hir::map as hir_map; @@ -23,12 +24,13 @@ use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; -use syntax::codemap; +use syntax::{ast, codemap}; use syntax::feature_gate::UnstableFeatures; use errors; use errors::emitter::ColorConfig; use std::cell::{RefCell, Cell}; +use std::mem; use std::rc::Rc; use visit_ast::RustdocVisitor; @@ -63,6 +65,14 @@ pub struct DocContext<'a, 'tcx: 'a> { pub renderinfo: RefCell<RenderInfo>, /// Later on moved through `clean::Crate` into `html::render::CACHE_KEY` pub external_traits: RefCell<FnvHashMap<DefId, clean::Trait>>, + + // The current set of type and lifetime substitutions, + // for expanding type aliases at the HIR level: + + /// Table type parameter definition -> substituted type + pub ty_substs: RefCell<FnvHashMap<Def, clean::Type>>, + /// Table node id of lifetime parameter definition -> substituted lifetime + pub lt_substs: RefCell<FnvHashMap<ast::NodeId, clean::Lifetime>>, } impl<'b, 'tcx> DocContext<'b, 'tcx> { @@ -84,6 +94,22 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> { let tcx_opt = self.tcx_opt(); tcx_opt.expect("tcx not present") } + + /// Call the closure with the given parameters set as + /// the substitutions for a type alias' RHS. + pub fn enter_alias<F, R>(&self, + ty_substs: FnvHashMap<Def, clean::Type>, + lt_substs: FnvHashMap<ast::NodeId, clean::Lifetime>, + f: F) -> R + where F: FnOnce() -> R { + let (old_tys, old_lts) = + (mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs), + mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs)); + let r = f(); + *self.ty_substs.borrow_mut() = old_tys; + *self.lt_substs.borrow_mut() = old_lts; + r + } } pub trait DocAccessLevels { @@ -179,12 +205,14 @@ pub fn run_core(search_paths: SearchPaths, map: &tcx.map, maybe_typed: Typed(tcx), input: input, - populated_crate_impls: RefCell::new(FnvHashSet()), + populated_crate_impls: Default::default(), deref_trait_did: Cell::new(None), deref_mut_trait_did: Cell::new(None), access_levels: RefCell::new(access_levels), - external_traits: RefCell::new(FnvHashMap()), - renderinfo: RefCell::new(Default::default()), + external_traits: Default::default(), + renderinfo: Default::default(), + ty_substs: Default::default(), + lt_substs: Default::default(), }; debug!("crate: {:?}", ctxt.map.krate()); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 851cf95f996..3d2caeda146 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell::{RefCell, Cell}; +use std::cell::Cell; use std::env; use std::ffi::OsString; use std::io::prelude::*; @@ -28,7 +28,6 @@ use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType, OutputTypes, Externs}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -107,12 +106,14 @@ pub fn run(input: &str, map: &map, maybe_typed: core::NotTyped(&sess), input: input, - external_traits: RefCell::new(FnvHashMap()), - populated_crate_impls: RefCell::new(FnvHashSet()), + external_traits: Default::default(), + populated_crate_impls: Default::default(), deref_trait_did: Cell::new(None), deref_mut_trait_did: Cell::new(None), access_levels: Default::default(), renderinfo: Default::default(), + ty_substs: Default::default(), + lt_substs: Default::default(), }; let mut v = RustdocVisitor::new(&ctx); |
