2014-07-27 11:50:46 +00:00
|
|
|
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
2012-12-04 00:48:01 +00:00
|
|
|
// 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.
|
|
|
|
|
2014-07-09 21:48:12 +00:00
|
|
|
//! A Folder represents an AST->AST fold; it accepts an AST piece,
|
|
|
|
//! and returns a piece of the same type. So, for instance, macro
|
|
|
|
//! expansion is a Folder that walks over an AST and produces another
|
|
|
|
//! AST.
|
|
|
|
//!
|
|
|
|
//! Note: using a Folder (other than the MacroExpander Folder) on
|
|
|
|
//! an AST before macro expansion is probably a bad idea. For instance,
|
|
|
|
//! a folder renaming item names in a module will miss all of those
|
|
|
|
//! that are created by the expansion of a macro.
|
|
|
|
|
2012-09-04 18:37:29 +00:00
|
|
|
use ast::*;
|
2012-12-23 22:41:37 +00:00
|
|
|
use ast;
|
2016-06-21 22:08:13 +00:00
|
|
|
use syntax_pos::Span;
|
2018-02-04 12:19:14 +00:00
|
|
|
use codemap::{Spanned, respan};
|
2017-03-29 01:55:01 +00:00
|
|
|
use parse::token::{self, Token};
|
2014-09-07 17:00:54 +00:00
|
|
|
use ptr::P;
|
2016-11-16 08:21:52 +00:00
|
|
|
use symbol::keywords;
|
2016-06-20 15:49:33 +00:00
|
|
|
use tokenstream::*;
|
2013-11-25 07:08:53 +00:00
|
|
|
use util::small_vector::SmallVector;
|
2015-11-15 20:19:53 +00:00
|
|
|
use util::move_map::MoveMap;
|
2012-12-23 22:41:37 +00:00
|
|
|
|
2018-02-27 16:11:14 +00:00
|
|
|
use rustc_data_structures::sync::Lrc;
|
2016-07-04 10:25:50 +00:00
|
|
|
|
2014-12-18 20:27:41 +00:00
|
|
|
pub trait Folder : Sized {
|
2014-07-25 19:00:33 +00:00
|
|
|
// 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.
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn fold_crate(&mut self, c: Crate) -> Crate {
|
2013-08-29 19:10:02 +00:00
|
|
|
noop_fold_crate(c, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2016-11-15 10:17:24 +00:00
|
|
|
fn fold_meta_items(&mut self, meta_items: Vec<MetaItem>) -> Vec<MetaItem> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_meta_items(meta_items, self)
|
|
|
|
}
|
|
|
|
|
2016-08-20 01:58:14 +00:00
|
|
|
fn fold_meta_list_item(&mut self, list_item: NestedMetaItem) -> NestedMetaItem {
|
|
|
|
noop_fold_meta_list_item(list_item, self)
|
|
|
|
}
|
|
|
|
|
2016-11-15 10:17:24 +00:00
|
|
|
fn fold_meta_item(&mut self, meta_item: MetaItem) -> MetaItem {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_meta_item(meta_item, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2017-09-26 21:04:00 +00:00
|
|
|
fn fold_use_tree(&mut self, use_tree: UseTree) -> UseTree {
|
|
|
|
noop_fold_use_tree(use_tree, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_foreign_item(&mut self, ni: ForeignItem) -> ForeignItem {
|
2014-09-07 17:00:54 +00:00
|
|
|
noop_fold_foreign_item(ni, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_item(&mut self, i: P<Item>) -> SmallVector<P<Item>> {
|
|
|
|
noop_fold_item(i, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_item_simple(&mut self, i: Item) -> Item {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_item_simple(i, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_struct_field(&mut self, sf: StructField) -> StructField {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_struct_field(sf, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2016-02-09 10:36:51 +00:00
|
|
|
fn fold_item_kind(&mut self, i: ItemKind) -> ItemKind {
|
|
|
|
noop_fold_item_kind(i, self)
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_trait_item(&mut self, i: TraitItem) -> SmallVector<TraitItem> {
|
2014-12-02 18:07:41 +00:00
|
|
|
noop_fold_trait_item(i, self)
|
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_impl_item(&mut self, i: ImplItem) -> SmallVector<ImplItem> {
|
2014-12-02 18:07:41 +00:00
|
|
|
noop_fold_impl_item(i, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_fn_decl(&mut self, d: P<FnDecl>) -> P<FnDecl> {
|
2014-01-06 12:00:46 +00:00
|
|
|
noop_fold_fn_decl(d, self)
|
|
|
|
}
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn fold_block(&mut self, b: P<Block>) -> P<Block> {
|
2013-08-29 19:10:02 +00:00
|
|
|
noop_fold_block(b, self)
|
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_stmt(&mut self, s: Stmt) -> SmallVector<Stmt> {
|
|
|
|
noop_fold_stmt(s, self)
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_arm(&mut self, a: Arm) -> Arm {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_arm(a, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_pat(&mut self, p: P<Pat>) -> P<Pat> {
|
2014-01-06 12:00:46 +00:00
|
|
|
noop_fold_pat(p, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_expr(&mut self, e: P<Expr>) -> P<Expr> {
|
|
|
|
e.map(|e| noop_fold_expr(e, self))
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 21:13:53 +00:00
|
|
|
fn fold_range_end(&mut self, re: RangeEnd) -> RangeEnd {
|
|
|
|
noop_fold_range_end(re, self)
|
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
fn fold_opt_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
|
|
|
|
noop_fold_opt_expr(e, self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fold_exprs(&mut self, es: Vec<P<Expr>>) -> Vec<P<Expr>> {
|
|
|
|
noop_fold_exprs(es, self)
|
|
|
|
}
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn fold_ty(&mut self, t: P<Ty>) -> P<Ty> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_ty(t, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_ty_binding(&mut self, t: TypeBinding) -> TypeBinding {
|
2014-11-29 04:08:30 +00:00
|
|
|
noop_fold_ty_binding(t, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_mod(&mut self, m: Mod) -> Mod {
|
2013-08-29 19:10:02 +00:00
|
|
|
noop_fold_mod(m, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_foreign_mod(&mut self, nm: ForeignMod) -> ForeignMod {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_foreign_mod(nm, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2017-03-16 02:27:40 +00:00
|
|
|
fn fold_global_asm(&mut self, ga: P<GlobalAsm>) -> P<GlobalAsm> {
|
|
|
|
noop_fold_global_asm(ga, self)
|
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
fn fold_variant(&mut self, v: Variant) -> Variant {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_variant(v, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn fold_ident(&mut self, i: Ident) -> Ident {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_ident(i, self)
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
2013-09-07 02:11:55 +00:00
|
|
|
|
2015-01-17 23:49:08 +00:00
|
|
|
fn fold_usize(&mut self, i: usize) -> usize {
|
|
|
|
noop_fold_usize(i, self)
|
2014-08-10 03:54:33 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_path(&mut self, p: Path) -> Path {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_path(p, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_local(&mut self, l: P<Local>) -> P<Local> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_local(l, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2015-01-02 21:39:05 +00:00
|
|
|
fn fold_mac(&mut self, _mac: Mac) -> Mac {
|
2014-10-09 19:17:22 +00:00
|
|
|
panic!("fold_mac disabled by default");
|
2014-07-09 21:48:12 +00:00
|
|
|
// NB: see note about macros above.
|
|
|
|
// if you really want a folder that
|
|
|
|
// works on macros, use this
|
|
|
|
// definition in your trait impl:
|
2015-01-02 21:39:05 +00:00
|
|
|
// fold::noop_fold_mac(_mac, self)
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
2017-03-17 21:58:48 +00:00
|
|
|
fn fold_macro_def(&mut self, def: MacroDef) -> MacroDef {
|
|
|
|
noop_fold_macro_def(def, self)
|
|
|
|
}
|
|
|
|
|
2018-01-15 22:44:32 +00:00
|
|
|
fn fold_label(&mut self, label: Label) -> Label {
|
|
|
|
noop_fold_label(label, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_lifetime(&mut self, l: Lifetime) -> Lifetime {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_lifetime(l, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_lifetime_def(&mut self, l: LifetimeDef) -> LifetimeDef {
|
2014-08-06 02:59:24 +00:00
|
|
|
noop_fold_lifetime_def(l, self)
|
|
|
|
}
|
|
|
|
|
2015-02-09 17:01:15 +00:00
|
|
|
fn fold_attribute(&mut self, at: Attribute) -> Option<Attribute> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_attribute(at, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_arg(&mut self, a: Arg) -> Arg {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_arg(a, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_generics(&mut self, generics: Generics) -> Generics {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_generics(generics, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_trait_ref(&mut self, p: TraitRef) -> TraitRef {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_trait_ref(p, self)
|
|
|
|
}
|
|
|
|
|
2014-11-07 11:53:45 +00:00
|
|
|
fn fold_poly_trait_ref(&mut self, p: PolyTraitRef) -> PolyTraitRef {
|
|
|
|
noop_fold_poly_trait_ref(p, self)
|
|
|
|
}
|
|
|
|
|
2015-10-25 15:33:51 +00:00
|
|
|
fn fold_variant_data(&mut self, vdata: VariantData) -> VariantData {
|
|
|
|
noop_fold_variant_data(vdata, self)
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_lifetimes(&mut self, lts: Vec<Lifetime>) -> Vec<Lifetime> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_lifetimes(lts, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_lifetime_defs(&mut self, lts: Vec<LifetimeDef>) -> Vec<LifetimeDef> {
|
2014-08-06 02:59:24 +00:00
|
|
|
noop_fold_lifetime_defs(lts, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_ty_param(&mut self, tp: TyParam) -> TyParam {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_ty_param(tp, self)
|
|
|
|
}
|
|
|
|
|
2017-10-16 19:07:26 +00:00
|
|
|
fn fold_generic_param(&mut self, param: GenericParam) -> GenericParam {
|
|
|
|
noop_fold_generic_param(param, self)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn fold_generic_params(&mut self, params: Vec<GenericParam>) -> Vec<GenericParam> {
|
|
|
|
noop_fold_generic_params(params, self)
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
fn fold_tt(&mut self, tt: TokenTree) -> TokenTree {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_tt(tt, self)
|
|
|
|
}
|
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
fn fold_tts(&mut self, tts: TokenStream) -> TokenStream {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_tts(tts, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_token(&mut self, t: token::Token) -> token::Token {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_token(t, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_interpolated(&mut self, nt: token::Nonterminal) -> token::Nonterminal {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_interpolated(nt, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_opt_lifetime(&mut self, o_lt: Option<Lifetime>) -> Option<Lifetime> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_opt_lifetime(o_lt, self)
|
|
|
|
}
|
|
|
|
|
2015-12-16 18:44:33 +00:00
|
|
|
fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>)
|
|
|
|
-> Option<TyParamBounds> {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_opt_bounds(b, self)
|
|
|
|
}
|
|
|
|
|
2015-12-16 18:44:33 +00:00
|
|
|
fn fold_bounds(&mut self, b: TyParamBounds)
|
|
|
|
-> TyParamBounds {
|
2014-08-28 01:46:52 +00:00
|
|
|
noop_fold_bounds(b, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound {
|
2014-08-28 01:46:52 +00:00
|
|
|
noop_fold_ty_param_bound(tpb, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_mt(&mut self, mt: MutTy) -> MutTy {
|
2014-07-25 19:00:33 +00:00
|
|
|
noop_fold_mt(mt, self)
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
|
2014-07-25 19:00:33 +00:00
|
|
|
fn fold_field(&mut self, field: Field) -> Field {
|
|
|
|
noop_fold_field(field, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_where_clause(&mut self, where_clause: WhereClause)
|
2014-08-11 16:32:26 +00:00
|
|
|
-> WhereClause {
|
|
|
|
noop_fold_where_clause(where_clause, self)
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn fold_where_predicate(&mut self, where_predicate: WherePredicate)
|
2014-08-11 16:32:26 +00:00
|
|
|
-> WherePredicate {
|
|
|
|
noop_fold_where_predicate(where_predicate, self)
|
|
|
|
}
|
|
|
|
|
2016-03-31 19:10:38 +00:00
|
|
|
fn fold_vis(&mut self, vis: Visibility) -> Visibility {
|
|
|
|
noop_fold_vis(vis, self)
|
|
|
|
}
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn new_id(&mut self, i: NodeId) -> NodeId {
|
2013-08-29 19:10:02 +00:00
|
|
|
i
|
|
|
|
}
|
|
|
|
|
2013-12-28 03:34:51 +00:00
|
|
|
fn new_span(&mut self, sp: Span) -> Span {
|
2013-08-29 19:10:02 +00:00
|
|
|
sp
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
2013-10-29 10:03:32 +00:00
|
|
|
|
2016-11-15 10:17:24 +00:00
|
|
|
pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<MetaItem>, fld: &mut T) -> Vec<MetaItem> {
|
2014-09-07 17:00:54 +00:00
|
|
|
meta_items.move_map(|x| fld.fold_meta_item(x))
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
2017-09-26 21:04:00 +00:00
|
|
|
pub fn noop_fold_use_tree<T: Folder>(use_tree: UseTree, fld: &mut T) -> UseTree {
|
|
|
|
UseTree {
|
|
|
|
span: fld.new_span(use_tree.span),
|
|
|
|
prefix: fld.fold_path(use_tree.prefix),
|
|
|
|
kind: match use_tree.kind {
|
2018-03-09 15:58:44 +00:00
|
|
|
UseTreeKind::Simple(rename) =>
|
|
|
|
UseTreeKind::Simple(rename.map(|ident| fld.fold_ident(ident))),
|
2017-09-26 21:04:00 +00:00
|
|
|
UseTreeKind::Glob => UseTreeKind::Glob,
|
|
|
|
UseTreeKind::Nested(items) => UseTreeKind::Nested(items.move_map(|(tree, id)| {
|
|
|
|
(fld.fold_use_tree(tree), fld.new_id(id))
|
|
|
|
})),
|
2014-09-07 17:00:54 +00:00
|
|
|
},
|
2017-09-26 21:04:00 +00:00
|
|
|
}
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
2013-10-29 10:03:32 +00:00
|
|
|
|
2015-02-09 17:01:15 +00:00
|
|
|
pub fn fold_attrs<T: Folder>(attrs: Vec<Attribute>, fld: &mut T) -> Vec<Attribute> {
|
2015-11-15 20:19:53 +00:00
|
|
|
attrs.move_flat_map(|x| fld.fold_attribute(x))
|
2015-02-09 17:01:15 +00:00
|
|
|
}
|
|
|
|
|
2016-06-18 04:01:57 +00:00
|
|
|
pub fn fold_thin_attrs<T: Folder>(attrs: ThinVec<Attribute>, fld: &mut T) -> ThinVec<Attribute> {
|
|
|
|
fold_attrs(attrs.into(), fld).into()
|
2015-11-15 17:20:09 +00:00
|
|
|
}
|
|
|
|
|
2018-01-30 20:56:02 +00:00
|
|
|
pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm,
|
2017-08-26 22:09:31 +00:00
|
|
|
fld: &mut T) -> Arm {
|
2014-07-25 19:00:33 +00:00
|
|
|
Arm {
|
2015-02-09 17:01:15 +00:00
|
|
|
attrs: fold_attrs(attrs, fld),
|
2014-09-07 17:00:54 +00:00
|
|
|
pats: pats.move_map(|x| fld.fold_pat(x)),
|
|
|
|
guard: guard.map(|x| fld.fold_expr(x)),
|
|
|
|
body: fld.fold_expr(body),
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
pub fn noop_fold_ty_binding<T: Folder>(b: TypeBinding, fld: &mut T) -> TypeBinding {
|
|
|
|
TypeBinding {
|
|
|
|
id: fld.new_id(b.id),
|
2016-12-23 02:16:31 +00:00
|
|
|
ident: fld.fold_ident(b.ident),
|
2016-02-11 20:33:09 +00:00
|
|
|
ty: fld.fold_ty(b.ty),
|
|
|
|
span: fld.new_span(b.span),
|
|
|
|
}
|
2014-11-29 04:08:30 +00:00
|
|
|
}
|
|
|
|
|
2014-07-25 19:00:33 +00:00
|
|
|
pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
2014-09-07 17:00:54 +00:00
|
|
|
t.map(|Ty {id, node, span}| Ty {
|
|
|
|
id: fld.new_id(id),
|
|
|
|
node: match node {
|
2017-03-29 01:56:29 +00:00
|
|
|
TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => node,
|
2016-09-20 14:54:24 +00:00
|
|
|
TyKind::Slice(ty) => TyKind::Slice(fld.fold_ty(ty)),
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::Ptr(mt) => TyKind::Ptr(fld.fold_mt(mt)),
|
|
|
|
TyKind::Rptr(region, mt) => {
|
|
|
|
TyKind::Rptr(fld.fold_opt_lifetime(region), fld.fold_mt(mt))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::BareFn(f) => {
|
2017-10-16 19:07:26 +00:00
|
|
|
TyKind::BareFn(f.map(|BareFnTy {generic_params, unsafety, abi, decl}| BareFnTy {
|
|
|
|
generic_params: fld.fold_generic_params(generic_params),
|
2017-08-07 05:54:09 +00:00
|
|
|
unsafety,
|
|
|
|
abi,
|
2014-09-07 17:00:54 +00:00
|
|
|
decl: fld.fold_fn_decl(decl)
|
|
|
|
}))
|
|
|
|
}
|
2016-08-02 07:56:20 +00:00
|
|
|
TyKind::Never => node,
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))),
|
|
|
|
TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)),
|
|
|
|
TyKind::Path(qself, path) => {
|
2015-02-17 17:29:13 +00:00
|
|
|
let qself = qself.map(|QSelf { ty, position }| {
|
|
|
|
QSelf {
|
|
|
|
ty: fld.fold_ty(ty),
|
2017-08-07 05:54:09 +00:00
|
|
|
position,
|
2015-02-17 17:29:13 +00:00
|
|
|
}
|
|
|
|
});
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::Path(qself, fld.fold_path(path))
|
2015-01-30 08:09:44 +00:00
|
|
|
}
|
2016-09-20 14:54:24 +00:00
|
|
|
TyKind::Array(ty, e) => {
|
|
|
|
TyKind::Array(fld.fold_ty(ty), fld.fold_expr(e))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::Typeof(expr) => {
|
|
|
|
TyKind::Typeof(fld.fold_expr(expr))
|
2014-11-15 21:55:27 +00:00
|
|
|
}
|
2017-10-10 14:33:19 +00:00
|
|
|
TyKind::TraitObject(bounds, syntax) => {
|
|
|
|
TyKind::TraitObject(bounds.move_map(|b| fld.fold_ty_param_bound(b)), syntax)
|
2014-11-15 21:55:27 +00:00
|
|
|
}
|
2016-08-01 01:25:32 +00:00
|
|
|
TyKind::ImplTrait(bounds) => {
|
|
|
|
TyKind::ImplTrait(bounds.move_map(|b| fld.fold_ty_param_bound(b)))
|
|
|
|
}
|
2016-02-08 15:53:21 +00:00
|
|
|
TyKind::Mac(mac) => {
|
|
|
|
TyKind::Mac(fld.fold_mac(mac))
|
2015-07-26 04:30:35 +00:00
|
|
|
}
|
2014-09-07 17:00:54 +00:00
|
|
|
},
|
|
|
|
span: fld.new_span(span)
|
2014-07-25 19:00:33 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-01-13 15:30:17 +00:00
|
|
|
pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
|
2014-09-07 17:00:54 +00:00
|
|
|
fld: &mut T) -> ForeignMod {
|
|
|
|
ForeignMod {
|
2017-08-07 05:54:09 +00:00
|
|
|
abi,
|
2014-09-07 17:00:54 +00:00
|
|
|
items: items.move_map(|x| fld.fold_foreign_item(x)),
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-16 02:27:40 +00:00
|
|
|
pub fn noop_fold_global_asm<T: Folder>(ga: P<GlobalAsm>,
|
|
|
|
_: &mut T) -> P<GlobalAsm> {
|
|
|
|
ga
|
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
pub fn noop_fold_variant<T: Folder>(v: Variant, fld: &mut T) -> Variant {
|
|
|
|
Spanned {
|
2014-09-07 17:00:54 +00:00
|
|
|
node: Variant_ {
|
2017-03-22 08:39:51 +00:00
|
|
|
name: fld.fold_ident(v.node.name),
|
2016-02-11 20:33:09 +00:00
|
|
|
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)),
|
2014-09-07 17:00:54 +00:00
|
|
|
},
|
2016-02-11 20:33:09 +00:00
|
|
|
span: fld.new_span(v.span),
|
|
|
|
}
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_ident<T: Folder>(i: Ident, _: &mut T) -> Ident {
|
|
|
|
i
|
|
|
|
}
|
|
|
|
|
2015-01-17 23:49:08 +00:00
|
|
|
pub fn noop_fold_usize<T: Folder>(i: usize, _: &mut T) -> usize {
|
2014-08-10 03:54:33 +00:00
|
|
|
i
|
|
|
|
}
|
|
|
|
|
2016-12-05 03:51:11 +00:00
|
|
|
pub fn noop_fold_path<T: Folder>(Path { segments, span }: Path, fld: &mut T) -> Path {
|
2014-09-07 17:00:54 +00:00
|
|
|
Path {
|
2017-03-08 17:30:06 +00:00
|
|
|
segments: segments.move_map(|PathSegment {identifier, span, parameters}| PathSegment {
|
2014-09-07 17:00:54 +00:00
|
|
|
identifier: fld.fold_ident(identifier),
|
2017-03-08 17:30:06 +00:00
|
|
|
span: fld.new_span(span),
|
2016-12-10 06:45:58 +00:00
|
|
|
parameters: parameters.map(|ps| ps.map(|ps| fld.fold_path_parameters(ps))),
|
2014-09-07 17:00:54 +00:00
|
|
|
}),
|
|
|
|
span: fld.new_span(span)
|
2014-04-11 09:28:43 +00:00
|
|
|
}
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
2014-06-26 01:15:07 +00:00
|
|
|
|
2014-11-04 02:52:52 +00:00
|
|
|
pub fn noop_fold_path_parameters<T: Folder>(path_parameters: PathParameters, fld: &mut T)
|
|
|
|
-> PathParameters
|
|
|
|
{
|
|
|
|
match path_parameters {
|
2015-12-22 15:56:13 +00:00
|
|
|
PathParameters::AngleBracketed(data) =>
|
|
|
|
PathParameters::AngleBracketed(fld.fold_angle_bracketed_parameter_data(data)),
|
|
|
|
PathParameters::Parenthesized(data) =>
|
|
|
|
PathParameters::Parenthesized(fld.fold_parenthesized_parameter_data(data)),
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_angle_bracketed_parameter_data<T: Folder>(data: AngleBracketedParameterData,
|
|
|
|
fld: &mut T)
|
|
|
|
-> AngleBracketedParameterData
|
|
|
|
{
|
2017-07-23 17:50:56 +00:00
|
|
|
let AngleBracketedParameterData { lifetimes, types, bindings, span } = data;
|
2014-11-04 02:52:52 +00:00
|
|
|
AngleBracketedParameterData { lifetimes: fld.fold_lifetimes(lifetimes),
|
2014-11-29 04:08:30 +00:00
|
|
|
types: types.move_map(|ty| fld.fold_ty(ty)),
|
2017-07-23 17:50:56 +00:00
|
|
|
bindings: bindings.move_map(|b| fld.fold_ty_binding(b)),
|
|
|
|
span: fld.new_span(span) }
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_parenthesized_parameter_data<T: Folder>(data: ParenthesizedParameterData,
|
|
|
|
fld: &mut T)
|
|
|
|
-> ParenthesizedParameterData
|
|
|
|
{
|
2015-01-10 16:54:15 +00:00
|
|
|
let ParenthesizedParameterData { inputs, output, span } = data;
|
2014-11-04 02:52:52 +00:00
|
|
|
ParenthesizedParameterData { inputs: inputs.move_map(|ty| fld.fold_ty(ty)),
|
2015-01-10 16:54:15 +00:00
|
|
|
output: output.map(|ty| fld.fold_ty(ty)),
|
|
|
|
span: fld.new_span(span) }
|
2014-11-04 02:52:52 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> {
|
2015-11-03 16:39:51 +00:00
|
|
|
l.map(|Local {id, pat, ty, init, span, attrs}| Local {
|
2014-05-17 23:38:13 +00:00
|
|
|
id: fld.new_id(id),
|
2014-09-07 17:00:54 +00:00
|
|
|
pat: fld.fold_pat(pat),
|
2016-09-17 23:14:09 +00:00
|
|
|
ty: ty.map(|t| fld.fold_ty(t)),
|
2014-09-07 17:00:54 +00:00
|
|
|
init: init.map(|e| fld.fold_expr(e)),
|
2015-11-03 16:39:51 +00:00
|
|
|
span: fld.new_span(span),
|
2016-06-18 04:01:57 +00:00
|
|
|
attrs: fold_attrs(attrs.into(), fld).into(),
|
2014-09-07 17:00:54 +00:00
|
|
|
})
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
|
|
|
|
2016-11-14 12:00:25 +00:00
|
|
|
pub fn noop_fold_attribute<T: Folder>(attr: Attribute, fld: &mut T) -> Option<Attribute> {
|
|
|
|
Some(Attribute {
|
|
|
|
id: attr.id,
|
|
|
|
style: attr.style,
|
2017-03-03 09:23:59 +00:00
|
|
|
path: fld.fold_path(attr.path),
|
|
|
|
tokens: fld.fold_tts(attr.tokens),
|
2016-11-14 12:00:25 +00:00
|
|
|
is_sugared_doc: attr.is_sugared_doc,
|
|
|
|
span: fld.new_span(attr.span),
|
2015-02-09 17:01:15 +00:00
|
|
|
})
|
2014-07-25 19:00:33 +00:00
|
|
|
}
|
2014-06-26 01:15:07 +00:00
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
|
2014-07-09 21:48:12 +00:00
|
|
|
Spanned {
|
2015-09-20 20:15:37 +00:00
|
|
|
node: Mac_ {
|
2017-02-21 05:05:59 +00:00
|
|
|
tts: fld.fold_tts(node.stream()).into(),
|
2015-09-20 20:15:37 +00:00
|
|
|
path: fld.fold_path(node.path),
|
2014-07-09 21:48:12 +00:00
|
|
|
},
|
2014-09-07 17:00:54 +00:00
|
|
|
span: fld.new_span(span)
|
2014-07-09 21:48:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-17 21:58:48 +00:00
|
|
|
pub fn noop_fold_macro_def<T: Folder>(def: MacroDef, fld: &mut T) -> MacroDef {
|
|
|
|
MacroDef {
|
|
|
|
tokens: fld.fold_tts(def.tokens.into()).into(),
|
2017-03-18 01:55:51 +00:00
|
|
|
legacy: def.legacy,
|
2017-03-17 21:58:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-20 01:58:14 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-15 10:17:24 +00:00
|
|
|
pub fn noop_fold_meta_item<T: Folder>(mi: MetaItem, fld: &mut T) -> MetaItem {
|
|
|
|
MetaItem {
|
|
|
|
name: mi.name,
|
|
|
|
node: match mi.node {
|
2016-11-15 07:37:10 +00:00
|
|
|
MetaItemKind::Word => MetaItemKind::Word,
|
|
|
|
MetaItemKind::List(mis) => {
|
|
|
|
MetaItemKind::List(mis.move_map(|e| fld.fold_meta_list_item(e)))
|
|
|
|
},
|
|
|
|
MetaItemKind::NameValue(s) => MetaItemKind::NameValue(s),
|
2014-09-07 17:00:54 +00:00
|
|
|
},
|
2016-11-15 10:17:24 +00:00
|
|
|
span: fld.new_span(mi.span)
|
|
|
|
}
|
2013-01-08 22:00:45 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_arg<T: Folder>(Arg {id, pat, ty}: Arg, fld: &mut T) -> Arg {
|
2014-01-09 13:05:33 +00:00
|
|
|
Arg {
|
2014-05-17 23:38:13 +00:00
|
|
|
id: fld.new_id(id),
|
2014-09-07 17:00:54 +00:00
|
|
|
pat: fld.fold_pat(pat),
|
|
|
|
ty: fld.fold_ty(ty)
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
pub fn noop_fold_tt<T: Folder>(tt: TokenTree, fld: &mut T) -> TokenTree {
|
|
|
|
match tt {
|
|
|
|
TokenTree::Token(span, tok) =>
|
|
|
|
TokenTree::Token(fld.new_span(span), fld.fold_token(tok)),
|
|
|
|
TokenTree::Delimited(span, delimed) => TokenTree::Delimited(fld.new_span(span), Delimited {
|
|
|
|
tts: fld.fold_tts(delimed.stream()).into(),
|
|
|
|
delim: delimed.delim,
|
|
|
|
}),
|
2014-06-27 23:10:23 +00:00
|
|
|
}
|
2013-06-06 21:17:18 +00:00
|
|
|
}
|
|
|
|
|
2017-02-21 05:05:59 +00:00
|
|
|
pub fn noop_fold_tts<T: Folder>(tts: TokenStream, fld: &mut T) -> TokenStream {
|
2017-03-17 23:41:09 +00:00
|
|
|
tts.map(|tt| fld.fold_tt(tt))
|
2014-06-27 23:10:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// apply ident folder if it's an ident, apply other folds to interpolated nodes
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_token<T: Folder>(t: token::Token, fld: &mut T) -> token::Token {
|
|
|
|
match t {
|
2016-04-16 01:12:02 +00:00
|
|
|
token::Ident(id) => token::Ident(fld.fold_ident(id)),
|
2014-10-27 08:22:52 +00:00
|
|
|
token::Lifetime(id) => token::Lifetime(fld.fold_ident(id)),
|
2016-11-02 03:03:55 +00:00
|
|
|
token::Interpolated(nt) => {
|
2018-02-27 16:11:14 +00:00
|
|
|
let nt = match Lrc::try_unwrap(nt) {
|
2016-11-02 03:03:55 +00:00
|
|
|
Ok(nt) => nt,
|
|
|
|
Err(nt) => (*nt).clone(),
|
|
|
|
};
|
2017-03-29 01:55:01 +00:00
|
|
|
Token::interpolated(fld.fold_interpolated(nt.0))
|
2016-11-02 03:03:55 +00:00
|
|
|
}
|
2014-09-07 17:00:54 +00:00
|
|
|
_ => t
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2011-07-08 23:35:09 +00:00
|
|
|
}
|
|
|
|
|
2014-07-25 19:00:33 +00:00
|
|
|
/// apply folder to elements of interpolated nodes
|
2014-06-27 23:10:23 +00:00
|
|
|
//
|
|
|
|
// NB: this can occur only when applying a fold to partially expanded code, where
|
|
|
|
// parsed pieces have gotten implanted ito *other* macro invocations. This is relevant
|
|
|
|
// for macro hygiene, but possibly not elsewhere.
|
|
|
|
//
|
|
|
|
// One problem here occurs because the types for fold_item, fold_stmt, etc. allow the
|
|
|
|
// folder to return *multiple* items; this is a problem for the nodes here, because
|
|
|
|
// they insist on having exactly one piece. One solution would be to mangle the fold
|
|
|
|
// trait to include one-to-many and one-to-one versions of these entry points, but that
|
|
|
|
// would probably confuse a lot of people and help very few. Instead, I'm just going
|
|
|
|
// to put in dynamic checks. I think the performance impact of this will be pretty much
|
|
|
|
// nonexistent. The danger is that someone will apply a fold to a partially expanded
|
|
|
|
// node, and will be confused by the fact that their "fold_item" or "fold_stmt" isn't
|
|
|
|
// getting called on NtItem or NtStmt nodes. Hopefully they'll wind up reading this
|
|
|
|
// comment, and doing something appropriate.
|
|
|
|
//
|
|
|
|
// BTW, design choice: I considered just changing the type of, e.g., NtItem to contain
|
|
|
|
// multiple items, but decided against it when I looked at parse_item_or_view_item and
|
|
|
|
// tried to figure out what I would do with multiple items there....
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
|
2014-07-25 19:00:33 +00:00
|
|
|
-> token::Nonterminal {
|
2014-09-07 17:00:54 +00:00
|
|
|
match nt {
|
2014-06-27 23:10:23 +00:00
|
|
|
token::NtItem(item) =>
|
|
|
|
token::NtItem(fld.fold_item(item)
|
2014-07-13 05:33:30 +00:00
|
|
|
// this is probably okay, because the only folds likely
|
|
|
|
// to peek inside interpolated nodes will be renamings/markings,
|
|
|
|
// which map single items to single items
|
2014-06-27 23:10:23 +00:00
|
|
|
.expect_one("expected fold to produce exactly one item")),
|
|
|
|
token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
|
|
|
|
token::NtStmt(stmt) =>
|
2016-11-02 03:03:55 +00:00
|
|
|
token::NtStmt(fld.fold_stmt(stmt)
|
2014-07-13 05:33:30 +00:00
|
|
|
// this is probably okay, because the only folds likely
|
|
|
|
// to peek inside interpolated nodes will be renamings/markings,
|
|
|
|
// which map single items to single items
|
2016-11-02 03:03:55 +00:00
|
|
|
.expect_one("expected fold to produce exactly one statement")),
|
2014-06-27 23:10:23 +00:00
|
|
|
token::NtPat(pat) => token::NtPat(fld.fold_pat(pat)),
|
|
|
|
token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
|
|
|
|
token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
|
2016-11-02 03:03:55 +00:00
|
|
|
token::NtIdent(id) => token::NtIdent(Spanned::<Ident>{node: fld.fold_ident(id.node), ..id}),
|
2017-03-03 09:23:59 +00:00
|
|
|
token::NtMeta(meta) => token::NtMeta(fld.fold_meta_item(meta)),
|
2016-11-02 03:03:55 +00:00
|
|
|
token::NtPath(path) => token::NtPath(fld.fold_path(path)),
|
2017-02-21 05:05:59 +00:00
|
|
|
token::NtTT(tt) => token::NtTT(fld.fold_tt(tt)),
|
Interpolate AST nodes in quasiquote.
This changes the `ToTokens` implementations for expressions, statements,
etc. with almost-trivial ones that produce `Interpolated(*Nt(...))`
pseudo-tokens. In this way, quasiquote now works the same way as macros
do: already-parsed AST fragments are used as-is, not reparsed.
The `ToSource` trait is removed. Quasiquote no longer involves
pretty-printing at all, which removes the need for the
`encode_with_hygiene` hack. All associated machinery is removed.
A new `Nonterminal` is added, NtArm, which the parser now interpolates.
This is just for quasiquote, not macros (although it could be in the
future).
`ToTokens` is no longer implemented for `Arg` (although this could be
added again) and `Generics` (which I don't think makes sense).
This breaks any compiler extensions that relied on the ability of
`ToTokens` to turn AST fragments back into inspectable token trees. For
this reason, this closes #16987.
As such, this is a [breaking-change].
Fixes #16472.
Fixes #15962.
Fixes #17397.
Fixes #16617.
2015-03-05 20:06:49 +00:00
|
|
|
token::NtArm(arm) => token::NtArm(fld.fold_arm(arm)),
|
2016-11-02 03:03:55 +00:00
|
|
|
token::NtImplItem(item) =>
|
|
|
|
token::NtImplItem(fld.fold_impl_item(item)
|
|
|
|
.expect_one("expected fold to produce exactly one item")),
|
|
|
|
token::NtTraitItem(item) =>
|
|
|
|
token::NtTraitItem(fld.fold_trait_item(item)
|
|
|
|
.expect_one("expected fold to produce exactly one item")),
|
2015-05-02 17:55:41 +00:00
|
|
|
token::NtGenerics(generics) => token::NtGenerics(fld.fold_generics(generics)),
|
|
|
|
token::NtWhereClause(where_clause) =>
|
|
|
|
token::NtWhereClause(fld.fold_where_clause(where_clause)),
|
2015-11-11 20:19:01 +00:00
|
|
|
token::NtArg(arg) => token::NtArg(fld.fold_arg(arg)),
|
2016-04-24 16:04:01 +00:00
|
|
|
token::NtVis(vis) => token::NtVis(fld.fold_vis(vis)),
|
2017-05-10 00:30:47 +00:00
|
|
|
token::NtLifetime(lifetime) => token::NtLifetime(fld.fold_lifetime(lifetime)),
|
2014-06-27 23:10:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
|
2014-11-09 15:14:15 +00:00
|
|
|
decl.map(|FnDecl {inputs, output, variadic}| FnDecl {
|
2014-09-07 17:00:54 +00:00
|
|
|
inputs: inputs.move_map(|x| fld.fold_arg(x)),
|
2014-11-09 15:14:15 +00:00
|
|
|
output: match output {
|
2016-02-08 14:04:11 +00:00
|
|
|
FunctionRetTy::Ty(ty) => FunctionRetTy::Ty(fld.fold_ty(ty)),
|
2017-01-03 01:33:40 +00:00
|
|
|
FunctionRetTy::Default(span) => FunctionRetTy::Default(fld.new_span(span)),
|
2014-11-09 15:14:15 +00:00
|
|
|
},
|
2017-08-07 05:54:09 +00:00
|
|
|
variadic,
|
2013-11-30 22:00:39 +00:00
|
|
|
})
|
2011-12-20 19:03:21 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
|
2014-09-06 04:27:47 +00:00
|
|
|
pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
|
|
|
|
-> TyParamBound
|
|
|
|
where T: Folder {
|
2014-09-07 17:00:54 +00:00
|
|
|
match tpb {
|
2014-12-24 06:38:10 +00:00
|
|
|
TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier),
|
2014-09-07 17:00:54 +00:00
|
|
|
RegionTyParamBound(lifetime) => RegionTyParamBound(fld.fold_lifetime(lifetime)),
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
2012-02-14 23:21:53 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
|
2016-05-17 16:51:45 +00:00
|
|
|
let TyParam {attrs, id, ident, bounds, default, span} = tp;
|
|
|
|
let attrs: Vec<_> = attrs.into();
|
2013-08-29 19:10:02 +00:00
|
|
|
TyParam {
|
2016-05-17 16:51:45 +00:00
|
|
|
attrs: attrs.into_iter()
|
|
|
|
.flat_map(|x| fld.fold_attribute(x).into_iter())
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.into(),
|
2014-09-07 17:00:54 +00:00
|
|
|
id: fld.new_id(id),
|
2016-12-23 02:16:31 +00:00
|
|
|
ident: fld.fold_ident(ident),
|
2014-09-07 17:00:54 +00:00
|
|
|
bounds: fld.fold_bounds(bounds),
|
|
|
|
default: default.map(|x| fld.fold_ty(x)),
|
2017-01-03 01:33:40 +00:00
|
|
|
span: fld.new_span(span),
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-16 19:07:26 +00:00
|
|
|
pub fn noop_fold_generic_param<T: Folder>(param: GenericParam, fld: &mut T) -> GenericParam {
|
|
|
|
match param {
|
|
|
|
GenericParam::Lifetime(l) => GenericParam::Lifetime(fld.fold_lifetime_def(l)),
|
|
|
|
GenericParam::Type(t) => GenericParam::Type(fld.fold_ty_param(t)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_generic_params<T: Folder>(
|
|
|
|
params: Vec<GenericParam>,
|
|
|
|
fld: &mut T
|
|
|
|
) -> Vec<GenericParam> {
|
|
|
|
params.move_map(|p| fld.fold_generic_param(p))
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2018-01-15 22:44:32 +00:00
|
|
|
pub fn noop_fold_label<T: Folder>(label: Label, fld: &mut T) -> Label {
|
|
|
|
Label {
|
|
|
|
ident: fld.fold_ident(label.ident),
|
|
|
|
span: fld.new_span(label.span),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_lifetime<T: Folder>(l: Lifetime, fld: &mut T) -> Lifetime {
|
2013-08-29 19:10:02 +00:00
|
|
|
Lifetime {
|
2014-09-07 17:00:54 +00:00
|
|
|
id: fld.new_id(l.id),
|
2017-03-25 21:14:18 +00:00
|
|
|
ident: fld.fold_ident(l.ident),
|
2014-09-07 17:00:54 +00:00
|
|
|
span: fld.new_span(l.span)
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_lifetime_def<T: Folder>(l: LifetimeDef, fld: &mut T)
|
|
|
|
-> LifetimeDef {
|
2016-05-17 16:51:45 +00:00
|
|
|
let attrs: Vec<_> = l.attrs.into();
|
2014-08-06 02:59:24 +00:00
|
|
|
LifetimeDef {
|
2016-05-17 16:51:45 +00:00
|
|
|
attrs: attrs.into_iter()
|
|
|
|
.flat_map(|x| fld.fold_attribute(x).into_iter())
|
|
|
|
.collect::<Vec<_>>()
|
|
|
|
.into(),
|
2014-09-07 17:00:54 +00:00
|
|
|
lifetime: fld.fold_lifetime(l.lifetime),
|
|
|
|
bounds: fld.fold_lifetimes(l.bounds),
|
2014-08-06 02:59:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_lifetimes<T: Folder>(lts: Vec<Lifetime>, fld: &mut T) -> Vec<Lifetime> {
|
|
|
|
lts.move_map(|l| fld.fold_lifetime(l))
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_lifetime_defs<T: Folder>(lts: Vec<LifetimeDef>, fld: &mut T)
|
|
|
|
-> Vec<LifetimeDef> {
|
|
|
|
lts.move_map(|l| fld.fold_lifetime_def(l))
|
2014-08-06 02:59:24 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
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))
|
2013-10-29 10:03:32 +00:00
|
|
|
}
|
|
|
|
|
2017-10-16 19:07:26 +00:00
|
|
|
pub fn noop_fold_generics<T: Folder>(Generics { params, where_clause, span }: Generics,
|
2014-09-07 17:00:54 +00:00
|
|
|
fld: &mut T) -> Generics {
|
2014-08-11 16:32:26 +00:00
|
|
|
Generics {
|
2017-10-16 19:07:26 +00:00
|
|
|
params: fld.fold_generic_params(params),
|
2014-09-07 17:00:54 +00:00
|
|
|
where_clause: fld.fold_where_clause(where_clause),
|
2016-08-10 17:39:12 +00:00
|
|
|
span: fld.new_span(span),
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_where_clause<T: Folder>(
|
2017-07-27 04:37:35 +00:00
|
|
|
WhereClause {id, predicates, span}: WhereClause,
|
2014-08-11 16:32:26 +00:00
|
|
|
fld: &mut T)
|
|
|
|
-> WhereClause {
|
|
|
|
WhereClause {
|
2014-09-07 17:00:54 +00:00
|
|
|
id: fld.new_id(id),
|
|
|
|
predicates: predicates.move_map(|predicate| {
|
2014-08-11 16:32:26 +00:00
|
|
|
fld.fold_where_predicate(predicate)
|
2017-07-27 04:37:35 +00:00
|
|
|
}),
|
2017-08-07 05:54:09 +00:00
|
|
|
span,
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_where_predicate<T: Folder>(
|
2014-11-29 04:08:30 +00:00
|
|
|
pred: WherePredicate,
|
2014-08-11 16:32:26 +00:00
|
|
|
fld: &mut T)
|
|
|
|
-> WherePredicate {
|
2014-11-29 04:08:30 +00:00
|
|
|
match pred {
|
2017-10-16 19:07:26 +00:00
|
|
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bound_generic_params,
|
2015-02-05 08:46:01 +00:00
|
|
|
bounded_ty,
|
2014-11-29 04:08:30 +00:00
|
|
|
bounds,
|
|
|
|
span}) => {
|
|
|
|
ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
|
2017-10-16 19:07:26 +00:00
|
|
|
bound_generic_params: fld.fold_generic_params(bound_generic_params),
|
2014-12-20 10:29:19 +00:00
|
|
|
bounded_ty: fld.fold_ty(bounded_ty),
|
2014-11-29 04:08:30 +00:00
|
|
|
bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
|
|
|
|
span: fld.new_span(span)
|
|
|
|
})
|
|
|
|
}
|
2014-12-20 10:29:19 +00:00
|
|
|
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{lifetime,
|
2014-12-20 10:48:43 +00:00
|
|
|
bounds,
|
2014-12-20 10:29:19 +00:00
|
|
|
span}) => {
|
|
|
|
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
|
|
|
span: fld.new_span(span),
|
|
|
|
lifetime: fld.fold_lifetime(lifetime),
|
2014-12-20 10:48:43 +00:00
|
|
|
bounds: bounds.move_map(|bound| fld.fold_lifetime(bound))
|
2014-12-20 10:29:19 +00:00
|
|
|
})
|
|
|
|
}
|
2014-11-29 04:08:30 +00:00
|
|
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
|
2017-01-16 18:32:13 +00:00
|
|
|
lhs_ty,
|
|
|
|
rhs_ty,
|
2014-11-29 04:08:30 +00:00
|
|
|
span}) => {
|
|
|
|
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{
|
|
|
|
id: fld.new_id(id),
|
2017-01-16 18:32:13 +00:00
|
|
|
lhs_ty: fld.fold_ty(lhs_ty),
|
|
|
|
rhs_ty: fld.fold_ty(rhs_ty),
|
2014-11-29 04:08:30 +00:00
|
|
|
span: fld.new_span(span)
|
|
|
|
})
|
|
|
|
}
|
2014-08-11 16:32:26 +00:00
|
|
|
}
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2015-10-25 15:33:51 +00:00
|
|
|
pub fn noop_fold_variant_data<T: Folder>(vdata: VariantData, fld: &mut T) -> VariantData {
|
|
|
|
match vdata {
|
|
|
|
ast::VariantData::Struct(fields, id) => {
|
|
|
|
ast::VariantData::Struct(fields.move_map(|f| fld.fold_struct_field(f)),
|
|
|
|
fld.new_id(id))
|
2015-10-10 00:28:40 +00:00
|
|
|
}
|
2015-10-25 15:33:51 +00:00
|
|
|
ast::VariantData::Tuple(fields, id) => {
|
|
|
|
ast::VariantData::Tuple(fields.move_map(|f| fld.fold_struct_field(f)),
|
|
|
|
fld.new_id(id))
|
|
|
|
}
|
|
|
|
ast::VariantData::Unit(id) => ast::VariantData::Unit(fld.new_id(id))
|
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2014-09-05 19:21:02 +00:00
|
|
|
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,
|
2014-11-07 11:53:45 +00:00
|
|
|
ref_id: _,
|
2014-09-05 19:21:02 +00:00
|
|
|
} = p;
|
|
|
|
ast::TraitRef {
|
2014-09-07 17:00:54 +00:00
|
|
|
path: fld.fold_path(path),
|
2014-09-05 19:21:02 +00:00
|
|
|
ref_id: id,
|
2014-11-07 11:53:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_poly_trait_ref<T: Folder>(p: PolyTraitRef, fld: &mut T) -> PolyTraitRef {
|
|
|
|
ast::PolyTraitRef {
|
2017-10-16 19:07:26 +00:00
|
|
|
bound_generic_params: fld.fold_generic_params(p.bound_generic_params),
|
2015-02-05 08:46:01 +00:00
|
|
|
trait_ref: fld.fold_trait_ref(p.trait_ref),
|
|
|
|
span: fld.new_span(p.span),
|
2013-01-13 20:02:16 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_struct_field<T: Folder>(f: StructField, fld: &mut T) -> StructField {
|
2016-04-06 08:19:10 +00:00
|
|
|
StructField {
|
|
|
|
span: fld.new_span(f.span),
|
|
|
|
id: fld.new_id(f.id),
|
|
|
|
ident: f.ident.map(|ident| fld.fold_ident(ident)),
|
2016-04-10 23:10:46 +00:00
|
|
|
vis: fld.fold_vis(f.vis),
|
2016-04-06 08:19:10 +00:00
|
|
|
ty: fld.fold_ty(f.ty),
|
|
|
|
attrs: fold_attrs(f.attrs, fld),
|
2013-06-28 00:41:35 +00:00
|
|
|
}
|
2012-02-01 03:30:40 +00:00
|
|
|
}
|
|
|
|
|
2016-10-27 00:15:13 +00:00
|
|
|
pub fn noop_fold_field<T: Folder>(f: Field, folder: &mut T) -> Field {
|
2014-09-07 17:00:54 +00:00
|
|
|
Field {
|
2016-10-27 00:15:13 +00:00
|
|
|
ident: respan(f.ident.span, folder.fold_ident(f.ident.node)),
|
|
|
|
expr: folder.fold_expr(f.expr),
|
|
|
|
span: folder.new_span(f.span),
|
|
|
|
is_shorthand: f.is_shorthand,
|
2017-01-04 03:13:01 +00:00
|
|
|
attrs: fold_thin_attrs(f.attrs, folder),
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_mt<T: Folder>(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutTy {
|
2014-01-09 13:05:33 +00:00
|
|
|
MutTy {
|
2014-09-07 17:00:54 +00:00
|
|
|
ty: folder.fold_ty(ty),
|
2017-08-07 05:54:09 +00:00
|
|
|
mutbl,
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 18:44:33 +00:00
|
|
|
pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, folder: &mut T)
|
|
|
|
-> Option<TyParamBounds> {
|
2014-09-07 17:00:54 +00:00
|
|
|
b.map(|bounds| folder.fold_bounds(bounds))
|
2014-08-28 01:46:52 +00:00
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T)
|
2014-08-28 01:46:52 +00:00
|
|
|
-> TyParamBounds {
|
2014-09-07 17:00:54 +00:00
|
|
|
bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
|
2017-12-14 07:05:49 +00:00
|
|
|
b.map(|Block {id, stmts, rules, span, recovered}| Block {
|
2014-05-17 23:38:13 +00:00
|
|
|
id: folder.new_id(id),
|
2015-11-15 20:19:53 +00:00
|
|
|
stmts: stmts.move_flat_map(|s| folder.fold_stmt(s).into_iter()),
|
2017-08-07 05:54:09 +00:00
|
|
|
rules,
|
2014-09-07 17:00:54 +00:00
|
|
|
span: folder.new_span(span),
|
2017-12-14 07:05:49 +00:00
|
|
|
recovered,
|
2013-11-30 22:00:39 +00:00
|
|
|
})
|
2013-08-29 19:10:02 +00:00
|
|
|
}
|
|
|
|
|
2016-02-09 10:36:51 +00:00
|
|
|
pub fn noop_fold_item_kind<T: Folder>(i: ItemKind, folder: &mut T) -> ItemKind {
|
2014-09-07 17:00:54 +00:00
|
|
|
match i {
|
2018-03-09 15:51:48 +00:00
|
|
|
ItemKind::ExternCrate(orig_name) => ItemKind::ExternCrate(orig_name),
|
2017-09-26 21:04:00 +00:00
|
|
|
ItemKind::Use(use_tree) => {
|
|
|
|
ItemKind::Use(use_tree.map(|tree| folder.fold_use_tree(tree)))
|
2015-01-13 15:30:17 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Static(t, m, e) => {
|
|
|
|
ItemKind::Static(folder.fold_ty(t), m, folder.fold_expr(e))
|
2013-09-07 02:11:55 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Const(t, e) => {
|
|
|
|
ItemKind::Const(folder.fold_ty(t), folder.fold_expr(e))
|
rustc: Add `const` globals to the language
This change is an implementation of [RFC 69][rfc] which adds a third kind of
global to the language, `const`. This global is most similar to what the old
`static` was, and if you're unsure about what to use then you should use a
`const`.
The semantics of these three kinds of globals are:
* A `const` does not represent a memory location, but only a value. Constants
are translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
* A `static` now always represents a memory location (unconditionally). Any
references to the same `static` are actually a reference to the same memory
location. Only values whose types ascribe to `Sync` are allowed in a `static`.
This restriction is in place because many threads may access a `static`
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
* A `static mut` continues to always represent a memory location. All references
to a `static mut` continue to be `unsafe`.
This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
* Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-`static` to a `const`.
static FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
change this code to:
const FOO: uint = 4;
match n {
FOO => { /* ... */ }
_ => { /* ... */ }
}
* Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
* Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a `const` instead.
[breaking-change]
[rfc]: https://github.com/rust-lang/rfcs/pull/246
2014-10-06 15:17:01 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Fn(decl, unsafety, constness, abi, generics, body) => {
|
2016-09-17 23:14:09 +00:00
|
|
|
let generics = folder.fold_generics(generics);
|
|
|
|
let decl = folder.fold_fn_decl(decl);
|
|
|
|
let body = folder.fold_block(body);
|
|
|
|
ItemKind::Fn(decl, unsafety, constness, abi, generics, body)
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Mod(m) => ItemKind::Mod(folder.fold_mod(m)),
|
|
|
|
ItemKind::ForeignMod(nm) => ItemKind::ForeignMod(folder.fold_foreign_mod(nm)),
|
2017-03-16 02:27:40 +00:00
|
|
|
ItemKind::GlobalAsm(ga) => ItemKind::GlobalAsm(folder.fold_global_asm(ga)),
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Ty(t, generics) => {
|
|
|
|
ItemKind::Ty(folder.fold_ty(t), folder.fold_generics(generics))
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Enum(enum_definition, generics) => {
|
2016-09-17 23:14:09 +00:00
|
|
|
let generics = folder.fold_generics(generics);
|
|
|
|
let variants = enum_definition.variants.move_map(|x| folder.fold_variant(x));
|
|
|
|
ItemKind::Enum(ast::EnumDef { variants: variants }, generics)
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Struct(struct_def, generics) => {
|
2016-09-17 23:14:09 +00:00
|
|
|
let generics = folder.fold_generics(generics);
|
|
|
|
ItemKind::Struct(folder.fold_variant_data(struct_def), generics)
|
2013-02-11 16:02:51 +00:00
|
|
|
}
|
2016-08-29 05:04:31 +00:00
|
|
|
ItemKind::Union(struct_def, generics) => {
|
2016-09-17 23:14:09 +00:00
|
|
|
let generics = folder.fold_generics(generics);
|
|
|
|
ItemKind::Union(folder.fold_variant_data(struct_def), generics)
|
2016-08-29 05:04:31 +00:00
|
|
|
}
|
2016-11-18 16:14:42 +00:00
|
|
|
ItemKind::Impl(unsafety,
|
|
|
|
polarity,
|
|
|
|
defaultness,
|
|
|
|
generics,
|
|
|
|
ifce,
|
|
|
|
ty,
|
|
|
|
impl_items) => ItemKind::Impl(
|
2016-09-17 23:14:09 +00:00
|
|
|
unsafety,
|
|
|
|
polarity,
|
2016-11-18 16:14:42 +00:00
|
|
|
defaultness,
|
2016-09-17 23:14:09 +00:00
|
|
|
folder.fold_generics(generics),
|
|
|
|
ifce.map(|trait_ref| folder.fold_trait_ref(trait_ref.clone())),
|
|
|
|
folder.fold_ty(ty),
|
|
|
|
impl_items.move_flat_map(|item| folder.fold_impl_item(item)),
|
|
|
|
),
|
2017-10-12 12:51:31 +00:00
|
|
|
ItemKind::Trait(is_auto, unsafety, generics, bounds, items) => ItemKind::Trait(
|
|
|
|
is_auto,
|
2016-09-17 23:14:09 +00:00
|
|
|
unsafety,
|
|
|
|
folder.fold_generics(generics),
|
|
|
|
folder.fold_bounds(bounds),
|
|
|
|
items.move_flat_map(|item| folder.fold_trait_item(item)),
|
|
|
|
),
|
2017-10-02 12:27:45 +00:00
|
|
|
ItemKind::TraitAlias(generics, bounds) => ItemKind::TraitAlias(
|
|
|
|
folder.fold_generics(generics),
|
|
|
|
folder.fold_bounds(bounds)),
|
2016-02-09 10:36:51 +00:00
|
|
|
ItemKind::Mac(m) => ItemKind::Mac(folder.fold_mac(m)),
|
2017-03-17 21:58:48 +00:00
|
|
|
ItemKind::MacroDef(def) => ItemKind::MacroDef(folder.fold_macro_def(def)),
|
2013-02-11 16:02:51 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
pub fn noop_fold_trait_item<T: Folder>(i: TraitItem, folder: &mut T)
|
|
|
|
-> SmallVector<TraitItem> {
|
|
|
|
SmallVector::one(TraitItem {
|
|
|
|
id: folder.new_id(i.id),
|
|
|
|
ident: folder.fold_ident(i.ident),
|
|
|
|
attrs: fold_attrs(i.attrs, folder),
|
2017-09-22 02:18:47 +00:00
|
|
|
generics: folder.fold_generics(i.generics),
|
2016-02-11 20:33:09 +00:00
|
|
|
node: match i.node {
|
2016-02-09 16:54:11 +00:00
|
|
|
TraitItemKind::Const(ty, default) => {
|
|
|
|
TraitItemKind::Const(folder.fold_ty(ty),
|
2015-03-14 18:05:00 +00:00
|
|
|
default.map(|x| folder.fold_expr(x)))
|
|
|
|
}
|
2016-02-09 16:54:11 +00:00
|
|
|
TraitItemKind::Method(sig, body) => {
|
|
|
|
TraitItemKind::Method(noop_fold_method_sig(sig, folder),
|
2015-03-11 21:38:58 +00:00
|
|
|
body.map(|x| folder.fold_block(x)))
|
|
|
|
}
|
2016-02-09 16:54:11 +00:00
|
|
|
TraitItemKind::Type(bounds, default) => {
|
|
|
|
TraitItemKind::Type(folder.fold_bounds(bounds),
|
2015-03-10 10:28:44 +00:00
|
|
|
default.map(|x| folder.fold_ty(x)))
|
|
|
|
}
|
2016-06-11 01:00:07 +00:00
|
|
|
ast::TraitItemKind::Macro(mac) => {
|
|
|
|
TraitItemKind::Macro(folder.fold_mac(mac))
|
|
|
|
}
|
2015-03-10 10:28:44 +00:00
|
|
|
},
|
2017-07-12 16:50:05 +00:00
|
|
|
span: folder.new_span(i.span),
|
|
|
|
tokens: i.tokens,
|
2016-02-11 20:33:09 +00:00
|
|
|
})
|
2014-12-02 18:07:41 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
pub fn noop_fold_impl_item<T: Folder>(i: ImplItem, folder: &mut T)
|
|
|
|
-> SmallVector<ImplItem> {
|
|
|
|
SmallVector::one(ImplItem {
|
|
|
|
id: folder.new_id(i.id),
|
2016-09-17 23:14:09 +00:00
|
|
|
vis: folder.fold_vis(i.vis),
|
2016-02-11 20:33:09 +00:00
|
|
|
ident: folder.fold_ident(i.ident),
|
|
|
|
attrs: fold_attrs(i.attrs, folder),
|
2017-09-22 02:18:47 +00:00
|
|
|
generics: folder.fold_generics(i.generics),
|
2015-12-18 22:38:28 +00:00
|
|
|
defaultness: i.defaultness,
|
2016-02-11 20:33:09 +00:00
|
|
|
node: match i.node {
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Const(ty, expr) => {
|
|
|
|
ast::ImplItemKind::Const(folder.fold_ty(ty), folder.fold_expr(expr))
|
2015-03-14 18:05:00 +00:00
|
|
|
}
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Method(sig, body) => {
|
|
|
|
ast::ImplItemKind::Method(noop_fold_method_sig(sig, folder),
|
2015-03-11 21:38:58 +00:00
|
|
|
folder.fold_block(body))
|
|
|
|
}
|
2015-11-13 13:15:04 +00:00
|
|
|
ast::ImplItemKind::Type(ty) => ast::ImplItemKind::Type(folder.fold_ty(ty)),
|
|
|
|
ast::ImplItemKind::Macro(mac) => ast::ImplItemKind::Macro(folder.fold_mac(mac))
|
2015-03-10 10:28:44 +00:00
|
|
|
},
|
2017-07-12 16:50:05 +00:00
|
|
|
span: folder.new_span(i.span),
|
|
|
|
tokens: i.tokens,
|
2016-02-11 20:33:09 +00:00
|
|
|
})
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2015-01-13 15:30:17 +00:00
|
|
|
pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
|
2014-09-07 17:00:54 +00:00
|
|
|
Mod {
|
|
|
|
inner: folder.new_span(inner),
|
2015-11-15 20:19:53 +00:00
|
|
|
items: items.move_flat_map(|x| folder.fold_item(x)),
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2017-03-05 05:15:58 +00:00
|
|
|
pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, span}: Crate,
|
2014-09-07 17:00:54 +00:00
|
|
|
folder: &mut T) -> Crate {
|
2014-11-04 22:59:42 +00:00
|
|
|
let mut items = folder.fold_item(P(ast::Item {
|
2016-04-18 19:53:50 +00:00
|
|
|
ident: keywords::Invalid.ident(),
|
2017-08-07 05:54:09 +00:00
|
|
|
attrs,
|
2014-11-04 22:59:42 +00:00
|
|
|
id: ast::DUMMY_NODE_ID,
|
2018-03-10 14:45:47 +00:00
|
|
|
vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Public),
|
2017-08-07 05:54:09 +00:00
|
|
|
span,
|
2016-02-09 10:36:51 +00:00
|
|
|
node: ast::ItemKind::Mod(module),
|
2017-07-11 00:44:46 +00:00
|
|
|
tokens: None,
|
2014-11-04 22:59:42 +00:00
|
|
|
})).into_iter();
|
|
|
|
|
|
|
|
let (module, attrs, span) = match items.next() {
|
|
|
|
Some(item) => {
|
|
|
|
assert!(items.next().is_none(),
|
|
|
|
"a crate cannot expand to more than one item");
|
|
|
|
item.and_then(|ast::Item { attrs, span, node, .. }| {
|
|
|
|
match node {
|
2016-02-09 10:36:51 +00:00
|
|
|
ast::ItemKind::Mod(m) => (m, attrs, span),
|
2014-11-04 22:59:42 +00:00
|
|
|
_ => panic!("fold converted a module to not a module"),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
None => (ast::Mod {
|
|
|
|
inner: span,
|
2015-01-13 15:30:17 +00:00
|
|
|
items: vec![],
|
|
|
|
}, vec![], span)
|
2014-11-04 22:59:42 +00:00
|
|
|
};
|
|
|
|
|
2013-08-29 19:10:02 +00:00
|
|
|
Crate {
|
2017-08-07 05:54:09 +00:00
|
|
|
module,
|
|
|
|
attrs,
|
|
|
|
span,
|
2013-02-18 06:20:36 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-27 23:10:23 +00:00
|
|
|
// fold one item into possibly many items
|
2014-09-07 17:00:54 +00:00
|
|
|
pub fn noop_fold_item<T: Folder>(i: P<Item>, folder: &mut T) -> SmallVector<P<Item>> {
|
|
|
|
SmallVector::one(i.map(|i| folder.fold_item_simple(i)))
|
2014-06-27 23:10:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// fold one item into exactly one item
|
2017-07-11 00:44:46 +00:00
|
|
|
pub fn noop_fold_item_simple<T: Folder>(Item {id, ident, attrs, node, vis, span, tokens}: Item,
|
2014-09-07 17:00:54 +00:00
|
|
|
folder: &mut T) -> Item {
|
2014-06-27 23:10:23 +00:00
|
|
|
Item {
|
2016-09-17 23:14:09 +00:00
|
|
|
id: folder.new_id(id),
|
|
|
|
vis: folder.fold_vis(vis),
|
2014-02-14 05:07:09 +00:00
|
|
|
ident: folder.fold_ident(ident),
|
2015-02-09 17:01:15 +00:00
|
|
|
attrs: fold_attrs(attrs, folder),
|
2016-09-17 23:14:09 +00:00
|
|
|
node: folder.fold_item_kind(node),
|
2017-07-11 00:44:46 +00:00
|
|
|
span: folder.new_span(span),
|
2017-07-12 16:50:05 +00:00
|
|
|
|
|
|
|
// FIXME: if this is replaced with a call to `folder.fold_tts` it causes
|
|
|
|
// an ICE during resolve... odd!
|
2017-08-07 05:54:09 +00:00
|
|
|
tokens,
|
2014-06-27 23:10:23 +00:00
|
|
|
}
|
2012-01-23 00:30:07 +00:00
|
|
|
}
|
|
|
|
|
2016-02-11 20:33:09 +00:00
|
|
|
pub fn noop_fold_foreign_item<T: Folder>(ni: ForeignItem, folder: &mut T) -> ForeignItem {
|
|
|
|
ForeignItem {
|
|
|
|
id: folder.new_id(ni.id),
|
2016-09-17 23:14:09 +00:00
|
|
|
vis: folder.fold_vis(ni.vis),
|
2016-02-11 20:33:09 +00:00
|
|
|
ident: folder.fold_ident(ni.ident),
|
|
|
|
attrs: fold_attrs(ni.attrs, folder),
|
|
|
|
node: match ni.node {
|
2016-02-09 10:31:19 +00:00
|
|
|
ForeignItemKind::Fn(fdec, generics) => {
|
|
|
|
ForeignItemKind::Fn(folder.fold_fn_decl(fdec), folder.fold_generics(generics))
|
2014-01-06 12:00:46 +00:00
|
|
|
}
|
2016-02-09 10:31:19 +00:00
|
|
|
ForeignItemKind::Static(t, m) => {
|
|
|
|
ForeignItemKind::Static(folder.fold_ty(t), m)
|
2014-01-06 12:00:46 +00:00
|
|
|
}
|
2017-09-03 18:53:58 +00:00
|
|
|
ForeignItemKind::Ty => ForeignItemKind::Ty,
|
2014-01-06 12:00:46 +00:00
|
|
|
},
|
2016-02-11 20:33:09 +00:00
|
|
|
span: folder.new_span(ni.span)
|
|
|
|
}
|
2014-01-06 12:00:46 +00:00
|
|
|
}
|
|
|
|
|
2015-03-11 06:38:27 +00:00
|
|
|
pub fn noop_fold_method_sig<T: Folder>(sig: MethodSig, folder: &mut T) -> MethodSig {
|
|
|
|
MethodSig {
|
|
|
|
abi: sig.abi,
|
|
|
|
unsafety: sig.unsafety,
|
2015-05-05 12:47:04 +00:00
|
|
|
constness: sig.constness,
|
2015-03-11 06:38:27 +00:00
|
|
|
decl: folder.fold_fn_decl(sig.decl)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-07 17:00:54 +00:00
|
|
|
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 {
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Wild => PatKind::Wild,
|
|
|
|
PatKind::Ident(binding_mode, pth1, sub) => {
|
|
|
|
PatKind::Ident(binding_mode,
|
2014-09-07 17:00:54 +00:00
|
|
|
Spanned{span: folder.new_span(pth1.span),
|
|
|
|
node: folder.fold_ident(pth1.node)},
|
|
|
|
sub.map(|x| folder.fold_pat(x)))
|
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)),
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::TupleStruct(pth, pats, ddpos) => {
|
2016-02-13 12:51:27 +00:00
|
|
|
PatKind::TupleStruct(folder.fold_path(pth),
|
2016-03-06 12:54:44 +00:00
|
|
|
pats.move_map(|x| folder.fold_pat(x)), ddpos)
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-06-11 15:47:47 +00:00
|
|
|
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))
|
2015-03-25 16:53:28 +00:00
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Struct(pth, fields, etc) => {
|
2014-09-07 17:00:54 +00:00
|
|
|
let pth = folder.fold_path(pth);
|
|
|
|
let fs = fields.move_map(|f| {
|
2014-10-06 00:36:53 +00:00
|
|
|
Spanned { span: folder.new_span(f.span),
|
|
|
|
node: ast::FieldPat {
|
2016-12-23 02:16:31 +00:00
|
|
|
ident: folder.fold_ident(f.node.ident),
|
2014-10-06 00:36:53 +00:00
|
|
|
pat: folder.fold_pat(f.node.pat),
|
|
|
|
is_shorthand: f.node.is_shorthand,
|
2017-01-04 03:13:01 +00:00
|
|
|
attrs: fold_attrs(f.node.attrs.into(), folder).into()
|
2014-10-06 00:36:53 +00:00
|
|
|
}}
|
2014-09-07 17:00:54 +00:00
|
|
|
});
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Struct(pth, fs, etc)
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-03-06 12:54:44 +00:00
|
|
|
PatKind::Tuple(elts, ddpos) => {
|
|
|
|
PatKind::Tuple(elts.move_map(|x| folder.fold_pat(x)), ddpos)
|
|
|
|
}
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Box(inner) => PatKind::Box(folder.fold_pat(inner)),
|
|
|
|
PatKind::Ref(inner, mutbl) => PatKind::Ref(folder.fold_pat(inner), mutbl),
|
2017-01-10 21:13:53 +00:00
|
|
|
PatKind::Range(e1, e2, end) => {
|
|
|
|
PatKind::Range(folder.fold_expr(e1),
|
|
|
|
folder.fold_expr(e2),
|
|
|
|
folder.fold_range_end(end))
|
2014-09-07 17:00:54 +00:00
|
|
|
},
|
2016-09-20 14:54:24 +00:00
|
|
|
PatKind::Slice(before, slice, after) => {
|
|
|
|
PatKind::Slice(before.move_map(|x| folder.fold_pat(x)),
|
2014-09-07 17:00:54 +00:00
|
|
|
slice.map(|x| folder.fold_pat(x)),
|
|
|
|
after.move_map(|x| folder.fold_pat(x)))
|
|
|
|
}
|
2018-02-24 12:27:06 +00:00
|
|
|
PatKind::Paren(inner) => PatKind::Paren(folder.fold_pat(inner)),
|
2016-02-11 18:16:33 +00:00
|
|
|
PatKind::Mac(mac) => PatKind::Mac(folder.fold_mac(mac))
|
2014-01-06 12:00:46 +00:00
|
|
|
},
|
2014-09-07 17:00:54 +00:00
|
|
|
span: folder.new_span(span)
|
|
|
|
})
|
2014-01-06 12:00:46 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 21:13:53 +00:00
|
|
|
pub fn noop_fold_range_end<T: Folder>(end: RangeEnd, _folder: &mut T) -> RangeEnd {
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mut T) -> Expr {
|
2014-09-07 17:00:54 +00:00
|
|
|
Expr {
|
|
|
|
node: match node {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Box(e) => {
|
|
|
|
ExprKind::Box(folder.fold_expr(e))
|
2015-09-24 15:00:08 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::InPlace(p, e) => {
|
|
|
|
ExprKind::InPlace(folder.fold_expr(p), folder.fold_expr(e))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2017-01-16 07:36:10 +00:00
|
|
|
ExprKind::Array(exprs) => {
|
|
|
|
ExprKind::Array(folder.fold_exprs(exprs))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Repeat(expr, count) => {
|
|
|
|
ExprKind::Repeat(folder.fold_expr(expr), folder.fold_expr(count))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Tup(exprs) => ExprKind::Tup(folder.fold_exprs(exprs)),
|
|
|
|
ExprKind::Call(f, args) => {
|
|
|
|
ExprKind::Call(folder.fold_expr(f),
|
2015-11-03 16:39:51 +00:00
|
|
|
folder.fold_exprs(args))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2017-07-06 23:39:55 +00:00
|
|
|
ExprKind::MethodCall(seg, args) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::MethodCall(
|
2017-07-06 23:39:55 +00:00
|
|
|
PathSegment {
|
|
|
|
identifier: folder.fold_ident(seg.identifier),
|
|
|
|
span: folder.new_span(seg.span),
|
|
|
|
parameters: seg.parameters.map(|ps| {
|
|
|
|
ps.map(|ps| folder.fold_path_parameters(ps))
|
|
|
|
}),
|
|
|
|
},
|
2015-11-03 16:39:51 +00:00
|
|
|
folder.fold_exprs(args))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Binary(binop, lhs, rhs) => {
|
|
|
|
ExprKind::Binary(binop,
|
2014-09-07 17:00:54 +00:00
|
|
|
folder.fold_expr(lhs),
|
|
|
|
folder.fold_expr(rhs))
|
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Unary(binop, ohs) => {
|
|
|
|
ExprKind::Unary(binop, folder.fold_expr(ohs))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Lit(l) => ExprKind::Lit(l),
|
|
|
|
ExprKind::Cast(expr, ty) => {
|
|
|
|
ExprKind::Cast(folder.fold_expr(expr), folder.fold_ty(ty))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Type(expr, ty) => {
|
|
|
|
ExprKind::Type(folder.fold_expr(expr), folder.fold_ty(ty))
|
2015-02-01 07:59:46 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::AddrOf(m, ohs) => ExprKind::AddrOf(m, folder.fold_expr(ohs)),
|
|
|
|
ExprKind::If(cond, tr, fl) => {
|
|
|
|
ExprKind::If(folder.fold_expr(cond),
|
2014-09-07 17:00:54 +00:00
|
|
|
folder.fold_block(tr),
|
|
|
|
fl.map(|x| folder.fold_expr(x)))
|
|
|
|
}
|
2018-02-24 00:12:35 +00:00
|
|
|
ExprKind::IfLet(pats, expr, tr, fl) => {
|
|
|
|
ExprKind::IfLet(pats.move_map(|pat| folder.fold_pat(pat)),
|
2014-08-25 01:04:29 +00:00
|
|
|
folder.fold_expr(expr),
|
|
|
|
folder.fold_block(tr),
|
|
|
|
fl.map(|x| folder.fold_expr(x)))
|
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprKind::While(cond, body, opt_label) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::While(folder.fold_expr(cond),
|
2014-09-07 17:00:54 +00:00
|
|
|
folder.fold_block(body),
|
2018-01-15 22:44:32 +00:00
|
|
|
opt_label.map(|label| folder.fold_label(label)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2018-02-24 00:12:35 +00:00
|
|
|
ExprKind::WhileLet(pats, expr, body, opt_label) => {
|
|
|
|
ExprKind::WhileLet(pats.move_map(|pat| folder.fold_pat(pat)),
|
2014-10-03 02:45:46 +00:00
|
|
|
folder.fold_expr(expr),
|
|
|
|
folder.fold_block(body),
|
2018-01-15 22:44:32 +00:00
|
|
|
opt_label.map(|label| folder.fold_label(label)))
|
2014-10-03 02:45:46 +00:00
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprKind::ForLoop(pat, iter, body, opt_label) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::ForLoop(folder.fold_pat(pat),
|
2014-09-07 17:00:54 +00:00
|
|
|
folder.fold_expr(iter),
|
|
|
|
folder.fold_block(body),
|
2018-01-15 22:44:32 +00:00
|
|
|
opt_label.map(|label| folder.fold_label(label)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprKind::Loop(body, opt_label) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Loop(folder.fold_block(body),
|
2018-01-15 22:44:32 +00:00
|
|
|
opt_label.map(|label| folder.fold_label(label)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Match(expr, arms) => {
|
|
|
|
ExprKind::Match(folder.fold_expr(expr),
|
2015-09-30 04:18:09 +00:00
|
|
|
arms.move_map(|x| folder.fold_arm(x)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2017-10-07 14:36:28 +00:00
|
|
|
ExprKind::Closure(capture_clause, movability, decl, body, span) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Closure(capture_clause,
|
2017-10-07 14:36:28 +00:00
|
|
|
movability,
|
2016-04-20 18:44:07 +00:00
|
|
|
folder.fold_fn_decl(decl),
|
2016-10-25 23:17:29 +00:00
|
|
|
folder.fold_expr(body),
|
2016-04-20 18:44:07 +00:00
|
|
|
folder.new_span(span))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)),
|
|
|
|
ExprKind::Assign(el, er) => {
|
|
|
|
ExprKind::Assign(folder.fold_expr(el), folder.fold_expr(er))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::AssignOp(op, el, er) => {
|
|
|
|
ExprKind::AssignOp(op,
|
2014-09-07 17:00:54 +00:00
|
|
|
folder.fold_expr(el),
|
|
|
|
folder.fold_expr(er))
|
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Field(el, ident) => {
|
|
|
|
ExprKind::Field(folder.fold_expr(el),
|
2015-04-03 08:27:04 +00:00
|
|
|
respan(folder.new_span(ident.span),
|
|
|
|
folder.fold_ident(ident.node)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::TupField(el, ident) => {
|
|
|
|
ExprKind::TupField(folder.fold_expr(el),
|
2015-04-03 08:27:04 +00:00
|
|
|
respan(folder.new_span(ident.span),
|
|
|
|
folder.fold_usize(ident.node)))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Index(el, er) => {
|
|
|
|
ExprKind::Index(folder.fold_expr(el), folder.fold_expr(er))
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2016-01-13 06:23:31 +00:00
|
|
|
ExprKind::Range(e1, e2, lim) => {
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Range(e1.map(|x| folder.fold_expr(x)),
|
2016-01-13 06:23:31 +00:00
|
|
|
e2.map(|x| folder.fold_expr(x)),
|
|
|
|
lim)
|
2014-12-13 05:41:02 +00:00
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Path(qself, path) => {
|
2015-02-17 17:29:13 +00:00
|
|
|
let qself = qself.map(|QSelf { ty, position }| {
|
|
|
|
QSelf {
|
|
|
|
ty: folder.fold_ty(ty),
|
2017-08-07 05:54:09 +00:00
|
|
|
position,
|
2015-02-17 17:29:13 +00:00
|
|
|
}
|
|
|
|
});
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Path(qself, folder.fold_path(path))
|
2015-02-17 17:29:13 +00:00
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprKind::Break(opt_label, opt_expr) => {
|
|
|
|
ExprKind::Break(opt_label.map(|label| folder.fold_label(label)),
|
Implement the `loop_break_value` feature.
This implements RFC 1624, tracking issue #37339.
- `FnCtxt` (in typeck) gets a stack of `LoopCtxt`s, which store the
currently deduced type of that loop, the desired type, and a list of
break expressions currently seen. `loop` loops get a fresh type
variable as their initial type (this logic is stolen from that for
arrays). `while` loops get `()`.
- `break {expr}` looks up the broken loop, and unifies the type of
`expr` with the type of the loop.
- `break` with no expr unifies the loop's type with `()`.
- When building MIR, `loop` loops no longer construct a `()` value at
termination of the loop; rather, the `break` expression assigns the
result of the loop. `while` loops are unchanged.
- `break` respects contexts in which expressions may not end with braced
blocks. That is, `while break { break-value } { while-body }` is
illegal; this preserves backwards compatibility.
- The RFC did not make it clear, but I chose to make `break ()` inside
of a `while` loop illegal, just in case we wanted to do anything with
that design space in the future.
This is my first time dealing with this part of rustc so I'm sure
there's plenty of problems to pick on here ^_^
2016-10-29 22:15:06 +00:00
|
|
|
opt_expr.map(|e| folder.fold_expr(e)))
|
|
|
|
}
|
2018-01-15 22:44:32 +00:00
|
|
|
ExprKind::Continue(opt_label) => {
|
|
|
|
ExprKind::Continue(opt_label.map(|label| folder.fold_label(label)))
|
|
|
|
}
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Ret(e) => ExprKind::Ret(e.map(|x| folder.fold_expr(x))),
|
2016-11-03 08:38:17 +00:00
|
|
|
ExprKind::InlineAsm(asm) => ExprKind::InlineAsm(asm.map(|asm| {
|
|
|
|
InlineAsm {
|
|
|
|
inputs: asm.inputs.move_map(|(c, input)| {
|
|
|
|
(c, folder.fold_expr(input))
|
|
|
|
}),
|
|
|
|
outputs: asm.outputs.move_map(|out| {
|
|
|
|
InlineAsmOutput {
|
|
|
|
constraint: out.constraint,
|
|
|
|
expr: folder.fold_expr(out.expr),
|
|
|
|
is_rw: out.is_rw,
|
|
|
|
is_indirect: out.is_indirect,
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
..asm
|
|
|
|
}
|
|
|
|
})),
|
2016-02-08 15:05:05 +00:00
|
|
|
ExprKind::Mac(mac) => ExprKind::Mac(folder.fold_mac(mac)),
|
|
|
|
ExprKind::Struct(path, fields, maybe_expr) => {
|
|
|
|
ExprKind::Struct(folder.fold_path(path),
|
2014-09-07 17:00:54 +00:00
|
|
|
fields.move_map(|x| folder.fold_field(x)),
|
|
|
|
maybe_expr.map(|x| folder.fold_expr(x)))
|
|
|
|
},
|
2016-06-19 02:00:11 +00:00
|
|
|
ExprKind::Paren(ex) => {
|
|
|
|
let sub_expr = folder.fold_expr(ex);
|
|
|
|
return Expr {
|
|
|
|
// Nodes that are equal modulo `Paren` sugar no-ops should have the same ids.
|
|
|
|
id: sub_expr.id,
|
|
|
|
node: ExprKind::Paren(sub_expr),
|
|
|
|
span: folder.new_span(span),
|
|
|
|
attrs: fold_attrs(attrs.into(), folder).into(),
|
|
|
|
};
|
|
|
|
}
|
2016-12-26 13:34:03 +00:00
|
|
|
ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))),
|
2016-02-28 22:38:48 +00:00
|
|
|
ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
|
2017-02-17 23:12:47 +00:00
|
|
|
ExprKind::Catch(body) => ExprKind::Catch(folder.fold_block(body)),
|
2013-02-18 06:20:36 +00:00
|
|
|
},
|
2016-06-19 02:00:11 +00:00
|
|
|
id: folder.new_id(id),
|
2015-11-03 16:39:51 +00:00
|
|
|
span: folder.new_span(span),
|
2016-06-18 04:01:57 +00:00
|
|
|
attrs: fold_attrs(attrs.into(), folder).into(),
|
2013-01-15 04:52:28 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
|
|
|
|
2015-11-03 16:39:51 +00:00
|
|
|
pub fn noop_fold_opt_expr<T: Folder>(e: P<Expr>, folder: &mut T) -> Option<P<Expr>> {
|
|
|
|
Some(folder.fold_expr(e))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn noop_fold_exprs<T: Folder>(es: Vec<P<Expr>>, folder: &mut T) -> Vec<P<Expr>> {
|
2015-11-15 20:19:53 +00:00
|
|
|
es.move_flat_map(|e| folder.fold_opt_expr(e))
|
2015-11-03 16:39:51 +00:00
|
|
|
}
|
|
|
|
|
2016-09-04 22:49:45 +00:00
|
|
|
pub fn noop_fold_stmt<T: Folder>(Stmt {node, span, id}: Stmt, folder: &mut T) -> SmallVector<Stmt> {
|
2016-06-17 02:30:01 +00:00
|
|
|
let id = folder.new_id(id);
|
2014-09-07 17:00:54 +00:00
|
|
|
let span = folder.new_span(span);
|
2016-09-04 22:49:45 +00:00
|
|
|
noop_fold_stmt_kind(node, folder).into_iter().map(|node| {
|
|
|
|
Stmt { id: id, node: node, span: span }
|
|
|
|
}).collect()
|
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
|
2016-09-04 22:49:45 +00:00
|
|
|
pub fn noop_fold_stmt_kind<T: Folder>(node: StmtKind, folder: &mut T) -> SmallVector<StmtKind> {
|
2014-09-07 17:00:54 +00:00
|
|
|
match node {
|
2016-09-04 22:49:45 +00:00
|
|
|
StmtKind::Local(local) => SmallVector::one(StmtKind::Local(folder.fold_local(local))),
|
|
|
|
StmtKind::Item(item) => folder.fold_item(item).into_iter().map(StmtKind::Item).collect(),
|
2016-06-17 02:30:01 +00:00
|
|
|
StmtKind::Expr(expr) => {
|
2016-09-04 22:49:45 +00:00
|
|
|
folder.fold_opt_expr(expr).into_iter().map(StmtKind::Expr).collect()
|
2013-01-15 21:51:43 +00:00
|
|
|
}
|
2016-06-17 02:30:01 +00:00
|
|
|
StmtKind::Semi(expr) => {
|
2016-09-04 22:49:45 +00:00
|
|
|
folder.fold_opt_expr(expr).into_iter().map(StmtKind::Semi).collect()
|
2013-01-15 22:59:39 +00:00
|
|
|
}
|
2016-09-04 22:49:45 +00:00
|
|
|
StmtKind::Mac(mac) => SmallVector::one(StmtKind::Mac(mac.map(|(mac, semi, attrs)| {
|
|
|
|
(folder.fold_mac(mac), semi, fold_attrs(attrs.into(), folder).into())
|
|
|
|
}))),
|
2014-09-07 17:00:54 +00:00
|
|
|
}
|
2011-06-21 00:25:49 +00:00
|
|
|
}
|
2013-06-06 21:17:00 +00:00
|
|
|
|
2016-03-31 19:10:38 +00:00
|
|
|
pub fn noop_fold_vis<T: Folder>(vis: Visibility, folder: &mut T) -> Visibility {
|
2018-01-29 05:12:09 +00:00
|
|
|
match vis.node {
|
|
|
|
VisibilityKind::Restricted { path, id } => {
|
|
|
|
respan(vis.span, VisibilityKind::Restricted {
|
|
|
|
path: path.map(|path| folder.fold_path(path)),
|
|
|
|
id: folder.new_id(id),
|
|
|
|
})
|
|
|
|
}
|
2016-03-31 19:10:38 +00:00
|
|
|
_ => vis,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-06 21:17:00 +00:00
|
|
|
#[cfg(test)]
|
2015-04-24 15:30:41 +00:00
|
|
|
mod tests {
|
2015-02-27 05:00:43 +00:00
|
|
|
use std::io;
|
2016-11-17 14:04:36 +00:00
|
|
|
use ast::{self, Ident};
|
2013-06-06 21:17:00 +00:00
|
|
|
use util::parser_testing::{string_to_crate, matches_codepattern};
|
|
|
|
use print::pprust;
|
2014-07-09 21:48:12 +00:00
|
|
|
use fold;
|
2018-03-07 01:44:10 +00:00
|
|
|
use with_globals;
|
2013-06-06 21:17:00 +00:00
|
|
|
use super::*;
|
2013-09-17 06:37:54 +00:00
|
|
|
|
2013-06-06 21:17:00 +00:00
|
|
|
// this version doesn't care about getting comments or docstrings in.
|
2014-03-18 05:27:37 +00:00
|
|
|
fn fake_print_crate(s: &mut pprust::State,
|
2015-02-27 05:00:43 +00:00
|
|
|
krate: &ast::Crate) -> io::Result<()> {
|
2015-02-02 02:53:25 +00:00
|
|
|
s.print_mod(&krate.module, &krate.attrs)
|
2013-06-06 21:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// change every identifier to "zz"
|
2013-08-31 01:00:38 +00:00
|
|
|
struct ToZzIdentFolder;
|
|
|
|
|
2014-01-09 13:05:33 +00:00
|
|
|
impl Folder for ToZzIdentFolder {
|
2013-12-28 03:34:51 +00:00
|
|
|
fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
|
2016-11-17 14:04:36 +00:00
|
|
|
Ident::from_str("zz")
|
2013-08-31 01:00:38 +00:00
|
|
|
}
|
2015-01-02 21:39:05 +00:00
|
|
|
fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
|
|
|
|
fold::noop_fold_mac(mac, self)
|
2014-07-09 21:48:12 +00:00
|
|
|
}
|
2013-06-06 21:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// maybe add to expand.rs...
|
2014-11-14 17:18:10 +00:00
|
|
|
macro_rules! assert_pred {
|
2013-06-06 21:17:00 +00:00
|
|
|
($pred:expr, $predname:expr, $a:expr , $b:expr) => (
|
|
|
|
{
|
|
|
|
let pred_val = $pred;
|
|
|
|
let a_val = $a;
|
|
|
|
let b_val = $b;
|
2015-02-02 02:53:25 +00:00
|
|
|
if !(pred_val(&a_val, &b_val)) {
|
2014-10-09 19:17:22 +00:00
|
|
|
panic!("expected args satisfying {}, got {} and {}",
|
2013-06-06 21:17:00 +00:00
|
|
|
$predname, a_val, b_val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
2014-11-14 17:18:10 +00:00
|
|
|
}
|
2013-06-06 21:17:00 +00:00
|
|
|
|
|
|
|
// make sure idents get transformed everywhere
|
|
|
|
#[test] fn ident_transformation () {
|
2018-03-07 01:44:10 +00:00
|
|
|
with_globals(|| {
|
|
|
|
let mut zz_fold = ToZzIdentFolder;
|
|
|
|
let ast = string_to_crate(
|
|
|
|
"#[a] mod b {fn c (d : e, f : g) {h!(i,j,k);l;m}}".to_string());
|
|
|
|
let folded_crate = zz_fold.fold_crate(ast);
|
|
|
|
assert_pred!(
|
|
|
|
matches_codepattern,
|
|
|
|
"matches_codepattern",
|
|
|
|
pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
|
|
|
|
"#[zz]mod zz{fn zz(zz:zz,zz:zz){zz!(zz,zz,zz);zz;zz}}".to_string());
|
|
|
|
})
|
2013-06-06 21:17:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// even inside macro defs....
|
|
|
|
#[test] fn ident_transformation_in_defs () {
|
2018-03-07 01:44:10 +00:00
|
|
|
with_globals(|| {
|
|
|
|
let mut zz_fold = ToZzIdentFolder;
|
|
|
|
let ast = string_to_crate(
|
|
|
|
"macro_rules! a {(b $c:expr $(d $e:token)f+ => \
|
|
|
|
(g $(d $d $e)+))} ".to_string());
|
|
|
|
let folded_crate = zz_fold.fold_crate(ast);
|
|
|
|
assert_pred!(
|
|
|
|
matches_codepattern,
|
|
|
|
"matches_codepattern",
|
|
|
|
pprust::to_string(|s| fake_print_crate(s, &folded_crate)),
|
|
|
|
"macro_rules! zz((zz$zz:zz$(zz $zz:zz)zz+=>(zz$(zz$zz$zz)+)));".to_string());
|
|
|
|
})
|
2013-06-06 21:17:00 +00:00
|
|
|
}
|
|
|
|
}
|