From 8b0937293bdb70ab4a5efed02b90a71af2b234f6 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 29 Mar 2016 08:50:44 +0300 Subject: rustc: move rustc_front to rustc::hir. --- src/librustc/Cargo.toml | 1 - src/librustc/cfg/construct.rs | 4 +- src/librustc/cfg/graphviz.rs | 2 +- src/librustc/cfg/mod.rs | 2 +- src/librustc/dep_graph/mod.rs | 4 +- src/librustc/front/check_attr.rs | 110 - src/librustc/front/map/blocks.rs | 264 --- src/librustc/front/map/collector.rs | 342 --- src/librustc/front/map/definitions.rs | 292 --- src/librustc/front/map/mod.rs | 1128 --------- src/librustc/hir/check_attr.rs | 110 + src/librustc/hir/fold.rs | 1151 ++++++++++ src/librustc/hir/intravisit.rs | 837 +++++++ src/librustc/hir/lowering.rs | 2149 +++++++++++++++++ src/librustc/hir/map/blocks.rs | 264 +++ src/librustc/hir/map/collector.rs | 341 +++ src/librustc/hir/map/definitions.rs | 292 +++ src/librustc/hir/map/mod.rs | 1127 +++++++++ src/librustc/hir/mod.rs | 1465 ++++++++++++ src/librustc/hir/print.rs | 2413 ++++++++++++++++++++ src/librustc/hir/svh.rs | 439 ++++ src/librustc/hir/util.rs | 362 +++ src/librustc/infer/error_reporting.rs | 6 +- src/librustc/infer/mod.rs | 2 +- src/librustc/lib.rs | 14 +- src/librustc/lint/context.rs | 6 +- src/librustc/lint/mod.rs | 4 +- src/librustc/middle/astconv_util.rs | 2 +- src/librustc/middle/cstore.rs | 10 +- src/librustc/middle/dataflow.rs | 6 +- src/librustc/middle/dead.rs | 6 +- src/librustc/middle/def.rs | 2 +- src/librustc/middle/effect.rs | 6 +- src/librustc/middle/entry.rs | 6 +- src/librustc/middle/expr_use_visitor.rs | 8 +- src/librustc/middle/intrinsicck.rs | 4 +- src/librustc/middle/lang_items.rs | 6 +- src/librustc/middle/liveness.rs | 12 +- src/librustc/middle/mem_categorization.rs | 6 +- src/librustc/middle/pat_util.rs | 4 +- src/librustc/middle/reachable.rs | 8 +- src/librustc/middle/region.rs | 10 +- src/librustc/middle/resolve_lifetime.rs | 8 +- src/librustc/middle/stability.rs | 8 +- src/librustc/middle/weak_lang_items.rs | 6 +- src/librustc/mir/repr.rs | 2 +- src/librustc/mir/tcx.rs | 2 +- src/librustc/traits/select.rs | 2 +- src/librustc/ty/adjustment.rs | 2 +- src/librustc/ty/context.rs | 4 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/mod.rs | 10 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/structural_impls.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc/ty/trait_def.rs | 2 +- src/librustc/ty/util.rs | 4 +- src/librustc/util/common.rs | 6 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_back/Cargo.toml | 1 - src/librustc_back/lib.rs | 2 - src/librustc_back/svh.rs | 439 ---- src/librustc_borrowck/Cargo.toml | 1 - src/librustc_borrowck/borrowck/check_loans.rs | 2 +- .../borrowck/gather_loans/gather_moves.rs | 2 +- src/librustc_borrowck/borrowck/gather_loans/mod.rs | 8 +- .../borrowck/gather_loans/move_error.rs | 2 +- src/librustc_borrowck/borrowck/mir/mod.rs | 4 +- src/librustc_borrowck/borrowck/mod.rs | 14 +- src/librustc_borrowck/borrowck/move_data.rs | 2 +- src/librustc_borrowck/lib.rs | 1 - src/librustc_const_eval/Cargo.toml | 1 - src/librustc_const_eval/check_match.rs | 12 +- src/librustc_const_eval/eval.rs | 10 +- src/librustc_const_eval/lib.rs | 1 - src/librustc_driver/Cargo.toml | 1 - src/librustc_driver/driver.rs | 9 +- src/librustc_driver/lib.rs | 1 - src/librustc_driver/pretty.rs | 10 +- src/librustc_driver/test.rs | 6 +- src/librustc_front/Cargo.toml | 15 - src/librustc_front/fold.rs | 1151 ---------- src/librustc_front/hir.rs | 1458 ------------ src/librustc_front/intravisit.rs | 837 ------- src/librustc_front/lib.rs | 58 - src/librustc_front/lowering.rs | 2149 ----------------- src/librustc_front/print/pprust.rs | 2413 -------------------- src/librustc_front/util.rs | 362 --- src/librustc_lint/Cargo.toml | 1 - src/librustc_lint/bad_style.rs | 4 +- src/librustc_lint/builtin.rs | 6 +- src/librustc_lint/lib.rs | 1 - src/librustc_lint/types.rs | 4 +- src/librustc_lint/unused.rs | 4 +- src/librustc_metadata/Cargo.toml | 1 - src/librustc_metadata/astencode.rs | 14 +- src/librustc_metadata/creader.rs | 8 +- src/librustc_metadata/csearch.rs | 8 +- src/librustc_metadata/cstore.rs | 2 +- src/librustc_metadata/decoder.rs | 6 +- src/librustc_metadata/encoder.rs | 12 +- src/librustc_metadata/lib.rs | 1 - src/librustc_metadata/loader.rs | 2 +- src/librustc_metadata/tydecode.rs | 2 +- src/librustc_metadata/tyencode.rs | 2 +- src/librustc_mir/Cargo.toml | 1 - src/librustc_mir/build/block.rs | 2 +- src/librustc_mir/build/mod.rs | 2 +- src/librustc_mir/hair/cx/block.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 6 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/hair/cx/pattern.rs | 2 +- src/librustc_mir/hair/cx/to_ref.rs | 2 +- src/librustc_mir/hair/mod.rs | 2 +- src/librustc_mir/lib.rs | 1 - src/librustc_mir/mir_map.rs | 5 +- src/librustc_passes/Cargo.toml | 1 - src/librustc_passes/consts.rs | 4 +- src/librustc_passes/lib.rs | 1 - src/librustc_passes/loops.rs | 6 +- src/librustc_passes/rvalues.rs | 4 +- src/librustc_passes/static_recursion.rs | 6 +- src/librustc_plugin/Cargo.toml | 1 - src/librustc_plugin/build.rs | 6 +- src/librustc_plugin/lib.rs | 1 - src/librustc_privacy/Cargo.toml | 1 - src/librustc_privacy/lib.rs | 7 +- src/librustc_resolve/Cargo.toml | 1 - src/librustc_resolve/build_reduced_graph.rs | 18 +- src/librustc_resolve/check_unused.rs | 6 +- src/librustc_resolve/lib.rs | 39 +- src/librustc_save_analysis/Cargo.toml | 1 - src/librustc_save_analysis/dump_visitor.rs | 2 +- src/librustc_save_analysis/lib.rs | 7 +- src/librustc_trans/Cargo.toml | 1 - src/librustc_trans/_match.rs | 4 +- src/librustc_trans/abi.rs | 2 +- src/librustc_trans/asm.rs | 2 +- src/librustc_trans/assert_dep_graph.rs | 4 +- src/librustc_trans/back/link.rs | 2 +- src/librustc_trans/back/symbol_names.rs | 2 +- src/librustc_trans/base.rs | 9 +- src/librustc_trans/callee.rs | 4 +- src/librustc_trans/closure.rs | 2 +- src/librustc_trans/collector.rs | 6 +- src/librustc_trans/common.rs | 2 +- src/librustc_trans/consts.rs | 4 +- src/librustc_trans/controlflow.rs | 4 +- src/librustc_trans/debuginfo/create_scope_map.rs | 5 +- src/librustc_trans/debuginfo/metadata.rs | 4 +- src/librustc_trans/debuginfo/mod.rs | 7 +- src/librustc_trans/debuginfo/namespace.rs | 2 +- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/expr.rs | 7 +- src/librustc_trans/inline.rs | 2 +- src/librustc_trans/intrinsic.rs | 2 +- src/librustc_trans/lib.rs | 3 +- src/librustc_trans/mir/rvalue.rs | 2 +- src/librustc_trans/monomorphize.rs | 4 +- src/librustc_trans/symbol_names_test.rs | 4 +- src/librustc_trans/tvec.rs | 2 +- src/librustc_typeck/Cargo.toml | 1 - src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/_match.rs | 6 +- src/librustc_typeck/check/callee.rs | 2 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/demand.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 10 +- src/librustc_typeck/check/mod.rs | 10 +- src/librustc_typeck/check/op.rs | 4 +- src/librustc_typeck/check/regionck.rs | 6 +- src/librustc_typeck/check/upvar.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 4 +- src/librustc_typeck/check/writeback.rs | 8 +- src/librustc_typeck/coherence/mod.rs | 8 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/coherence/overlap.rs | 4 +- src/librustc_typeck/coherence/unsafety.rs | 4 +- src/librustc_typeck/collect.rs | 8 +- src/librustc_typeck/lib.rs | 6 +- src/librustc_typeck/variance/constraints.rs | 6 +- src/librustc_typeck/variance/terms.rs | 4 +- src/librustdoc/Cargo.toml | 1 - src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 12 +- src/librustdoc/core.rs | 4 +- src/librustdoc/doctree.rs | 2 +- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/lib.rs | 1 - src/librustdoc/passes.rs | 2 +- src/librustdoc/test.rs | 6 +- src/librustdoc/visit_ast.rs | 4 +- src/rustc/Cargo.lock | 24 - src/test/auxiliary/dummy_mir_pass.rs | 1 - src/test/auxiliary/lint_for_crate.rs | 3 +- src/test/auxiliary/lint_group_plugin_test.rs | 4 +- src/test/run-make/execution-engine/test.rs | 5 +- 205 files changed, 11314 insertions(+), 11460 deletions(-) delete mode 100644 src/librustc/front/check_attr.rs delete mode 100644 src/librustc/front/map/blocks.rs delete mode 100644 src/librustc/front/map/collector.rs delete mode 100644 src/librustc/front/map/definitions.rs delete mode 100644 src/librustc/front/map/mod.rs create mode 100644 src/librustc/hir/check_attr.rs create mode 100644 src/librustc/hir/fold.rs create mode 100644 src/librustc/hir/intravisit.rs create mode 100644 src/librustc/hir/lowering.rs create mode 100644 src/librustc/hir/map/blocks.rs create mode 100644 src/librustc/hir/map/collector.rs create mode 100644 src/librustc/hir/map/definitions.rs create mode 100644 src/librustc/hir/map/mod.rs create mode 100644 src/librustc/hir/mod.rs create mode 100644 src/librustc/hir/print.rs create mode 100644 src/librustc/hir/svh.rs create mode 100644 src/librustc/hir/util.rs delete mode 100644 src/librustc_back/svh.rs delete mode 100644 src/librustc_front/Cargo.toml delete mode 100644 src/librustc_front/fold.rs delete mode 100644 src/librustc_front/hir.rs delete mode 100644 src/librustc_front/intravisit.rs delete mode 100644 src/librustc_front/lib.rs delete mode 100644 src/librustc_front/lowering.rs delete mode 100644 src/librustc_front/print/pprust.rs delete mode 100644 src/librustc_front/util.rs (limited to 'src') diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index e7aaaef45a1..d77268219fc 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -19,6 +19,5 @@ rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_front = { path = "../librustc_front" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index cd1e3b5f30e..4fc0a092613 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -16,7 +16,7 @@ use ty::{self, TyCtxt}; use syntax::ast; use syntax::ptr::P; -use rustc_front::hir::{self, PatKind}; +use hir::{self, PatKind}; struct CFGBuilder<'a, 'tcx: 'a> { tcx: &'a TyCtxt<'tcx>, @@ -257,7 +257,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.match_(expr.id, &discr, &arms, pred) } - hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => { + hir::ExprBinary(op, ref l, ref r) if hir::util::lazy_binop(op.node) => { // // [pred] // | diff --git a/src/librustc/cfg/graphviz.rs b/src/librustc/cfg/graphviz.rs index c867ec94b25..c651baae282 100644 --- a/src/librustc/cfg/graphviz.rs +++ b/src/librustc/cfg/graphviz.rs @@ -17,7 +17,7 @@ use graphviz::IntoCow; use syntax::ast; -use front::map as ast_map; +use hir::map as ast_map; use cfg; pub type Node<'a> = (cfg::CFGIndex, &'a cfg::CFGNode); diff --git a/src/librustc/cfg/mod.rs b/src/librustc/cfg/mod.rs index 8df4dc5fce5..e86bf6ebc58 100644 --- a/src/librustc/cfg/mod.rs +++ b/src/librustc/cfg/mod.rs @@ -14,7 +14,7 @@ use rustc_data_structures::graph; use ty::TyCtxt; use syntax::ast; -use rustc_front::hir; +use hir; mod construct; pub mod graphviz; diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index 731c33868df..70e7f675fce 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -12,8 +12,8 @@ use self::thread::{DepGraphThreadData, DepMessage}; use middle::def_id::DefId; use syntax::ast::NodeId; use ty::TyCtxt; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; +use hir; +use hir::intravisit::Visitor; use std::rc::Rc; mod dep_tracking_map; diff --git a/src/librustc/front/check_attr.rs b/src/librustc/front/check_attr.rs deleted file mode 100644 index 085acc198d1..00000000000 --- a/src/librustc/front/check_attr.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use session::Session; - -use syntax::ast; -use syntax::attr::AttrMetaMethods; -use syntax::visit; -use syntax::visit::Visitor; - -#[derive(Copy, Clone, PartialEq)] -enum Target { - Fn, - Struct, - Enum, - Other, -} - -impl Target { - fn from_item(item: &ast::Item) -> Target { - match item.node { - ast::ItemKind::Fn(..) => Target::Fn, - ast::ItemKind::Struct(..) => Target::Struct, - ast::ItemKind::Enum(..) => Target::Enum, - _ => Target::Other, - } - } -} - -struct CheckAttrVisitor<'a> { - sess: &'a Session, -} - -impl<'a> CheckAttrVisitor<'a> { - fn check_inline(&self, attr: &ast::Attribute, target: Target) { - if target != Target::Fn { - span_err!(self.sess, attr.span, E0518, "attribute should be applied to function"); - } - } - - fn check_repr(&self, attr: &ast::Attribute, target: Target) { - let words = match attr.meta_item_list() { - Some(words) => words, - None => { - return; - } - }; - for word in words { - let word: &str = &word.name(); - let message = match word { - "C" => { - if target != Target::Struct && target != Target::Enum { - "attribute should be applied to struct or enum" - } else { - continue - } - } - "packed" | - "simd" => { - if target != Target::Struct { - "attribute should be applied to struct" - } else { - continue - } - } - "i8" | "u8" | "i16" | "u16" | - "i32" | "u32" | "i64" | "u64" | - "isize" | "usize" => { - if target != Target::Enum { - "attribute should be applied to enum" - } else { - continue - } - } - _ => continue, - }; - span_err!(self.sess, attr.span, E0517, "{}", message); - } - } - - fn check_attribute(&self, attr: &ast::Attribute, target: Target) { - let name: &str = &attr.name(); - match name { - "inline" => self.check_inline(attr, target), - "repr" => self.check_repr(attr, target), - _ => (), - } - } -} - -impl<'a, 'v> Visitor<'v> for CheckAttrVisitor<'a> { - fn visit_item(&mut self, item: &ast::Item) { - let target = Target::from_item(item); - for attr in &item.attrs { - self.check_attribute(attr, target); - } - visit::walk_item(self, item); - } -} - -pub fn check_crate(sess: &Session, krate: &ast::Crate) { - visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate); -} diff --git a/src/librustc/front/map/blocks.rs b/src/librustc/front/map/blocks.rs deleted file mode 100644 index 2eb3d56bb5e..00000000000 --- a/src/librustc/front/map/blocks.rs +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! This module provides a simplified abstraction for working with -//! code blocks identified by their integer node-id. In particular, -//! it captures a common set of attributes that all "function-like -//! things" (represented by `FnLike` instances) share. For example, -//! all `FnLike` instances have a type signature (be it explicit or -//! inferred). And all `FnLike` instances have a body, i.e. the code -//! that is run when the function-like thing it represents is invoked. -//! -//! With the above abstraction in place, one can treat the program -//! text as a collection of blocks of code (and most such blocks are -//! nested within a uniquely determined `FnLike`), and users can ask -//! for the `Code` associated with a particular NodeId. - -pub use self::Code::*; - -use front::map::{self, Node}; -use syntax::abi; -use rustc_front::hir::{Block, FnDecl}; -use syntax::ast::{Attribute, Name, NodeId}; -use syntax::attr::ThinAttributesExt; -use rustc_front::hir as ast; -use syntax::codemap::Span; -use rustc_front::intravisit::FnKind; - -/// An FnLikeNode is a Node that is like a fn, in that it has a decl -/// and a body (as well as a NodeId, a span, etc). -/// -/// More specifically, it is one of either: -/// - A function item, -/// - A closure expr (i.e. an ExprClosure), or -/// - The default implementation for a trait method. -/// -/// To construct one, use the `Code::from_node` function. -#[derive(Copy, Clone)] -pub struct FnLikeNode<'a> { node: map::Node<'a> } - -/// MaybeFnLike wraps a method that indicates if an object -/// corresponds to some FnLikeNode. -pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; } - -/// Components shared by fn-like things (fn items, methods, closures). -pub struct FnParts<'a> { - pub decl: &'a FnDecl, - pub body: &'a Block, - pub kind: FnKind<'a>, - pub span: Span, - pub id: NodeId, -} - -impl MaybeFnLike for ast::Item { - fn is_fn_like(&self) -> bool { - match self.node { ast::ItemFn(..) => true, _ => false, } - } -} - -impl MaybeFnLike for ast::TraitItem { - fn is_fn_like(&self) -> bool { - match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, } - } -} - -impl MaybeFnLike for ast::Expr { - fn is_fn_like(&self) -> bool { - match self.node { - ast::ExprClosure(..) => true, - _ => false, - } - } -} - -/// Carries either an FnLikeNode or a Block, as these are the two -/// constructs that correspond to "code" (as in, something from which -/// we can construct a control-flow graph). -#[derive(Copy, Clone)] -pub enum Code<'a> { - FnLikeCode(FnLikeNode<'a>), - BlockCode(&'a Block), -} - -impl<'a> Code<'a> { - pub fn id(&self) -> NodeId { - match *self { - FnLikeCode(node) => node.id(), - BlockCode(block) => block.id, - } - } - - /// Attempts to construct a Code from presumed FnLike or Block node input. - pub fn from_node(node: Node) -> Option { - if let map::NodeBlock(block) = node { - Some(BlockCode(block)) - } else { - FnLikeNode::from_node(node).map(|fn_like| FnLikeCode(fn_like)) - } - } -} - -/// These are all the components one can extract from a fn item for -/// use when implementing FnLikeNode operations. -struct ItemFnParts<'a> { - name: Name, - decl: &'a ast::FnDecl, - unsafety: ast::Unsafety, - constness: ast::Constness, - abi: abi::Abi, - vis: ast::Visibility, - generics: &'a ast::Generics, - body: &'a Block, - id: NodeId, - span: Span, - attrs: &'a [Attribute], -} - -/// These are all the components one can extract from a closure expr -/// for use when implementing FnLikeNode operations. -struct ClosureParts<'a> { - decl: &'a FnDecl, - body: &'a Block, - id: NodeId, - span: Span, - attrs: &'a [Attribute], -} - -impl<'a> ClosureParts<'a> { - fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self { - ClosureParts { decl: d, body: b, id: id, span: s, attrs: attrs } - } -} - -impl<'a> FnLikeNode<'a> { - /// Attempts to construct a FnLikeNode from presumed FnLike node input. - pub fn from_node(node: Node) -> Option { - let fn_like = match node { - map::NodeItem(item) => item.is_fn_like(), - map::NodeTraitItem(tm) => tm.is_fn_like(), - map::NodeImplItem(_) => true, - map::NodeExpr(e) => e.is_fn_like(), - _ => false - }; - if fn_like { - Some(FnLikeNode { - node: node - }) - } else { - None - } - } - - pub fn to_fn_parts(self) -> FnParts<'a> { - FnParts { - decl: self.decl(), - body: self.body(), - kind: self.kind(), - span: self.span(), - id: self.id(), - } - } - - pub fn body(self) -> &'a Block { - self.handle(|i: ItemFnParts<'a>| &*i.body, - |_, _, _: &'a ast::MethodSig, _, body: &'a ast::Block, _, _| body, - |c: ClosureParts<'a>| c.body) - } - - pub fn decl(self) -> &'a FnDecl { - self.handle(|i: ItemFnParts<'a>| &*i.decl, - |_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl, - |c: ClosureParts<'a>| c.decl) - } - - pub fn span(self) -> Span { - self.handle(|i: ItemFnParts| i.span, - |_, _, _: &'a ast::MethodSig, _, _, span, _| span, - |c: ClosureParts| c.span) - } - - pub fn id(self) -> NodeId { - self.handle(|i: ItemFnParts| i.id, - |id, _, _: &'a ast::MethodSig, _, _, _, _| id, - |c: ClosureParts| c.id) - } - - pub fn kind(self) -> FnKind<'a> { - let item = |p: ItemFnParts<'a>| -> FnKind<'a> { - FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs) - }; - let closure = |c: ClosureParts<'a>| { - FnKind::Closure(c.attrs) - }; - let method = |_, name: Name, sig: &'a ast::MethodSig, vis, _, _, attrs| { - FnKind::Method(name, sig, vis, attrs) - }; - self.handle(item, method, closure) - } - - fn handle(self, item_fn: I, method: M, closure: C) -> A where - I: FnOnce(ItemFnParts<'a>) -> A, - M: FnOnce(NodeId, - Name, - &'a ast::MethodSig, - Option, - &'a ast::Block, - Span, - &'a [Attribute]) - -> A, - C: FnOnce(ClosureParts<'a>) -> A, - { - match self.node { - map::NodeItem(i) => match i.node { - ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) => - item_fn(ItemFnParts { - id: i.id, - name: i.name, - decl: &decl, - unsafety: unsafety, - body: &block, - generics: generics, - abi: abi, - vis: i.vis, - constness: constness, - span: i.span, - attrs: &i.attrs, - }), - _ => bug!("item FnLikeNode that is not fn-like"), - }, - map::NodeTraitItem(ti) => match ti.node { - ast::MethodTraitItem(ref sig, Some(ref body)) => { - method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs) - } - _ => bug!("trait method FnLikeNode that is not fn-like"), - }, - map::NodeImplItem(ii) => { - match ii.node { - ast::ImplItemKind::Method(ref sig, ref body) => { - method(ii.id, ii.name, sig, Some(ii.vis), body, ii.span, &ii.attrs) - } - _ => { - bug!("impl method FnLikeNode that is not fn-like") - } - } - } - map::NodeExpr(e) => match e.node { - ast::ExprClosure(_, ref decl, ref block) => - closure(ClosureParts::new(&decl, - &block, - e.id, - e.span, - e.attrs.as_attr_slice())), - _ => bug!("expr FnLikeNode that is not fn-like"), - }, - _ => bug!("other FnLikeNode that is not fn-like"), - } - } -} diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs deleted file mode 100644 index 4ae03b1b9d7..00000000000 --- a/src/librustc/front/map/collector.rs +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use super::*; -use super::MapEntry::*; - -use rustc_front::hir::*; -use rustc_front::util; -use rustc_front::intravisit::{self, Visitor}; -use middle::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; -use std::iter::repeat; -use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; -use syntax::codemap::Span; - -/// A Visitor that walks over an AST and collects Node's into an AST -/// Map. -pub struct NodeCollector<'ast> { - pub krate: &'ast Crate, - pub map: Vec>, - pub definitions: Definitions, - pub parent_node: NodeId, -} - -impl<'ast> NodeCollector<'ast> { - pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { - let mut collector = NodeCollector { - krate: krate, - map: vec![], - definitions: Definitions::new(), - parent_node: CRATE_NODE_ID, - }; - collector.insert_entry(CRATE_NODE_ID, RootCrate); - - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); - assert_eq!(result, CRATE_DEF_INDEX); - - collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); - - collector - } - - pub fn extend(krate: &'ast Crate, - parent: &'ast InlinedParent, - parent_node: NodeId, - parent_def_path: DefPath, - parent_def_id: DefId, - map: Vec>, - definitions: Definitions) - -> NodeCollector<'ast> { - let mut collector = NodeCollector { - krate: krate, - map: map, - parent_node: parent_node, - definitions: definitions, - }; - - assert_eq!(parent_def_path.krate, parent_def_id.krate); - let root_path = Box::new(InlinedRootPath { - data: parent_def_path.data, - def_id: parent_def_id, - }); - - collector.insert_entry(parent_node, RootInlinedParent(parent)); - collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); - - collector - } - - fn parent_def(&self) -> Option { - let mut parent_node = Some(self.parent_node); - while let Some(p) = parent_node { - if let Some(q) = self.definitions.opt_def_index(p) { - return Some(q); - } - parent_node = self.map[p as usize].parent_node(); - } - None - } - - fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { - let parent_def = self.parent_def(); - debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.definitions.create_def_with_parent(parent_def, node_id, data) - } - - fn create_def_with_parent(&mut self, - parent: Option, - node_id: NodeId, - data: DefPathData) - -> DefIndex { - self.definitions.create_def_with_parent(parent, node_id, data) - } - - fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { - debug!("ast_map: {:?} => {:?}", id, entry); - let len = self.map.len(); - if id as usize >= len { - self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); - } - self.map[id as usize] = entry; - } - - fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex { - self.insert(id, node); - self.create_def(id, data) - } - - fn insert(&mut self, id: NodeId, node: Node<'ast>) { - let entry = MapEntry::from_node(self.parent_node, node); - self.insert_entry(id, entry); - } -} - -impl<'ast> Visitor<'ast> for NodeCollector<'ast> { - /// Because we want to track parent items and so forth, enable - /// deep walking so that we walk nested items in the context of - /// their outer items. - fn visit_nested_item(&mut self, item: ItemId) { - debug!("visit_nested_item: {:?}", item); - self.visit_item(self.krate.item(item.id)) - } - - fn visit_item(&mut self, i: &'ast Item) { - debug!("visit_item: {:?}", i); - - // Pick the def data. This need not be unique, but the more - // information we encapsulate into - let def_data = match i.node { - ItemDefaultImpl(..) | ItemImpl(..) => - DefPathData::Impl, - ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | - ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | - ItemTy(..) => - DefPathData::TypeNs(i.name), - ItemStatic(..) | ItemConst(..) | ItemFn(..) => - DefPathData::ValueNs(i.name), - ItemUse(..) => - DefPathData::Misc, - }; - - self.insert_def(i.id, NodeItem(i), def_data); - - let parent_node = self.parent_node; - self.parent_node = i.id; - - match i.node { - ItemImpl(..) => {} - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - let variant_def_index = - self.insert_def(v.node.data.id(), - NodeVariant(v), - DefPathData::EnumVariant(v.node.name)); - - for field in v.node.data.fields() { - self.create_def_with_parent( - Some(variant_def_index), - field.id, - DefPathData::Field(field.name)); - } - } - } - ItemForeignMod(..) => { - } - ItemStruct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.insert_def(struct_def.id(), - NodeStructCtor(struct_def), - DefPathData::StructCtor); - } - - for field in struct_def.fields() { - self.create_def(field.id, DefPathData::Field(field.name)); - } - } - ItemTrait(_, _, ref bounds, _) => { - for b in bounds.iter() { - if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { - self.insert(t.trait_ref.ref_id, NodeItem(i)); - } - } - } - ItemUse(ref view_path) => { - match view_path.node { - ViewPathList(_, ref paths) => { - for path in paths { - self.insert(path.node.id(), NodeItem(i)); - } - } - _ => () - } - } - _ => {} - } - intravisit::walk_item(self, i); - self.parent_node = parent_node; - } - - fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - self.insert_def(foreign_item.id, - NodeForeignItem(foreign_item), - DefPathData::ValueNs(foreign_item.name)); - - let parent_node = self.parent_node; - self.parent_node = foreign_item.id; - intravisit::walk_foreign_item(self, foreign_item); - self.parent_node = parent_node; - } - - fn visit_generics(&mut self, generics: &'ast Generics) { - for ty_param in generics.ty_params.iter() { - self.insert_def(ty_param.id, - NodeTyParam(ty_param), - DefPathData::TypeParam(ty_param.name)); - } - - intravisit::walk_generics(self, generics); - } - - fn visit_trait_item(&mut self, ti: &'ast TraitItem) { - let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), - }; - - self.insert(ti.id, NodeTraitItem(ti)); - self.create_def(ti.id, def_data); - - let parent_node = self.parent_node; - self.parent_node = ti.id; - - match ti.node { - ConstTraitItem(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_trait_item(self, ti); - - self.parent_node = parent_node; - } - - fn visit_impl_item(&mut self, ii: &'ast ImplItem) { - let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), - }; - - self.insert_def(ii.id, NodeImplItem(ii), def_data); - - let parent_node = self.parent_node; - self.parent_node = ii.id; - - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_impl_item(self, ii); - - self.parent_node = parent_node; - } - - fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - - if let Some(id) = maybe_binding { - self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); - } else { - self.insert(pat.id, NodePat(pat)); - } - - let parent_node = self.parent_node; - self.parent_node = pat.id; - intravisit::walk_pat(self, pat); - self.parent_node = parent_node; - } - - fn visit_expr(&mut self, expr: &'ast Expr) { - self.insert(expr.id, NodeExpr(expr)); - - match expr.node { - ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); } - _ => { } - } - - let parent_node = self.parent_node; - self.parent_node = expr.id; - intravisit::walk_expr(self, expr); - self.parent_node = parent_node; - } - - fn visit_stmt(&mut self, stmt: &'ast Stmt) { - let id = util::stmt_id(stmt); - self.insert(id, NodeStmt(stmt)); - let parent_node = self.parent_node; - self.parent_node = id; - intravisit::walk_stmt(self, stmt); - self.parent_node = parent_node; - } - - fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, - b: &'ast Block, s: Span, id: NodeId) { - assert_eq!(self.parent_node, id); - intravisit::walk_fn(self, fk, fd, b, s); - } - - fn visit_block(&mut self, block: &'ast Block) { - self.insert(block.id, NodeBlock(block)); - let parent_node = self.parent_node; - self.parent_node = block.id; - intravisit::walk_block(self, block); - self.parent_node = parent_node; - } - - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { - self.insert(lifetime.id, NodeLifetime(lifetime)); - } - - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { - self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); - self.visit_lifetime(&def.lifetime); - } - - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); - } -} diff --git a/src/librustc/front/map/definitions.rs b/src/librustc/front/map/definitions.rs deleted file mode 100644 index 82574b85229..00000000000 --- a/src/librustc/front/map/definitions.rs +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use middle::cstore::LOCAL_CRATE; -use middle::def_id::{DefId, DefIndex}; -use rustc_data_structures::fnv::FnvHashMap; -use syntax::ast; -use syntax::parse::token::InternedString; -use util::nodemap::NodeMap; - -#[derive(Clone)] -pub struct Definitions { - data: Vec, - key_map: FnvHashMap, - node_map: NodeMap, -} - -/// A unique identifier that we can use to lookup a definition -/// precisely. It combines the index of the definition's parent (if -/// any) with a `DisambiguatedDefPathData`. -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub struct DefKey { - /// Parent path. - pub parent: Option, - - /// Identifier of this node. - pub disambiguated_data: DisambiguatedDefPathData, -} - -/// Pair of `DefPathData` and an integer disambiguator. The integer is -/// normally 0, but in the event that there are multiple defs with the -/// same `parent` and `data`, we use this field to disambiguate -/// between them. This introduces some artificial ordering dependency -/// but means that if you have (e.g.) two impls for the same type in -/// the same module, they do get distinct def-ids. -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub struct DisambiguatedDefPathData { - pub data: DefPathData, - pub disambiguator: u32 -} - -/// For each definition, we track the following data. A definition -/// here is defined somewhat circularly as "something with a def-id", -/// but it generally corresponds to things like structs, enums, etc. -/// There are also some rather random cases (like const initializer -/// expressions) that are mostly just leftovers. -#[derive(Clone, Debug)] -pub struct DefData { - pub key: DefKey, - - /// Local ID within the HIR. - pub node_id: ast::NodeId, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub struct DefPath { - /// the path leading from the crate root to the item - pub data: Vec, - - /// what krate root is this path relative to? - pub krate: ast::CrateNum, -} - -impl DefPath { - pub fn is_local(&self) -> bool { - self.krate == LOCAL_CRATE - } - - pub fn make(start_krate: ast::CrateNum, - start_index: DefIndex, - mut get_key: FN) -> DefPath - where FN: FnMut(DefIndex) -> DefKey - { - let mut krate = start_krate; - let mut data = vec![]; - let mut index = Some(start_index); - loop { - let p = index.unwrap(); - let key = get_key(p); - match key.disambiguated_data.data { - DefPathData::CrateRoot => { - assert!(key.parent.is_none()); - break; - } - DefPathData::InlinedRoot(ref p) => { - assert!(key.parent.is_none()); - assert!(!p.def_id.is_local()); - data.extend(p.data.iter().cloned().rev()); - krate = p.def_id.krate; - break; - } - _ => { - data.push(key.disambiguated_data); - index = key.parent; - } - } - } - data.reverse(); - DefPath { data: data, krate: krate } - } -} - -/// Root of an inlined item. We track the `DefPath` of the item within -/// the original crate but also its def-id. This is kind of an -/// augmented version of a `DefPath` that includes a `DefId`. This is -/// all sort of ugly but the hope is that inlined items will be going -/// away soon anyway. -/// -/// Some of the constraints that led to the current approach: -/// -/// - I don't want to have a `DefId` in the main `DefPath` because -/// that gets serialized for incr. comp., and when reloaded the -/// `DefId` is no longer valid. I'd rather maintain the invariant -/// that every `DefId` is valid, and a potentially outdated `DefId` is -/// represented as a `DefPath`. -/// - (We don't serialize def-paths from inlined items, so it's ok to have one here.) -/// - We need to be able to extract the def-id from inline items to -/// make the symbol name. In theory we could retrace it from the -/// data, but the metadata doesn't have the required indices, and I -/// don't want to write the code to create one just for this. -/// - It may be that we don't actually need `data` at all. We'll have -/// to see about that. -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub struct InlinedRootPath { - pub data: Vec, - pub def_id: DefId, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub enum DefPathData { - // Root: these should only be used for the root nodes, because - // they are treated specially by the `def_path` function. - CrateRoot, - InlinedRoot(Box), - - // Catch-all for random DefId things like DUMMY_NODE_ID - Misc, - - // Different kinds of items and item-like things: - Impl, - TypeNs(ast::Name), // something in the type NS - ValueNs(ast::Name), // something in the value NS - MacroDef(ast::Name), - ClosureExpr, - - // Subportions of items - TypeParam(ast::Name), - LifetimeDef(ast::Name), - EnumVariant(ast::Name), - Field(ast::Name), - StructCtor, // implicit ctor for a tuple-like struct - Initializer, // initializer for a const - Binding(ast::Name), // pattern binding -} - -impl Definitions { - pub fn new() -> Definitions { - Definitions { - data: vec![], - key_map: FnvHashMap(), - node_map: NodeMap(), - } - } - - pub fn len(&self) -> usize { - self.data.len() - } - - pub fn def_key(&self, index: DefIndex) -> DefKey { - self.data[index.as_usize()].key.clone() - } - - /// Returns the path from the crate root to `index`. The root - /// nodes are not included in the path (i.e., this will be an - /// empty vector for the crate root). For an inlined item, this - /// will be the path of the item in the external crate (but the - /// path will begin with the path to the external crate). - pub fn def_path(&self, index: DefIndex) -> DefPath { - DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p)) - } - - pub fn opt_def_index(&self, node: ast::NodeId) -> Option { - self.node_map.get(&node).cloned() - } - - pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { - self.opt_def_index(node).map(DefId::local) - } - - pub fn as_local_node_id(&self, def_id: DefId) -> Option { - if def_id.krate == LOCAL_CRATE { - assert!(def_id.index.as_usize() < self.data.len()); - Some(self.data[def_id.index.as_usize()].node_id) - } else { - None - } - } - - pub fn create_def_with_parent(&mut self, - parent: Option, - node_id: ast::NodeId, - data: DefPathData) - -> DefIndex { - assert!(!self.node_map.contains_key(&node_id), - "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}", - node_id, - data, - self.data[self.node_map[&node_id].as_usize()]); - - // Find a unique DefKey. This basically means incrementing the disambiguator - // until we get no match. - let mut key = DefKey { - parent: parent, - disambiguated_data: DisambiguatedDefPathData { - data: data, - disambiguator: 0 - } - }; - - while self.key_map.contains_key(&key) { - key.disambiguated_data.disambiguator += 1; - } - - // Create the definition. - let index = DefIndex::new(self.data.len()); - self.data.push(DefData { key: key.clone(), node_id: node_id }); - self.node_map.insert(node_id, index); - self.key_map.insert(key, index); - - index - } -} - -impl DefPathData { - pub fn as_interned_str(&self) -> InternedString { - use self::DefPathData::*; - match *self { - TypeNs(name) | - ValueNs(name) | - MacroDef(name) | - TypeParam(name) | - LifetimeDef(name) | - EnumVariant(name) | - Binding(name) | - Field(name) => { - name.as_str() - } - - Impl => { - InternedString::new("{{impl}}") - } - - // note that this does not show up in user printouts - CrateRoot => { - InternedString::new("{{root}}") - } - - // note that this does not show up in user printouts - InlinedRoot(_) => { - InternedString::new("{{inlined-root}}") - } - - Misc => { - InternedString::new("{{?}}") - } - - ClosureExpr => { - InternedString::new("{{closure}}") - } - - StructCtor => { - InternedString::new("{{constructor}}") - } - - Initializer => { - InternedString::new("{{initializer}}") - } - } - } - - pub fn to_string(&self) -> String { - self.as_interned_str().to_string() - } -} - diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs deleted file mode 100644 index 817bec58407..00000000000 --- a/src/librustc/front/map/mod.rs +++ /dev/null @@ -1,1128 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use self::Node::*; -pub use self::PathElem::*; -use self::MapEntry::*; -use self::collector::NodeCollector; -pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, - DisambiguatedDefPathData, InlinedRootPath}; - -use dep_graph::{DepGraph, DepNode}; - -use middle::cstore::InlinedItem; -use middle::cstore::InlinedItem as II; -use middle::def_id::{CRATE_DEF_INDEX, DefId}; - -use syntax::abi::Abi; -use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; -use syntax::attr::ThinAttributesExt; -use syntax::codemap::{Span, Spanned}; -use syntax::parse::token; - -use rustc_front::hir::*; -use rustc_front::fold::Folder; -use rustc_front::intravisit; -use rustc_front::print::pprust; - -use arena::TypedArena; -use std::cell::RefCell; -use std::fmt; -use std::io; -use std::iter; -use std::mem; -use std::slice; - -pub mod blocks; -mod collector; -pub mod definitions; - -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum PathElem { - PathMod(Name), - PathName(Name) -} - -impl PathElem { - pub fn name(&self) -> Name { - match *self { - PathMod(name) | PathName(name) => name - } - } -} - -impl fmt::Display for PathElem { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name()) - } -} - -#[derive(Clone)] -pub struct LinkedPathNode<'a> { - node: PathElem, - next: LinkedPath<'a>, -} - -#[derive(Copy, Clone)] -pub struct LinkedPath<'a>(Option<&'a LinkedPathNode<'a>>); - -impl<'a> LinkedPath<'a> { - pub fn empty() -> LinkedPath<'a> { - LinkedPath(None) - } - - pub fn from(node: &'a LinkedPathNode) -> LinkedPath<'a> { - LinkedPath(Some(node)) - } -} - -impl<'a> Iterator for LinkedPath<'a> { - type Item = PathElem; - - fn next(&mut self) -> Option { - match self.0 { - Some(node) => { - *self = node.next; - Some(node.node) - } - None => None - } - } -} - -/// The type of the iterator used by with_path. -pub type PathElems<'a, 'b> = iter::Chain>, LinkedPath<'b>>; - -pub fn path_to_string>(path: PI) -> String { - let itr = token::get_ident_interner(); - - path.fold(String::new(), |mut s, e| { - let e = itr.get(e.name()); - if !s.is_empty() { - s.push_str("::"); - } - s.push_str(&e[..]); - s - }) -} - -#[derive(Copy, Clone, Debug)] -pub enum Node<'ast> { - NodeItem(&'ast Item), - NodeForeignItem(&'ast ForeignItem), - NodeTraitItem(&'ast TraitItem), - NodeImplItem(&'ast ImplItem), - NodeVariant(&'ast Variant), - NodeExpr(&'ast Expr), - NodeStmt(&'ast Stmt), - NodeLocal(&'ast Pat), - NodePat(&'ast Pat), - NodeBlock(&'ast Block), - - /// NodeStructCtor represents a tuple struct. - NodeStructCtor(&'ast VariantData), - - NodeLifetime(&'ast Lifetime), - NodeTyParam(&'ast TyParam) -} - -/// Represents an entry and its parent NodeID. -/// The odd layout is to bring down the total size. -#[derive(Copy, Debug)] -pub enum MapEntry<'ast> { - /// Placeholder for holes in the map. - NotPresent, - - /// All the node types, with a parent ID. - EntryItem(NodeId, &'ast Item), - EntryForeignItem(NodeId, &'ast ForeignItem), - EntryTraitItem(NodeId, &'ast TraitItem), - EntryImplItem(NodeId, &'ast ImplItem), - EntryVariant(NodeId, &'ast Variant), - EntryExpr(NodeId, &'ast Expr), - EntryStmt(NodeId, &'ast Stmt), - EntryLocal(NodeId, &'ast Pat), - EntryPat(NodeId, &'ast Pat), - EntryBlock(NodeId, &'ast Block), - EntryStructCtor(NodeId, &'ast VariantData), - EntryLifetime(NodeId, &'ast Lifetime), - EntryTyParam(NodeId, &'ast TyParam), - - /// Roots for node trees. - RootCrate, - RootInlinedParent(&'ast InlinedParent) -} - -impl<'ast> Clone for MapEntry<'ast> { - fn clone(&self) -> MapEntry<'ast> { - *self - } -} - -#[derive(Debug)] -pub struct InlinedParent { - path: Vec, - ii: InlinedItem -} - -impl<'ast> MapEntry<'ast> { - fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { - match node { - NodeItem(n) => EntryItem(p, n), - NodeForeignItem(n) => EntryForeignItem(p, n), - NodeTraitItem(n) => EntryTraitItem(p, n), - NodeImplItem(n) => EntryImplItem(p, n), - NodeVariant(n) => EntryVariant(p, n), - NodeExpr(n) => EntryExpr(p, n), - NodeStmt(n) => EntryStmt(p, n), - NodeLocal(n) => EntryLocal(p, n), - NodePat(n) => EntryPat(p, n), - NodeBlock(n) => EntryBlock(p, n), - NodeStructCtor(n) => EntryStructCtor(p, n), - NodeLifetime(n) => EntryLifetime(p, n), - NodeTyParam(n) => EntryTyParam(p, n), - } - } - - fn parent_node(self) -> Option { - Some(match self { - EntryItem(id, _) => id, - EntryForeignItem(id, _) => id, - EntryTraitItem(id, _) => id, - EntryImplItem(id, _) => id, - EntryVariant(id, _) => id, - EntryExpr(id, _) => id, - EntryStmt(id, _) => id, - EntryLocal(id, _) => id, - EntryPat(id, _) => id, - EntryBlock(id, _) => id, - EntryStructCtor(id, _) => id, - EntryLifetime(id, _) => id, - EntryTyParam(id, _) => id, - _ => return None - }) - } - - fn to_node(self) -> Option> { - Some(match self { - EntryItem(_, n) => NodeItem(n), - EntryForeignItem(_, n) => NodeForeignItem(n), - EntryTraitItem(_, n) => NodeTraitItem(n), - EntryImplItem(_, n) => NodeImplItem(n), - EntryVariant(_, n) => NodeVariant(n), - EntryExpr(_, n) => NodeExpr(n), - EntryStmt(_, n) => NodeStmt(n), - EntryLocal(_, n) => NodeLocal(n), - EntryPat(_, n) => NodePat(n), - EntryBlock(_, n) => NodeBlock(n), - EntryStructCtor(_, n) => NodeStructCtor(n), - EntryLifetime(_, n) => NodeLifetime(n), - EntryTyParam(_, n) => NodeTyParam(n), - _ => return None - }) - } -} - -/// Stores a crate and any number of inlined items from other crates. -pub struct Forest { - krate: Crate, - pub dep_graph: DepGraph, - inlined_items: TypedArena -} - -impl Forest { - pub fn new(krate: Crate, dep_graph: DepGraph) -> Forest { - Forest { - krate: krate, - dep_graph: dep_graph, - inlined_items: TypedArena::new() - } - } - - pub fn krate<'ast>(&'ast self) -> &'ast Crate { - self.dep_graph.read(DepNode::Krate); - &self.krate - } -} - -/// Represents a mapping from Node IDs to AST elements and their parent -/// Node IDs -#[derive(Clone)] -pub struct Map<'ast> { - /// The backing storage for all the AST nodes. - pub forest: &'ast Forest, - - /// Same as the dep_graph in forest, just available with one fewer - /// deref. This is a gratuitious micro-optimization. - pub dep_graph: DepGraph, - - /// NodeIds are sequential integers from 0, so we can be - /// super-compact by storing them in a vector. Not everything with - /// a NodeId is in the map, but empirically the occupancy is about - /// 75-80%, so there's not too much overhead (certainly less than - /// a hashmap, since they (at the time of writing) have a maximum - /// of 75% occupancy). - /// - /// Also, indexing is pretty quick when you've got a vector and - /// plain old integers. - map: RefCell>>, - - definitions: RefCell, -} - -impl<'ast> Map<'ast> { - /// Registers a read in the dependency graph of the AST node with - /// the given `id`. This needs to be called each time a public - /// function returns the HIR for a node -- in other words, when it - /// "reveals" the content of a node to the caller (who might not - /// otherwise have had access to those contents, and hence needs a - /// read recorded). If the function just returns a DefId or - /// NodeId, no actual content was returned, so no read is needed. - fn read(&self, id: NodeId) { - self.dep_graph.read(self.dep_node(id)); - } - - fn dep_node(&self, id0: NodeId) -> DepNode { - let map = self.map.borrow(); - let mut id = id0; - loop { - match map[id as usize] { - EntryItem(_, item) => { - let def_id = self.local_def_id(item.id); - // NB ^~~~~~~ - // - // You would expect that `item.id == id`, but this - // is not always the case. In particular, for a - // ViewPath item like `use self::{mem, foo}`, we - // map the ids for `mem` and `foo` to the - // enclosing view path item. This seems mega super - // ultra wrong, but then who am I to judge? - // -nmatsakis - return DepNode::Hir(def_id); - } - - EntryForeignItem(p, _) | - EntryTraitItem(p, _) | - EntryImplItem(p, _) | - EntryVariant(p, _) | - EntryExpr(p, _) | - EntryStmt(p, _) | - EntryLocal(p, _) | - EntryPat(p, _) | - EntryBlock(p, _) | - EntryStructCtor(p, _) | - EntryLifetime(p, _) | - EntryTyParam(p, _) => - id = p, - - RootCrate | - RootInlinedParent(_) => - // FIXME(#32015) clarify story about cross-crate dep tracking - return DepNode::Krate, - - NotPresent => - // Some nodes, notably struct fields, are not - // present in the map for whatever reason, but - // they *do* have def-ids. So if we encounter an - // empty hole, check for that case. - return self.opt_local_def_id(id) - .map(|def_id| DepNode::Hir(def_id)) - .unwrap_or_else(|| { - bug!("Walking parents from `{}` \ - led to `NotPresent` at `{}`", - id0, id) - }), - } - } - } - - pub fn num_local_def_ids(&self) -> usize { - self.definitions.borrow().len() - } - - pub fn def_key(&self, def_id: DefId) -> DefKey { - assert!(def_id.is_local()); - self.definitions.borrow().def_key(def_id.index) - } - - pub fn def_path_from_id(&self, id: NodeId) -> DefPath { - self.def_path(self.local_def_id(id)) - } - - pub fn def_path(&self, def_id: DefId) -> DefPath { - assert!(def_id.is_local()); - self.definitions.borrow().def_path(def_id.index) - } - - pub fn local_def_id(&self, node: NodeId) -> DefId { - self.opt_local_def_id(node).unwrap_or_else(|| { - bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`", - node, self.find_entry(node)) - }) - } - - pub fn opt_local_def_id(&self, node: NodeId) -> Option { - self.definitions.borrow().opt_local_def_id(node) - } - - pub fn as_local_node_id(&self, def_id: DefId) -> Option { - self.definitions.borrow().as_local_node_id(def_id) - } - - fn entry_count(&self) -> usize { - self.map.borrow().len() - } - - fn find_entry(&self, id: NodeId) -> Option> { - self.map.borrow().get(id as usize).cloned() - } - - pub fn krate(&self) -> &'ast Crate { - self.forest.krate() - } - - /// Get the attributes on the krate. This is preferable to - /// invoking `krate.attrs` because it registers a tighter - /// dep-graph access. - pub fn krate_attrs(&self) -> &'ast [ast::Attribute] { - let crate_root_def_id = DefId::local(CRATE_DEF_INDEX); - self.dep_graph.read(DepNode::Hir(crate_root_def_id)); - &self.forest.krate.attrs - } - - /// Retrieve the Node corresponding to `id`, panicking if it cannot - /// be found. - pub fn get(&self, id: NodeId) -> Node<'ast> { - match self.find(id) { - Some(node) => node, // read recorded by `find` - None => bug!("couldn't find node id {} in the AST map", id) - } - } - - pub fn get_if_local(&self, id: DefId) -> Option> { - self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` - } - - /// Retrieve the Node corresponding to `id`, returning None if - /// cannot be found. - pub fn find(&self, id: NodeId) -> Option> { - let result = self.find_entry(id).and_then(|x| x.to_node()); - if result.is_some() { - self.read(id); - } - result - } - - /// Similar to get_parent, returns the parent node id or id if there is no - /// parent. - /// This function returns the immediate parent in the AST, whereas get_parent - /// returns the enclosing item. Note that this might not be the actual parent - /// node in the AST - some kinds of nodes are not in the map and these will - /// never appear as the parent_node. So you can always walk the parent_nodes - /// from a node to the root of the ast (unless you get the same id back here - /// that can happen if the id is not in the map itself or is just weird). - pub fn get_parent_node(&self, id: NodeId) -> NodeId { - self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) - } - - /// Check if the node is an argument. An argument is a local variable whose - /// immediate parent is an item or a closure. - pub fn is_argument(&self, id: NodeId) -> bool { - match self.find(id) { - Some(NodeLocal(_)) => (), - _ => return false, - } - match self.find(self.get_parent_node(id)) { - Some(NodeItem(_)) | - Some(NodeTraitItem(_)) | - Some(NodeImplItem(_)) => true, - Some(NodeExpr(e)) => { - match e.node { - ExprClosure(..) => true, - _ => false, - } - } - _ => false, - } - } - - /// If there is some error when walking the parents (e.g., a node does not - /// have a parent in the map or a node can't be found), then we return the - /// last good node id we found. Note that reaching the crate root (id == 0), - /// is not an error, since items in the crate module have the crate root as - /// parent. - fn walk_parent_nodes(&self, start_id: NodeId, found: F) -> Result - where F: Fn(&Node<'ast>) -> bool - { - let mut id = start_id; - loop { - let parent_node = self.get_parent_node(id); - if parent_node == 0 { - return Ok(0); - } - if parent_node == id { - return Err(id); - } - - let node = self.find_entry(parent_node); - if node.is_none() { - return Err(id); - } - let node = node.unwrap().to_node(); - match node { - Some(ref node) => { - if found(node) { - return Ok(parent_node); - } - } - None => { - return Err(parent_node); - } - } - id = parent_node; - } - } - - /// Retrieve the NodeId for `id`'s parent item, or `id` itself if no - /// parent item is in this map. The "parent item" is the closest parent node - /// in the AST which is recorded by the map and is an item, either an item - /// in a module, trait, or impl. - pub fn get_parent(&self, id: NodeId) -> NodeId { - match self.walk_parent_nodes(id, |node| match *node { - NodeItem(_) | - NodeForeignItem(_) | - NodeTraitItem(_) | - NodeImplItem(_) => true, - _ => false, - }) { - Ok(id) => id, - Err(id) => id, - } - } - - /// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no - /// module parent is in this map. - fn get_module_parent(&self, id: NodeId) -> NodeId { - match self.walk_parent_nodes(id, |node| match *node { - NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true, - _ => false, - }) { - Ok(id) => id, - Err(id) => id, - } - } - - pub fn private_item_is_visible_from(&self, item: NodeId, block: NodeId) -> bool { - // A private item is visible from everything in its nearest module parent. - let visibility = self.get_module_parent(item); - let mut block_ancestor = self.get_module_parent(block); - loop { - if block_ancestor == visibility { return true } - let block_ancestor_parent = self.get_module_parent(block_ancestor); - if block_ancestor_parent == block_ancestor { return false } - block_ancestor = block_ancestor_parent; - } - } - - /// Returns the nearest enclosing scope. A scope is an item or block. - /// FIXME it is not clear to me that all items qualify as scopes - statics - /// and associated types probably shouldn't, for example. Behaviour in this - /// regard should be expected to be highly unstable. - pub fn get_enclosing_scope(&self, id: NodeId) -> Option { - match self.walk_parent_nodes(id, |node| match *node { - NodeItem(_) | - NodeForeignItem(_) | - NodeTraitItem(_) | - NodeImplItem(_) | - NodeBlock(_) => true, - _ => false, - }) { - Ok(id) => Some(id), - Err(_) => None, - } - } - - pub fn get_parent_did(&self, id: NodeId) -> DefId { - let parent = self.get_parent(id); - match self.find_entry(parent) { - Some(RootInlinedParent(&InlinedParent {ii: II::TraitItem(did, _), ..})) => did, - Some(RootInlinedParent(&InlinedParent {ii: II::ImplItem(did, _), ..})) => did, - _ => self.local_def_id(parent) - } - } - - pub fn get_foreign_abi(&self, id: NodeId) -> Abi { - let parent = self.get_parent(id); - let abi = match self.find_entry(parent) { - Some(EntryItem(_, i)) => { - match i.node { - ItemForeignMod(ref nm) => Some(nm.abi), - _ => None - } - } - /// Wrong but OK, because the only inlined foreign items are intrinsics. - Some(RootInlinedParent(_)) => Some(Abi::RustIntrinsic), - _ => None - }; - match abi { - Some(abi) => { - self.read(id); // reveals some of the content of a node - abi - } - None => bug!("expected foreign mod or inlined parent, found {}", - self.node_to_string(parent)) - } - } - - pub fn expect_item(&self, id: NodeId) -> &'ast Item { - match self.find(id) { // read recorded by `find` - Some(NodeItem(item)) => item, - _ => bug!("expected item, found {}", self.node_to_string(id)) - } - } - - pub fn expect_trait_item(&self, id: NodeId) -> &'ast TraitItem { - match self.find(id) { - Some(NodeTraitItem(item)) => item, - _ => bug!("expected trait item, found {}", self.node_to_string(id)) - } - } - - pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData { - match self.find(id) { - Some(NodeItem(i)) => { - match i.node { - ItemStruct(ref struct_def, _) => struct_def, - _ => bug!("struct ID bound to non-struct") - } - } - Some(NodeVariant(variant)) => { - if variant.node.data.is_struct() { - &variant.node.data - } else { - bug!("struct ID bound to enum variant that isn't struct-like") - } - } - _ => bug!("expected struct, found {}", self.node_to_string(id)), - } - } - - pub fn expect_variant(&self, id: NodeId) -> &'ast Variant { - match self.find(id) { - Some(NodeVariant(variant)) => variant, - _ => bug!("expected variant, found {}", self.node_to_string(id)), - } - } - - pub fn expect_foreign_item(&self, id: NodeId) -> &'ast ForeignItem { - match self.find(id) { - Some(NodeForeignItem(item)) => item, - _ => bug!("expected foreign item, found {}", self.node_to_string(id)) - } - } - - pub fn expect_expr(&self, id: NodeId) -> &'ast Expr { - match self.find(id) { // read recorded by find - Some(NodeExpr(expr)) => expr, - _ => bug!("expected expr, found {}", self.node_to_string(id)) - } - } - - /// returns the name associated with the given NodeId's AST - pub fn get_path_elem(&self, id: NodeId) -> PathElem { - let node = self.get(id); - match node { - NodeItem(item) => { - match item.node { - ItemMod(_) | ItemForeignMod(_) => { - PathMod(item.name) - } - _ => PathName(item.name) - } - } - NodeForeignItem(i) => PathName(i.name), - NodeImplItem(ii) => PathName(ii.name), - NodeTraitItem(ti) => PathName(ti.name), - NodeVariant(v) => PathName(v.node.name), - NodeLifetime(lt) => PathName(lt.name), - NodeTyParam(tp) => PathName(tp.name), - NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => { - PathName(l.node.name) - }, - _ => bug!("no path elem for {:?}", node) - } - } - - pub fn with_path(&self, id: NodeId, f: F) -> T where - F: FnOnce(PathElems) -> T, - { - self.with_path_next(id, LinkedPath::empty(), f) - } - - pub fn path_to_string(&self, id: NodeId) -> String { - self.with_path(id, |path| path_to_string(path)) - } - - fn path_to_str_with_name(&self, id: NodeId, name: Name) -> String { - self.with_path(id, |path| { - path_to_string(path.chain(Some(PathName(name)))) - }) - } - - fn with_path_next(&self, id: NodeId, next: LinkedPath, f: F) -> T where - F: FnOnce(PathElems) -> T, - { - // This function reveals the name of the item and hence is a - // kind of read. This is inefficient, since it walks ancestors - // and we are walking them anyhow, but whatever. - self.read(id); - - let parent = self.get_parent(id); - let parent = match self.find_entry(id) { - Some(EntryForeignItem(..)) => { - // Anonymous extern items go in the parent scope. - self.get_parent(parent) - } - // But tuple struct ctors don't have names, so use the path of its - // parent, the struct item. Similarly with closure expressions. - Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => { - return self.with_path_next(parent, next, f); - } - _ => parent - }; - if parent == id { - match self.find_entry(id) { - Some(RootInlinedParent(data)) => { - f(data.path.iter().cloned().chain(next)) - } - _ => f([].iter().cloned().chain(next)) - } - } else { - self.with_path_next(parent, LinkedPath::from(&LinkedPathNode { - node: self.get_path_elem(id), - next: next - }), f) - } - } - - /// Given a node ID, get a list of attributes associated with the AST - /// corresponding to the Node ID - pub fn attrs(&self, id: NodeId) -> &'ast [ast::Attribute] { - self.read(id); // reveals attributes on the node - let attrs = match self.find(id) { - Some(NodeItem(i)) => Some(&i.attrs[..]), - Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]), - Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]), - Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]), - Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]), - Some(NodeExpr(ref e)) => Some(e.attrs.as_attr_slice()), - Some(NodeStmt(ref s)) => Some(s.node.attrs()), - // unit/tuple structs take the attributes straight from - // the struct definition. - Some(NodeStructCtor(_)) => { - return self.attrs(self.get_parent(id)); - } - _ => None - }; - attrs.unwrap_or(&[]) - } - - /// Returns an iterator that yields the node id's with paths that - /// match `parts`. (Requires `parts` is non-empty.) - /// - /// For example, if given `parts` equal to `["bar", "quux"]`, then - /// the iterator will produce node id's for items with paths - /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and - /// any other such items it can find in the map. - pub fn nodes_matching_suffix<'a>(&'a self, parts: &'a [String]) - -> NodesMatchingSuffix<'a, 'ast> { - NodesMatchingSuffix { - map: self, - item_name: parts.last().unwrap(), - in_which: &parts[..parts.len() - 1], - idx: 0, - } - } - - pub fn opt_span(&self, id: NodeId) -> Option { - let sp = match self.find(id) { - Some(NodeItem(item)) => item.span, - Some(NodeForeignItem(foreign_item)) => foreign_item.span, - Some(NodeTraitItem(trait_method)) => trait_method.span, - Some(NodeImplItem(ref impl_item)) => impl_item.span, - Some(NodeVariant(variant)) => variant.span, - Some(NodeExpr(expr)) => expr.span, - Some(NodeStmt(stmt)) => stmt.span, - Some(NodeLocal(pat)) => pat.span, - Some(NodePat(pat)) => pat.span, - Some(NodeBlock(block)) => block.span, - Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span, - Some(NodeTyParam(ty_param)) => ty_param.span, - _ => return None, - }; - Some(sp) - } - - pub fn span(&self, id: NodeId) -> Span { - self.read(id); // reveals span from node - self.opt_span(id) - .unwrap_or_else(|| bug!("AstMap.span: could not find span for id {:?}", id)) - } - - pub fn span_if_local(&self, id: DefId) -> Option { - self.as_local_node_id(id).map(|id| self.span(id)) - } - - pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span { - if let Some(node_id) = self.as_local_node_id(def_id) { - self.opt_span(node_id).unwrap_or(fallback) - } else { - fallback - } - } - - pub fn node_to_string(&self, id: NodeId) -> String { - node_id_to_string(self, id, true) - } - - pub fn node_to_user_string(&self, id: NodeId) -> String { - node_id_to_string(self, id, false) - } -} - -pub struct NodesMatchingSuffix<'a, 'ast:'a> { - map: &'a Map<'ast>, - item_name: &'a String, - in_which: &'a [String], - idx: NodeId, -} - -impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { - /// Returns true only if some suffix of the module path for parent - /// matches `self.in_which`. - /// - /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`; - /// returns true if parent's path ends with the suffix - /// `x_0::x_1::...::x_k`. - fn suffix_matches(&self, parent: NodeId) -> bool { - let mut cursor = parent; - for part in self.in_which.iter().rev() { - let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) { - None => return false, - Some((node_id, name)) => (node_id, name), - }; - if &part[..] != mod_name.as_str() { - return false; - } - cursor = self.map.get_parent(mod_id); - } - return true; - - // Finds the first mod in parent chain for `id`, along with - // that mod's name. - // - // If `id` itself is a mod named `m` with parent `p`, then - // returns `Some(id, m, p)`. If `id` has no mod in its parent - // chain, then returns `None`. - fn find_first_mod_parent<'a>(map: &'a Map, mut id: NodeId) -> Option<(NodeId, Name)> { - loop { - match map.find(id) { - None => return None, - Some(NodeItem(item)) if item_is_mod(&item) => - return Some((id, item.name)), - _ => {} - } - let parent = map.get_parent(id); - if parent == id { return None } - id = parent; - } - - fn item_is_mod(item: &Item) -> bool { - match item.node { - ItemMod(_) => true, - _ => false, - } - } - } - } - - // We are looking at some node `n` with a given name and parent - // id; do their names match what I am seeking? - fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool { - name.as_str() == &self.item_name[..] && - self.suffix_matches(parent_of_n) - } -} - -impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> { - type Item = NodeId; - - fn next(&mut self) -> Option { - loop { - let idx = self.idx; - if idx as usize >= self.map.entry_count() { - return None; - } - self.idx += 1; - let name = match self.map.find_entry(idx) { - Some(EntryItem(_, n)) => n.name(), - Some(EntryForeignItem(_, n))=> n.name(), - Some(EntryTraitItem(_, n)) => n.name(), - Some(EntryImplItem(_, n)) => n.name(), - Some(EntryVariant(_, n)) => n.name(), - _ => continue, - }; - if self.matches_names(self.map.get_parent(idx), name) { - return Some(idx) - } - } - } -} - -trait Named { - fn name(&self) -> Name; -} - -impl Named for Spanned { fn name(&self) -> Name { self.node.name() } } - -impl Named for Item { fn name(&self) -> Name { self.name } } -impl Named for ForeignItem { fn name(&self) -> Name { self.name } } -impl Named for Variant_ { fn name(&self) -> Name { self.name } } -impl Named for TraitItem { fn name(&self) -> Name { self.name } } -impl Named for ImplItem { fn name(&self) -> Name { self.name } } - -pub trait FoldOps { - fn new_id(&self, id: NodeId) -> NodeId { - id - } - fn new_def_id(&self, def_id: DefId) -> DefId { - def_id - } - fn new_span(&self, span: Span) -> Span { - span - } -} - -/// A Folder that updates IDs and Span's according to fold_ops. -struct IdAndSpanUpdater { - fold_ops: F -} - -impl Folder for IdAndSpanUpdater { - fn new_id(&mut self, id: NodeId) -> NodeId { - self.fold_ops.new_id(id) - } - - fn new_span(&mut self, span: Span) -> Span { - self.fold_ops.new_span(span) - } -} - -pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { - let (map, definitions) = { - let mut collector = NodeCollector::root(&forest.krate); - intravisit::walk_crate(&mut collector, &forest.krate); - (collector.map, collector.definitions) - }; - - if log_enabled!(::log::DEBUG) { - // This only makes sense for ordered stores; note the - // enumerate to count the number of entries. - let (entries_less_1, _) = map.iter().filter(|&x| { - match *x { - NotPresent => false, - _ => true - } - }).enumerate().last().expect("AST map was empty after folding?"); - - let entries = entries_less_1 + 1; - let vector_length = map.len(); - debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%", - entries, vector_length, (entries as f64 / vector_length as f64) * 100.); - } - - Map { - forest: forest, - dep_graph: forest.dep_graph.clone(), - map: RefCell::new(map), - definitions: RefCell::new(definitions), - } -} - -/// Used for items loaded from external crate that are being inlined into this -/// crate. -pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, - parent_path: Vec, - parent_def_path: DefPath, - parent_def_id: DefId, - ii: InlinedItem, - fold_ops: F) - -> &'ast InlinedItem { - let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; - let ii = match ii { - II::Item(i) => II::Item(i.map(|i| fld.fold_item(i))), - II::TraitItem(d, ti) => { - II::TraitItem(fld.fold_ops.new_def_id(d), - ti.map(|ti| fld.fold_trait_item(ti))) - } - II::ImplItem(d, ii) => { - II::ImplItem(fld.fold_ops.new_def_id(d), - ii.map(|ii| fld.fold_impl_item(ii))) - } - II::Foreign(i) => II::Foreign(i.map(|i| fld.fold_foreign_item(i))) - }; - - let ii_parent = map.forest.inlined_items.alloc(InlinedParent { - path: parent_path, - ii: ii - }); - - let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - let mut collector = - NodeCollector::extend( - map.krate(), - ii_parent, - ii_parent_id, - parent_def_path, - parent_def_id, - mem::replace(&mut *map.map.borrow_mut(), vec![]), - mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); - ii_parent.ii.visit(&mut collector); - - *map.map.borrow_mut() = collector.map; - *map.definitions.borrow_mut() = collector.definitions; - - &ii_parent.ii -} - -pub trait NodePrinter { - fn print_node(&mut self, node: &Node) -> io::Result<()>; -} - -impl<'a> NodePrinter for pprust::State<'a> { - fn print_node(&mut self, node: &Node) -> io::Result<()> { - match *node { - NodeItem(a) => self.print_item(&a), - NodeForeignItem(a) => self.print_foreign_item(&a), - NodeTraitItem(a) => self.print_trait_item(a), - NodeImplItem(a) => self.print_impl_item(a), - NodeVariant(a) => self.print_variant(&a), - NodeExpr(a) => self.print_expr(&a), - NodeStmt(a) => self.print_stmt(&a), - NodePat(a) => self.print_pat(&a), - NodeBlock(a) => self.print_block(&a), - NodeLifetime(a) => self.print_lifetime(&a), - NodeTyParam(_) => bug!("cannot print TyParam"), - // these cases do not carry enough information in the - // ast_map to reconstruct their full structure for pretty - // printing. - NodeLocal(_) => bug!("cannot print isolated Local"), - NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), - } - } -} - -fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { - let id_str = format!(" (id={})", id); - let id_str = if include_id { &id_str[..] } else { "" }; - - match map.find(id) { - Some(NodeItem(item)) => { - let path_str = map.path_to_str_with_name(id, item.name); - let item_str = match item.node { - ItemExternCrate(..) => "extern crate", - ItemUse(..) => "use", - ItemStatic(..) => "static", - ItemConst(..) => "const", - ItemFn(..) => "fn", - ItemMod(..) => "mod", - ItemForeignMod(..) => "foreign mod", - ItemTy(..) => "ty", - ItemEnum(..) => "enum", - ItemStruct(..) => "struct", - ItemTrait(..) => "trait", - ItemImpl(..) => "impl", - ItemDefaultImpl(..) => "default impl", - }; - format!("{} {}{}", item_str, path_str, id_str) - } - Some(NodeForeignItem(item)) => { - let path_str = map.path_to_str_with_name(id, item.name); - format!("foreign item {}{}", path_str, id_str) - } - Some(NodeImplItem(ii)) => { - match ii.node { - ImplItemKind::Const(..) => { - format!("assoc const {} in {}{}", - ii.name, - map.path_to_string(id), - id_str) - } - ImplItemKind::Method(..) => { - format!("method {} in {}{}", - ii.name, - map.path_to_string(id), id_str) - } - ImplItemKind::Type(_) => { - format!("assoc type {} in {}{}", - ii.name, - map.path_to_string(id), - id_str) - } - } - } - Some(NodeTraitItem(ti)) => { - let kind = match ti.node { - ConstTraitItem(..) => "assoc constant", - MethodTraitItem(..) => "trait method", - TypeTraitItem(..) => "assoc type", - }; - - format!("{} {} in {}{}", - kind, - ti.name, - map.path_to_string(id), - id_str) - } - Some(NodeVariant(ref variant)) => { - format!("variant {} in {}{}", - variant.node.name, - map.path_to_string(id), id_str) - } - Some(NodeExpr(ref expr)) => { - format!("expr {}{}", pprust::expr_to_string(&expr), id_str) - } - Some(NodeStmt(ref stmt)) => { - format!("stmt {}{}", pprust::stmt_to_string(&stmt), id_str) - } - Some(NodeLocal(ref pat)) => { - format!("local {}{}", pprust::pat_to_string(&pat), id_str) - } - Some(NodePat(ref pat)) => { - format!("pat {}{}", pprust::pat_to_string(&pat), id_str) - } - Some(NodeBlock(ref block)) => { - format!("block {}{}", pprust::block_to_string(&block), id_str) - } - Some(NodeStructCtor(_)) => { - format!("struct_ctor {}{}", map.path_to_string(id), id_str) - } - Some(NodeLifetime(ref l)) => { - format!("lifetime {}{}", - pprust::lifetime_to_string(&l), id_str) - } - Some(NodeTyParam(ref ty_param)) => { - format!("typaram {:?}{}", ty_param, id_str) - } - None => { - format!("unknown node{}", id_str) - } - } -} diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs new file mode 100644 index 00000000000..085acc198d1 --- /dev/null +++ b/src/librustc/hir/check_attr.rs @@ -0,0 +1,110 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use session::Session; + +use syntax::ast; +use syntax::attr::AttrMetaMethods; +use syntax::visit; +use syntax::visit::Visitor; + +#[derive(Copy, Clone, PartialEq)] +enum Target { + Fn, + Struct, + Enum, + Other, +} + +impl Target { + fn from_item(item: &ast::Item) -> Target { + match item.node { + ast::ItemKind::Fn(..) => Target::Fn, + ast::ItemKind::Struct(..) => Target::Struct, + ast::ItemKind::Enum(..) => Target::Enum, + _ => Target::Other, + } + } +} + +struct CheckAttrVisitor<'a> { + sess: &'a Session, +} + +impl<'a> CheckAttrVisitor<'a> { + fn check_inline(&self, attr: &ast::Attribute, target: Target) { + if target != Target::Fn { + span_err!(self.sess, attr.span, E0518, "attribute should be applied to function"); + } + } + + fn check_repr(&self, attr: &ast::Attribute, target: Target) { + let words = match attr.meta_item_list() { + Some(words) => words, + None => { + return; + } + }; + for word in words { + let word: &str = &word.name(); + let message = match word { + "C" => { + if target != Target::Struct && target != Target::Enum { + "attribute should be applied to struct or enum" + } else { + continue + } + } + "packed" | + "simd" => { + if target != Target::Struct { + "attribute should be applied to struct" + } else { + continue + } + } + "i8" | "u8" | "i16" | "u16" | + "i32" | "u32" | "i64" | "u64" | + "isize" | "usize" => { + if target != Target::Enum { + "attribute should be applied to enum" + } else { + continue + } + } + _ => continue, + }; + span_err!(self.sess, attr.span, E0517, "{}", message); + } + } + + fn check_attribute(&self, attr: &ast::Attribute, target: Target) { + let name: &str = &attr.name(); + match name { + "inline" => self.check_inline(attr, target), + "repr" => self.check_repr(attr, target), + _ => (), + } + } +} + +impl<'a, 'v> Visitor<'v> for CheckAttrVisitor<'a> { + fn visit_item(&mut self, item: &ast::Item) { + let target = Target::from_item(item); + for attr in &item.attrs { + self.check_attribute(attr, target); + } + visit::walk_item(self, item); + } +} + +pub fn check_crate(sess: &Session, krate: &ast::Crate) { + visit::walk_crate(&mut CheckAttrVisitor { sess: sess }, krate); +} diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs new file mode 100644 index 00000000000..e65f2fc37de --- /dev/null +++ b/src/librustc/hir/fold.rs @@ -0,0 +1,1151 @@ +// 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 or the MIT license +// , 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_, MetaItem}; +use syntax::ast::MetaItemKind; +use syntax::attr::ThinAttributesExt; +use hir; +use syntax::codemap::{respan, Span, Spanned}; +use syntax::ptr::P; +use syntax::parse::token; +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>) -> HirVec> { + noop_fold_meta_items(meta_items, self) + } + + fn fold_meta_item(&mut self, meta_item: P) -> P { + noop_fold_meta_item(meta_item, self) + } + + fn fold_view_path(&mut self, view_path: P) -> P { + 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) -> P { + noop_fold_fn_decl(d, self) + } + + fn fold_block(&mut self, b: P) -> P { + 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) -> P { + noop_fold_pat(p, self) + } + + fn fold_decl(&mut self, d: P) -> P { + noop_fold_decl(d, self) + } + + fn fold_expr(&mut self, e: P) -> P { + e.map(|e| noop_fold_expr(e, self)) + } + + fn fold_ty(&mut self, t: P) -> P { + 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_ident(&mut self, i: Ident) -> Ident { + noop_fold_ident(i, 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) -> P { + noop_fold_local(l, self) + } + + fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { + noop_fold_explicit_self(es, self) + } + + fn fold_explicit_self_underscore(&mut self, es: ExplicitSelf_) -> ExplicitSelf_ { + noop_fold_explicit_self_underscore(es, 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 { + 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) -> HirVec { + noop_fold_lifetimes(lts, self) + } + + fn fold_lifetime_defs(&mut self, lts: HirVec) -> HirVec { + 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) -> HirVec { + noop_fold_ty_params(tps, self) + } + + fn fold_opt_lifetime(&mut self, o_lt: Option) -> Option { + noop_fold_opt_lifetime(o_lt, self) + } + + fn fold_opt_bounds(&mut self, + b: Option) + -> Option { + 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(meta_items: HirVec>, + fld: &mut T) + -> HirVec> { + meta_items.move_map(|x| fld.fold_meta_item(x)) +} + +pub fn noop_fold_view_path(view_path: P, fld: &mut T) -> P { + 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: match path_list_ident.node { + PathListIdent { id, name, rename } => PathListIdent { + id: fld.new_id(id), + name: name, + rename: rename, + }, + PathListMod { id, rename } => PathListMod { + id: fld.new_id(id), + rename: rename, + }, + }, + span: fld.new_span(path_list_ident.span), + } + })) + } + }, + span: fld.new_span(span), + } + }) +} + +pub fn fold_attrs(attrs: HirVec, fld: &mut T) -> HirVec { + attrs.move_flat_map(|x| fld.fold_attribute(x)) +} + +pub fn noop_fold_arm(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(d: P, fld: &mut T) -> P { + 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(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: P, fld: &mut T) -> P { + 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), + } + })) + } + 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))) + } + }, + span: fld.new_span(span), + } + }) +} + +pub fn noop_fold_foreign_mod(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(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(n: Name, _: &mut T) -> Name { + n +} + +pub fn noop_fold_ident(i: Ident, _: &mut T) -> Ident { + i +} + +pub fn noop_fold_usize(i: usize, _: &mut T) -> usize { + i +} + +pub fn noop_fold_path(Path { global, segments, span }: Path, fld: &mut T) -> Path { + Path { + global: global, + segments: segments.move_map(|PathSegment { identifier, parameters }| { + PathSegment { + identifier: fld.fold_ident(identifier), + parameters: fld.fold_path_parameters(parameters), + } + }), + span: fld.new_span(span), + } +} + +pub fn noop_fold_path_parameters(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(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(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(l: P, fld: &mut T) -> P { + 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: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), fld).into()), + } + }) +} + +pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Option { + 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_explicit_self_underscore(es: ExplicitSelf_, + fld: &mut T) + -> ExplicitSelf_ { + match es { + SelfStatic | SelfValue(_) => es, + SelfRegion(lifetime, m, name) => { + SelfRegion(fld.fold_opt_lifetime(lifetime), m, name) + } + SelfExplicit(typ, name) => { + SelfExplicit(fld.fold_ty(typ), name) + } + } +} + +pub fn noop_fold_explicit_self(Spanned { span, node }: ExplicitSelf, + fld: &mut T) + -> ExplicitSelf { + Spanned { + node: fld.fold_explicit_self_underscore(node), + span: fld.new_span(span), + } +} + +pub fn noop_fold_meta_item(mi: P, fld: &mut T) -> P { + 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_item(e))) + } + MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s), + }, + span: fld.new_span(span), + } + }) +} + +pub fn noop_fold_arg(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(decl: P, fld: &mut T) -> P { + 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), + NoReturn(span) => NoReturn(span), + }, + variadic: variadic, + } + }) +} + +pub fn noop_fold_ty_param_bound(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(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(tps: HirVec, + fld: &mut T) + -> HirVec { + tps.move_map(|tp| fld.fold_ty_param(tp)) +} + +pub fn noop_fold_lifetime(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(l: LifetimeDef, fld: &mut T) -> LifetimeDef { + LifetimeDef { + lifetime: fld.fold_lifetime(l.lifetime), + bounds: fld.fold_lifetimes(l.bounds), + } +} + +pub fn noop_fold_lifetimes(lts: HirVec, fld: &mut T) -> HirVec { + lts.move_map(|l| fld.fold_lifetime(l)) +} + +pub fn noop_fold_lifetime_defs(lts: HirVec, + fld: &mut T) + -> HirVec { + lts.move_map(|l| fld.fold_lifetime_def(l)) +} + +pub fn noop_fold_opt_lifetime(o_lt: Option, fld: &mut T) -> Option { + o_lt.map(|lt| fld.fold_lifetime(lt)) +} + +pub fn noop_fold_generics(Generics { ty_params, lifetimes, where_clause }: 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), + } +} + +pub fn noop_fold_where_clause(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(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(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(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(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(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(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(MutTy { ty, mutbl }: MutTy, folder: &mut T) -> MutTy { + MutTy { + ty: folder.fold_ty(ty), + mutbl: mutbl, + } +} + +pub fn noop_fold_opt_bounds(b: Option, + folder: &mut T) + -> Option { + b.map(|bounds| folder.fold_bounds(bounds)) +} + +fn noop_fold_bounds(bounds: TyParamBounds, folder: &mut T) -> TyParamBounds { + bounds.move_map(|bound| folder.fold_ty_param_bound(bound)) +} + +pub fn noop_fold_block(b: P, folder: &mut T) -> P { + 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(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)) + } + 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(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(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(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(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: token::special_idents::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(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(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); + // FIXME: we should update the impl_pretty_name, but it uses pretty printing. + // let ident = match node { + // // The node may have changed, recompute the "pretty" impl name. + // ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => { + // impl_pretty_name(maybe_trait, Some(&**ty)) + // } + // _ => ident + // }; + + 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(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(sig: MethodSig, folder: &mut T) -> MethodSig { + MethodSig { + generics: folder.fold_generics(sig.generics), + abi: sig.abi, + explicit_self: folder.fold_explicit_self(sig.explicit_self), + unsafety: sig.unsafety, + constness: sig.constness, + decl: folder.fold_fn_decl(sig.decl), + } +} + +pub fn noop_fold_pat(p: P, folder: &mut T) -> P { + p.map(|Pat { id, node, span }| { + Pat { + id: folder.new_id(id), + node: match node { + PatKind::Wild => PatKind::Wild, + PatKind::Ident(binding_mode, pth1, sub) => { + PatKind::Ident(binding_mode, + Spanned { + span: folder.new_span(pth1.span), + node: folder.fold_ident(pth1.node), + }, + sub.map(|x| folder.fold_pat(x))) + } + PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), + PatKind::TupleStruct(pth, pats) => { + PatKind::TupleStruct(folder.fold_path(pth), + pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) + } + PatKind::Path(pth) => { + PatKind::Path(folder.fold_path(pth)) + } + PatKind::QPath(qself, pth) => { + let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself }; + PatKind::QPath(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::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))), + 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(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_ident) => { + ExprWhile(folder.fold_expr(cond), + folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) + } + ExprLoop(body, opt_ident) => { + ExprLoop(folder.fold_block(body), + opt_ident.map(|i| folder.fold_ident(i))) + } + ExprMatch(expr, arms, source) => { + ExprMatch(folder.fold_expr(expr), + arms.move_map(|x| folder.fold_arm(x)), + source) + } + ExprClosure(capture_clause, decl, body) => { + ExprClosure(capture_clause, + folder.fold_fn_decl(decl), + folder.fold_block(body)) + } + 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_ident) => ExprBreak(opt_ident.map(|label| { + respan(folder.new_span(label.span), folder.fold_ident(label.node)) + })), + ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label| { + respan(folder.new_span(label.span), folder.fold_ident(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: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), folder).into()), + } +} + +pub fn noop_fold_stmt(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/intravisit.rs b/src/librustc/hir/intravisit.rs new file mode 100644 index 00000000000..be1cc528d88 --- /dev/null +++ b/src/librustc/hir/intravisit.rs @@ -0,0 +1,837 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! HIR walker. Each overridden visit method has full control over what +//! happens with its node, it can do its own traversal of the node's children, +//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent +//! deeper traversal by doing nothing. +//! +//! When visiting the HIR, the contents of nested items are NOT visited +//! by default. This is different from the AST visitor, which does a deep walk. +//! Hence this module is called `intravisit`; see the method `visit_nested_item` +//! for more details. +//! +//! Note: it is an important invariant that the default visitor walks +//! the body of a function in "execution order" (more concretely, +//! reverse post-order with respect to the CFG implied by the AST), +//! meaning that if AST node A may execute before AST node B, then A +//! is visited first. The borrow checker in particular relies on this +//! property. + +use syntax::abi::Abi; +use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; +use syntax::attr::ThinAttributesExt; +use syntax::codemap::Span; +use hir::*; + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum FnKind<'a> { + /// fn foo() or extern "Abi" fn foo() + ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, Visibility, &'a [Attribute]), + + /// fn foo(&self) + Method(Name, &'a MethodSig, Option, &'a [Attribute]), + + /// |x, y| {} + Closure(&'a [Attribute]), +} + +impl<'a> FnKind<'a> { + pub fn attrs(&self) -> &'a [Attribute] { + match *self { + FnKind::ItemFn(_, _, _, _, _, _, attrs) => attrs, + FnKind::Method(_, _, _, attrs) => attrs, + FnKind::Closure(attrs) => attrs, + } + } +} + +/// Each method of the Visitor trait is a hook to be potentially +/// overridden. Each method's default implementation recursively visits +/// the substructure of the input via the corresponding `walk` method; +/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`. +/// +/// Note that this visitor does NOT visit nested items by default +/// (this is why the module is called `intravisit`, to distinguish it +/// from the AST's `visit` module, which acts differently). If you +/// simply want to visit all items in the crate in some order, you +/// should call `Crate::visit_all_items`. Otherwise, see the comment +/// on `visit_nested_item` for details on how to visit nested items. +/// +/// If you want to ensure that your code handles every variant +/// explicitly, you need to override each method. (And you also need +/// to monitor future changes to `Visitor` in case a new method with a +/// new default implementation gets introduced.) +pub trait Visitor<'v> : Sized { + /////////////////////////////////////////////////////////////////////////// + // Nested items. + + /// Invoked when a nested item is encountered. By default, does + /// nothing. If you want a deep walk, you need to override to + /// fetch the item contents. But most of the time, it is easier + /// (and better) to invoke `Crate::visit_all_items`, which visits + /// all items in the crate in some order (but doesn't respect + /// nesting). + #[allow(unused_variables)] + fn visit_nested_item(&mut self, id: ItemId) { + } + + /// Visit the top-level item and (optionally) nested items. See + /// `visit_nested_item` for details. + fn visit_item(&mut self, i: &'v Item) { + walk_item(self, i) + } + + /////////////////////////////////////////////////////////////////////////// + + fn visit_name(&mut self, _span: Span, _name: Name) { + // Nothing to do. + } + fn visit_ident(&mut self, span: Span, ident: Ident) { + walk_ident(self, span, ident); + } + fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { + walk_mod(self, m) + } + fn visit_foreign_item(&mut self, i: &'v ForeignItem) { + walk_foreign_item(self, i) + } + fn visit_local(&mut self, l: &'v Local) { + walk_local(self, l) + } + fn visit_block(&mut self, b: &'v Block) { + walk_block(self, b) + } + fn visit_stmt(&mut self, s: &'v Stmt) { + walk_stmt(self, s) + } + fn visit_arm(&mut self, a: &'v Arm) { + walk_arm(self, a) + } + fn visit_pat(&mut self, p: &'v Pat) { + walk_pat(self, p) + } + fn visit_decl(&mut self, d: &'v Decl) { + walk_decl(self, d) + } + fn visit_expr(&mut self, ex: &'v Expr) { + walk_expr(self, ex) + } + fn visit_expr_post(&mut self, _ex: &'v Expr) { + } + fn visit_ty(&mut self, t: &'v Ty) { + walk_ty(self, t) + } + fn visit_generics(&mut self, g: &'v Generics) { + walk_generics(self, g) + } + fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) { + walk_fn(self, fk, fd, b, s) + } + fn visit_trait_item(&mut self, ti: &'v TraitItem) { + walk_trait_item(self, ti) + } + fn visit_impl_item(&mut self, ii: &'v ImplItem) { + walk_impl_item(self, ii) + } + fn visit_trait_ref(&mut self, t: &'v TraitRef) { + walk_trait_ref(self, t) + } + fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) { + walk_ty_param_bound(self, bounds) + } + fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) { + walk_poly_trait_ref(self, t, m) + } + fn visit_variant_data(&mut self, + s: &'v VariantData, + _: Name, + _: &'v Generics, + _: NodeId, + _: Span) { + walk_struct_def(self, s) + } + fn visit_struct_field(&mut self, s: &'v StructField) { + walk_struct_field(self, s) + } + fn visit_enum_def(&mut self, + enum_definition: &'v EnumDef, + generics: &'v Generics, + item_id: NodeId, + _: Span) { + walk_enum_def(self, enum_definition, generics, item_id) + } + fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) { + walk_variant(self, v, g, item_id) + } + fn visit_lifetime(&mut self, lifetime: &'v Lifetime) { + walk_lifetime(self, lifetime) + } + fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) { + walk_lifetime_def(self, lifetime) + } + fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { + walk_explicit_self(self, es) + } + fn visit_path(&mut self, path: &'v Path, _id: NodeId) { + walk_path(self, path) + } + fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) { + walk_path_list_item(self, prefix, item) + } + fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) { + walk_path_segment(self, path_span, path_segment) + } + fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) { + walk_path_parameters(self, path_span, path_parameters) + } + fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) { + walk_assoc_type_binding(self, type_binding) + } + fn visit_attribute(&mut self, _attr: &'v Attribute) { + } + fn visit_macro_def(&mut self, macro_def: &'v MacroDef) { + walk_macro_def(self, macro_def) + } +} + +pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option) { + for name in opt_name { + visitor.visit_name(span, name); + } +} + +pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option) { + for ident in opt_ident { + visitor.visit_ident(span, ident); + } +} + +pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) { + visitor.visit_name(span, ident.name); +} + +/// Walks the contents of a crate. See also `Crate::visit_all_items`. +pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { + visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID); + walk_list!(visitor, visit_attribute, &krate.attrs); + walk_list!(visitor, visit_macro_def, &krate.exported_macros); +} + +pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) { + visitor.visit_name(macro_def.span, macro_def.name); + walk_opt_name(visitor, macro_def.span, macro_def.imported_from); + walk_list!(visitor, visit_attribute, ¯o_def.attrs); +} + +pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { + for &item_id in &module.item_ids { + visitor.visit_nested_item(item_id); + } +} + +pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { + visitor.visit_pat(&local.pat); + walk_list!(visitor, visit_ty, &local.ty); + walk_list!(visitor, visit_expr, &local.init); +} + +pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { + visitor.visit_name(lifetime.span, lifetime.name); +} + +pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) { + visitor.visit_lifetime(&lifetime_def.lifetime); + walk_list!(visitor, visit_lifetime, &lifetime_def.bounds); +} + +pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, explicit_self: &'v ExplicitSelf) { + match explicit_self.node { + SelfStatic => {} + SelfValue(name) => { + visitor.visit_name(explicit_self.span, name) + } + SelfRegion(ref opt_lifetime, _, name) => { + visitor.visit_name(explicit_self.span, name); + walk_list!(visitor, visit_lifetime, opt_lifetime); + } + SelfExplicit(ref typ, name) => { + visitor.visit_name(explicit_self.span, name); + visitor.visit_ty(typ) + } + } +} + +pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, + trait_ref: &'v PolyTraitRef, + _modifier: &'v TraitBoundModifier) + where V: Visitor<'v> +{ + walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes); + visitor.visit_trait_ref(&trait_ref.trait_ref); +} + +pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) + where V: Visitor<'v> +{ + visitor.visit_path(&trait_ref.path, trait_ref.ref_id) +} + +pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { + visitor.visit_name(item.span, item.name); + match item.node { + ItemExternCrate(opt_name) => { + walk_opt_name(visitor, item.span, opt_name) + } + ItemUse(ref vp) => { + match vp.node { + ViewPathSimple(name, ref path) => { + visitor.visit_name(vp.span, name); + visitor.visit_path(path, item.id); + } + ViewPathGlob(ref path) => { + visitor.visit_path(path, item.id); + } + ViewPathList(ref prefix, ref list) => { + if !list.is_empty() { + for item in list { + visitor.visit_path_list_item(prefix, item) + } + } else { + visitor.visit_path(prefix, item.id); + } + } + } + } + ItemStatic(ref typ, _, ref expr) | + ItemConst(ref typ, ref expr) => { + visitor.visit_ty(typ); + visitor.visit_expr(expr); + } + ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => { + visitor.visit_fn(FnKind::ItemFn(item.name, + generics, + unsafety, + constness, + abi, + item.vis, + &item.attrs), + declaration, + body, + item.span, + item.id) + } + ItemMod(ref module) => { + visitor.visit_mod(module, item.span, item.id) + } + ItemForeignMod(ref foreign_module) => { + walk_list!(visitor, visit_foreign_item, &foreign_module.items); + } + ItemTy(ref typ, ref type_parameters) => { + visitor.visit_ty(typ); + visitor.visit_generics(type_parameters) + } + ItemEnum(ref enum_definition, ref type_parameters) => { + visitor.visit_generics(type_parameters); + visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span) + } + ItemDefaultImpl(_, ref trait_ref) => { + visitor.visit_trait_ref(trait_ref) + } + ItemImpl(_, _, ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => { + visitor.visit_generics(type_parameters); + walk_list!(visitor, visit_trait_ref, opt_trait_reference); + visitor.visit_ty(typ); + walk_list!(visitor, visit_impl_item, impl_items); + } + ItemStruct(ref struct_definition, ref generics) => { + visitor.visit_generics(generics); + visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); + } + ItemTrait(_, ref generics, ref bounds, ref methods) => { + visitor.visit_generics(generics); + walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_trait_item, methods); + } + } + walk_list!(visitor, visit_attribute, &item.attrs); +} + +pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, + enum_definition: &'v EnumDef, + generics: &'v Generics, + item_id: NodeId) { + walk_list!(visitor, + visit_variant, + &enum_definition.variants, + generics, + item_id); +} + +pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, + variant: &'v Variant, + generics: &'v Generics, + item_id: NodeId) { + visitor.visit_name(variant.span, variant.node.name); + visitor.visit_variant_data(&variant.node.data, + variant.node.name, + generics, + item_id, + variant.span); + walk_list!(visitor, visit_expr, &variant.node.disr_expr); + walk_list!(visitor, visit_attribute, &variant.node.attrs); +} + +pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { + match typ.node { + TyVec(ref ty) => { + visitor.visit_ty(ty) + } + TyPtr(ref mutable_type) => { + visitor.visit_ty(&mutable_type.ty) + } + TyRptr(ref opt_lifetime, ref mutable_type) => { + walk_list!(visitor, visit_lifetime, opt_lifetime); + visitor.visit_ty(&mutable_type.ty) + } + TyTup(ref tuple_element_types) => { + walk_list!(visitor, visit_ty, tuple_element_types); + } + TyBareFn(ref function_declaration) => { + walk_fn_decl(visitor, &function_declaration.decl); + walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes); + } + TyPath(ref maybe_qself, ref path) => { + if let Some(ref qself) = *maybe_qself { + visitor.visit_ty(&qself.ty); + } + visitor.visit_path(path, typ.id); + } + TyObjectSum(ref ty, ref bounds) => { + visitor.visit_ty(ty); + walk_list!(visitor, visit_ty_param_bound, bounds); + } + TyFixedLengthVec(ref ty, ref expression) => { + visitor.visit_ty(ty); + visitor.visit_expr(expression) + } + TyPolyTraitRef(ref bounds) => { + walk_list!(visitor, visit_ty_param_bound, bounds); + } + TyTypeof(ref expression) => { + visitor.visit_expr(expression) + } + TyInfer => {} + } +} + +pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { + for segment in &path.segments { + visitor.visit_path_segment(path.span, segment); + } +} + +pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, + prefix: &'v Path, + item: &'v PathListItem) { + for segment in &prefix.segments { + visitor.visit_path_segment(prefix.span, segment); + } + + walk_opt_name(visitor, item.span, item.node.name()); + walk_opt_name(visitor, item.span, item.node.rename()); +} + +pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, + path_span: Span, + segment: &'v PathSegment) { + visitor.visit_ident(path_span, segment.identifier); + visitor.visit_path_parameters(path_span, &segment.parameters); +} + +pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V, + _path_span: Span, + path_parameters: &'v PathParameters) { + match *path_parameters { + AngleBracketedParameters(ref data) => { + walk_list!(visitor, visit_ty, &data.types); + walk_list!(visitor, visit_lifetime, &data.lifetimes); + walk_list!(visitor, visit_assoc_type_binding, &data.bindings); + } + ParenthesizedParameters(ref data) => { + walk_list!(visitor, visit_ty, &data.inputs); + walk_list!(visitor, visit_ty, &data.output); + } + } +} + +pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, + type_binding: &'v TypeBinding) { + visitor.visit_name(type_binding.span, type_binding.name); + visitor.visit_ty(&type_binding.ty); +} + +pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { + match pattern.node { + PatKind::TupleStruct(ref path, ref opt_children) => { + visitor.visit_path(path, pattern.id); + if let Some(ref children) = *opt_children { + walk_list!(visitor, visit_pat, children); + } + } + PatKind::Path(ref path) => { + visitor.visit_path(path, pattern.id); + } + PatKind::QPath(ref qself, ref path) => { + visitor.visit_ty(&qself.ty); + visitor.visit_path(path, pattern.id) + } + PatKind::Struct(ref path, ref fields, _) => { + visitor.visit_path(path, pattern.id); + for field in fields { + visitor.visit_name(field.span, field.node.name); + visitor.visit_pat(&field.node.pat) + } + } + PatKind::Tup(ref tuple_elements) => { + walk_list!(visitor, visit_pat, tuple_elements); + } + PatKind::Box(ref subpattern) | + PatKind::Ref(ref subpattern, _) => { + visitor.visit_pat(subpattern) + } + PatKind::Ident(_, ref pth1, ref optional_subpattern) => { + visitor.visit_ident(pth1.span, pth1.node); + walk_list!(visitor, visit_pat, optional_subpattern); + } + PatKind::Lit(ref expression) => visitor.visit_expr(expression), + PatKind::Range(ref lower_bound, ref upper_bound) => { + visitor.visit_expr(lower_bound); + visitor.visit_expr(upper_bound) + } + PatKind::Wild => (), + PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => { + walk_list!(visitor, visit_pat, prepatterns); + walk_list!(visitor, visit_pat, slice_pattern); + walk_list!(visitor, visit_pat, postpatterns); + } + } +} + +pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { + visitor.visit_name(foreign_item.span, foreign_item.name); + + match foreign_item.node { + ForeignItemFn(ref function_declaration, ref generics) => { + walk_fn_decl(visitor, function_declaration); + visitor.visit_generics(generics) + } + ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ), + } + + walk_list!(visitor, visit_attribute, &foreign_item.attrs); +} + +pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) { + match *bound { + TraitTyParamBound(ref typ, ref modifier) => { + visitor.visit_poly_trait_ref(typ, modifier); + } + RegionTyParamBound(ref lifetime) => { + visitor.visit_lifetime(lifetime); + } + } +} + +pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { + for param in &generics.ty_params { + visitor.visit_name(param.span, param.name); + walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); + walk_list!(visitor, visit_ty, ¶m.default); + } + walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); + for predicate in &generics.where_clause.predicates { + match predicate { + &WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, + ref bounds, + ref bound_lifetimes, + ..}) => { + visitor.visit_ty(bounded_ty); + walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_lifetime_def, bound_lifetimes); + } + &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, + ref bounds, + ..}) => { + visitor.visit_lifetime(lifetime); + walk_list!(visitor, visit_lifetime, bounds); + } + &WherePredicate::EqPredicate(WhereEqPredicate{id, + ref path, + ref ty, + ..}) => { + visitor.visit_path(path, id); + visitor.visit_ty(ty); + } + } + } +} + +pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) { + if let Return(ref output_ty) = *ret_ty { + visitor.visit_ty(output_ty) + } +} + +pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { + for argument in &function_declaration.inputs { + visitor.visit_pat(&argument.pat); + visitor.visit_ty(&argument.ty) + } + walk_fn_ret_ty(visitor, &function_declaration.output) +} + +pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { + for argument in &function_declaration.inputs { + visitor.visit_ty(&argument.ty) + } + walk_fn_ret_ty(visitor, &function_declaration.output) +} + +pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) { + match function_kind { + FnKind::ItemFn(_, generics, _, _, _, _, _) => { + visitor.visit_generics(generics); + } + FnKind::Method(_, sig, _, _) => { + visitor.visit_generics(&sig.generics); + visitor.visit_explicit_self(&sig.explicit_self); + } + FnKind::Closure(_) => {} + } +} + +pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, + function_kind: FnKind<'v>, + function_declaration: &'v FnDecl, + function_body: &'v Block, + _span: Span) { + walk_fn_decl(visitor, function_declaration); + walk_fn_kind(visitor, function_kind); + visitor.visit_block(function_body) +} + +pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { + visitor.visit_name(trait_item.span, trait_item.name); + walk_list!(visitor, visit_attribute, &trait_item.attrs); + match trait_item.node { + ConstTraitItem(ref ty, ref default) => { + visitor.visit_ty(ty); + walk_list!(visitor, visit_expr, default); + } + MethodTraitItem(ref sig, None) => { + visitor.visit_explicit_self(&sig.explicit_self); + visitor.visit_generics(&sig.generics); + walk_fn_decl(visitor, &sig.decl); + } + MethodTraitItem(ref sig, Some(ref body)) => { + visitor.visit_fn(FnKind::Method(trait_item.name, + sig, + None, + &trait_item.attrs), + &sig.decl, + body, + trait_item.span, + trait_item.id); + } + TypeTraitItem(ref bounds, ref default) => { + walk_list!(visitor, visit_ty_param_bound, bounds); + walk_list!(visitor, visit_ty, default); + } + } +} + +pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) { + visitor.visit_name(impl_item.span, impl_item.name); + walk_list!(visitor, visit_attribute, &impl_item.attrs); + match impl_item.node { + ImplItemKind::Const(ref ty, ref expr) => { + visitor.visit_ty(ty); + visitor.visit_expr(expr); + } + ImplItemKind::Method(ref sig, ref body) => { + visitor.visit_fn(FnKind::Method(impl_item.name, + sig, + Some(impl_item.vis), + &impl_item.attrs), + &sig.decl, + body, + impl_item.span, + impl_item.id); + } + ImplItemKind::Type(ref ty) => { + visitor.visit_ty(ty); + } + } +} + +pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { + walk_list!(visitor, visit_struct_field, struct_definition.fields()); +} + +pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { + visitor.visit_name(struct_field.span, struct_field.name); + visitor.visit_ty(&struct_field.ty); + walk_list!(visitor, visit_attribute, &struct_field.attrs); +} + +pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { + walk_list!(visitor, visit_stmt, &block.stmts); + walk_list!(visitor, visit_expr, &block.expr); +} + +pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { + match statement.node { + StmtDecl(ref declaration, _) => visitor.visit_decl(declaration), + StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => { + visitor.visit_expr(expression) + } + } +} + +pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { + match declaration.node { + DeclLocal(ref local) => visitor.visit_local(local), + DeclItem(item) => visitor.visit_nested_item(item), + } +} + +pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { + match expression.node { + ExprBox(ref subexpression) => { + visitor.visit_expr(subexpression) + } + ExprVec(ref subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); + } + ExprRepeat(ref element, ref count) => { + visitor.visit_expr(element); + visitor.visit_expr(count) + } + ExprStruct(ref path, ref fields, ref optional_base) => { + visitor.visit_path(path, expression.id); + for field in fields { + visitor.visit_name(field.name.span, field.name.node); + visitor.visit_expr(&field.expr) + } + walk_list!(visitor, visit_expr, optional_base); + } + ExprTup(ref subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); + } + ExprCall(ref callee_expression, ref arguments) => { + walk_list!(visitor, visit_expr, arguments); + visitor.visit_expr(callee_expression) + } + ExprMethodCall(ref name, ref types, ref arguments) => { + visitor.visit_name(name.span, name.node); + walk_list!(visitor, visit_expr, arguments); + walk_list!(visitor, visit_ty, types); + } + ExprBinary(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(left_expression); + visitor.visit_expr(right_expression) + } + ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => { + visitor.visit_expr(subexpression) + } + ExprLit(_) => {} + ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => { + visitor.visit_expr(subexpression); + visitor.visit_ty(typ) + } + ExprIf(ref head_expression, ref if_block, ref optional_else) => { + visitor.visit_expr(head_expression); + visitor.visit_block(if_block); + walk_list!(visitor, visit_expr, optional_else); + } + ExprWhile(ref subexpression, ref block, opt_ident) => { + visitor.visit_expr(subexpression); + visitor.visit_block(block); + walk_opt_ident(visitor, expression.span, opt_ident) + } + ExprLoop(ref block, opt_ident) => { + visitor.visit_block(block); + walk_opt_ident(visitor, expression.span, opt_ident) + } + ExprMatch(ref subexpression, ref arms, _) => { + visitor.visit_expr(subexpression); + walk_list!(visitor, visit_arm, arms); + } + ExprClosure(_, ref function_declaration, ref body) => { + visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()), + function_declaration, + body, + expression.span, + expression.id) + } + ExprBlock(ref block) => visitor.visit_block(block), + ExprAssign(ref left_hand_expression, ref right_hand_expression) => { + visitor.visit_expr(right_hand_expression); + visitor.visit_expr(left_hand_expression) + } + ExprAssignOp(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(right_expression); + visitor.visit_expr(left_expression) + } + ExprField(ref subexpression, ref name) => { + visitor.visit_expr(subexpression); + visitor.visit_name(name.span, name.node); + } + ExprTupField(ref subexpression, _) => { + visitor.visit_expr(subexpression); + } + ExprIndex(ref main_expression, ref index_expression) => { + visitor.visit_expr(main_expression); + visitor.visit_expr(index_expression) + } + ExprPath(ref maybe_qself, ref path) => { + if let Some(ref qself) = *maybe_qself { + visitor.visit_ty(&qself.ty); + } + visitor.visit_path(path, expression.id) + } + ExprBreak(ref opt_sp_ident) | ExprAgain(ref opt_sp_ident) => { + for sp_ident in opt_sp_ident { + visitor.visit_ident(sp_ident.span, sp_ident.node); + } + } + ExprRet(ref optional_expression) => { + walk_list!(visitor, visit_expr, optional_expression); + } + ExprInlineAsm(_, ref outputs, ref inputs) => { + for output in outputs { + visitor.visit_expr(output) + } + for input in inputs { + visitor.visit_expr(input) + } + } + } + + visitor.visit_expr_post(expression) +} + +pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { + walk_list!(visitor, visit_pat, &arm.pats); + walk_list!(visitor, visit_expr, &arm.guard); + visitor.visit_expr(&arm.body); + walk_list!(visitor, visit_attribute, &arm.attrs); +} diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs new file mode 100644 index 00000000000..66b9e217bd3 --- /dev/null +++ b/src/librustc/hir/lowering.rs @@ -0,0 +1,2149 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Lowers the AST to the HIR. +// +// Since the AST and HIR are fairly similar, this is mostly a simple procedure, +// much like a fold. Where lowering involves a bit more work things get more +// interesting and there are some invariants you should know about. These mostly +// concern spans and ids. +// +// Spans are assigned to AST nodes during parsing and then are modified during +// expansion to indicate the origin of a node and the process it went through +// being expanded. Ids are assigned to AST nodes just before lowering. +// +// For the simpler lowering steps, ids and spans should be preserved. Unlike +// expansion we do not preserve the process of lowering in the spans, so spans +// should not be modified here. When creating a new node (as opposed to +// 'folding' an existing one), then you create a new id using `next_id()`. +// +// You must ensure that ids are unique. That means that you should only use the +// id from an AST node in a single HIR node (you can assume that AST node ids +// are unique). Every new node must have a unique id. Avoid cloning HIR nodes. +// If you do, you must then set the new node's id to a fresh one. +// +// Lowering must be reproducable (the compiler only lowers once, but tools and +// custom lints may lower an AST node to a HIR node to interact with the +// compiler). The most interesting bit of this is ids - if you lower an AST node +// and create new HIR nodes with fresh ids, when re-lowering the same node, you +// must ensure you get the same ids! To do this, we keep track of the next id +// when we translate a node which requires new ids. By checking this cache and +// using node ids starting with the cached id, we ensure ids are reproducible. +// To use this system, you just need to hold on to a CachedIdSetter object +// whilst lowering. This is an RAII object that takes care of setting and +// restoring the cached id, etc. +// +// This whole system relies on node ids being incremented one at a time and +// all increments being for lowering. This means that you should not call any +// non-lowering function which will use new node ids. +// +// We must also cache gensym'ed Idents to ensure that we get the same Ident +// every time we lower a node with gensym'ed names. One consequence of this is +// that you can only gensym a name once in a lowering (you don't need to worry +// about nested lowering though). That's because we cache based on the name and +// the currently cached node id, which is unique per lowered node. +// +// Spans are used for error messages and for tools to map semantics back to +// source code. It is therefore not as important with spans as ids to be strict +// about use (you can't break the compiler by screwing up a span). Obviously, a +// HIR node can only have a single span. But multiple nodes can have the same +// span and spans don't need to be kept in order, etc. Where code is preserved +// by lowering, it should have the same span as in the AST. Where HIR nodes are +// new it is probably best to give a span for the whole AST node being lowered. +// All nodes should have real spans, don't use dummy spans. Tools are likely to +// get confused if the spans from leaf AST nodes occur in multiple places +// in the HIR, especially for multiple identifiers. + +use hir; + +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::iter; +use syntax::ast::*; +use syntax::attr::{ThinAttributes, ThinAttributesExt}; +use syntax::errors::Handler; +use syntax::ext::mtwt; +use syntax::ptr::P; +use syntax::codemap::{respan, Spanned, Span}; +use syntax::parse::token; +use syntax::std_inject; +use syntax::visit::{self, Visitor}; + +use std::cell::{Cell, RefCell}; + +pub struct LoweringContext<'a> { + crate_root: Option<&'static str>, + // Map AST ids to ids used for expanded nodes. + id_cache: RefCell>, + // Use if there are no cached ids for the current node. + id_assigner: &'a NodeIdAssigner, + // 0 == no cached id. Must be incremented to align with previous id + // incrementing. + cached_id: Cell, + // Keep track of gensym'ed idents. + gensym_cache: RefCell>, + // A copy of cached_id, but is also set to an id while a node is lowered for + // the first time. + gensym_key: Cell, +} + +impl<'a, 'hir> LoweringContext<'a> { + pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> { + let crate_root = c.and_then(|c| { + if std_inject::no_core(c) { + None + } else if std_inject::no_std(c) { + Some("core") + } else { + Some("std") + } + }); + + LoweringContext { + crate_root: crate_root, + id_cache: RefCell::new(HashMap::new()), + id_assigner: id_assigner, + cached_id: Cell::new(0), + gensym_cache: RefCell::new(HashMap::new()), + gensym_key: Cell::new(0), + } + } + + fn next_id(&self) -> NodeId { + let cached_id = self.cached_id.get(); + if cached_id == 0 { + return self.id_assigner.next_node_id(); + } + + self.cached_id.set(cached_id + 1); + cached_id + } + + fn str_to_ident(&self, s: &'static str) -> hir::Ident { + let gensym_key = self.gensym_key.get(); + if gensym_key == 0 { + return hir::Ident::from_name(token::gensym(s)); + } + + let cached = self.gensym_cache.borrow().contains_key(&(gensym_key, s)); + if cached { + self.gensym_cache.borrow()[&(gensym_key, s)] + } else { + let result = hir::Ident::from_name(token::gensym(s)); + self.gensym_cache.borrow_mut().insert((gensym_key, s), result); + result + } + } + + // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics. + fn diagnostic(&self) -> &Handler { + self.id_assigner.diagnostic() + } +} + +// Utility fn for setting and unsetting the cached id. +fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R + where OP: FnOnce(&LoweringContext) -> R +{ + // Only reset the id if it was previously 0, i.e., was not cached. + // If it was cached, we are in a nested node, but our id count will + // still count towards the parent's count. + let reset_cached_id = lctx.cached_id.get() == 0; + // We always reset gensym_key so that if we use the same name in a nested + // node and after that node, they get different values. + let old_gensym_key = lctx.gensym_key.get(); + + { + let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut(); + + if id_cache.contains_key(&expr_id) { + let cached_id = lctx.cached_id.get(); + if cached_id == 0 { + // We're entering a node where we need to track ids, but are not + // yet tracking. + lctx.cached_id.set(id_cache[&expr_id]); + } else { + // We're already tracking - check that the tracked id is the same + // as the expected id. + assert!(cached_id == id_cache[&expr_id], "id mismatch"); + } + lctx.gensym_key.set(id_cache[&expr_id]); + } else { + // We've never lowered this node before, remember it for next time. + let next_id = lctx.id_assigner.peek_node_id(); + id_cache.insert(expr_id, next_id); + lctx.gensym_key.set(next_id); + // self.cached_id is not set when we lower a node for the first time, + // only on re-lowering. + } + } + + let result = op(lctx); + + if reset_cached_id { + lctx.cached_id.set(0); + } + lctx.gensym_key.set(old_gensym_key); + + result +} + +pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident { + hir::Ident { + name: mtwt::resolve(ident), + unhygienic_name: ident.name, + } +} + +pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec) -> hir::HirVec { + attrs.clone().into() +} + +pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { + P(Spanned { + node: match view_path.node { + ViewPathSimple(ident, ref path) => { + hir::ViewPathSimple(ident.name, lower_path(lctx, path)) + } + ViewPathGlob(ref path) => { + hir::ViewPathGlob(lower_path(lctx, path)) + } + ViewPathList(ref path, ref path_list_idents) => { + hir::ViewPathList(lower_path(lctx, path), + path_list_idents.iter() + .map(lower_path_list_item) + .collect()) + } + }, + span: view_path.span, + }) +} + +fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { + Spanned { + node: match path_list_ident.node { + PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { + id: id, + name: name.name, + rename: rename.map(|x| x.name), + }, + PathListItemKind::Mod { id, rename } => hir::PathListMod { + id: id, + rename: rename.map(|x| x.name), + }, + }, + span: path_list_ident.span, + } +} + +pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { + hir::Arm { + attrs: lower_attrs(lctx, &arm.attrs), + pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), + guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)), + body: lower_expr(lctx, &arm.body), + } +} + +pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { + match d.node { + DeclKind::Local(ref l) => P(Spanned { + node: hir::DeclLocal(lower_local(lctx, l)), + span: d.span, + }), + DeclKind::Item(ref it) => P(Spanned { + node: hir::DeclItem(lower_item_id(lctx, it)), + span: d.span, + }), + } +} + +pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBinding { + hir::TypeBinding { + id: b.id, + name: b.ident.name, + ty: lower_ty(lctx, &b.ty), + span: b.span, + } +} + +pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { + use syntax::ast::TyKind::*; + P(hir::Ty { + id: t.id, + node: match t.node { + Infer => hir::TyInfer, + Vec(ref ty) => hir::TyVec(lower_ty(lctx, ty)), + Ptr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)), + Rptr(ref region, ref mt) => { + hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt)) + } + BareFn(ref f) => { + hir::TyBareFn(P(hir::BareFnTy { + lifetimes: lower_lifetime_defs(lctx, &f.lifetimes), + unsafety: lower_unsafety(lctx, f.unsafety), + abi: f.abi, + decl: lower_fn_decl(lctx, &f.decl), + })) + } + Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()), + Paren(ref ty) => { + return lower_ty(lctx, ty); + } + Path(ref qself, ref path) => { + let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: lower_ty(lctx, ty), + position: position, + } + }); + hir::TyPath(qself, lower_path(lctx, path)) + } + ObjectSum(ref ty, ref bounds) => { + hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds)) + } + FixedLengthVec(ref ty, ref e) => { + hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e)) + } + Typeof(ref expr) => { + hir::TyTypeof(lower_expr(lctx, expr)) + } + PolyTraitRef(ref bounds) => { + hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect()) + } + Mac(_) => panic!("TyMac should have been expanded by now."), + }, + span: t.span, + }) +} + +pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { + hir::ForeignMod { + abi: fm.abi, + items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), + } +} + +pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { + Spanned { + node: hir::Variant_ { + name: v.node.name.name, + attrs: lower_attrs(lctx, &v.node.attrs), + data: lower_variant_data(lctx, &v.node.data), + disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)), + }, + span: v.span, + } +} + +// Path segments are usually unhygienic, hygienic path segments can occur only in +// identifier-like paths originating from `ExprPath`. +// Make life simpler for rustc_resolve by renaming only such segments. +pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { + let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; + hir::Path { + global: p.global, + segments: p.segments + .iter() + .map(|&PathSegment { identifier, ref parameters }| { + hir::PathSegment { + identifier: if maybe_hygienic { + lower_ident(lctx, identifier) + } else { + hir::Ident::from_name(identifier.name) + }, + parameters: lower_path_parameters(lctx, parameters), + } + }) + .collect(), + span: p.span, + } +} + +pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { + lower_path_full(lctx, p, false) +} + +pub fn lower_path_parameters(lctx: &LoweringContext, + path_parameters: &PathParameters) + -> hir::PathParameters { + match *path_parameters { + PathParameters::AngleBracketed(ref data) => + hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), + PathParameters::Parenthesized(ref data) => + hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)), + } +} + +pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, + data: &AngleBracketedParameterData) + -> hir::AngleBracketedParameterData { + let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; + hir::AngleBracketedParameterData { + lifetimes: lower_lifetimes(lctx, lifetimes), + types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(), + bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(), + } +} + +pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, + data: &ParenthesizedParameterData) + -> hir::ParenthesizedParameterData { + let &ParenthesizedParameterData { ref inputs, ref output, span } = data; + hir::ParenthesizedParameterData { + inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), + output: output.as_ref().map(|ty| lower_ty(lctx, ty)), + span: span, + } +} + +pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { + P(hir::Local { + id: l.id, + ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), + pat: lower_pat(lctx, &l.pat), + init: l.init.as_ref().map(|e| lower_expr(lctx, e)), + span: l.span, + attrs: l.attrs.clone(), + }) +} + +pub fn lower_explicit_self_underscore(lctx: &LoweringContext, + es: &SelfKind) + -> hir::ExplicitSelf_ { + match *es { + SelfKind::Static => hir::SelfStatic, + SelfKind::Value(v) => hir::SelfValue(v.name), + SelfKind::Region(ref lifetime, m, ident) => { + hir::SelfRegion(lower_opt_lifetime(lctx, lifetime), + lower_mutability(lctx, m), + ident.name) + } + SelfKind::Explicit(ref typ, ident) => { + hir::SelfExplicit(lower_ty(lctx, typ), ident.name) + } + } +} + +pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability { + match m { + Mutability::Mutable => hir::MutMutable, + Mutability::Immutable => hir::MutImmutable, + } +} + +pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { + Spanned { + node: lower_explicit_self_underscore(lctx, &s.node), + span: s.span, + } +} + +pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { + hir::Arg { + id: arg.id, + pat: lower_pat(lctx, &arg.pat), + ty: lower_ty(lctx, &arg.ty), + } +} + +pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { + P(hir::FnDecl { + inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), + output: match decl.output { + FunctionRetTy::Ty(ref ty) => hir::Return(lower_ty(lctx, ty)), + FunctionRetTy::Default(span) => hir::DefaultReturn(span), + FunctionRetTy::None(span) => hir::NoReturn(span), + }, + variadic: decl.variadic, + }) +} + +pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { + match *tpb { + TraitTyParamBound(ref ty, modifier) => { + hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), + lower_trait_bound_modifier(lctx, modifier)) + } + RegionTyParamBound(ref lifetime) => { + hir::RegionTyParamBound(lower_lifetime(lctx, lifetime)) + } + } +} + +pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { + hir::TyParam { + id: tp.id, + name: tp.ident.name, + bounds: lower_bounds(lctx, &tp.bounds), + default: tp.default.as_ref().map(|x| lower_ty(lctx, x)), + span: tp.span, + } +} + +pub fn lower_ty_params(lctx: &LoweringContext, + tps: &P<[TyParam]>) + -> hir::HirVec { + tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() +} + +pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { + hir::Lifetime { + id: l.id, + name: l.name, + span: l.span, + } +} + +pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { + hir::LifetimeDef { + lifetime: lower_lifetime(lctx, &l.lifetime), + bounds: lower_lifetimes(lctx, &l.bounds), + } +} + +pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec) -> hir::HirVec { + lts.iter().map(|l| lower_lifetime(lctx, l)).collect() +} + +pub fn lower_lifetime_defs(lctx: &LoweringContext, + lts: &Vec) + -> hir::HirVec { + lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() +} + +pub fn lower_opt_lifetime(lctx: &LoweringContext, + o_lt: &Option) + -> Option { + o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) +} + +pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { + hir::Generics { + ty_params: lower_ty_params(lctx, &g.ty_params), + lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), + where_clause: lower_where_clause(lctx, &g.where_clause), + } +} + +pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { + hir::WhereClause { + id: wc.id, + predicates: wc.predicates + .iter() + .map(|predicate| lower_where_predicate(lctx, predicate)) + .collect(), + } +} + +pub fn lower_where_predicate(lctx: &LoweringContext, + pred: &WherePredicate) + -> hir::WherePredicate { + match *pred { + WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, + ref bounded_ty, + ref bounds, + span}) => { + hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes), + bounded_ty: lower_ty(lctx, bounded_ty), + bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(), + span: span, + }) + } + WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, + ref bounds, + span}) => { + hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { + span: span, + lifetime: lower_lifetime(lctx, lifetime), + bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(), + }) + } + WherePredicate::EqPredicate(WhereEqPredicate{ id, + ref path, + ref ty, + span}) => { + hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { + id: id, + path: lower_path(lctx, path), + ty: lower_ty(lctx, ty), + span: span, + }) + } + } +} + +pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { + match *vdata { + VariantData::Struct(ref fields, id) => { + hir::VariantData::Struct(fields.iter() + .enumerate() + .map(|f| lower_struct_field(lctx, f)) + .collect(), + id) + } + VariantData::Tuple(ref fields, id) => { + hir::VariantData::Tuple(fields.iter() + .enumerate() + .map(|f| lower_struct_field(lctx, f)) + .collect(), + id) + } + VariantData::Unit(id) => hir::VariantData::Unit(id), + } +} + +pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { + hir::TraitRef { + path: lower_path(lctx, &p.path), + ref_id: p.ref_id, + } +} + +pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { + hir::PolyTraitRef { + bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), + trait_ref: lower_trait_ref(lctx, &p.trait_ref), + span: p.span, + } +} + +pub fn lower_struct_field(lctx: &LoweringContext, + (index, f): (usize, &StructField)) + -> hir::StructField { + hir::StructField { + span: f.span, + id: f.node.id, + name: f.node.ident().map(|ident| ident.name) + .unwrap_or(token::intern(&index.to_string())), + vis: lower_visibility(lctx, f.node.kind.visibility()), + ty: lower_ty(lctx, &f.node.ty), + attrs: lower_attrs(lctx, &f.node.attrs), + } +} + +pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { + hir::Field { + name: respan(f.ident.span, f.ident.node.name), + expr: lower_expr(lctx, &f.expr), + span: f.span, + } +} + +pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { + hir::MutTy { + ty: lower_ty(lctx, &mt.ty), + mutbl: lower_mutability(lctx, mt.mutbl), + } +} + +pub fn lower_opt_bounds(lctx: &LoweringContext, + b: &Option) + -> Option { + b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds)) +} + +fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { + bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() +} + +pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { + P(hir::Block { + id: b.id, + stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), + expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)), + rules: lower_block_check_mode(lctx, &b.rules), + span: b.span, + }) +} + +pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { + match *i { + ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), + ItemKind::Use(ref view_path) => { + hir::ItemUse(lower_view_path(lctx, view_path)) + } + ItemKind::Static(ref t, m, ref e) => { + hir::ItemStatic(lower_ty(lctx, t), + lower_mutability(lctx, m), + lower_expr(lctx, e)) + } + ItemKind::Const(ref t, ref e) => { + hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e)) + } + ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { + hir::ItemFn(lower_fn_decl(lctx, decl), + lower_unsafety(lctx, unsafety), + lower_constness(lctx, constness), + abi, + lower_generics(lctx, generics), + lower_block(lctx, body)) + } + ItemKind::Mod(ref m) => hir::ItemMod(lower_mod(lctx, m)), + ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)), + ItemKind::Ty(ref t, ref generics) => { + hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics)) + } + ItemKind::Enum(ref enum_definition, ref generics) => { + hir::ItemEnum(hir::EnumDef { + variants: enum_definition.variants + .iter() + .map(|x| lower_variant(lctx, x)) + .collect(), + }, + lower_generics(lctx, generics)) + } + ItemKind::Struct(ref struct_def, ref generics) => { + let struct_def = lower_variant_data(lctx, struct_def); + hir::ItemStruct(struct_def, lower_generics(lctx, generics)) + } + ItemKind::DefaultImpl(unsafety, ref trait_ref) => { + hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety), + lower_trait_ref(lctx, trait_ref)) + } + ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { + let new_impl_items = impl_items.iter() + .map(|item| lower_impl_item(lctx, item)) + .collect(); + let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref)); + hir::ItemImpl(lower_unsafety(lctx, unsafety), + lower_impl_polarity(lctx, polarity), + lower_generics(lctx, generics), + ifce, + lower_ty(lctx, ty), + new_impl_items) + } + ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { + let bounds = lower_bounds(lctx, bounds); + let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect(); + hir::ItemTrait(lower_unsafety(lctx, unsafety), + lower_generics(lctx, generics), + bounds, + items) + } + ItemKind::Mac(_) => panic!("Shouldn't still be around"), + } +} + +pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { + hir::TraitItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + TraitItemKind::Const(ref ty, ref default) => { + hir::ConstTraitItem(lower_ty(lctx, ty), + default.as_ref().map(|x| lower_expr(lctx, x))) + } + TraitItemKind::Method(ref sig, ref body) => { + hir::MethodTraitItem(lower_method_sig(lctx, sig), + body.as_ref().map(|x| lower_block(lctx, x))) + } + TraitItemKind::Type(ref bounds, ref default) => { + hir::TypeTraitItem(lower_bounds(lctx, bounds), + default.as_ref().map(|x| lower_ty(lctx, x))) + } + }, + span: i.span, + } +} + +pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { + hir::ImplItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + vis: lower_visibility(lctx, &i.vis), + defaultness: lower_defaultness(lctx, i.defaultness), + node: match i.node { + ImplItemKind::Const(ref ty, ref expr) => { + hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) + } + ImplItemKind::Method(ref sig, ref body) => { + hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) + } + ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), + ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }, + span: i.span, + } +} + +pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { + hir::Mod { + inner: m.inner, + item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), + } +} + +struct ItemLowerer<'lcx, 'interner: 'lcx> { + items: BTreeMap, + lctx: &'lcx LoweringContext<'interner>, +} + +impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { + fn visit_item(&mut self, item: &'lcx Item) { + self.items.insert(item.id, lower_item(self.lctx, item)); + visit::walk_item(self, item); + } +} + +pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { + let items = { + let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; + visit::walk_crate(&mut item_lowerer, c); + item_lowerer.items + }; + + hir::Crate { + module: lower_mod(lctx, &c.module), + attrs: lower_attrs(lctx, &c.attrs), + config: c.config.clone().into(), + span: c.span, + exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(), + items: items, + } +} + +pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { + hir::MacroDef { + name: m.ident.name, + attrs: lower_attrs(lctx, &m.attrs), + id: m.id, + span: m.span, + imported_from: m.imported_from.map(|x| x.name), + export: m.export, + use_locally: m.use_locally, + allow_internal_unstable: m.allow_internal_unstable, + body: m.body.clone().into(), + } +} + +pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { + hir::ItemId { id: i.id } +} + +pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { + let node = lower_item_kind(lctx, &i.node); + + hir::Item { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: node, + vis: lower_visibility(lctx, &i.vis), + span: i.span, + } +} + +pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { + hir::ForeignItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + ForeignItemKind::Fn(ref fdec, ref generics) => { + hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) + } + ForeignItemKind::Static(ref t, m) => { + hir::ForeignItemStatic(lower_ty(lctx, t), m) + } + }, + vis: lower_visibility(lctx, &i.vis), + span: i.span, + } +} + +pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { + hir::MethodSig { + generics: lower_generics(lctx, &sig.generics), + abi: sig.abi, + explicit_self: lower_explicit_self(lctx, &sig.explicit_self), + unsafety: lower_unsafety(lctx, sig.unsafety), + constness: lower_constness(lctx, sig.constness), + decl: lower_fn_decl(lctx, &sig.decl), + } +} + +pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety { + match u { + Unsafety::Unsafe => hir::Unsafety::Unsafe, + Unsafety::Normal => hir::Unsafety::Normal, + } +} + +pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness { + match c { + Constness::Const => hir::Constness::Const, + Constness::NotConst => hir::Constness::NotConst, + } +} + +pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { + match u { + UnOp::Deref => hir::UnDeref, + UnOp::Not => hir::UnNot, + UnOp::Neg => hir::UnNeg, + } +} + +pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { + Spanned { + node: match b.node { + BinOpKind::Add => hir::BiAdd, + BinOpKind::Sub => hir::BiSub, + BinOpKind::Mul => hir::BiMul, + BinOpKind::Div => hir::BiDiv, + BinOpKind::Rem => hir::BiRem, + BinOpKind::And => hir::BiAnd, + BinOpKind::Or => hir::BiOr, + BinOpKind::BitXor => hir::BiBitXor, + BinOpKind::BitAnd => hir::BiBitAnd, + BinOpKind::BitOr => hir::BiBitOr, + BinOpKind::Shl => hir::BiShl, + BinOpKind::Shr => hir::BiShr, + BinOpKind::Eq => hir::BiEq, + BinOpKind::Lt => hir::BiLt, + BinOpKind::Le => hir::BiLe, + BinOpKind::Ne => hir::BiNe, + BinOpKind::Ge => hir::BiGe, + BinOpKind::Gt => hir::BiGt, + }, + span: b.span, + } +} + +pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { + P(hir::Pat { + id: p.id, + node: match p.node { + PatKind::Wild => hir::PatKind::Wild, + PatKind::Ident(ref binding_mode, pth1, ref sub) => { + hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), + respan(pth1.span, lower_ident(lctx, pth1.node)), + sub.as_ref().map(|x| lower_pat(lctx, x))) + } + PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), + PatKind::TupleStruct(ref pth, ref pats) => { + hir::PatKind::TupleStruct(lower_path(lctx, pth), + pats.as_ref() + .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) + } + PatKind::Path(ref pth) => { + hir::PatKind::Path(lower_path(lctx, pth)) + } + PatKind::QPath(ref qself, ref pth) => { + let qself = hir::QSelf { + ty: lower_ty(lctx, &qself.ty), + position: qself.position, + }; + hir::PatKind::QPath(qself, lower_path(lctx, pth)) + } + PatKind::Struct(ref pth, ref fields, etc) => { + let pth = lower_path(lctx, pth); + let fs = fields.iter() + .map(|f| { + Spanned { + span: f.span, + node: hir::FieldPat { + name: f.node.ident.name, + pat: lower_pat(lctx, &f.node.pat), + is_shorthand: f.node.is_shorthand, + }, + } + }) + .collect(); + hir::PatKind::Struct(pth, fs, etc) + } + PatKind::Tup(ref elts) => { + hir::PatKind::Tup(elts.iter().map(|x| lower_pat(lctx, x)).collect()) + } + PatKind::Box(ref inner) => hir::PatKind::Box(lower_pat(lctx, inner)), + PatKind::Ref(ref inner, mutbl) => { + hir::PatKind::Ref(lower_pat(lctx, inner), lower_mutability(lctx, mutbl)) + } + PatKind::Range(ref e1, ref e2) => { + hir::PatKind::Range(lower_expr(lctx, e1), lower_expr(lctx, e2)) + } + PatKind::Vec(ref before, ref slice, ref after) => { + hir::PatKind::Vec(before.iter().map(|x| lower_pat(lctx, x)).collect(), + slice.as_ref().map(|x| lower_pat(lctx, x)), + after.iter().map(|x| lower_pat(lctx, x)).collect()) + } + PatKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: p.span, + }) +} + +pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { + P(hir::Expr { + id: e.id, + node: match e.node { + // Issue #22181: + // Eventually a desugaring for `box EXPR` + // (similar to the desugaring above for `in PLACE BLOCK`) + // should go here, desugaring + // + // to: + // + // let mut place = BoxPlace::make_place(); + // let raw_place = Place::pointer(&mut place); + // let value = $value; + // unsafe { + // ::std::ptr::write(raw_place, value); + // Boxed::finalize(place) + // } + // + // But for now there are type-inference issues doing that. + ExprKind::Box(ref e) => { + hir::ExprBox(lower_expr(lctx, e)) + } + + // Desugar ExprBox: `in (PLACE) EXPR` + ExprKind::InPlace(ref placer, ref value_expr) => { + // to: + // + // let p = PLACE; + // let mut place = Placer::make_place(p); + // let raw_place = Place::pointer(&mut place); + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + return cache_ids(lctx, e.id, |lctx| { + let placer_expr = lower_expr(lctx, placer); + let value_expr = lower_expr(lctx, value_expr); + + let placer_ident = lctx.str_to_ident("placer"); + let place_ident = lctx.str_to_ident("place"); + let p_ptr_ident = lctx.str_to_ident("p_ptr"); + + let make_place = ["ops", "Placer", "make_place"]; + let place_pointer = ["ops", "Place", "pointer"]; + let move_val_init = ["intrinsics", "move_val_init"]; + let inplace_finalize = ["ops", "InPlace", "finalize"]; + + let make_call = |lctx: &LoweringContext, p, args| { + let path = core_path(lctx, e.span, p); + let path = expr_path(lctx, path, None); + expr_call(lctx, e.span, path, args, None) + }; + + let mk_stmt_let = |lctx: &LoweringContext, bind, expr| { + stmt_let(lctx, e.span, false, bind, expr, None) + }; + + let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| { + stmt_let(lctx, e.span, true, bind, expr, None) + }; + + // let placer = ; + let s1 = { + let placer_expr = signal_block_expr(lctx, + hir_vec![], + placer_expr, + e.span, + hir::PopUnstableBlock, + None); + mk_stmt_let(lctx, placer_ident, placer_expr) + }; + + // let mut place = Placer::make_place(placer); + let s2 = { + let placer = expr_ident(lctx, e.span, placer_ident, None); + let call = make_call(lctx, &make_place, hir_vec![placer]); + mk_stmt_let_mut(lctx, place_ident, call) + }; + + // let p_ptr = Place::pointer(&mut place); + let s3 = { + let agent = expr_ident(lctx, e.span, place_ident, None); + let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)]; + let call = make_call(lctx, &place_pointer, args); + mk_stmt_let(lctx, p_ptr_ident, call) + }; + + // pop_unsafe!(EXPR)); + let pop_unsafe_expr = { + let value_expr = signal_block_expr(lctx, + hir_vec![], + value_expr, + e.span, + hir::PopUnstableBlock, + None); + signal_block_expr(lctx, + hir_vec![], + value_expr, + e.span, + hir::PopUnsafeBlock(hir::CompilerGenerated), None) + }; + + // push_unsafe!({ + // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); + // InPlace::finalize(place) + // }) + let expr = { + let ptr = expr_ident(lctx, e.span, p_ptr_ident, None); + let call_move_val_init = + hir::StmtSemi( + make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), + lctx.next_id()); + let call_move_val_init = respan(e.span, call_move_val_init); + + let place = expr_ident(lctx, e.span, place_ident, None); + let call = make_call(lctx, &inplace_finalize, hir_vec![place]); + signal_block_expr(lctx, + hir_vec![call_move_val_init], + call, + e.span, + hir::PushUnsafeBlock(hir::CompilerGenerated), None) + }; + + signal_block_expr(lctx, + hir_vec![s1, s2, s3], + expr, + e.span, + hir::PushUnstableBlock, + e.attrs.clone()) + }); + } + + ExprKind::Vec(ref exprs) => { + hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect()) + } + ExprKind::Repeat(ref expr, ref count) => { + let expr = lower_expr(lctx, expr); + let count = lower_expr(lctx, count); + hir::ExprRepeat(expr, count) + } + ExprKind::Tup(ref elts) => { + hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect()) + } + ExprKind::Call(ref f, ref args) => { + let f = lower_expr(lctx, f); + hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect()) + } + ExprKind::MethodCall(i, ref tps, ref args) => { + let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect(); + let args = args.iter().map(|x| lower_expr(lctx, x)).collect(); + hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) + } + ExprKind::Binary(binop, ref lhs, ref rhs) => { + let binop = lower_binop(lctx, binop); + let lhs = lower_expr(lctx, lhs); + let rhs = lower_expr(lctx, rhs); + hir::ExprBinary(binop, lhs, rhs) + } + ExprKind::Unary(op, ref ohs) => { + let op = lower_unop(lctx, op); + let ohs = lower_expr(lctx, ohs); + hir::ExprUnary(op, ohs) + } + ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())), + ExprKind::Cast(ref expr, ref ty) => { + let expr = lower_expr(lctx, expr); + hir::ExprCast(expr, lower_ty(lctx, ty)) + } + ExprKind::Type(ref expr, ref ty) => { + let expr = lower_expr(lctx, expr); + hir::ExprType(expr, lower_ty(lctx, ty)) + } + ExprKind::AddrOf(m, ref ohs) => { + let m = lower_mutability(lctx, m); + let ohs = lower_expr(lctx, ohs); + hir::ExprAddrOf(m, ohs) + } + // More complicated than you might expect because the else branch + // might be `if let`. + ExprKind::If(ref cond, ref blk, ref else_opt) => { + let else_opt = else_opt.as_ref().map(|els| { + match els.node { + ExprKind::IfLet(..) => { + cache_ids(lctx, e.id, |lctx| { + // wrap the if-let expr in a block + let span = els.span; + let els = lower_expr(lctx, els); + let id = lctx.next_id(); + let blk = P(hir::Block { + stmts: hir_vec![], + expr: Some(els), + id: id, + rules: hir::DefaultBlock, + span: span, + }); + expr_block(lctx, blk, None) + }) + } + _ => lower_expr(lctx, els), + } + }); + + hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt) + } + ExprKind::While(ref cond, ref body, opt_ident) => { + hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), + opt_ident.map(|ident| lower_ident(lctx, ident))) + } + ExprKind::Loop(ref body, opt_ident) => { + hir::ExprLoop(lower_block(lctx, body), + opt_ident.map(|ident| lower_ident(lctx, ident))) + } + ExprKind::Match(ref expr, ref arms) => { + hir::ExprMatch(lower_expr(lctx, expr), + arms.iter().map(|x| lower_arm(lctx, x)).collect(), + hir::MatchSource::Normal) + } + ExprKind::Closure(capture_clause, ref decl, ref body) => { + hir::ExprClosure(lower_capture_clause(lctx, capture_clause), + lower_fn_decl(lctx, decl), + lower_block(lctx, body)) + } + ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), + ExprKind::Assign(ref el, ref er) => { + hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er)) + } + ExprKind::AssignOp(op, ref el, ref er) => { + hir::ExprAssignOp(lower_binop(lctx, op), + lower_expr(lctx, el), + lower_expr(lctx, er)) + } + ExprKind::Field(ref el, ident) => { + hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name)) + } + ExprKind::TupField(ref el, ident) => { + hir::ExprTupField(lower_expr(lctx, el), ident) + } + ExprKind::Index(ref el, ref er) => { + hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) + } + ExprKind::Range(ref e1, ref e2, lims) => { + fn make_struct(lctx: &LoweringContext, + ast_expr: &Expr, + path: &[&str], + fields: &[(&str, &P)]) -> P { + let strs = std_path(lctx, &iter::once(&"ops") + .chain(path) + .map(|s| *s) + .collect::>()); + + let structpath = path_global(ast_expr.span, strs); + + let hir_expr = if fields.len() == 0 { + expr_path(lctx, + structpath, + ast_expr.attrs.clone()) + } else { + expr_struct(lctx, + ast_expr.span, + structpath, + fields.into_iter().map(|&(s, e)| { + field(token::intern(s), + signal_block_expr(lctx, + hir_vec![], + lower_expr(lctx, &**e), + e.span, + hir::PopUnstableBlock, + None), + ast_expr.span) + }).collect(), + None, + ast_expr.attrs.clone()) + }; + + signal_block_expr(lctx, + hir_vec![], + hir_expr, + ast_expr.span, + hir::PushUnstableBlock, + None) + } + + return cache_ids(lctx, e.id, |lctx| { + use syntax::ast::RangeLimits::*; + + match (e1, e2, lims) { + (&None, &None, HalfOpen) => + make_struct(lctx, e, &["RangeFull"], + &[]), + + (&Some(ref e1), &None, HalfOpen) => + make_struct(lctx, e, &["RangeFrom"], + &[("start", e1)]), + + (&None, &Some(ref e2), HalfOpen) => + make_struct(lctx, e, &["RangeTo"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), HalfOpen) => + make_struct(lctx, e, &["Range"], + &[("start", e1), ("end", e2)]), + + (&None, &Some(ref e2), Closed) => + make_struct(lctx, e, &["RangeToInclusive"], + &[("end", e2)]), + + (&Some(ref e1), &Some(ref e2), Closed) => + make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], + &[("start", e1), ("end", e2)]), + + _ => panic!(lctx.diagnostic().span_fatal(e.span, + "inclusive range with no end")) + } + }); + } + ExprKind::Path(ref qself, ref path) => { + let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { + hir::QSelf { + ty: lower_ty(lctx, ty), + position: position, + } + }); + hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none())) + } + ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { + respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) + })), + ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { + respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) + })), + ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))), + ExprKind::InlineAsm(InlineAsm { + ref inputs, + ref outputs, + ref asm, + asm_str_style, + ref clobbers, + volatile, + alignstack, + dialect, + expn_id, + }) => hir::ExprInlineAsm(hir::InlineAsm { + inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), + outputs: outputs.iter() + .map(|out| { + hir::InlineAsmOutput { + constraint: out.constraint.clone(), + is_rw: out.is_rw, + is_indirect: out.is_indirect, + } + }) + .collect(), + asm: asm.clone(), + asm_str_style: asm_str_style, + clobbers: clobbers.clone().into(), + volatile: volatile, + alignstack: alignstack, + dialect: dialect, + expn_id: expn_id, + }, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(), + inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()), + ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { + hir::ExprStruct(lower_path(lctx, path), + fields.iter().map(|x| lower_field(lctx, x)).collect(), + maybe_expr.as_ref().map(|x| lower_expr(lctx, x))) + } + ExprKind::Paren(ref ex) => { + // merge attributes into the inner expression. + return lower_expr(lctx, ex).map(|mut ex| { + ex.attrs.update(|attrs| { + attrs.prepend(e.attrs.clone()) + }); + ex + }); + } + + // Desugar ExprIfLet + // From: `if let = []` + ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { + // to: + // + // match { + // => , + // [_ if => ,] + // _ => [ | ()] + // } + + return cache_ids(lctx, e.id, |lctx| { + // ` => ` + let pat_arm = { + let body = lower_block(lctx, body); + let body_expr = expr_block(lctx, body, None); + arm(hir_vec![lower_pat(lctx, pat)], body_expr) + }; + + // `[_ if => ,]` + let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); + let else_if_arms = { + let mut arms = vec![]; + loop { + let else_opt_continue = else_opt.and_then(|els| { + els.and_then(|els| { + match els.node { + // else if + hir::ExprIf(cond, then, else_opt) => { + let pat_under = pat_wild(lctx, e.span); + arms.push(hir::Arm { + attrs: hir_vec![], + pats: hir_vec![pat_under], + guard: Some(cond), + body: expr_block(lctx, then, None), + }); + else_opt.map(|else_opt| (else_opt, true)) + } + _ => Some((P(els), false)), + } + }) + }); + match else_opt_continue { + Some((e, true)) => { + else_opt = Some(e); + } + Some((e, false)) => { + else_opt = Some(e); + break; + } + None => { + else_opt = None; + break; + } + } + } + arms + }; + + let contains_else_clause = else_opt.is_some(); + + // `_ => [ | ()]` + let else_arm = { + let pat_under = pat_wild(lctx, e.span); + let else_expr = + else_opt.unwrap_or_else( + || expr_tuple(lctx, e.span, hir_vec![], None)); + arm(hir_vec![pat_under], else_expr) + }; + + let mut arms = Vec::with_capacity(else_if_arms.len() + 2); + arms.push(pat_arm); + arms.extend(else_if_arms); + arms.push(else_arm); + + let sub_expr = lower_expr(lctx, sub_expr); + // add attributes to the outer returned expr node + expr(lctx, + e.span, + hir::ExprMatch(sub_expr, + arms.into(), + hir::MatchSource::IfLetDesugar { + contains_else_clause: contains_else_clause, + }), + e.attrs.clone()) + }); + } + + // Desugar ExprWhileLet + // From: `[opt_ident]: while let = ` + ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { + // to: + // + // [opt_ident]: loop { + // match { + // => , + // _ => break + // } + // } + + return cache_ids(lctx, e.id, |lctx| { + // ` => ` + let pat_arm = { + let body = lower_block(lctx, body); + let body_expr = expr_block(lctx, body, None); + arm(hir_vec![lower_pat(lctx, pat)], body_expr) + }; + + // `_ => break` + let break_arm = { + let pat_under = pat_wild(lctx, e.span); + let break_expr = expr_break(lctx, e.span, None); + arm(hir_vec![pat_under], break_expr) + }; + + // `match { ... }` + let arms = hir_vec![pat_arm, break_arm]; + let sub_expr = lower_expr(lctx, sub_expr); + let match_expr = expr(lctx, + e.span, + hir::ExprMatch(sub_expr, + arms, + hir::MatchSource::WhileLetDesugar), + None); + + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(lctx, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| lower_ident(lctx, ident))); + // add attributes to the outer returned expr node + expr(lctx, e.span, loop_expr, e.attrs.clone()) + }); + } + + // Desugar ExprForLoop + // From: `[opt_ident]: for in ` + ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { + // to: + // + // { + // let result = match ::std::iter::IntoIterator::into_iter() { + // mut iter => { + // [opt_ident]: loop { + // match ::std::iter::Iterator::next(&mut iter) { + // ::std::option::Option::Some() => , + // ::std::option::Option::None => break + // } + // } + // } + // }; + // result + // } + + return cache_ids(lctx, e.id, |lctx| { + // expand + let head = lower_expr(lctx, head); + + let iter = lctx.str_to_ident("iter"); + + // `::std::option::Option::Some() => ` + let pat_arm = { + let body_block = lower_block(lctx, body); + let body_span = body_block.span; + let body_expr = P(hir::Expr { + id: lctx.next_id(), + node: hir::ExprBlock(body_block), + span: body_span, + attrs: None, + }); + let pat = lower_pat(lctx, pat); + let some_pat = pat_some(lctx, e.span, pat); + + arm(hir_vec![some_pat], body_expr) + }; + + // `::std::option::Option::None => break` + let break_arm = { + let break_expr = expr_break(lctx, e.span, None); + + arm(hir_vec![pat_none(lctx, e.span)], break_expr) + }; + + // `match ::std::iter::Iterator::next(&mut iter) { ... }` + let match_expr = { + let next_path = { + let strs = std_path(lctx, &["iter", "Iterator", "next"]); + + path_global(e.span, strs) + }; + let iter = expr_ident(lctx, e.span, iter, None); + let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None); + let next_path = expr_path(lctx, next_path, None); + let next_expr = expr_call(lctx, + e.span, + next_path, + hir_vec![ref_mut_iter], + None); + let arms = hir_vec![pat_arm, break_arm]; + + expr(lctx, + e.span, + hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), + None) + }; + + // `[opt_ident]: loop { ... }` + let loop_block = block_expr(lctx, match_expr); + let loop_expr = hir::ExprLoop(loop_block, + opt_ident.map(|ident| lower_ident(lctx, ident))); + let loop_expr = expr(lctx, e.span, loop_expr, None); + + // `mut iter => { ... }` + let iter_arm = { + let iter_pat = pat_ident_binding_mode(lctx, + e.span, + iter, + hir::BindByValue(hir::MutMutable)); + arm(hir_vec![iter_pat], loop_expr) + }; + + // `match ::std::iter::IntoIterator::into_iter() { ... }` + let into_iter_expr = { + let into_iter_path = { + let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); + + path_global(e.span, strs) + }; + + let into_iter = expr_path(lctx, into_iter_path, None); + expr_call(lctx, e.span, into_iter, hir_vec![head], None) + }; + + let match_expr = expr_match(lctx, + e.span, + into_iter_expr, + hir_vec![iter_arm], + hir::MatchSource::ForLoopDesugar, + None); + + // `{ let _result = ...; _result }` + // underscore prevents an unused_variables lint if the head diverges + let result_ident = lctx.str_to_ident("_result"); + let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None); + let result = expr_ident(lctx, e.span, result_ident, None); + let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); + // add the attributes to the outer returned expr node + expr_block(lctx, block, e.attrs.clone()) + }); + } + + // Desugar ExprKind::Try + // From: `?` + ExprKind::Try(ref sub_expr) => { + // to: + // + // { + // match { + // Ok(val) => val, + // Err(err) => { + // return Err(From::from(err)) + // } + // } + // } + + return cache_ids(lctx, e.id, |lctx| { + // expand + let sub_expr = lower_expr(lctx, sub_expr); + + // Ok(val) => val + let ok_arm = { + let val_ident = lctx.str_to_ident("val"); + let val_pat = pat_ident(lctx, e.span, val_ident); + let val_expr = expr_ident(lctx, e.span, val_ident, None); + let ok_pat = pat_ok(lctx, e.span, val_pat); + + arm(hir_vec![ok_pat], val_expr) + }; + + // Err(err) => return Err(From::from(err)) + let err_arm = { + let err_ident = lctx.str_to_ident("err"); + let from_expr = { + let path = std_path(lctx, &["convert", "From", "from"]); + let path = path_global(e.span, path); + let from = expr_path(lctx, path, None); + let err_expr = expr_ident(lctx, e.span, err_ident, None); + + expr_call(lctx, e.span, from, hir_vec![err_expr], None) + }; + let err_expr = { + let path = std_path(lctx, &["result", "Result", "Err"]); + let path = path_global(e.span, path); + let err_ctor = expr_path(lctx, path, None); + expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) + }; + let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident)); + let ret_expr = expr(lctx, e.span, + hir::Expr_::ExprRet(Some(err_expr)), None); + + arm(hir_vec![err_pat], ret_expr) + }; + + expr_match(lctx, e.span, sub_expr, hir_vec![err_arm, ok_arm], + hir::MatchSource::TryDesugar, None) + }) + } + + ExprKind::Mac(_) => panic!("Shouldn't exist here"), + }, + span: e.span, + attrs: e.attrs.clone(), + }) +} + +pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { + match s.node { + StmtKind::Decl(ref d, id) => { + Spanned { + node: hir::StmtDecl(lower_decl(lctx, d), id), + span: s.span, + } + } + StmtKind::Expr(ref e, id) => { + Spanned { + node: hir::StmtExpr(lower_expr(lctx, e), id), + span: s.span, + } + } + StmtKind::Semi(ref e, id) => { + Spanned { + node: hir::StmtSemi(lower_expr(lctx, e), id), + span: s.span, + } + } + StmtKind::Mac(..) => panic!("Shouldn't exist here"), + } +} + +pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::CaptureClause { + match c { + CaptureBy::Value => hir::CaptureByValue, + CaptureBy::Ref => hir::CaptureByRef, + } +} + +pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility { + match *v { + Visibility::Public => hir::Public, + Visibility::Inherited => hir::Inherited, + _ => panic!(lctx.diagnostic().fatal("pub(restricted) is not implemented yet!")) + } +} + +pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness { + match d { + Defaultness::Default => hir::Defaultness::Default, + Defaultness::Final => hir::Defaultness::Final, + } +} + +pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { + match *b { + BlockCheckMode::Default => hir::DefaultBlock, + BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), + } +} + +pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { + match *b { + BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), + BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), + } +} + +pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { + match u { + CompilerGenerated => hir::CompilerGenerated, + UserProvided => hir::UserProvided, + } +} + +pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { + match i { + ImplPolarity::Positive => hir::ImplPolarity::Positive, + ImplPolarity::Negative => hir::ImplPolarity::Negative, + } +} + +pub fn lower_trait_bound_modifier(_lctx: &LoweringContext, + f: TraitBoundModifier) + -> hir::TraitBoundModifier { + match f { + TraitBoundModifier::None => hir::TraitBoundModifier::None, + TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, + } +} + +// Helper methods for building HIR. + +fn arm(pats: hir::HirVec>, expr: P) -> hir::Arm { + hir::Arm { + attrs: hir_vec![], + pats: pats, + guard: None, + body: expr, + } +} + +fn field(name: Name, expr: P, span: Span) -> hir::Field { + hir::Field { + name: Spanned { + node: name, + span: span, + }, + span: span, + expr: expr, + } +} + +fn expr_break(lctx: &LoweringContext, span: Span, + attrs: ThinAttributes) -> P { + expr(lctx, span, hir::ExprBreak(None), attrs) +} + +fn expr_call(lctx: &LoweringContext, + span: Span, + e: P, + args: hir::HirVec>, + attrs: ThinAttributes) + -> P { + expr(lctx, span, hir::ExprCall(e, args), attrs) +} + +fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident, + attrs: ThinAttributes) -> P { + expr_path(lctx, path_ident(span, id), attrs) +} + +fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P, + attrs: ThinAttributes) -> P { + expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) +} + +fn expr_path(lctx: &LoweringContext, path: hir::Path, + attrs: ThinAttributes) -> P { + expr(lctx, path.span, hir::ExprPath(None, path), attrs) +} + +fn expr_match(lctx: &LoweringContext, + span: Span, + arg: P, + arms: hir::HirVec, + source: hir::MatchSource, + attrs: ThinAttributes) + -> P { + expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) +} + +fn expr_block(lctx: &LoweringContext, b: P, + attrs: ThinAttributes) -> P { + expr(lctx, b.span, hir::ExprBlock(b), attrs) +} + +fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec>, + attrs: ThinAttributes) -> P { + expr(lctx, sp, hir::ExprTup(exprs), attrs) +} + +fn expr_struct(lctx: &LoweringContext, + sp: Span, + path: hir::Path, + fields: hir::HirVec, + e: Option>, + attrs: ThinAttributes) -> P { + expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs) +} + +fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, + attrs: ThinAttributes) -> P { + P(hir::Expr { + id: lctx.next_id(), + node: node, + span: span, + attrs: attrs, + }) +} + +fn stmt_let(lctx: &LoweringContext, + sp: Span, + mutbl: bool, + ident: hir::Ident, + ex: P, + attrs: ThinAttributes) + -> hir::Stmt { + let pat = if mutbl { + pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable)) + } else { + pat_ident(lctx, sp, ident) + }; + let local = P(hir::Local { + pat: pat, + ty: None, + init: Some(ex), + id: lctx.next_id(), + span: sp, + attrs: attrs, + }); + let decl = respan(sp, hir::DeclLocal(local)); + respan(sp, hir::StmtDecl(P(decl), lctx.next_id())) +} + +fn block_expr(lctx: &LoweringContext, expr: P) -> P { + block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) +} + +fn block_all(lctx: &LoweringContext, + span: Span, + stmts: hir::HirVec, + expr: Option>) + -> P { + P(hir::Block { + stmts: stmts, + expr: expr, + id: lctx.next_id(), + rules: hir::DefaultBlock, + span: span, + }) +} + +fn pat_ok(lctx: &LoweringContext, span: Span, pat: P) -> P { + let ok = std_path(lctx, &["result", "Result", "Ok"]); + let path = path_global(span, ok); + pat_enum(lctx, span, path, hir_vec![pat]) +} + +fn pat_err(lctx: &LoweringContext, span: Span, pat: P) -> P { + let err = std_path(lctx, &["result", "Result", "Err"]); + let path = path_global(span, err); + pat_enum(lctx, span, path, hir_vec![pat]) +} + +fn pat_some(lctx: &LoweringContext, span: Span, pat: P) -> P { + let some = std_path(lctx, &["option", "Option", "Some"]); + let path = path_global(span, some); + pat_enum(lctx, span, path, hir_vec![pat]) +} + +fn pat_none(lctx: &LoweringContext, span: Span) -> P { + let none = std_path(lctx, &["option", "Option", "None"]); + let path = path_global(span, none); + pat_enum(lctx, span, path, hir_vec![]) +} + +fn pat_enum(lctx: &LoweringContext, + span: Span, + path: hir::Path, + subpats: hir::HirVec>) + -> P { + let pt = if subpats.is_empty() { + hir::PatKind::Path(path) + } else { + hir::PatKind::TupleStruct(path, Some(subpats)) + }; + pat(lctx, span, pt) +} + +fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P { + pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) +} + +fn pat_ident_binding_mode(lctx: &LoweringContext, + span: Span, + ident: hir::Ident, + bm: hir::BindingMode) + -> P { + let pat_ident = hir::PatKind::Ident(bm, + Spanned { + span: span, + node: ident, + }, + None); + pat(lctx, span, pat_ident) +} + +fn pat_wild(lctx: &LoweringContext, span: Span) -> P { + pat(lctx, span, hir::PatKind::Wild) +} + +fn pat(lctx: &LoweringContext, span: Span, pat: hir::PatKind) -> P { + P(hir::Pat { + id: lctx.next_id(), + node: pat, + span: span, + }) +} + +fn path_ident(span: Span, id: hir::Ident) -> hir::Path { + path(span, vec![id]) +} + +fn path(span: Span, strs: Vec) -> hir::Path { + path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) +} + +fn path_global(span: Span, strs: Vec) -> hir::Path { + path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) +} + +fn path_all(sp: Span, + global: bool, + mut idents: Vec, + lifetimes: hir::HirVec, + types: hir::HirVec>, + bindings: hir::HirVec) + -> hir::Path { + let last_identifier = idents.pop().unwrap(); + let mut segments: Vec = idents.into_iter() + .map(|ident| { + hir::PathSegment { + identifier: ident, + parameters: hir::PathParameters::none(), + } + }) + .collect(); + segments.push(hir::PathSegment { + identifier: last_identifier, + parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { + lifetimes: lifetimes, + types: types, + bindings: bindings, + }), + }); + hir::Path { + span: sp, + global: global, + segments: segments.into(), + } +} + +fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { + let mut v = Vec::new(); + if let Some(s) = lctx.crate_root { + v.push(hir::Ident::from_name(token::intern(s))); + } + v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); + return v; +} + +// Given suffix ["b","c","d"], returns path `::std::b::c::d` when +// `fld.cx.use_std`, and `::core::b::c::d` otherwise. +fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path { + let idents = std_path(lctx, components); + path_global(span, idents) +} + +fn signal_block_expr(lctx: &LoweringContext, + stmts: hir::HirVec, + expr: P, + span: Span, + rule: hir::BlockCheckMode, + attrs: ThinAttributes) + -> P { + let id = lctx.next_id(); + expr_block(lctx, + P(hir::Block { + rules: rule, + span: span, + id: id, + stmts: stmts, + expr: Some(expr), + }), + attrs) +} + + + +#[cfg(test)] +mod test { + use super::*; + use syntax::ast::{self, NodeId, NodeIdAssigner}; + use syntax::{parse, codemap}; + use syntax::fold::Folder; + use std::cell::Cell; + + struct MockAssigner { + next_id: Cell, + } + + impl MockAssigner { + fn new() -> MockAssigner { + MockAssigner { next_id: Cell::new(0) } + } + } + + trait FakeExtCtxt { + fn call_site(&self) -> codemap::Span; + fn cfg(&self) -> ast::CrateConfig; + fn ident_of(&self, st: &str) -> ast::Ident; + fn name_of(&self, st: &str) -> ast::Name; + fn parse_sess(&self) -> &parse::ParseSess; + } + + impl FakeExtCtxt for parse::ParseSess { + fn call_site(&self) -> codemap::Span { + codemap::Span { + lo: codemap::BytePos(0), + hi: codemap::BytePos(0), + expn_id: codemap::NO_EXPANSION, + } + } + fn cfg(&self) -> ast::CrateConfig { + Vec::new() + } + fn ident_of(&self, st: &str) -> ast::Ident { + parse::token::str_to_ident(st) + } + fn name_of(&self, st: &str) -> ast::Name { + parse::token::intern(st) + } + fn parse_sess(&self) -> &parse::ParseSess { + self + } + } + + impl NodeIdAssigner for MockAssigner { + fn next_node_id(&self) -> NodeId { + let result = self.next_id.get(); + self.next_id.set(result + 1); + result + } + + fn peek_node_id(&self) -> NodeId { + self.next_id.get() + } + } + + impl Folder for MockAssigner { + fn new_id(&mut self, old_id: NodeId) -> NodeId { + assert_eq!(old_id, ast::DUMMY_NODE_ID); + self.next_node_id() + } + } + + #[test] + fn test_preserves_ids() { + let cx = parse::ParseSess::new(); + let mut assigner = MockAssigner::new(); + + let ast_if_let = quote_expr!(&cx, + if let Some(foo) = baz { + bar(foo); + }); + let ast_if_let = assigner.fold_expr(ast_if_let); + let ast_while_let = quote_expr!(&cx, + while let Some(foo) = baz { + bar(foo); + }); + let ast_while_let = assigner.fold_expr(ast_while_let); + let ast_for = quote_expr!(&cx, + for i in 0..10 { + for j in 0..10 { + foo(i, j); + } + }); + let ast_for = assigner.fold_expr(ast_for); + let ast_in = quote_expr!(&cx, in HEAP { foo() }); + let ast_in = assigner.fold_expr(ast_in); + + let lctx = LoweringContext::new(&assigner, None); + let hir1 = lower_expr(&lctx, &ast_if_let); + let hir2 = lower_expr(&lctx, &ast_if_let); + assert!(hir1 == hir2); + + let hir1 = lower_expr(&lctx, &ast_while_let); + let hir2 = lower_expr(&lctx, &ast_while_let); + assert!(hir1 == hir2); + + let hir1 = lower_expr(&lctx, &ast_for); + let hir2 = lower_expr(&lctx, &ast_for); + assert!(hir1 == hir2); + + let hir1 = lower_expr(&lctx, &ast_in); + let hir2 = lower_expr(&lctx, &ast_in); + assert!(hir1 == hir2); + } +} diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs new file mode 100644 index 00000000000..7b1c692d54b --- /dev/null +++ b/src/librustc/hir/map/blocks.rs @@ -0,0 +1,264 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! This module provides a simplified abstraction for working with +//! code blocks identified by their integer node-id. In particular, +//! it captures a common set of attributes that all "function-like +//! things" (represented by `FnLike` instances) share. For example, +//! all `FnLike` instances have a type signature (be it explicit or +//! inferred). And all `FnLike` instances have a body, i.e. the code +//! that is run when the function-like thing it represents is invoked. +//! +//! With the above abstraction in place, one can treat the program +//! text as a collection of blocks of code (and most such blocks are +//! nested within a uniquely determined `FnLike`), and users can ask +//! for the `Code` associated with a particular NodeId. + +pub use self::Code::*; + +use hir::map::{self, Node}; +use syntax::abi; +use hir::{Block, FnDecl}; +use syntax::ast::{Attribute, Name, NodeId}; +use syntax::attr::ThinAttributesExt; +use hir as ast; +use syntax::codemap::Span; +use hir::intravisit::FnKind; + +/// An FnLikeNode is a Node that is like a fn, in that it has a decl +/// and a body (as well as a NodeId, a span, etc). +/// +/// More specifically, it is one of either: +/// - A function item, +/// - A closure expr (i.e. an ExprClosure), or +/// - The default implementation for a trait method. +/// +/// To construct one, use the `Code::from_node` function. +#[derive(Copy, Clone)] +pub struct FnLikeNode<'a> { node: map::Node<'a> } + +/// MaybeFnLike wraps a method that indicates if an object +/// corresponds to some FnLikeNode. +pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; } + +/// Components shared by fn-like things (fn items, methods, closures). +pub struct FnParts<'a> { + pub decl: &'a FnDecl, + pub body: &'a Block, + pub kind: FnKind<'a>, + pub span: Span, + pub id: NodeId, +} + +impl MaybeFnLike for ast::Item { + fn is_fn_like(&self) -> bool { + match self.node { ast::ItemFn(..) => true, _ => false, } + } +} + +impl MaybeFnLike for ast::TraitItem { + fn is_fn_like(&self) -> bool { + match self.node { ast::MethodTraitItem(_, Some(_)) => true, _ => false, } + } +} + +impl MaybeFnLike for ast::Expr { + fn is_fn_like(&self) -> bool { + match self.node { + ast::ExprClosure(..) => true, + _ => false, + } + } +} + +/// Carries either an FnLikeNode or a Block, as these are the two +/// constructs that correspond to "code" (as in, something from which +/// we can construct a control-flow graph). +#[derive(Copy, Clone)] +pub enum Code<'a> { + FnLikeCode(FnLikeNode<'a>), + BlockCode(&'a Block), +} + +impl<'a> Code<'a> { + pub fn id(&self) -> NodeId { + match *self { + FnLikeCode(node) => node.id(), + BlockCode(block) => block.id, + } + } + + /// Attempts to construct a Code from presumed FnLike or Block node input. + pub fn from_node(node: Node) -> Option { + if let map::NodeBlock(block) = node { + Some(BlockCode(block)) + } else { + FnLikeNode::from_node(node).map(|fn_like| FnLikeCode(fn_like)) + } + } +} + +/// These are all the components one can extract from a fn item for +/// use when implementing FnLikeNode operations. +struct ItemFnParts<'a> { + name: Name, + decl: &'a ast::FnDecl, + unsafety: ast::Unsafety, + constness: ast::Constness, + abi: abi::Abi, + vis: ast::Visibility, + generics: &'a ast::Generics, + body: &'a Block, + id: NodeId, + span: Span, + attrs: &'a [Attribute], +} + +/// These are all the components one can extract from a closure expr +/// for use when implementing FnLikeNode operations. +struct ClosureParts<'a> { + decl: &'a FnDecl, + body: &'a Block, + id: NodeId, + span: Span, + attrs: &'a [Attribute], +} + +impl<'a> ClosureParts<'a> { + fn new(d: &'a FnDecl, b: &'a Block, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self { + ClosureParts { decl: d, body: b, id: id, span: s, attrs: attrs } + } +} + +impl<'a> FnLikeNode<'a> { + /// Attempts to construct a FnLikeNode from presumed FnLike node input. + pub fn from_node(node: Node) -> Option { + let fn_like = match node { + map::NodeItem(item) => item.is_fn_like(), + map::NodeTraitItem(tm) => tm.is_fn_like(), + map::NodeImplItem(_) => true, + map::NodeExpr(e) => e.is_fn_like(), + _ => false + }; + if fn_like { + Some(FnLikeNode { + node: node + }) + } else { + None + } + } + + pub fn to_fn_parts(self) -> FnParts<'a> { + FnParts { + decl: self.decl(), + body: self.body(), + kind: self.kind(), + span: self.span(), + id: self.id(), + } + } + + pub fn body(self) -> &'a Block { + self.handle(|i: ItemFnParts<'a>| &*i.body, + |_, _, _: &'a ast::MethodSig, _, body: &'a ast::Block, _, _| body, + |c: ClosureParts<'a>| c.body) + } + + pub fn decl(self) -> &'a FnDecl { + self.handle(|i: ItemFnParts<'a>| &*i.decl, + |_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl, + |c: ClosureParts<'a>| c.decl) + } + + pub fn span(self) -> Span { + self.handle(|i: ItemFnParts| i.span, + |_, _, _: &'a ast::MethodSig, _, _, span, _| span, + |c: ClosureParts| c.span) + } + + pub fn id(self) -> NodeId { + self.handle(|i: ItemFnParts| i.id, + |id, _, _: &'a ast::MethodSig, _, _, _, _| id, + |c: ClosureParts| c.id) + } + + pub fn kind(self) -> FnKind<'a> { + let item = |p: ItemFnParts<'a>| -> FnKind<'a> { + FnKind::ItemFn(p.name, p.generics, p.unsafety, p.constness, p.abi, p.vis, p.attrs) + }; + let closure = |c: ClosureParts<'a>| { + FnKind::Closure(c.attrs) + }; + let method = |_, name: Name, sig: &'a ast::MethodSig, vis, _, _, attrs| { + FnKind::Method(name, sig, vis, attrs) + }; + self.handle(item, method, closure) + } + + fn handle(self, item_fn: I, method: M, closure: C) -> A where + I: FnOnce(ItemFnParts<'a>) -> A, + M: FnOnce(NodeId, + Name, + &'a ast::MethodSig, + Option, + &'a ast::Block, + Span, + &'a [Attribute]) + -> A, + C: FnOnce(ClosureParts<'a>) -> A, + { + match self.node { + map::NodeItem(i) => match i.node { + ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) => + item_fn(ItemFnParts { + id: i.id, + name: i.name, + decl: &decl, + unsafety: unsafety, + body: &block, + generics: generics, + abi: abi, + vis: i.vis, + constness: constness, + span: i.span, + attrs: &i.attrs, + }), + _ => bug!("item FnLikeNode that is not fn-like"), + }, + map::NodeTraitItem(ti) => match ti.node { + ast::MethodTraitItem(ref sig, Some(ref body)) => { + method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs) + } + _ => bug!("trait method FnLikeNode that is not fn-like"), + }, + map::NodeImplItem(ii) => { + match ii.node { + ast::ImplItemKind::Method(ref sig, ref body) => { + method(ii.id, ii.name, sig, Some(ii.vis), body, ii.span, &ii.attrs) + } + _ => { + bug!("impl method FnLikeNode that is not fn-like") + } + } + } + map::NodeExpr(e) => match e.node { + ast::ExprClosure(_, ref decl, ref block) => + closure(ClosureParts::new(&decl, + &block, + e.id, + e.span, + e.attrs.as_attr_slice())), + _ => bug!("expr FnLikeNode that is not fn-like"), + }, + _ => bug!("other FnLikeNode that is not fn-like"), + } + } +} diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs new file mode 100644 index 00000000000..70368222172 --- /dev/null +++ b/src/librustc/hir/map/collector.rs @@ -0,0 +1,341 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; +use super::MapEntry::*; + +use hir::*; +use hir::intravisit::Visitor; +use middle::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use std::iter::repeat; +use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; +use syntax::codemap::Span; + +/// A Visitor that walks over an AST and collects Node's into an AST +/// Map. +pub struct NodeCollector<'ast> { + pub krate: &'ast Crate, + pub map: Vec>, + pub definitions: Definitions, + pub parent_node: NodeId, +} + +impl<'ast> NodeCollector<'ast> { + pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: vec![], + definitions: Definitions::new(), + parent_node: CRATE_NODE_ID, + }; + collector.insert_entry(CRATE_NODE_ID, RootCrate); + + let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); + assert_eq!(result, CRATE_DEF_INDEX); + + collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); + + collector + } + + pub fn extend(krate: &'ast Crate, + parent: &'ast InlinedParent, + parent_node: NodeId, + parent_def_path: DefPath, + parent_def_id: DefId, + map: Vec>, + definitions: Definitions) + -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: map, + parent_node: parent_node, + definitions: definitions, + }; + + assert_eq!(parent_def_path.krate, parent_def_id.krate); + let root_path = Box::new(InlinedRootPath { + data: parent_def_path.data, + def_id: parent_def_id, + }); + + collector.insert_entry(parent_node, RootInlinedParent(parent)); + collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + + collector + } + + fn parent_def(&self) -> Option { + let mut parent_node = Some(self.parent_node); + while let Some(p) = parent_node { + if let Some(q) = self.definitions.opt_def_index(p) { + return Some(q); + } + parent_node = self.map[p as usize].parent_node(); + } + None + } + + fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { + let parent_def = self.parent_def(); + debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); + self.definitions.create_def_with_parent(parent_def, node_id, data) + } + + fn create_def_with_parent(&mut self, + parent: Option, + node_id: NodeId, + data: DefPathData) + -> DefIndex { + self.definitions.create_def_with_parent(parent, node_id, data) + } + + fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { + debug!("ast_map: {:?} => {:?}", id, entry); + let len = self.map.len(); + if id as usize >= len { + self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); + } + self.map[id as usize] = entry; + } + + fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex { + self.insert(id, node); + self.create_def(id, data) + } + + fn insert(&mut self, id: NodeId, node: Node<'ast>) { + let entry = MapEntry::from_node(self.parent_node, node); + self.insert_entry(id, entry); + } +} + +impl<'ast> Visitor<'ast> for NodeCollector<'ast> { + /// Because we want to track parent items and so forth, enable + /// deep walking so that we walk nested items in the context of + /// their outer items. + fn visit_nested_item(&mut self, item: ItemId) { + debug!("visit_nested_item: {:?}", item); + self.visit_item(self.krate.item(item.id)) + } + + fn visit_item(&mut self, i: &'ast Item) { + debug!("visit_item: {:?}", i); + + // Pick the def data. This need not be unique, but the more + // information we encapsulate into + let def_data = match i.node { + ItemDefaultImpl(..) | ItemImpl(..) => + DefPathData::Impl, + ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | + ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | + ItemTy(..) => + DefPathData::TypeNs(i.name), + ItemStatic(..) | ItemConst(..) | ItemFn(..) => + DefPathData::ValueNs(i.name), + ItemUse(..) => + DefPathData::Misc, + }; + + self.insert_def(i.id, NodeItem(i), def_data); + + let parent_node = self.parent_node; + self.parent_node = i.id; + + match i.node { + ItemImpl(..) => {} + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + self.insert_def(v.node.data.id(), + NodeVariant(v), + DefPathData::EnumVariant(v.node.name)); + + for field in v.node.data.fields() { + self.create_def_with_parent( + Some(variant_def_index), + field.id, + DefPathData::Field(field.name)); + } + } + } + ItemForeignMod(..) => { + } + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + self.insert_def(struct_def.id(), + NodeStructCtor(struct_def), + DefPathData::StructCtor); + } + + for field in struct_def.fields() { + self.create_def(field.id, DefPathData::Field(field.name)); + } + } + ItemTrait(_, _, ref bounds, _) => { + for b in bounds.iter() { + if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { + self.insert(t.trait_ref.ref_id, NodeItem(i)); + } + } + } + ItemUse(ref view_path) => { + match view_path.node { + ViewPathList(_, ref paths) => { + for path in paths { + self.insert(path.node.id(), NodeItem(i)); + } + } + _ => () + } + } + _ => {} + } + intravisit::walk_item(self, i); + self.parent_node = parent_node; + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + self.insert_def(foreign_item.id, + NodeForeignItem(foreign_item), + DefPathData::ValueNs(foreign_item.name)); + + let parent_node = self.parent_node; + self.parent_node = foreign_item.id; + intravisit::walk_foreign_item(self, foreign_item); + self.parent_node = parent_node; + } + + fn visit_generics(&mut self, generics: &'ast Generics) { + for ty_param in generics.ty_params.iter() { + self.insert_def(ty_param.id, + NodeTyParam(ty_param), + DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + let def_data = match ti.node { + MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), + TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + self.insert(ti.id, NodeTraitItem(ti)); + self.create_def(ti.id, def_data); + + let parent_node = self.parent_node; + self.parent_node = ti.id; + + match ti.node { + ConstTraitItem(_, Some(ref expr)) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_trait_item(self, ti); + + self.parent_node = parent_node; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + let def_data = match ii.node { + ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + self.insert_def(ii.id, NodeImplItem(ii), def_data); + + let parent_node = self.parent_node; + self.parent_node = ii.id; + + match ii.node { + ImplItemKind::Const(_, ref expr) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_impl_item(self, ii); + + self.parent_node = parent_node; + } + + fn visit_pat(&mut self, pat: &'ast Pat) { + let maybe_binding = match pat.node { + PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + if let Some(id) = maybe_binding { + self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); + } else { + self.insert(pat.id, NodePat(pat)); + } + + let parent_node = self.parent_node; + self.parent_node = pat.id; + intravisit::walk_pat(self, pat); + self.parent_node = parent_node; + } + + fn visit_expr(&mut self, expr: &'ast Expr) { + self.insert(expr.id, NodeExpr(expr)); + + match expr.node { + ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); } + _ => { } + } + + let parent_node = self.parent_node; + self.parent_node = expr.id; + intravisit::walk_expr(self, expr); + self.parent_node = parent_node; + } + + fn visit_stmt(&mut self, stmt: &'ast Stmt) { + let id = util::stmt_id(stmt); + self.insert(id, NodeStmt(stmt)); + let parent_node = self.parent_node; + self.parent_node = id; + intravisit::walk_stmt(self, stmt); + self.parent_node = parent_node; + } + + fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, + b: &'ast Block, s: Span, id: NodeId) { + assert_eq!(self.parent_node, id); + intravisit::walk_fn(self, fk, fd, b, s); + } + + fn visit_block(&mut self, block: &'ast Block) { + self.insert(block.id, NodeBlock(block)); + let parent_node = self.parent_node; + self.parent_node = block.id; + intravisit::walk_block(self, block); + self.parent_node = parent_node; + } + + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { + self.insert(lifetime.id, NodeLifetime(lifetime)); + } + + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + self.visit_lifetime(&def.lifetime); + } + + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs new file mode 100644 index 00000000000..82574b85229 --- /dev/null +++ b/src/librustc/hir/map/definitions.rs @@ -0,0 +1,292 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use middle::cstore::LOCAL_CRATE; +use middle::def_id::{DefId, DefIndex}; +use rustc_data_structures::fnv::FnvHashMap; +use syntax::ast; +use syntax::parse::token::InternedString; +use util::nodemap::NodeMap; + +#[derive(Clone)] +pub struct Definitions { + data: Vec, + key_map: FnvHashMap, + node_map: NodeMap, +} + +/// A unique identifier that we can use to lookup a definition +/// precisely. It combines the index of the definition's parent (if +/// any) with a `DisambiguatedDefPathData`. +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct DefKey { + /// Parent path. + pub parent: Option, + + /// Identifier of this node. + pub disambiguated_data: DisambiguatedDefPathData, +} + +/// Pair of `DefPathData` and an integer disambiguator. The integer is +/// normally 0, but in the event that there are multiple defs with the +/// same `parent` and `data`, we use this field to disambiguate +/// between them. This introduces some artificial ordering dependency +/// but means that if you have (e.g.) two impls for the same type in +/// the same module, they do get distinct def-ids. +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct DisambiguatedDefPathData { + pub data: DefPathData, + pub disambiguator: u32 +} + +/// For each definition, we track the following data. A definition +/// here is defined somewhat circularly as "something with a def-id", +/// but it generally corresponds to things like structs, enums, etc. +/// There are also some rather random cases (like const initializer +/// expressions) that are mostly just leftovers. +#[derive(Clone, Debug)] +pub struct DefData { + pub key: DefKey, + + /// Local ID within the HIR. + pub node_id: ast::NodeId, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct DefPath { + /// the path leading from the crate root to the item + pub data: Vec, + + /// what krate root is this path relative to? + pub krate: ast::CrateNum, +} + +impl DefPath { + pub fn is_local(&self) -> bool { + self.krate == LOCAL_CRATE + } + + pub fn make(start_krate: ast::CrateNum, + start_index: DefIndex, + mut get_key: FN) -> DefPath + where FN: FnMut(DefIndex) -> DefKey + { + let mut krate = start_krate; + let mut data = vec![]; + let mut index = Some(start_index); + loop { + let p = index.unwrap(); + let key = get_key(p); + match key.disambiguated_data.data { + DefPathData::CrateRoot => { + assert!(key.parent.is_none()); + break; + } + DefPathData::InlinedRoot(ref p) => { + assert!(key.parent.is_none()); + assert!(!p.def_id.is_local()); + data.extend(p.data.iter().cloned().rev()); + krate = p.def_id.krate; + break; + } + _ => { + data.push(key.disambiguated_data); + index = key.parent; + } + } + } + data.reverse(); + DefPath { data: data, krate: krate } + } +} + +/// Root of an inlined item. We track the `DefPath` of the item within +/// the original crate but also its def-id. This is kind of an +/// augmented version of a `DefPath` that includes a `DefId`. This is +/// all sort of ugly but the hope is that inlined items will be going +/// away soon anyway. +/// +/// Some of the constraints that led to the current approach: +/// +/// - I don't want to have a `DefId` in the main `DefPath` because +/// that gets serialized for incr. comp., and when reloaded the +/// `DefId` is no longer valid. I'd rather maintain the invariant +/// that every `DefId` is valid, and a potentially outdated `DefId` is +/// represented as a `DefPath`. +/// - (We don't serialize def-paths from inlined items, so it's ok to have one here.) +/// - We need to be able to extract the def-id from inline items to +/// make the symbol name. In theory we could retrace it from the +/// data, but the metadata doesn't have the required indices, and I +/// don't want to write the code to create one just for this. +/// - It may be that we don't actually need `data` at all. We'll have +/// to see about that. +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct InlinedRootPath { + pub data: Vec, + pub def_id: DefId, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub enum DefPathData { + // Root: these should only be used for the root nodes, because + // they are treated specially by the `def_path` function. + CrateRoot, + InlinedRoot(Box), + + // Catch-all for random DefId things like DUMMY_NODE_ID + Misc, + + // Different kinds of items and item-like things: + Impl, + TypeNs(ast::Name), // something in the type NS + ValueNs(ast::Name), // something in the value NS + MacroDef(ast::Name), + ClosureExpr, + + // Subportions of items + TypeParam(ast::Name), + LifetimeDef(ast::Name), + EnumVariant(ast::Name), + Field(ast::Name), + StructCtor, // implicit ctor for a tuple-like struct + Initializer, // initializer for a const + Binding(ast::Name), // pattern binding +} + +impl Definitions { + pub fn new() -> Definitions { + Definitions { + data: vec![], + key_map: FnvHashMap(), + node_map: NodeMap(), + } + } + + pub fn len(&self) -> usize { + self.data.len() + } + + pub fn def_key(&self, index: DefIndex) -> DefKey { + self.data[index.as_usize()].key.clone() + } + + /// Returns the path from the crate root to `index`. The root + /// nodes are not included in the path (i.e., this will be an + /// empty vector for the crate root). For an inlined item, this + /// will be the path of the item in the external crate (but the + /// path will begin with the path to the external crate). + pub fn def_path(&self, index: DefIndex) -> DefPath { + DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p)) + } + + pub fn opt_def_index(&self, node: ast::NodeId) -> Option { + self.node_map.get(&node).cloned() + } + + pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { + self.opt_def_index(node).map(DefId::local) + } + + pub fn as_local_node_id(&self, def_id: DefId) -> Option { + if def_id.krate == LOCAL_CRATE { + assert!(def_id.index.as_usize() < self.data.len()); + Some(self.data[def_id.index.as_usize()].node_id) + } else { + None + } + } + + pub fn create_def_with_parent(&mut self, + parent: Option, + node_id: ast::NodeId, + data: DefPathData) + -> DefIndex { + assert!(!self.node_map.contains_key(&node_id), + "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}", + node_id, + data, + self.data[self.node_map[&node_id].as_usize()]); + + // Find a unique DefKey. This basically means incrementing the disambiguator + // until we get no match. + let mut key = DefKey { + parent: parent, + disambiguated_data: DisambiguatedDefPathData { + data: data, + disambiguator: 0 + } + }; + + while self.key_map.contains_key(&key) { + key.disambiguated_data.disambiguator += 1; + } + + // Create the definition. + let index = DefIndex::new(self.data.len()); + self.data.push(DefData { key: key.clone(), node_id: node_id }); + self.node_map.insert(node_id, index); + self.key_map.insert(key, index); + + index + } +} + +impl DefPathData { + pub fn as_interned_str(&self) -> InternedString { + use self::DefPathData::*; + match *self { + TypeNs(name) | + ValueNs(name) | + MacroDef(name) | + TypeParam(name) | + LifetimeDef(name) | + EnumVariant(name) | + Binding(name) | + Field(name) => { + name.as_str() + } + + Impl => { + InternedString::new("{{impl}}") + } + + // note that this does not show up in user printouts + CrateRoot => { + InternedString::new("{{root}}") + } + + // note that this does not show up in user printouts + InlinedRoot(_) => { + InternedString::new("{{inlined-root}}") + } + + Misc => { + InternedString::new("{{?}}") + } + + ClosureExpr => { + InternedString::new("{{closure}}") + } + + StructCtor => { + InternedString::new("{{constructor}}") + } + + Initializer => { + InternedString::new("{{initializer}}") + } + } + } + + pub fn to_string(&self) -> String { + self.as_interned_str().to_string() + } +} + diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs new file mode 100644 index 00000000000..4325be9b9a4 --- /dev/null +++ b/src/librustc/hir/map/mod.rs @@ -0,0 +1,1127 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub use self::Node::*; +pub use self::PathElem::*; +use self::MapEntry::*; +use self::collector::NodeCollector; +pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, + DisambiguatedDefPathData, InlinedRootPath}; + +use dep_graph::{DepGraph, DepNode}; + +use middle::cstore::InlinedItem; +use middle::cstore::InlinedItem as II; +use middle::def_id::{CRATE_DEF_INDEX, DefId}; + +use syntax::abi::Abi; +use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; +use syntax::attr::ThinAttributesExt; +use syntax::codemap::{Span, Spanned}; +use syntax::parse::token; + +use hir::*; +use hir::fold::Folder; +use hir::print as pprust; + +use arena::TypedArena; +use std::cell::RefCell; +use std::fmt; +use std::io; +use std::iter; +use std::mem; +use std::slice; + +pub mod blocks; +mod collector; +pub mod definitions; + +#[derive(Clone, Copy, PartialEq, Debug)] +pub enum PathElem { + PathMod(Name), + PathName(Name) +} + +impl PathElem { + pub fn name(&self) -> Name { + match *self { + PathMod(name) | PathName(name) => name + } + } +} + +impl fmt::Display for PathElem { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.name()) + } +} + +#[derive(Clone)] +pub struct LinkedPathNode<'a> { + node: PathElem, + next: LinkedPath<'a>, +} + +#[derive(Copy, Clone)] +pub struct LinkedPath<'a>(Option<&'a LinkedPathNode<'a>>); + +impl<'a> LinkedPath<'a> { + pub fn empty() -> LinkedPath<'a> { + LinkedPath(None) + } + + pub fn from(node: &'a LinkedPathNode) -> LinkedPath<'a> { + LinkedPath(Some(node)) + } +} + +impl<'a> Iterator for LinkedPath<'a> { + type Item = PathElem; + + fn next(&mut self) -> Option { + match self.0 { + Some(node) => { + *self = node.next; + Some(node.node) + } + None => None + } + } +} + +/// The type of the iterator used by with_path. +pub type PathElems<'a, 'b> = iter::Chain>, LinkedPath<'b>>; + +pub fn path_to_string>(path: PI) -> String { + let itr = token::get_ident_interner(); + + path.fold(String::new(), |mut s, e| { + let e = itr.get(e.name()); + if !s.is_empty() { + s.push_str("::"); + } + s.push_str(&e[..]); + s + }) +} + +#[derive(Copy, Clone, Debug)] +pub enum Node<'ast> { + NodeItem(&'ast Item), + NodeForeignItem(&'ast ForeignItem), + NodeTraitItem(&'ast TraitItem), + NodeImplItem(&'ast ImplItem), + NodeVariant(&'ast Variant), + NodeExpr(&'ast Expr), + NodeStmt(&'ast Stmt), + NodeLocal(&'ast Pat), + NodePat(&'ast Pat), + NodeBlock(&'ast Block), + + /// NodeStructCtor represents a tuple struct. + NodeStructCtor(&'ast VariantData), + + NodeLifetime(&'ast Lifetime), + NodeTyParam(&'ast TyParam) +} + +/// Represents an entry and its parent NodeID. +/// The odd layout is to bring down the total size. +#[derive(Copy, Debug)] +pub enum MapEntry<'ast> { + /// Placeholder for holes in the map. + NotPresent, + + /// All the node types, with a parent ID. + EntryItem(NodeId, &'ast Item), + EntryForeignItem(NodeId, &'ast ForeignItem), + EntryTraitItem(NodeId, &'ast TraitItem), + EntryImplItem(NodeId, &'ast ImplItem), + EntryVariant(NodeId, &'ast Variant), + EntryExpr(NodeId, &'ast Expr), + EntryStmt(NodeId, &'ast Stmt), + EntryLocal(NodeId, &'ast Pat), + EntryPat(NodeId, &'ast Pat), + EntryBlock(NodeId, &'ast Block), + EntryStructCtor(NodeId, &'ast VariantData), + EntryLifetime(NodeId, &'ast Lifetime), + EntryTyParam(NodeId, &'ast TyParam), + + /// Roots for node trees. + RootCrate, + RootInlinedParent(&'ast InlinedParent) +} + +impl<'ast> Clone for MapEntry<'ast> { + fn clone(&self) -> MapEntry<'ast> { + *self + } +} + +#[derive(Debug)] +pub struct InlinedParent { + path: Vec, + ii: InlinedItem +} + +impl<'ast> MapEntry<'ast> { + fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { + match node { + NodeItem(n) => EntryItem(p, n), + NodeForeignItem(n) => EntryForeignItem(p, n), + NodeTraitItem(n) => EntryTraitItem(p, n), + NodeImplItem(n) => EntryImplItem(p, n), + NodeVariant(n) => EntryVariant(p, n), + NodeExpr(n) => EntryExpr(p, n), + NodeStmt(n) => EntryStmt(p, n), + NodeLocal(n) => EntryLocal(p, n), + NodePat(n) => EntryPat(p, n), + NodeBlock(n) => EntryBlock(p, n), + NodeStructCtor(n) => EntryStructCtor(p, n), + NodeLifetime(n) => EntryLifetime(p, n), + NodeTyParam(n) => EntryTyParam(p, n), + } + } + + fn parent_node(self) -> Option { + Some(match self { + EntryItem(id, _) => id, + EntryForeignItem(id, _) => id, + EntryTraitItem(id, _) => id, + EntryImplItem(id, _) => id, + EntryVariant(id, _) => id, + EntryExpr(id, _) => id, + EntryStmt(id, _) => id, + EntryLocal(id, _) => id, + EntryPat(id, _) => id, + EntryBlock(id, _) => id, + EntryStructCtor(id, _) => id, + EntryLifetime(id, _) => id, + EntryTyParam(id, _) => id, + _ => return None + }) + } + + fn to_node(self) -> Option> { + Some(match self { + EntryItem(_, n) => NodeItem(n), + EntryForeignItem(_, n) => NodeForeignItem(n), + EntryTraitItem(_, n) => NodeTraitItem(n), + EntryImplItem(_, n) => NodeImplItem(n), + EntryVariant(_, n) => NodeVariant(n), + EntryExpr(_, n) => NodeExpr(n), + EntryStmt(_, n) => NodeStmt(n), + EntryLocal(_, n) => NodeLocal(n), + EntryPat(_, n) => NodePat(n), + EntryBlock(_, n) => NodeBlock(n), + EntryStructCtor(_, n) => NodeStructCtor(n), + EntryLifetime(_, n) => NodeLifetime(n), + EntryTyParam(_, n) => NodeTyParam(n), + _ => return None + }) + } +} + +/// Stores a crate and any number of inlined items from other crates. +pub struct Forest { + krate: Crate, + pub dep_graph: DepGraph, + inlined_items: TypedArena +} + +impl Forest { + pub fn new(krate: Crate, dep_graph: DepGraph) -> Forest { + Forest { + krate: krate, + dep_graph: dep_graph, + inlined_items: TypedArena::new() + } + } + + pub fn krate<'ast>(&'ast self) -> &'ast Crate { + self.dep_graph.read(DepNode::Krate); + &self.krate + } +} + +/// Represents a mapping from Node IDs to AST elements and their parent +/// Node IDs +#[derive(Clone)] +pub struct Map<'ast> { + /// The backing storage for all the AST nodes. + pub forest: &'ast Forest, + + /// Same as the dep_graph in forest, just available with one fewer + /// deref. This is a gratuitious micro-optimization. + pub dep_graph: DepGraph, + + /// NodeIds are sequential integers from 0, so we can be + /// super-compact by storing them in a vector. Not everything with + /// a NodeId is in the map, but empirically the occupancy is about + /// 75-80%, so there's not too much overhead (certainly less than + /// a hashmap, since they (at the time of writing) have a maximum + /// of 75% occupancy). + /// + /// Also, indexing is pretty quick when you've got a vector and + /// plain old integers. + map: RefCell>>, + + definitions: RefCell, +} + +impl<'ast> Map<'ast> { + /// Registers a read in the dependency graph of the AST node with + /// the given `id`. This needs to be called each time a public + /// function returns the HIR for a node -- in other words, when it + /// "reveals" the content of a node to the caller (who might not + /// otherwise have had access to those contents, and hence needs a + /// read recorded). If the function just returns a DefId or + /// NodeId, no actual content was returned, so no read is needed. + fn read(&self, id: NodeId) { + self.dep_graph.read(self.dep_node(id)); + } + + fn dep_node(&self, id0: NodeId) -> DepNode { + let map = self.map.borrow(); + let mut id = id0; + loop { + match map[id as usize] { + EntryItem(_, item) => { + let def_id = self.local_def_id(item.id); + // NB ^~~~~~~ + // + // You would expect that `item.id == id`, but this + // is not always the case. In particular, for a + // ViewPath item like `use self::{mem, foo}`, we + // map the ids for `mem` and `foo` to the + // enclosing view path item. This seems mega super + // ultra wrong, but then who am I to judge? + // -nmatsakis + return DepNode::Hir(def_id); + } + + EntryForeignItem(p, _) | + EntryTraitItem(p, _) | + EntryImplItem(p, _) | + EntryVariant(p, _) | + EntryExpr(p, _) | + EntryStmt(p, _) | + EntryLocal(p, _) | + EntryPat(p, _) | + EntryBlock(p, _) | + EntryStructCtor(p, _) | + EntryLifetime(p, _) | + EntryTyParam(p, _) => + id = p, + + RootCrate | + RootInlinedParent(_) => + // FIXME(#32015) clarify story about cross-crate dep tracking + return DepNode::Krate, + + NotPresent => + // Some nodes, notably struct fields, are not + // present in the map for whatever reason, but + // they *do* have def-ids. So if we encounter an + // empty hole, check for that case. + return self.opt_local_def_id(id) + .map(|def_id| DepNode::Hir(def_id)) + .unwrap_or_else(|| { + bug!("Walking parents from `{}` \ + led to `NotPresent` at `{}`", + id0, id) + }), + } + } + } + + pub fn num_local_def_ids(&self) -> usize { + self.definitions.borrow().len() + } + + pub fn def_key(&self, def_id: DefId) -> DefKey { + assert!(def_id.is_local()); + self.definitions.borrow().def_key(def_id.index) + } + + pub fn def_path_from_id(&self, id: NodeId) -> DefPath { + self.def_path(self.local_def_id(id)) + } + + pub fn def_path(&self, def_id: DefId) -> DefPath { + assert!(def_id.is_local()); + self.definitions.borrow().def_path(def_id.index) + } + + pub fn local_def_id(&self, node: NodeId) -> DefId { + self.opt_local_def_id(node).unwrap_or_else(|| { + bug!("local_def_id: no entry for `{}`, which has a map of `{:?}`", + node, self.find_entry(node)) + }) + } + + pub fn opt_local_def_id(&self, node: NodeId) -> Option { + self.definitions.borrow().opt_local_def_id(node) + } + + pub fn as_local_node_id(&self, def_id: DefId) -> Option { + self.definitions.borrow().as_local_node_id(def_id) + } + + fn entry_count(&self) -> usize { + self.map.borrow().len() + } + + fn find_entry(&self, id: NodeId) -> Option> { + self.map.borrow().get(id as usize).cloned() + } + + pub fn krate(&self) -> &'ast Crate { + self.forest.krate() + } + + /// Get the attributes on the krate. This is preferable to + /// invoking `krate.attrs` because it registers a tighter + /// dep-graph access. + pub fn krate_attrs(&self) -> &'ast [ast::Attribute] { + let crate_root_def_id = DefId::local(CRATE_DEF_INDEX); + self.dep_graph.read(DepNode::Hir(crate_root_def_id)); + &self.forest.krate.attrs + } + + /// Retrieve the Node corresponding to `id`, panicking if it cannot + /// be found. + pub fn get(&self, id: NodeId) -> Node<'ast> { + match self.find(id) { + Some(node) => node, // read recorded by `find` + None => bug!("couldn't find node id {} in the AST map", id) + } + } + + pub fn get_if_local(&self, id: DefId) -> Option> { + self.as_local_node_id(id).map(|id| self.get(id)) // read recorded by `get` + } + + /// Retrieve the Node corresponding to `id`, returning None if + /// cannot be found. + pub fn find(&self, id: NodeId) -> Option> { + let result = self.find_entry(id).and_then(|x| x.to_node()); + if result.is_some() { + self.read(id); + } + result + } + + /// Similar to get_parent, returns the parent node id or id if there is no + /// parent. + /// This function returns the immediate parent in the AST, whereas get_parent + /// returns the enclosing item. Note that this might not be the actual parent + /// node in the AST - some kinds of nodes are not in the map and these will + /// never appear as the parent_node. So you can always walk the parent_nodes + /// from a node to the root of the ast (unless you get the same id back here + /// that can happen if the id is not in the map itself or is just weird). + pub fn get_parent_node(&self, id: NodeId) -> NodeId { + self.find_entry(id).and_then(|x| x.parent_node()).unwrap_or(id) + } + + /// Check if the node is an argument. An argument is a local variable whose + /// immediate parent is an item or a closure. + pub fn is_argument(&self, id: NodeId) -> bool { + match self.find(id) { + Some(NodeLocal(_)) => (), + _ => return false, + } + match self.find(self.get_parent_node(id)) { + Some(NodeItem(_)) | + Some(NodeTraitItem(_)) | + Some(NodeImplItem(_)) => true, + Some(NodeExpr(e)) => { + match e.node { + ExprClosure(..) => true, + _ => false, + } + } + _ => false, + } + } + + /// If there is some error when walking the parents (e.g., a node does not + /// have a parent in the map or a node can't be found), then we return the + /// last good node id we found. Note that reaching the crate root (id == 0), + /// is not an error, since items in the crate module have the crate root as + /// parent. + fn walk_parent_nodes(&self, start_id: NodeId, found: F) -> Result + where F: Fn(&Node<'ast>) -> bool + { + let mut id = start_id; + loop { + let parent_node = self.get_parent_node(id); + if parent_node == 0 { + return Ok(0); + } + if parent_node == id { + return Err(id); + } + + let node = self.find_entry(parent_node); + if node.is_none() { + return Err(id); + } + let node = node.unwrap().to_node(); + match node { + Some(ref node) => { + if found(node) { + return Ok(parent_node); + } + } + None => { + return Err(parent_node); + } + } + id = parent_node; + } + } + + /// Retrieve the NodeId for `id`'s parent item, or `id` itself if no + /// parent item is in this map. The "parent item" is the closest parent node + /// in the AST which is recorded by the map and is an item, either an item + /// in a module, trait, or impl. + pub fn get_parent(&self, id: NodeId) -> NodeId { + match self.walk_parent_nodes(id, |node| match *node { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) => true, + _ => false, + }) { + Ok(id) => id, + Err(id) => id, + } + } + + /// Returns the NodeId of `id`'s nearest module parent, or `id` itself if no + /// module parent is in this map. + fn get_module_parent(&self, id: NodeId) -> NodeId { + match self.walk_parent_nodes(id, |node| match *node { + NodeItem(&Item { node: Item_::ItemMod(_), .. }) => true, + _ => false, + }) { + Ok(id) => id, + Err(id) => id, + } + } + + pub fn private_item_is_visible_from(&self, item: NodeId, block: NodeId) -> bool { + // A private item is visible from everything in its nearest module parent. + let visibility = self.get_module_parent(item); + let mut block_ancestor = self.get_module_parent(block); + loop { + if block_ancestor == visibility { return true } + let block_ancestor_parent = self.get_module_parent(block_ancestor); + if block_ancestor_parent == block_ancestor { return false } + block_ancestor = block_ancestor_parent; + } + } + + /// Returns the nearest enclosing scope. A scope is an item or block. + /// FIXME it is not clear to me that all items qualify as scopes - statics + /// and associated types probably shouldn't, for example. Behaviour in this + /// regard should be expected to be highly unstable. + pub fn get_enclosing_scope(&self, id: NodeId) -> Option { + match self.walk_parent_nodes(id, |node| match *node { + NodeItem(_) | + NodeForeignItem(_) | + NodeTraitItem(_) | + NodeImplItem(_) | + NodeBlock(_) => true, + _ => false, + }) { + Ok(id) => Some(id), + Err(_) => None, + } + } + + pub fn get_parent_did(&self, id: NodeId) -> DefId { + let parent = self.get_parent(id); + match self.find_entry(parent) { + Some(RootInlinedParent(&InlinedParent {ii: II::TraitItem(did, _), ..})) => did, + Some(RootInlinedParent(&InlinedParent {ii: II::ImplItem(did, _), ..})) => did, + _ => self.local_def_id(parent) + } + } + + pub fn get_foreign_abi(&self, id: NodeId) -> Abi { + let parent = self.get_parent(id); + let abi = match self.find_entry(parent) { + Some(EntryItem(_, i)) => { + match i.node { + ItemForeignMod(ref nm) => Some(nm.abi), + _ => None + } + } + /// Wrong but OK, because the only inlined foreign items are intrinsics. + Some(RootInlinedParent(_)) => Some(Abi::RustIntrinsic), + _ => None + }; + match abi { + Some(abi) => { + self.read(id); // reveals some of the content of a node + abi + } + None => bug!("expected foreign mod or inlined parent, found {}", + self.node_to_string(parent)) + } + } + + pub fn expect_item(&self, id: NodeId) -> &'ast Item { + match self.find(id) { // read recorded by `find` + Some(NodeItem(item)) => item, + _ => bug!("expected item, found {}", self.node_to_string(id)) + } + } + + pub fn expect_trait_item(&self, id: NodeId) -> &'ast TraitItem { + match self.find(id) { + Some(NodeTraitItem(item)) => item, + _ => bug!("expected trait item, found {}", self.node_to_string(id)) + } + } + + pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData { + match self.find(id) { + Some(NodeItem(i)) => { + match i.node { + ItemStruct(ref struct_def, _) => struct_def, + _ => bug!("struct ID bound to non-struct") + } + } + Some(NodeVariant(variant)) => { + if variant.node.data.is_struct() { + &variant.node.data + } else { + bug!("struct ID bound to enum variant that isn't struct-like") + } + } + _ => bug!("expected struct, found {}", self.node_to_string(id)), + } + } + + pub fn expect_variant(&self, id: NodeId) -> &'ast Variant { + match self.find(id) { + Some(NodeVariant(variant)) => variant, + _ => bug!("expected variant, found {}", self.node_to_string(id)), + } + } + + pub fn expect_foreign_item(&self, id: NodeId) -> &'ast ForeignItem { + match self.find(id) { + Some(NodeForeignItem(item)) => item, + _ => bug!("expected foreign item, found {}", self.node_to_string(id)) + } + } + + pub fn expect_expr(&self, id: NodeId) -> &'ast Expr { + match self.find(id) { // read recorded by find + Some(NodeExpr(expr)) => expr, + _ => bug!("expected expr, found {}", self.node_to_string(id)) + } + } + + /// returns the name associated with the given NodeId's AST + pub fn get_path_elem(&self, id: NodeId) -> PathElem { + let node = self.get(id); + match node { + NodeItem(item) => { + match item.node { + ItemMod(_) | ItemForeignMod(_) => { + PathMod(item.name) + } + _ => PathName(item.name) + } + } + NodeForeignItem(i) => PathName(i.name), + NodeImplItem(ii) => PathName(ii.name), + NodeTraitItem(ti) => PathName(ti.name), + NodeVariant(v) => PathName(v.node.name), + NodeLifetime(lt) => PathName(lt.name), + NodeTyParam(tp) => PathName(tp.name), + NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => { + PathName(l.node.name) + }, + _ => bug!("no path elem for {:?}", node) + } + } + + pub fn with_path(&self, id: NodeId, f: F) -> T where + F: FnOnce(PathElems) -> T, + { + self.with_path_next(id, LinkedPath::empty(), f) + } + + pub fn path_to_string(&self, id: NodeId) -> String { + self.with_path(id, |path| path_to_string(path)) + } + + fn path_to_str_with_name(&self, id: NodeId, name: Name) -> String { + self.with_path(id, |path| { + path_to_string(path.chain(Some(PathName(name)))) + }) + } + + fn with_path_next(&self, id: NodeId, next: LinkedPath, f: F) -> T where + F: FnOnce(PathElems) -> T, + { + // This function reveals the name of the item and hence is a + // kind of read. This is inefficient, since it walks ancestors + // and we are walking them anyhow, but whatever. + self.read(id); + + let parent = self.get_parent(id); + let parent = match self.find_entry(id) { + Some(EntryForeignItem(..)) => { + // Anonymous extern items go in the parent scope. + self.get_parent(parent) + } + // But tuple struct ctors don't have names, so use the path of its + // parent, the struct item. Similarly with closure expressions. + Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => { + return self.with_path_next(parent, next, f); + } + _ => parent + }; + if parent == id { + match self.find_entry(id) { + Some(RootInlinedParent(data)) => { + f(data.path.iter().cloned().chain(next)) + } + _ => f([].iter().cloned().chain(next)) + } + } else { + self.with_path_next(parent, LinkedPath::from(&LinkedPathNode { + node: self.get_path_elem(id), + next: next + }), f) + } + } + + /// Given a node ID, get a list of attributes associated with the AST + /// corresponding to the Node ID + pub fn attrs(&self, id: NodeId) -> &'ast [ast::Attribute] { + self.read(id); // reveals attributes on the node + let attrs = match self.find(id) { + Some(NodeItem(i)) => Some(&i.attrs[..]), + Some(NodeForeignItem(fi)) => Some(&fi.attrs[..]), + Some(NodeTraitItem(ref ti)) => Some(&ti.attrs[..]), + Some(NodeImplItem(ref ii)) => Some(&ii.attrs[..]), + Some(NodeVariant(ref v)) => Some(&v.node.attrs[..]), + Some(NodeExpr(ref e)) => Some(e.attrs.as_attr_slice()), + Some(NodeStmt(ref s)) => Some(s.node.attrs()), + // unit/tuple structs take the attributes straight from + // the struct definition. + Some(NodeStructCtor(_)) => { + return self.attrs(self.get_parent(id)); + } + _ => None + }; + attrs.unwrap_or(&[]) + } + + /// Returns an iterator that yields the node id's with paths that + /// match `parts`. (Requires `parts` is non-empty.) + /// + /// For example, if given `parts` equal to `["bar", "quux"]`, then + /// the iterator will produce node id's for items with paths + /// such as `foo::bar::quux`, `bar::quux`, `other::bar::quux`, and + /// any other such items it can find in the map. + pub fn nodes_matching_suffix<'a>(&'a self, parts: &'a [String]) + -> NodesMatchingSuffix<'a, 'ast> { + NodesMatchingSuffix { + map: self, + item_name: parts.last().unwrap(), + in_which: &parts[..parts.len() - 1], + idx: 0, + } + } + + pub fn opt_span(&self, id: NodeId) -> Option { + let sp = match self.find(id) { + Some(NodeItem(item)) => item.span, + Some(NodeForeignItem(foreign_item)) => foreign_item.span, + Some(NodeTraitItem(trait_method)) => trait_method.span, + Some(NodeImplItem(ref impl_item)) => impl_item.span, + Some(NodeVariant(variant)) => variant.span, + Some(NodeExpr(expr)) => expr.span, + Some(NodeStmt(stmt)) => stmt.span, + Some(NodeLocal(pat)) => pat.span, + Some(NodePat(pat)) => pat.span, + Some(NodeBlock(block)) => block.span, + Some(NodeStructCtor(_)) => self.expect_item(self.get_parent(id)).span, + Some(NodeTyParam(ty_param)) => ty_param.span, + _ => return None, + }; + Some(sp) + } + + pub fn span(&self, id: NodeId) -> Span { + self.read(id); // reveals span from node + self.opt_span(id) + .unwrap_or_else(|| bug!("AstMap.span: could not find span for id {:?}", id)) + } + + pub fn span_if_local(&self, id: DefId) -> Option { + self.as_local_node_id(id).map(|id| self.span(id)) + } + + pub fn def_id_span(&self, def_id: DefId, fallback: Span) -> Span { + if let Some(node_id) = self.as_local_node_id(def_id) { + self.opt_span(node_id).unwrap_or(fallback) + } else { + fallback + } + } + + pub fn node_to_string(&self, id: NodeId) -> String { + node_id_to_string(self, id, true) + } + + pub fn node_to_user_string(&self, id: NodeId) -> String { + node_id_to_string(self, id, false) + } +} + +pub struct NodesMatchingSuffix<'a, 'ast:'a> { + map: &'a Map<'ast>, + item_name: &'a String, + in_which: &'a [String], + idx: NodeId, +} + +impl<'a, 'ast> NodesMatchingSuffix<'a, 'ast> { + /// Returns true only if some suffix of the module path for parent + /// matches `self.in_which`. + /// + /// In other words: let `[x_0,x_1,...,x_k]` be `self.in_which`; + /// returns true if parent's path ends with the suffix + /// `x_0::x_1::...::x_k`. + fn suffix_matches(&self, parent: NodeId) -> bool { + let mut cursor = parent; + for part in self.in_which.iter().rev() { + let (mod_id, mod_name) = match find_first_mod_parent(self.map, cursor) { + None => return false, + Some((node_id, name)) => (node_id, name), + }; + if &part[..] != mod_name.as_str() { + return false; + } + cursor = self.map.get_parent(mod_id); + } + return true; + + // Finds the first mod in parent chain for `id`, along with + // that mod's name. + // + // If `id` itself is a mod named `m` with parent `p`, then + // returns `Some(id, m, p)`. If `id` has no mod in its parent + // chain, then returns `None`. + fn find_first_mod_parent<'a>(map: &'a Map, mut id: NodeId) -> Option<(NodeId, Name)> { + loop { + match map.find(id) { + None => return None, + Some(NodeItem(item)) if item_is_mod(&item) => + return Some((id, item.name)), + _ => {} + } + let parent = map.get_parent(id); + if parent == id { return None } + id = parent; + } + + fn item_is_mod(item: &Item) -> bool { + match item.node { + ItemMod(_) => true, + _ => false, + } + } + } + } + + // We are looking at some node `n` with a given name and parent + // id; do their names match what I am seeking? + fn matches_names(&self, parent_of_n: NodeId, name: Name) -> bool { + name.as_str() == &self.item_name[..] && + self.suffix_matches(parent_of_n) + } +} + +impl<'a, 'ast> Iterator for NodesMatchingSuffix<'a, 'ast> { + type Item = NodeId; + + fn next(&mut self) -> Option { + loop { + let idx = self.idx; + if idx as usize >= self.map.entry_count() { + return None; + } + self.idx += 1; + let name = match self.map.find_entry(idx) { + Some(EntryItem(_, n)) => n.name(), + Some(EntryForeignItem(_, n))=> n.name(), + Some(EntryTraitItem(_, n)) => n.name(), + Some(EntryImplItem(_, n)) => n.name(), + Some(EntryVariant(_, n)) => n.name(), + _ => continue, + }; + if self.matches_names(self.map.get_parent(idx), name) { + return Some(idx) + } + } + } +} + +trait Named { + fn name(&self) -> Name; +} + +impl Named for Spanned { fn name(&self) -> Name { self.node.name() } } + +impl Named for Item { fn name(&self) -> Name { self.name } } +impl Named for ForeignItem { fn name(&self) -> Name { self.name } } +impl Named for Variant_ { fn name(&self) -> Name { self.name } } +impl Named for TraitItem { fn name(&self) -> Name { self.name } } +impl Named for ImplItem { fn name(&self) -> Name { self.name } } + +pub trait FoldOps { + fn new_id(&self, id: NodeId) -> NodeId { + id + } + fn new_def_id(&self, def_id: DefId) -> DefId { + def_id + } + fn new_span(&self, span: Span) -> Span { + span + } +} + +/// A Folder that updates IDs and Span's according to fold_ops. +struct IdAndSpanUpdater { + fold_ops: F +} + +impl Folder for IdAndSpanUpdater { + fn new_id(&mut self, id: NodeId) -> NodeId { + self.fold_ops.new_id(id) + } + + fn new_span(&mut self, span: Span) -> Span { + self.fold_ops.new_span(span) + } +} + +pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { + let (map, definitions) = { + let mut collector = NodeCollector::root(&forest.krate); + intravisit::walk_crate(&mut collector, &forest.krate); + (collector.map, collector.definitions) + }; + + if log_enabled!(::log::DEBUG) { + // This only makes sense for ordered stores; note the + // enumerate to count the number of entries. + let (entries_less_1, _) = map.iter().filter(|&x| { + match *x { + NotPresent => false, + _ => true + } + }).enumerate().last().expect("AST map was empty after folding?"); + + let entries = entries_less_1 + 1; + let vector_length = map.len(); + debug!("The AST map has {} entries with a maximum of {}: occupancy {:.1}%", + entries, vector_length, (entries as f64 / vector_length as f64) * 100.); + } + + Map { + forest: forest, + dep_graph: forest.dep_graph.clone(), + map: RefCell::new(map), + definitions: RefCell::new(definitions), + } +} + +/// Used for items loaded from external crate that are being inlined into this +/// crate. +pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, + parent_path: Vec, + parent_def_path: DefPath, + parent_def_id: DefId, + ii: InlinedItem, + fold_ops: F) + -> &'ast InlinedItem { + let mut fld = IdAndSpanUpdater { fold_ops: fold_ops }; + let ii = match ii { + II::Item(i) => II::Item(i.map(|i| fld.fold_item(i))), + II::TraitItem(d, ti) => { + II::TraitItem(fld.fold_ops.new_def_id(d), + ti.map(|ti| fld.fold_trait_item(ti))) + } + II::ImplItem(d, ii) => { + II::ImplItem(fld.fold_ops.new_def_id(d), + ii.map(|ii| fld.fold_impl_item(ii))) + } + II::Foreign(i) => II::Foreign(i.map(|i| fld.fold_foreign_item(i))) + }; + + let ii_parent = map.forest.inlined_items.alloc(InlinedParent { + path: parent_path, + ii: ii + }); + + let ii_parent_id = fld.new_id(DUMMY_NODE_ID); + let mut collector = + NodeCollector::extend( + map.krate(), + ii_parent, + ii_parent_id, + parent_def_path, + parent_def_id, + mem::replace(&mut *map.map.borrow_mut(), vec![]), + mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + ii_parent.ii.visit(&mut collector); + + *map.map.borrow_mut() = collector.map; + *map.definitions.borrow_mut() = collector.definitions; + + &ii_parent.ii +} + +pub trait NodePrinter { + fn print_node(&mut self, node: &Node) -> io::Result<()>; +} + +impl<'a> NodePrinter for pprust::State<'a> { + fn print_node(&mut self, node: &Node) -> io::Result<()> { + match *node { + NodeItem(a) => self.print_item(&a), + NodeForeignItem(a) => self.print_foreign_item(&a), + NodeTraitItem(a) => self.print_trait_item(a), + NodeImplItem(a) => self.print_impl_item(a), + NodeVariant(a) => self.print_variant(&a), + NodeExpr(a) => self.print_expr(&a), + NodeStmt(a) => self.print_stmt(&a), + NodePat(a) => self.print_pat(&a), + NodeBlock(a) => self.print_block(&a), + NodeLifetime(a) => self.print_lifetime(&a), + NodeTyParam(_) => bug!("cannot print TyParam"), + // these cases do not carry enough information in the + // ast_map to reconstruct their full structure for pretty + // printing. + NodeLocal(_) => bug!("cannot print isolated Local"), + NodeStructCtor(_) => bug!("cannot print isolated StructCtor"), + } + } +} + +fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { + let id_str = format!(" (id={})", id); + let id_str = if include_id { &id_str[..] } else { "" }; + + match map.find(id) { + Some(NodeItem(item)) => { + let path_str = map.path_to_str_with_name(id, item.name); + let item_str = match item.node { + ItemExternCrate(..) => "extern crate", + ItemUse(..) => "use", + ItemStatic(..) => "static", + ItemConst(..) => "const", + ItemFn(..) => "fn", + ItemMod(..) => "mod", + ItemForeignMod(..) => "foreign mod", + ItemTy(..) => "ty", + ItemEnum(..) => "enum", + ItemStruct(..) => "struct", + ItemTrait(..) => "trait", + ItemImpl(..) => "impl", + ItemDefaultImpl(..) => "default impl", + }; + format!("{} {}{}", item_str, path_str, id_str) + } + Some(NodeForeignItem(item)) => { + let path_str = map.path_to_str_with_name(id, item.name); + format!("foreign item {}{}", path_str, id_str) + } + Some(NodeImplItem(ii)) => { + match ii.node { + ImplItemKind::Const(..) => { + format!("assoc const {} in {}{}", + ii.name, + map.path_to_string(id), + id_str) + } + ImplItemKind::Method(..) => { + format!("method {} in {}{}", + ii.name, + map.path_to_string(id), id_str) + } + ImplItemKind::Type(_) => { + format!("assoc type {} in {}{}", + ii.name, + map.path_to_string(id), + id_str) + } + } + } + Some(NodeTraitItem(ti)) => { + let kind = match ti.node { + ConstTraitItem(..) => "assoc constant", + MethodTraitItem(..) => "trait method", + TypeTraitItem(..) => "assoc type", + }; + + format!("{} {} in {}{}", + kind, + ti.name, + map.path_to_string(id), + id_str) + } + Some(NodeVariant(ref variant)) => { + format!("variant {} in {}{}", + variant.node.name, + map.path_to_string(id), id_str) + } + Some(NodeExpr(ref expr)) => { + format!("expr {}{}", pprust::expr_to_string(&expr), id_str) + } + Some(NodeStmt(ref stmt)) => { + format!("stmt {}{}", pprust::stmt_to_string(&stmt), id_str) + } + Some(NodeLocal(ref pat)) => { + format!("local {}{}", pprust::pat_to_string(&pat), id_str) + } + Some(NodePat(ref pat)) => { + format!("pat {}{}", pprust::pat_to_string(&pat), id_str) + } + Some(NodeBlock(ref block)) => { + format!("block {}{}", pprust::block_to_string(&block), id_str) + } + Some(NodeStructCtor(_)) => { + format!("struct_ctor {}{}", map.path_to_string(id), id_str) + } + Some(NodeLifetime(ref l)) => { + format!("lifetime {}{}", + pprust::lifetime_to_string(&l), id_str) + } + Some(NodeTyParam(ref ty_param)) => { + format!("typaram {:?}{}", ty_param, id_str) + } + None => { + format!("unknown node{}", id_str) + } + } +} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs new file mode 100644 index 00000000000..eaf59af2cc3 --- /dev/null +++ b/src/librustc/hir/mod.rs @@ -0,0 +1,1465 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// The Rust HIR. + +pub use self::BindingMode::*; +pub use self::BinOp_::*; +pub use self::BlockCheckMode::*; +pub use self::CaptureClause::*; +pub use self::Decl_::*; +pub use self::ExplicitSelf_::*; +pub use self::Expr_::*; +pub use self::FunctionRetTy::*; +pub use self::ForeignItem_::*; +pub use self::Item_::*; +pub use self::Mutability::*; +pub use self::PathListItem_::*; +pub use self::PrimTy::*; +pub use self::Stmt_::*; +pub use self::TraitItem_::*; +pub use self::Ty_::*; +pub use self::TyParamBound::*; +pub use self::UnOp::*; +pub use self::UnsafeSource::*; +pub use self::ViewPath_::*; +pub use self::Visibility::*; +pub use self::PathParameters::*; + +use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; +use syntax::abi::Abi; +use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; +use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; +use syntax::attr::{ThinAttributes, ThinAttributesExt}; +use syntax::parse::token::InternedString; +use syntax::ptr::P; + +use std::collections::BTreeMap; +use std::fmt; +use std::hash::{Hash, Hasher}; +use serialize::{Encodable, Decodable, Encoder, Decoder}; + +/// HIR doesn't commit to a concrete storage type and have its own alias for a vector. +/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar +/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead +/// of `Vec` to avoid keeping extra capacity. +pub type HirVec = P<[T]>; + +macro_rules! hir_vec { + ($elem:expr; $n:expr) => ( + $crate::hir::HirVec::from(vec![$elem; $n]) + ); + ($($x:expr),*) => ( + $crate::hir::HirVec::from(vec![$($x),*]) + ); + ($($x:expr,)*) => (vec![$($x),*]) +} + +pub mod check_attr; +pub mod fold; +pub mod intravisit; +pub mod lowering; +pub mod map; +pub mod print; +pub mod svh; +pub mod util; + +/// Identifier in HIR +#[derive(Clone, Copy, Eq)] +pub struct Ident { + /// Hygienic name (renamed), should be used by default + pub name: Name, + /// Unhygienic name (original, not renamed), needed in few places in name resolution + pub unhygienic_name: Name, +} + +impl Ident { + /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with + /// the argument. Hygiene properties of the created identifier depend entirely on this + /// argument. If the argument is a plain interned string `intern("iter")`, then the result + /// is unhygienic and can interfere with other entities named "iter". If the argument is + /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't + /// interfere with other entities having the same string as a name. + pub fn from_name(name: Name) -> Ident { + Ident { name: name, unhygienic_name: name } + } +} + +impl PartialEq for Ident { + fn eq(&self, other: &Ident) -> bool { + self.name == other.name + } +} + +impl Hash for Ident { + fn hash(&self, state: &mut H) { + self.name.hash(state) + } +} + +impl fmt::Debug for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self.name, f) + } +} + +impl fmt::Display for Ident { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&self.name, f) + } +} + +impl Encodable for Ident { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + self.name.encode(s) + } +} + +impl Decodable for Ident { + fn decode(d: &mut D) -> Result { + Ok(Ident::from_name(Name::decode(d)?)) + } +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] +pub struct Lifetime { + pub id: NodeId, + pub span: Span, + pub name: Name, +} + +impl fmt::Debug for Lifetime { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, + "lifetime({}: {})", + self.id, + print::lifetime_to_string(self)) + } +} + +/// A lifetime definition, eg `'a: 'b+'c+'d` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct LifetimeDef { + pub lifetime: Lifetime, + pub bounds: HirVec, +} + +/// A "Path" is essentially Rust's notion of a name; for instance: +/// std::cmp::PartialEq . It's represented as a sequence of identifiers, +/// along with a bunch of supporting information. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub struct Path { + pub span: Span, + /// A `::foo` path, is relative to the crate root rather than current + /// module (like paths in an import). + pub global: bool, + /// The segments in the path: the things separated by `::`. + pub segments: HirVec, +} + +impl fmt::Debug for Path { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "path({})", print::path_to_string(self)) + } +} + +impl fmt::Display for Path { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", print::path_to_string(self)) + } +} + +/// A segment of a path: an identifier, an optional lifetime, and a set of +/// types. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct PathSegment { + /// The identifier portion of this path segment. + /// + /// Hygiene properties of this identifier are worth noting. + /// Most path segments are not hygienic and they are not renamed during + /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from + /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths) + /// can be hygienic, so they are renamed. You should not normally care about this peculiarity + /// and just use `identifier.name` unless you modify identifier resolution code + /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`). + pub identifier: Ident, + + /// Type/lifetime parameters attached to this path. They come in + /// two flavors: `Path` and `Path(A,B) -> C`. Note that + /// this is more than just simple syntactic sugar; the use of + /// parens affects the region binding rules, so we preserve the + /// distinction. + pub parameters: PathParameters, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum PathParameters { + /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` + AngleBracketedParameters(AngleBracketedParameterData), + /// The `(A,B)` and `C` in `Foo(A,B) -> C` + ParenthesizedParameters(ParenthesizedParameterData), +} + +impl PathParameters { + pub fn none() -> PathParameters { + AngleBracketedParameters(AngleBracketedParameterData { + lifetimes: HirVec::new(), + types: HirVec::new(), + bindings: HirVec::new(), + }) + } + + pub fn is_empty(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => data.is_empty(), + + // Even if the user supplied no types, something like + // `X()` is equivalent to `X<(),()>`. + ParenthesizedParameters(..) => false, + } + } + + pub fn has_lifetimes(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), + ParenthesizedParameters(_) => false, + } + } + + pub fn has_types(&self) -> bool { + match *self { + AngleBracketedParameters(ref data) => !data.types.is_empty(), + ParenthesizedParameters(..) => true, + } + } + + /// Returns the types that the user wrote. Note that these do not necessarily map to the type + /// parameters in the parenthesized case. + pub fn types(&self) -> HirVec<&P> { + match *self { + AngleBracketedParameters(ref data) => { + data.types.iter().collect() + } + ParenthesizedParameters(ref data) => { + data.inputs + .iter() + .chain(data.output.iter()) + .collect() + } + } + } + + pub fn lifetimes(&self) -> HirVec<&Lifetime> { + match *self { + AngleBracketedParameters(ref data) => { + data.lifetimes.iter().collect() + } + ParenthesizedParameters(_) => { + HirVec::new() + } + } + } + + pub fn bindings(&self) -> HirVec<&TypeBinding> { + match *self { + AngleBracketedParameters(ref data) => { + data.bindings.iter().collect() + } + ParenthesizedParameters(_) => { + HirVec::new() + } + } + } +} + +/// A path like `Foo<'a, T>` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct AngleBracketedParameterData { + /// The lifetime parameters for this path segment. + pub lifetimes: HirVec, + /// The type parameters for this path segment, if present. + pub types: HirVec>, + /// Bindings (equality constraints) on associated types, if present. + /// E.g., `Foo`. + pub bindings: HirVec, +} + +impl AngleBracketedParameterData { + fn is_empty(&self) -> bool { + self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty() + } +} + +/// A path like `Foo(A,B) -> C` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ParenthesizedParameterData { + /// Overall span + pub span: Span, + + /// `(A,B)` + pub inputs: HirVec>, + + /// `C` + pub output: Option>, +} + +/// The AST represents all type param bounds as types. +/// typeck::collect::compute_bounds matches these against +/// the "special" built-in traits (see middle::lang_items) and +/// detects Copy, Send and Sync. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum TyParamBound { + TraitTyParamBound(PolyTraitRef, TraitBoundModifier), + RegionTyParamBound(Lifetime), +} + +/// A modifier on a bound, currently this is only used for `?Sized`, where the +/// modifier is `Maybe`. Negative bounds should also be handled here. +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum TraitBoundModifier { + None, + Maybe, +} + +pub type TyParamBounds = HirVec; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct TyParam { + pub name: Name, + pub id: NodeId, + pub bounds: TyParamBounds, + pub default: Option>, + pub span: Span, +} + +/// Represents lifetimes and type parameters attached to a declaration +/// of a function, enum, trait, etc. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Generics { + pub lifetimes: HirVec, + pub ty_params: HirVec, + pub where_clause: WhereClause, +} + +impl Generics { + pub fn is_lt_parameterized(&self) -> bool { + !self.lifetimes.is_empty() + } + pub fn is_type_parameterized(&self) -> bool { + !self.ty_params.is_empty() + } + pub fn is_parameterized(&self) -> bool { + self.is_lt_parameterized() || self.is_type_parameterized() + } +} + +/// A `where` clause in a definition +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct WhereClause { + pub id: NodeId, + pub predicates: HirVec, +} + +/// A single predicate in a `where` clause +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum WherePredicate { + /// A type binding, eg `for<'c> Foo: Send+Clone+'c` + BoundPredicate(WhereBoundPredicate), + /// A lifetime predicate, e.g. `'a: 'b+'c` + RegionPredicate(WhereRegionPredicate), + /// An equality predicate (unsupported) + EqPredicate(WhereEqPredicate), +} + +/// A type bound, eg `for<'c> Foo: Send+Clone+'c` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct WhereBoundPredicate { + pub span: Span, + /// Any lifetimes from a `for` binding + pub bound_lifetimes: HirVec, + /// The type being bounded + pub bounded_ty: P, + /// Trait and lifetime bounds (`Clone+Send+'static`) + pub bounds: TyParamBounds, +} + +/// A lifetime predicate, e.g. `'a: 'b+'c` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct WhereRegionPredicate { + pub span: Span, + pub lifetime: Lifetime, + pub bounds: HirVec, +} + +/// An equality predicate (unsupported), e.g. `T=int` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct WhereEqPredicate { + pub id: NodeId, + pub span: Span, + pub path: Path, + pub ty: P, +} + +pub type CrateConfig = HirVec>; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +pub struct Crate { + pub module: Mod, + pub attrs: HirVec, + pub config: CrateConfig, + pub span: Span, + pub exported_macros: HirVec, + + // NB: We use a BTreeMap here so that `visit_all_items` iterates + // over the ids in increasing order. In principle it should not + // matter what order we visit things in, but in *practice* it + // does, because it can affect the order in which errors are + // detected, which in turn can make compile-fail tests yield + // slightly different results. + pub items: BTreeMap, +} + +impl Crate { + pub fn item(&self, id: NodeId) -> &Item { + &self.items[&id] + } + + /// Visits all items in the crate in some determinstic (but + /// unspecified) order. If you just need to process every item, + /// but don't care about nesting, this method is the best choice. + /// + /// If you do care about nesting -- usually because your algorithm + /// follows lexical scoping rules -- then you want a different + /// approach. You should override `visit_nested_item` in your + /// visitor and then call `intravisit::walk_crate` instead. + pub fn visit_all_items<'hir, V>(&'hir self, visitor: &mut V) + where V: intravisit::Visitor<'hir> + { + for (_, item) in &self.items { + visitor.visit_item(item); + } + } +} + +/// A macro definition, in this crate or imported from another. +/// +/// Not parsed directly, but created on macro import or `macro_rules!` expansion. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct MacroDef { + pub name: Name, + pub attrs: HirVec, + pub id: NodeId, + pub span: Span, + pub imported_from: Option, + pub export: bool, + pub use_locally: bool, + pub allow_internal_unstable: bool, + pub body: HirVec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Block { + /// Statements in a block + pub stmts: HirVec, + /// An expression at the end of the block + /// without a semicolon, if any + pub expr: Option>, + pub id: NodeId, + /// Distinguishes between `unsafe { ... }` and `{ ... }` + pub rules: BlockCheckMode, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub struct Pat { + pub id: NodeId, + pub node: PatKind, + pub span: Span, +} + +impl fmt::Debug for Pat { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "pat({}: {})", self.id, print::pat_to_string(self)) + } +} + +/// A single field in a struct pattern +/// +/// Patterns like the fields of Foo `{ x, ref y, ref mut z }` +/// are treated the same as` x: x, y: ref y, z: ref mut z`, +/// except is_shorthand is true +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct FieldPat { + /// The identifier for the field + pub name: Name, + /// The pattern the field is destructured to + pub pat: P, + pub is_shorthand: bool, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum BindingMode { + BindByRef(Mutability), + BindByValue(Mutability), +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum PatKind { + /// Represents a wildcard pattern (`_`) + Wild, + + /// A `PatKind::Ident` may either be a new bound variable, + /// or a unit struct/variant pattern, or a const pattern (in the last two cases + /// the third field must be `None`). + /// + /// In the unit or const pattern case, the parser can't determine + /// which it is. The resolver determines this, and + /// records this pattern's `NodeId` in an auxiliary + /// set (of "PatIdents that refer to unit patterns or constants"). + Ident(BindingMode, Spanned, Option>), + + /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. + /// The `bool` is `true` in the presence of a `..`. + Struct(Path, HirVec>, bool), + + /// A tuple struct/variant pattern `Variant(x, y, z)`. + /// "None" means a `Variant(..)` pattern where we don't bind the fields to names. + TupleStruct(Path, Option>>), + + /// A path pattern. + /// Such pattern can be resolved to a unit struct/variant or a constant. + Path(Path), + + /// An associated const named using the qualified path `::CONST` or + /// `::CONST`. Associated consts from inherent impls can be + /// referred to as simply `T::CONST`, in which case they will end up as + /// PatKind::Path, and the resolver will have to sort that out. + QPath(QSelf, Path), + + /// A tuple pattern `(a, b)` + Tup(HirVec>), + /// A `box` pattern + Box(P), + /// A reference pattern, e.g. `&mut (a, b)` + Ref(P, Mutability), + /// A literal + Lit(P), + /// A range pattern, e.g. `1...2` + Range(P, P), + /// `[a, b, ..i, y, z]` is represented as: + /// `PatKind::Vec(box [a, b], Some(i), box [y, z])` + Vec(HirVec>, Option>, HirVec>), +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum Mutability { + MutMutable, + MutImmutable, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum BinOp_ { + /// The `+` operator (addition) + BiAdd, + /// The `-` operator (subtraction) + BiSub, + /// The `*` operator (multiplication) + BiMul, + /// The `/` operator (division) + BiDiv, + /// The `%` operator (modulus) + BiRem, + /// The `&&` operator (logical and) + BiAnd, + /// The `||` operator (logical or) + BiOr, + /// The `^` operator (bitwise xor) + BiBitXor, + /// The `&` operator (bitwise and) + BiBitAnd, + /// The `|` operator (bitwise or) + BiBitOr, + /// The `<<` operator (shift left) + BiShl, + /// The `>>` operator (shift right) + BiShr, + /// The `==` operator (equality) + BiEq, + /// The `<` operator (less than) + BiLt, + /// The `<=` operator (less than or equal to) + BiLe, + /// The `!=` operator (not equal to) + BiNe, + /// The `>=` operator (greater than or equal to) + BiGe, + /// The `>` operator (greater than) + BiGt, +} + +pub type BinOp = Spanned; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum UnOp { + /// The `*` operator for dereferencing + UnDeref, + /// The `!` operator for logical inversion + UnNot, + /// The `-` operator for negation + UnNeg, +} + +/// A statement +pub type Stmt = Spanned; + +impl fmt::Debug for Stmt_ { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Sadness. + let spanned = codemap::dummy_spanned(self.clone()); + write!(f, + "stmt({}: {})", + util::stmt_id(&spanned), + print::stmt_to_string(&spanned)) + } +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub enum Stmt_ { + /// Could be an item or a local (let) binding: + StmtDecl(P, NodeId), + + /// Expr without trailing semi-colon (must have unit type): + StmtExpr(P, NodeId), + + /// Expr with trailing semi-colon (may have any type): + StmtSemi(P, NodeId), +} + +impl Stmt_ { + pub fn attrs(&self) -> &[Attribute] { + match *self { + StmtDecl(ref d, _) => d.node.attrs(), + StmtExpr(ref e, _) | + StmtSemi(ref e, _) => e.attrs.as_attr_slice(), + } + } +} + +// FIXME (pending discussion of #1697, #2178...): local should really be +// a refinement on pat. +/// Local represents a `let` statement, e.g., `let : = ;` +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Local { + pub pat: P, + pub ty: Option>, + /// Initializer expression to set the value, if any + pub init: Option>, + pub id: NodeId, + pub span: Span, + pub attrs: ThinAttributes, +} + +pub type Decl = Spanned; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Decl_ { + /// A local (let) binding: + DeclLocal(P), + /// An item binding: + DeclItem(ItemId), +} + +impl Decl_ { + pub fn attrs(&self) -> &[Attribute] { + match *self { + DeclLocal(ref l) => l.attrs.as_attr_slice(), + DeclItem(_) => &[] + } + } +} + +/// represents one arm of a 'match' +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Arm { + pub attrs: HirVec, + pub pats: HirVec>, + pub guard: Option>, + pub body: P, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Field { + pub name: Spanned, + pub expr: P, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum BlockCheckMode { + DefaultBlock, + UnsafeBlock(UnsafeSource), + PushUnsafeBlock(UnsafeSource), + PopUnsafeBlock(UnsafeSource), + // Within this block (but outside a PopUnstableBlock), we suspend checking of stability. + PushUnstableBlock, + PopUnstableBlock, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum UnsafeSource { + CompilerGenerated, + UserProvided, +} + +/// An expression +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub struct Expr { + pub id: NodeId, + pub node: Expr_, + pub span: Span, + pub attrs: ThinAttributes, +} + +impl fmt::Debug for Expr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "expr({}: {})", self.id, print::expr_to_string(self)) + } +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Expr_ { + /// A `box x` expression. + ExprBox(P), + /// An array (`[a, b, c, d]`) + ExprVec(HirVec>), + /// A function call + /// + /// The first field resolves to the function itself, + /// and the second field is the list of arguments + ExprCall(P, HirVec>), + /// A method call (`x.foo::(a, b, c, d)`) + /// + /// The `Spanned` is the identifier for the method name. + /// The vector of `Ty`s are the ascripted type parameters for the method + /// (within the angle brackets). + /// + /// The first element of the vector of `Expr`s is the expression that evaluates + /// to the object on which the method is being called on (the receiver), + /// and the remaining elements are the rest of the arguments. + /// + /// Thus, `x.foo::(a, b, c, d)` is represented as + /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. + ExprMethodCall(Spanned, HirVec>, HirVec>), + /// A tuple (`(a, b, c ,d)`) + ExprTup(HirVec>), + /// A binary operation (For example: `a + b`, `a * b`) + ExprBinary(BinOp, P, P), + /// A unary operation (For example: `!x`, `*x`) + ExprUnary(UnOp, P), + /// A literal (For example: `1`, `"foo"`) + ExprLit(P), + /// A cast (`foo as f64`) + ExprCast(P, P), + ExprType(P, P), + /// An `if` block, with an optional else block + /// + /// `if expr { block } else { expr }` + ExprIf(P, P, Option>), + /// A while loop, with an optional label + /// + /// `'label: while expr { block }` + ExprWhile(P, P, Option), + /// Conditionless loop (can be exited with break, continue, or return) + /// + /// `'label: loop { block }` + ExprLoop(P, Option), + /// A `match` block, with a source that indicates whether or not it is + /// the result of a desugaring, and if so, which kind. + ExprMatch(P, HirVec, MatchSource), + /// A closure (for example, `move |a, b, c| {a + b + c}`) + ExprClosure(CaptureClause, P, P), + /// A block (`{ ... }`) + ExprBlock(P), + + /// An assignment (`a = foo()`) + ExprAssign(P, P), + /// An assignment with an operator + /// + /// For example, `a += 1`. + ExprAssignOp(BinOp, P, P), + /// Access of a named struct field (`obj.foo`) + ExprField(P, Spanned), + /// Access of an unnamed field of a struct or tuple-struct + /// + /// For example, `foo.0`. + ExprTupField(P, Spanned), + /// An indexing operation (`foo[2]`) + ExprIndex(P, P), + + /// Variable reference, possibly containing `::` and/or type + /// parameters, e.g. foo::bar::. + /// + /// Optionally "qualified", + /// e.g. ` as SomeTrait>::SomeType`. + ExprPath(Option, Path), + + /// A referencing operation (`&a` or `&mut a`) + ExprAddrOf(Mutability, P), + /// A `break`, with an optional label to break + ExprBreak(Option>), + /// A `continue`, with an optional label + ExprAgain(Option>), + /// A `return`, with an optional value to be returned + ExprRet(Option>), + + /// Inline assembly (from `asm!`), with its outputs and inputs. + ExprInlineAsm(InlineAsm, Vec>, Vec>), + + /// A struct literal expression. + /// + /// For example, `Foo {x: 1, y: 2}`, or + /// `Foo {x: 1, .. base}`, where `base` is the `Option`. + ExprStruct(Path, HirVec, Option>), + + /// A vector literal constructed from one repeated element. + /// + /// For example, `[1; 5]`. The first expression is the element + /// to be repeated; the second is the number of times to repeat it. + ExprRepeat(P, P), +} + +/// The explicit Self type in a "qualified path". The actual +/// path, including the trait and the associated item, is stored +/// separately. `position` represents the index of the associated +/// item qualified with this Self type. +/// +/// as a::b::Trait>::AssociatedItem +/// ^~~~~ ~~~~~~~~~~~~~~^ +/// ty position = 3 +/// +/// >::AssociatedItem +/// ^~~~~ ^ +/// ty position = 0 +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct QSelf { + pub ty: P, + pub position: usize, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum MatchSource { + Normal, + IfLetDesugar { + contains_else_clause: bool, + }, + WhileLetDesugar, + ForLoopDesugar, + TryDesugar, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum CaptureClause { + CaptureByValue, + CaptureByRef, +} + +// NB: If you change this, you'll probably want to change the corresponding +// type structure in middle/ty.rs as well. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct MutTy { + pub ty: P, + pub mutbl: Mutability, +} + +/// Represents a method's signature in a trait declaration, +/// or in an implementation. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct MethodSig { + pub unsafety: Unsafety, + pub constness: Constness, + pub abi: Abi, + pub decl: P, + pub generics: Generics, + pub explicit_self: ExplicitSelf, +} + +/// Represents an item declaration within a trait declaration, +/// possibly including a default implementation. A trait item is +/// either required (meaning it doesn't have an implementation, just a +/// signature) or provided (meaning it has a default implementation). +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct TraitItem { + pub id: NodeId, + pub name: Name, + pub attrs: HirVec, + pub node: TraitItem_, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum TraitItem_ { + ConstTraitItem(P, Option>), + MethodTraitItem(MethodSig, Option>), + TypeTraitItem(TyParamBounds, Option>), +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ImplItem { + pub id: NodeId, + pub name: Name, + pub vis: Visibility, + pub defaultness: Defaultness, + pub attrs: HirVec, + pub node: ImplItemKind, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ImplItemKind { + Const(P, P), + Method(MethodSig, P), + Type(P), +} + +// Bind a type to an associated type: `A=Foo`. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct TypeBinding { + pub id: NodeId, + pub name: Name, + pub ty: P, + pub span: Span, +} + + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub struct Ty { + pub id: NodeId, + pub node: Ty_, + pub span: Span, +} + +impl fmt::Debug for Ty { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "type({})", print::ty_to_string(self)) + } +} + +/// Not represented directly in the AST, referred to by name through a ty_path. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum PrimTy { + TyInt(IntTy), + TyUint(UintTy), + TyFloat(FloatTy), + TyStr, + TyBool, + TyChar, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct BareFnTy { + pub unsafety: Unsafety, + pub abi: Abi, + pub lifetimes: HirVec, + pub decl: P, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +/// The different kinds of types recognized by the compiler +pub enum Ty_ { + TyVec(P), + /// A fixed length array (`[T; n]`) + TyFixedLengthVec(P, P), + /// A raw pointer (`*const T` or `*mut T`) + TyPtr(MutTy), + /// A reference (`&'a T` or `&'a mut T`) + TyRptr(Option, MutTy), + /// A bare function (e.g. `fn(usize) -> bool`) + TyBareFn(P), + /// A tuple (`(A, B, C, D,...)`) + TyTup(HirVec>), + /// A path (`module::module::...::Type`), optionally + /// "qualified", e.g. ` as SomeTrait>::SomeType`. + /// + /// Type parameters are stored in the Path itself + TyPath(Option, Path), + /// Something like `A+B`. Note that `B` must always be a path. + TyObjectSum(P, TyParamBounds), + /// A type like `for<'a> Foo<&'a Bar>` + TyPolyTraitRef(TyParamBounds), + /// Unused for now + TyTypeof(P), + /// TyInfer means the type should be inferred instead of it having been + /// specified. This can appear anywhere in a type. + TyInfer, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct InlineAsmOutput { + pub constraint: InternedString, + pub is_rw: bool, + pub is_indirect: bool, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct InlineAsm { + pub asm: InternedString, + pub asm_str_style: StrStyle, + pub outputs: HirVec, + pub inputs: HirVec, + pub clobbers: HirVec, + pub volatile: bool, + pub alignstack: bool, + pub dialect: AsmDialect, + pub expn_id: ExpnId, +} + +/// represents an argument in a function header +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Arg { + pub ty: P, + pub pat: P, + pub id: NodeId, +} + +impl Arg { + pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { + let path = Spanned { + span: span, + node: self_ident, + }; + Arg { + // HACK(eddyb) fake type for the self argument. + ty: P(Ty { + id: DUMMY_NODE_ID, + node: TyInfer, + span: DUMMY_SP, + }), + pat: P(Pat { + id: DUMMY_NODE_ID, + node: PatKind::Ident(BindByValue(mutability), path, None), + span: span, + }), + id: DUMMY_NODE_ID, + } + } +} + +/// Represents the header (not the body) of a function declaration +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct FnDecl { + pub inputs: HirVec, + pub output: FunctionRetTy, + pub variadic: bool, +} + +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Unsafety { + Unsafe, + Normal, +} + +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Constness { + Const, + NotConst, +} + +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Defaultness { + Default, + Final, +} + +impl Defaultness { + pub fn is_final(&self) -> bool { + *self == Defaultness::Final + } + + pub fn is_default(&self) -> bool { + *self == Defaultness::Default + } +} + +impl fmt::Display for Unsafety { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(match *self { + Unsafety::Normal => "normal", + Unsafety::Unsafe => "unsafe", + }, + f) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] +pub enum ImplPolarity { + /// `impl Trait for Type` + Positive, + /// `impl !Trait for Type` + Negative, +} + +impl fmt::Debug for ImplPolarity { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + ImplPolarity::Positive => "positive".fmt(f), + ImplPolarity::Negative => "negative".fmt(f), + } + } +} + + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum FunctionRetTy { + /// Functions with return type `!`that always + /// raise an error or exit (i.e. never return to the caller) + NoReturn(Span), + /// Return type is not specified. + /// + /// Functions default to `()` and + /// closures default to inference. Span points to where return + /// type would be inserted. + DefaultReturn(Span), + /// Everything else + Return(P), +} + +impl FunctionRetTy { + pub fn span(&self) -> Span { + match *self { + NoReturn(span) => span, + DefaultReturn(span) => span, + Return(ref ty) => ty.span, + } + } +} + +/// Represents the kind of 'self' associated with a method +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ExplicitSelf_ { + /// No self + SelfStatic, + /// `self` + SelfValue(Name), + /// `&'lt self`, `&'lt mut self` + SelfRegion(Option, Mutability, Name), + /// `self: TYPE` + SelfExplicit(P, Name), +} + +pub type ExplicitSelf = Spanned; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Mod { + /// A span from the first token past `{` to the last token until `}`. + /// For `mod foo;`, the inner span ranges from the first token + /// to the last token in the external file. + pub inner: Span, + pub item_ids: HirVec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ForeignMod { + pub abi: Abi, + pub items: HirVec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct EnumDef { + pub variants: HirVec, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Variant_ { + pub name: Name, + pub attrs: HirVec, + pub data: VariantData, + /// Explicit discriminant, eg `Foo = 1` + pub disr_expr: Option>, +} + +pub type Variant = Spanned; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum PathListItem_ { + PathListIdent { + name: Name, + /// renamed in list, eg `use foo::{bar as baz};` + rename: Option, + id: NodeId, + }, + PathListMod { + /// renamed in list, eg `use foo::{self as baz};` + rename: Option, + id: NodeId, + }, +} + +impl PathListItem_ { + pub fn id(&self) -> NodeId { + match *self { + PathListIdent { id, .. } | PathListMod { id, .. } => id, + } + } + + pub fn name(&self) -> Option { + match *self { + PathListIdent { name, .. } => Some(name), + PathListMod { .. } => None, + } + } + + pub fn rename(&self) -> Option { + match *self { + PathListIdent { rename, .. } | PathListMod { rename, .. } => rename, + } + } +} + +pub type PathListItem = Spanned; + +pub type ViewPath = Spanned; + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ViewPath_ { + /// `foo::bar::baz as quux` + /// + /// or just + /// + /// `foo::bar::baz` (with `as baz` implicitly on the right) + ViewPathSimple(Name, Path), + + /// `foo::bar::*` + ViewPathGlob(Path), + + /// `foo::bar::{a,b,c}` + ViewPathList(Path, HirVec), +} + +/// TraitRef's appear in impls. +/// +/// resolve maps each TraitRef's ref_id to its defining trait; that's all +/// that the ref_id is for. The impl_id maps to the "self type" of this impl. +/// If this impl is an ItemImpl, the impl_id is redundant (it could be the +/// same as the impl's node id). +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct TraitRef { + pub path: Path, + pub ref_id: NodeId, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct PolyTraitRef { + /// The `'a` in `<'a> Foo<&'a T>` + pub bound_lifetimes: HirVec, + + /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` + pub trait_ref: TraitRef, + + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] +pub enum Visibility { + Public, + Inherited, +} + +impl Visibility { + pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility { + match self { + &Inherited => parent_visibility, + &Public => *self, + } + } +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct StructField { + pub span: Span, + pub name: Name, + pub vis: Visibility, + pub id: NodeId, + pub ty: P, + pub attrs: HirVec, +} + +impl StructField { + // Still necessary in couple of places + pub fn is_positional(&self) -> bool { + let first = self.name.as_str().as_bytes()[0]; + first >= b'0' && first <= b'9' + } +} + +/// Fields and Ids of enum variants and structs +/// +/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all +/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants). +/// One shared Id can be successfully used for these two purposes. +/// Id of the whole enum lives in `Item`. +/// +/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually +/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of +/// the variant itself" from enum variants. +/// Id of the whole struct lives in `Item`. +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum VariantData { + Struct(HirVec, NodeId), + Tuple(HirVec, NodeId), + Unit(NodeId), +} + +impl VariantData { + pub fn fields(&self) -> &[StructField] { + match *self { + VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields, + _ => &[], + } + } + pub fn id(&self) -> NodeId { + match *self { + VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id, + } + } + pub fn is_struct(&self) -> bool { + if let VariantData::Struct(..) = *self { + true + } else { + false + } + } + pub fn is_tuple(&self) -> bool { + if let VariantData::Tuple(..) = *self { + true + } else { + false + } + } + pub fn is_unit(&self) -> bool { + if let VariantData::Unit(..) = *self { + true + } else { + false + } + } +} + +// The bodies for items are stored "out of line", in a separate +// hashmap in the `Crate`. Here we just record the node-id of the item +// so it can fetched later. +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ItemId { + pub id: NodeId, +} + +// FIXME (#3300): Should allow items to be anonymous. Right now +// we just use dummy names for anon items. +/// An item +/// +/// The name might be a dummy name in case of anonymous items +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct Item { + pub name: Name, + pub attrs: HirVec, + pub id: NodeId, + pub node: Item_, + pub vis: Visibility, + pub span: Span, +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Item_ { + /// An`extern crate` item, with optional original crate name, + /// + /// e.g. `extern crate foo` or `extern crate foo_bar as foo` + ItemExternCrate(Option), + /// A `use` or `pub use` item + ItemUse(P), + + /// A `static` item + ItemStatic(P, Mutability, P), + /// A `const` item + ItemConst(P, P), + /// A function declaration + ItemFn(P, Unsafety, Constness, Abi, Generics, P), + /// A module + ItemMod(Mod), + /// An external module + ItemForeignMod(ForeignMod), + /// A type alias, e.g. `type Foo = Bar` + ItemTy(P, Generics), + /// An enum definition, e.g. `enum Foo {C, D}` + ItemEnum(EnumDef, Generics), + /// A struct definition, e.g. `struct Foo {x: A}` + ItemStruct(VariantData, Generics), + /// Represents a Trait Declaration + ItemTrait(Unsafety, Generics, TyParamBounds, HirVec), + + // Default trait implementations + /// + /// `impl Trait for .. {}` + ItemDefaultImpl(Unsafety, TraitRef), + /// An implementation, eg `impl Trait for Foo { .. }` + ItemImpl(Unsafety, + ImplPolarity, + Generics, + Option, // (optional) trait this impl implements + P, // self + HirVec), +} + +impl Item_ { + pub fn descriptive_variant(&self) -> &str { + match *self { + ItemExternCrate(..) => "extern crate", + ItemUse(..) => "use", + ItemStatic(..) => "static item", + ItemConst(..) => "constant item", + ItemFn(..) => "function", + ItemMod(..) => "module", + ItemForeignMod(..) => "foreign module", + ItemTy(..) => "type alias", + ItemEnum(..) => "enum", + ItemStruct(..) => "struct", + ItemTrait(..) => "trait", + ItemImpl(..) | + ItemDefaultImpl(..) => "item", + } + } +} + +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub struct ForeignItem { + pub name: Name, + pub attrs: HirVec, + pub node: ForeignItem_, + pub id: NodeId, + pub span: Span, + pub vis: Visibility, +} + +/// An item within an `extern` block +#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum ForeignItem_ { + /// A foreign function + ForeignItemFn(P, Generics), + /// A foreign static item (`static ext: u8`), with optional mutability + /// (the boolean is true when mutable) + ForeignItemStatic(P, bool), +} + +impl ForeignItem_ { + pub fn descriptive_variant(&self) -> &str { + match *self { + ForeignItemFn(..) => "foreign function", + ForeignItemStatic(..) => "foreign static item", + } + } +} diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs new file mode 100644 index 00000000000..568986f39c5 --- /dev/null +++ b/src/librustc/hir/print.rs @@ -0,0 +1,2413 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub use self::AnnNode::*; + +use syntax::abi::Abi; +use syntax::ast; +use syntax::codemap::{self, CodeMap, BytePos, Spanned}; +use syntax::errors; +use syntax::parse::token::{self, BinOpToken}; +use syntax::parse::lexer::comments; +use syntax::parse; +use syntax::print::pp::{self, break_offset, word, space, hardbreak}; +use syntax::print::pp::{Breaks, eof}; +use syntax::print::pp::Breaks::{Consistent, Inconsistent}; +use syntax::print::pprust::{self as ast_pp, PrintState}; +use syntax::ptr::P; + +use hir; +use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; + +use std::io::{self, Write, Read}; + +pub enum AnnNode<'a> { + NodeName(&'a ast::Name), + NodeBlock(&'a hir::Block), + NodeItem(&'a hir::Item), + NodeSubItem(ast::NodeId), + NodeExpr(&'a hir::Expr), + NodePat(&'a hir::Pat), +} + +pub trait PpAnn { + fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { + Ok(()) + } + fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { + Ok(()) + } +} + +#[derive(Copy, Clone)] +pub struct NoAnn; + +impl PpAnn for NoAnn {} + + +pub struct State<'a> { + krate: Option<&'a Crate>, + pub s: pp::Printer<'a>, + cm: Option<&'a CodeMap>, + comments: Option>, + literals: Option>, + cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral, + boxes: Vec, + ann: &'a (PpAnn + 'a), +} + +impl<'a> PrintState<'a> for State<'a> { + fn writer(&mut self) -> &mut pp::Printer<'a> { + &mut self.s + } + + fn boxes(&mut self) -> &mut Vec { + &mut self.boxes + } + + fn comments(&mut self) -> &mut Option> { + &mut self.comments + } + + fn cur_cmnt_and_lit(&mut self) -> &mut ast_pp::CurrentCommentAndLiteral { + &mut self.cur_cmnt_and_lit + } + + fn literals(&self) -> &Option> { + &self.literals + } +} + +pub fn rust_printer<'a>(writer: Box, krate: Option<&'a Crate>) -> State<'a> { + static NO_ANN: NoAnn = NoAnn; + rust_printer_annotated(writer, &NO_ANN, krate) +} + +pub fn rust_printer_annotated<'a>(writer: Box, + ann: &'a PpAnn, + krate: Option<&'a Crate>) + -> State<'a> { + State { + krate: krate, + s: pp::mk_printer(writer, default_columns), + cm: None, + comments: None, + literals: None, + cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral { + cur_cmnt: 0, + cur_lit: 0, + }, + boxes: Vec::new(), + ann: ann, + } +} + +#[allow(non_upper_case_globals)] +pub const indent_unit: usize = 4; + +#[allow(non_upper_case_globals)] +pub const default_columns: usize = 78; + + +/// Requires you to pass an input filename and reader so that +/// it can scan the input text for comments and literals to +/// copy forward. +pub fn print_crate<'a>(cm: &'a CodeMap, + span_diagnostic: &errors::Handler, + krate: &hir::Crate, + filename: String, + input: &mut Read, + out: Box, + ann: &'a PpAnn, + is_expanded: bool) + -> io::Result<()> { + let mut s = State::new_from_input(cm, span_diagnostic, filename, input, + out, ann, is_expanded, Some(krate)); + + // When printing the AST, we sometimes need to inject `#[no_std]` here. + // Since you can't compile the HIR, it's not necessary. + + s.print_mod(&krate.module, &krate.attrs)?; + s.print_remaining_comments()?; + eof(&mut s.s) +} + +impl<'a> State<'a> { + pub fn new_from_input(cm: &'a CodeMap, + span_diagnostic: &errors::Handler, + filename: String, + input: &mut Read, + out: Box, + ann: &'a PpAnn, + is_expanded: bool, + krate: Option<&'a Crate>) + -> State<'a> { + let (cmnts, lits) = comments::gather_comments_and_literals(span_diagnostic, + filename, + input); + + State::new(cm, + out, + ann, + Some(cmnts), + // If the code is post expansion, don't use the table of + // literals, since it doesn't correspond with the literals + // in the AST anymore. + if is_expanded { + None + } else { + Some(lits) + }, + krate) + } + + pub fn new(cm: &'a CodeMap, + out: Box, + ann: &'a PpAnn, + comments: Option>, + literals: Option>, + krate: Option<&'a Crate>) + -> State<'a> { + State { + krate: krate, + s: pp::mk_printer(out, default_columns), + cm: Some(cm), + comments: comments.clone(), + literals: literals.clone(), + cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral { + cur_cmnt: 0, + cur_lit: 0, + }, + boxes: Vec::new(), + ann: ann, + } + } +} + +pub fn to_string(f: F) -> String + where F: FnOnce(&mut State) -> io::Result<()> +{ + let mut wr = Vec::new(); + { + let mut printer = rust_printer(Box::new(&mut wr), None); + f(&mut printer).unwrap(); + eof(&mut printer.s).unwrap(); + } + String::from_utf8(wr).unwrap() +} + +pub fn binop_to_string(op: BinOpToken) -> &'static str { + match op { + token::Plus => "+", + token::Minus => "-", + token::Star => "*", + token::Slash => "/", + token::Percent => "%", + token::Caret => "^", + token::And => "&", + token::Or => "|", + token::Shl => "<<", + token::Shr => ">>", + } +} + +pub fn ty_to_string(ty: &hir::Ty) -> String { + to_string(|s| s.print_type(ty)) +} + +pub fn bounds_to_string(bounds: &[hir::TyParamBound]) -> String { + to_string(|s| s.print_bounds("", bounds)) +} + +pub fn pat_to_string(pat: &hir::Pat) -> String { + to_string(|s| s.print_pat(pat)) +} + +pub fn arm_to_string(arm: &hir::Arm) -> String { + to_string(|s| s.print_arm(arm)) +} + +pub fn expr_to_string(e: &hir::Expr) -> String { + to_string(|s| s.print_expr(e)) +} + +pub fn lifetime_to_string(e: &hir::Lifetime) -> String { + to_string(|s| s.print_lifetime(e)) +} + +pub fn stmt_to_string(stmt: &hir::Stmt) -> String { + to_string(|s| s.print_stmt(stmt)) +} + +pub fn item_to_string(i: &hir::Item) -> String { + to_string(|s| s.print_item(i)) +} + +pub fn impl_item_to_string(i: &hir::ImplItem) -> String { + to_string(|s| s.print_impl_item(i)) +} + +pub fn trait_item_to_string(i: &hir::TraitItem) -> String { + to_string(|s| s.print_trait_item(i)) +} + +pub fn generics_to_string(generics: &hir::Generics) -> String { + to_string(|s| s.print_generics(generics)) +} + +pub fn where_clause_to_string(i: &hir::WhereClause) -> String { + to_string(|s| s.print_where_clause(i)) +} + +pub fn fn_block_to_string(p: &hir::FnDecl) -> String { + to_string(|s| s.print_fn_block_args(p)) +} + +pub fn path_to_string(p: &hir::Path) -> String { + to_string(|s| s.print_path(p, false, 0)) +} + +pub fn name_to_string(name: ast::Name) -> String { + to_string(|s| s.print_name(name)) +} + +pub fn fun_to_string(decl: &hir::FnDecl, + unsafety: hir::Unsafety, + constness: hir::Constness, + name: ast::Name, + opt_explicit_self: Option<&hir::ExplicitSelf_>, + generics: &hir::Generics) + -> String { + to_string(|s| { + s.head("")?; + s.print_fn(decl, + unsafety, + constness, + Abi::Rust, + Some(name), + generics, + opt_explicit_self, + hir::Inherited)?; + s.end()?; // Close the head box + s.end() // Close the outer box + }) +} + +pub fn block_to_string(blk: &hir::Block) -> String { + to_string(|s| { + // containing cbox, will be closed by print-block at } + s.cbox(indent_unit)?; + // head-ibox, will be closed by print-block after { + s.ibox(0)?; + s.print_block(blk) + }) +} + +pub fn explicit_self_to_string(explicit_self: &hir::ExplicitSelf_) -> String { + to_string(|s| s.print_explicit_self(explicit_self, hir::MutImmutable).map(|_| {})) +} + +pub fn variant_to_string(var: &hir::Variant) -> String { + to_string(|s| s.print_variant(var)) +} + +pub fn arg_to_string(arg: &hir::Arg) -> String { + to_string(|s| s.print_arg(arg, false)) +} + +pub fn visibility_qualified(vis: hir::Visibility, s: &str) -> String { + match vis { + hir::Public => format!("pub {}", s), + hir::Inherited => s.to_string(), + } +} + +fn needs_parentheses(expr: &hir::Expr) -> bool { + match expr.node { + hir::ExprAssign(..) | + hir::ExprBinary(..) | + hir::ExprClosure(..) | + hir::ExprAssignOp(..) | + hir::ExprCast(..) | + hir::ExprType(..) => true, + _ => false, + } +} + +impl<'a> State<'a> { + pub fn cbox(&mut self, u: usize) -> io::Result<()> { + self.boxes.push(pp::Breaks::Consistent); + pp::cbox(&mut self.s, u) + } + + pub fn nbsp(&mut self) -> io::Result<()> { + word(&mut self.s, " ") + } + + pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { + word(&mut self.s, w)?; + self.nbsp() + } + + pub fn head(&mut self, w: &str) -> io::Result<()> { + // outer-box is consistent + self.cbox(indent_unit)?; + // head-box is inconsistent + self.ibox(w.len() + 1)?; + // keyword that starts the head + if !w.is_empty() { + self.word_nbsp(w)?; + } + Ok(()) + } + + pub fn bopen(&mut self) -> io::Result<()> { + word(&mut self.s, "{")?; + self.end() // close the head-box + } + + pub fn bclose_(&mut self, span: codemap::Span, indented: usize) -> io::Result<()> { + self.bclose_maybe_open(span, indented, true) + } + pub fn bclose_maybe_open(&mut self, + span: codemap::Span, + indented: usize, + close_box: bool) + -> io::Result<()> { + self.maybe_print_comment(span.hi)?; + self.break_offset_if_not_bol(1, -(indented as isize))?; + word(&mut self.s, "}")?; + if close_box { + self.end()?; // close the outer-box + } + Ok(()) + } + pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> { + self.bclose_(span, indent_unit) + } + + pub fn in_cbox(&self) -> bool { + match self.boxes.last() { + Some(&last_box) => last_box == pp::Breaks::Consistent, + None => false, + } + } + pub fn space_if_not_bol(&mut self) -> io::Result<()> { + if !self.is_bol() { + space(&mut self.s)?; + } + Ok(()) + } + pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> { + if !self.is_bol() { + break_offset(&mut self.s, n, off) + } else { + if off != 0 && self.s.last_token().is_hardbreak_tok() { + // We do something pretty sketchy here: tuck the nonzero + // offset-adjustment we were going to deposit along with the + // break into the previous hardbreak. + self.s.replace_last_token(pp::hardbreak_tok_offset(off)); + } + Ok(()) + } + } + + // Synthesizes a comment that was not textually present in the original source + // file. + pub fn synth_comment(&mut self, text: String) -> io::Result<()> { + word(&mut self.s, "/*")?; + space(&mut self.s)?; + word(&mut self.s, &text[..])?; + space(&mut self.s)?; + word(&mut self.s, "*/") + } + + + pub fn commasep_cmnt(&mut self, + b: Breaks, + elts: &[T], + mut op: F, + mut get_span: G) + -> io::Result<()> + where F: FnMut(&mut State, &T) -> io::Result<()>, + G: FnMut(&T) -> codemap::Span + { + self.rbox(0, b)?; + let len = elts.len(); + let mut i = 0; + for elt in elts { + self.maybe_print_comment(get_span(elt).hi)?; + op(self, elt)?; + i += 1; + if i < len { + word(&mut self.s, ",")?; + self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi))?; + self.space_if_not_bol()?; + } + } + self.end() + } + + pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P]) -> io::Result<()> { + self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span) + } + + pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { + self.print_inner_attributes(attrs)?; + for item_id in &_mod.item_ids { + self.print_item_id(item_id)?; + } + Ok(()) + } + + pub fn print_foreign_mod(&mut self, + nmod: &hir::ForeignMod, + attrs: &[ast::Attribute]) + -> io::Result<()> { + self.print_inner_attributes(attrs)?; + for item in &nmod.items { + self.print_foreign_item(item)?; + } + Ok(()) + } + + pub fn print_opt_lifetime(&mut self, lifetime: &Option) -> io::Result<()> { + if let Some(l) = *lifetime { + self.print_lifetime(&l)?; + self.nbsp()?; + } + Ok(()) + } + + pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> { + self.maybe_print_comment(ty.span.lo)?; + self.ibox(0)?; + match ty.node { + hir::TyVec(ref ty) => { + word(&mut self.s, "[")?; + self.print_type(&ty)?; + word(&mut self.s, "]")?; + } + hir::TyPtr(ref mt) => { + word(&mut self.s, "*")?; + match mt.mutbl { + hir::MutMutable => self.word_nbsp("mut")?, + hir::MutImmutable => self.word_nbsp("const")?, + } + self.print_type(&mt.ty)?; + } + hir::TyRptr(ref lifetime, ref mt) => { + word(&mut self.s, "&")?; + self.print_opt_lifetime(lifetime)?; + self.print_mt(mt)?; + } + hir::TyTup(ref elts) => { + self.popen()?; + self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?; + if elts.len() == 1 { + word(&mut self.s, ",")?; + } + self.pclose()?; + } + hir::TyBareFn(ref f) => { + let generics = hir::Generics { + lifetimes: f.lifetimes.clone(), + ty_params: hir::HirVec::new(), + where_clause: hir::WhereClause { + id: ast::DUMMY_NODE_ID, + predicates: hir::HirVec::new(), + }, + }; + self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics, None)?; + } + hir::TyPath(None, ref path) => { + self.print_path(path, false, 0)?; + } + hir::TyPath(Some(ref qself), ref path) => { + self.print_qpath(path, qself, false)? + } + hir::TyObjectSum(ref ty, ref bounds) => { + self.print_type(&ty)?; + self.print_bounds("+", &bounds[..])?; + } + hir::TyPolyTraitRef(ref bounds) => { + self.print_bounds("", &bounds[..])?; + } + hir::TyFixedLengthVec(ref ty, ref v) => { + word(&mut self.s, "[")?; + self.print_type(&ty)?; + word(&mut self.s, "; ")?; + self.print_expr(&v)?; + word(&mut self.s, "]")?; + } + hir::TyTypeof(ref e) => { + word(&mut self.s, "typeof(")?; + self.print_expr(&e)?; + word(&mut self.s, ")")?; + } + hir::TyInfer => { + word(&mut self.s, "_")?; + } + } + self.end() + } + + pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> { + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(item.span.lo)?; + self.print_outer_attributes(&item.attrs)?; + match item.node { + hir::ForeignItemFn(ref decl, ref generics) => { + self.head("")?; + self.print_fn(decl, + hir::Unsafety::Normal, + hir::Constness::NotConst, + Abi::Rust, + Some(item.name), + generics, + None, + item.vis)?; + self.end()?; // end head-ibox + word(&mut self.s, ";")?; + self.end() // end the outer fn box + } + hir::ForeignItemStatic(ref t, m) => { + self.head(&visibility_qualified(item.vis, "static"))?; + if m { + self.word_space("mut")?; + } + self.print_name(item.name)?; + self.word_space(":")?; + self.print_type(&t)?; + word(&mut self.s, ";")?; + self.end()?; // end the head-ibox + self.end() // end the outer cbox + } + } + } + + fn print_associated_const(&mut self, + name: ast::Name, + ty: &hir::Ty, + default: Option<&hir::Expr>, + vis: hir::Visibility) + -> io::Result<()> { + word(&mut self.s, &visibility_qualified(vis, ""))?; + self.word_space("const")?; + self.print_name(name)?; + self.word_space(":")?; + self.print_type(ty)?; + if let Some(expr) = default { + space(&mut self.s)?; + self.word_space("=")?; + self.print_expr(expr)?; + } + word(&mut self.s, ";") + } + + fn print_associated_type(&mut self, + name: ast::Name, + bounds: Option<&hir::TyParamBounds>, + ty: Option<&hir::Ty>) + -> io::Result<()> { + self.word_space("type")?; + self.print_name(name)?; + if let Some(bounds) = bounds { + self.print_bounds(":", bounds)?; + } + if let Some(ty) = ty { + space(&mut self.s)?; + self.word_space("=")?; + self.print_type(ty)?; + } + word(&mut self.s, ";") + } + + pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> { + if let Some(krate) = self.krate { + // skip nested items if krate context was not provided + let item = &krate.items[&item_id.id]; + self.print_item(item) + } else { + Ok(()) + } + } + + /// Pretty-print an item + pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(item.span.lo)?; + self.print_outer_attributes(&item.attrs)?; + self.ann.pre(self, NodeItem(item))?; + match item.node { + hir::ItemExternCrate(ref optional_path) => { + self.head(&visibility_qualified(item.vis, "extern crate"))?; + if let Some(p) = *optional_path { + let val = p.as_str(); + if val.contains("-") { + self.print_string(&val, ast::StrStyle::Cooked)?; + } else { + self.print_name(p)?; + } + space(&mut self.s)?; + word(&mut self.s, "as")?; + space(&mut self.s)?; + } + self.print_name(item.name)?; + word(&mut self.s, ";")?; + self.end()?; // end inner head-block + self.end()?; // end outer head-block + } + hir::ItemUse(ref vp) => { + self.head(&visibility_qualified(item.vis, "use"))?; + self.print_view_path(&vp)?; + word(&mut self.s, ";")?; + self.end()?; // end inner head-block + self.end()?; // end outer head-block + } + hir::ItemStatic(ref ty, m, ref expr) => { + self.head(&visibility_qualified(item.vis, "static"))?; + if m == hir::MutMutable { + self.word_space("mut")?; + } + self.print_name(item.name)?; + self.word_space(":")?; + self.print_type(&ty)?; + space(&mut self.s)?; + self.end()?; // end the head-ibox + + self.word_space("=")?; + self.print_expr(&expr)?; + word(&mut self.s, ";")?; + self.end()?; // end the outer cbox + } + hir::ItemConst(ref ty, ref expr) => { + self.head(&visibility_qualified(item.vis, "const"))?; + self.print_name(item.name)?; + self.word_space(":")?; + self.print_type(&ty)?; + space(&mut self.s)?; + self.end()?; // end the head-ibox + + self.word_space("=")?; + self.print_expr(&expr)?; + word(&mut self.s, ";")?; + self.end()?; // end the outer cbox + } + hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => { + self.head("")?; + self.print_fn(decl, + unsafety, + constness, + abi, + Some(item.name), + typarams, + None, + item.vis)?; + word(&mut self.s, " ")?; + self.print_block_with_attrs(&body, &item.attrs)?; + } + hir::ItemMod(ref _mod) => { + self.head(&visibility_qualified(item.vis, "mod"))?; + self.print_name(item.name)?; + self.nbsp()?; + self.bopen()?; + self.print_mod(_mod, &item.attrs)?; + self.bclose(item.span)?; + } + hir::ItemForeignMod(ref nmod) => { + self.head("extern")?; + self.word_nbsp(&nmod.abi.to_string())?; + self.bopen()?; + self.print_foreign_mod(nmod, &item.attrs)?; + self.bclose(item.span)?; + } + hir::ItemTy(ref ty, ref params) => { + self.ibox(indent_unit)?; + self.ibox(0)?; + self.word_nbsp(&visibility_qualified(item.vis, "type"))?; + self.print_name(item.name)?; + self.print_generics(params)?; + self.end()?; // end the inner ibox + + self.print_where_clause(¶ms.where_clause)?; + space(&mut self.s)?; + self.word_space("=")?; + self.print_type(&ty)?; + word(&mut self.s, ";")?; + self.end()?; // end the outer ibox + } + hir::ItemEnum(ref enum_definition, ref params) => { + self.print_enum_def(enum_definition, params, item.name, item.span, item.vis)?; + } + hir::ItemStruct(ref struct_def, ref generics) => { + self.head(&visibility_qualified(item.vis, "struct"))?; + self.print_struct(struct_def, generics, item.name, item.span, true)?; + } + + hir::ItemDefaultImpl(unsafety, ref trait_ref) => { + self.head("")?; + self.print_visibility(item.vis)?; + self.print_unsafety(unsafety)?; + self.word_nbsp("impl")?; + self.print_trait_ref(trait_ref)?; + space(&mut self.s)?; + self.word_space("for")?; + self.word_space("..")?; + self.bopen()?; + self.bclose(item.span)?; + } + hir::ItemImpl(unsafety, + polarity, + ref generics, + ref opt_trait, + ref ty, + ref impl_items) => { + self.head("")?; + self.print_visibility(item.vis)?; + self.print_unsafety(unsafety)?; + self.word_nbsp("impl")?; + + if generics.is_parameterized() { + self.print_generics(generics)?; + space(&mut self.s)?; + } + + match polarity { + hir::ImplPolarity::Negative => { + word(&mut self.s, "!")?; + } + _ => {} + } + + match opt_trait { + &Some(ref t) => { + self.print_trait_ref(t)?; + space(&mut self.s)?; + self.word_space("for")?; + } + &None => {} + } + + self.print_type(&ty)?; + self.print_where_clause(&generics.where_clause)?; + + space(&mut self.s)?; + self.bopen()?; + self.print_inner_attributes(&item.attrs)?; + for impl_item in impl_items { + self.print_impl_item(impl_item)?; + } + self.bclose(item.span)?; + } + hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => { + self.head("")?; + self.print_visibility(item.vis)?; + self.print_unsafety(unsafety)?; + self.word_nbsp("trait")?; + self.print_name(item.name)?; + self.print_generics(generics)?; + let mut real_bounds = Vec::with_capacity(bounds.len()); + for b in bounds.iter() { + if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b { + space(&mut self.s)?; + self.word_space("for ?")?; + self.print_trait_ref(&ptr.trait_ref)?; + } else { + real_bounds.push(b.clone()); + } + } + self.print_bounds(":", &real_bounds[..])?; + self.print_where_clause(&generics.where_clause)?; + word(&mut self.s, " ")?; + self.bopen()?; + for trait_item in trait_items { + self.print_trait_item(trait_item)?; + } + self.bclose(item.span)?; + } + } + self.ann.post(self, NodeItem(item)) + } + + fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> { + self.print_path(&t.path, false, 0) + } + + fn print_formal_lifetime_list(&mut self, lifetimes: &[hir::LifetimeDef]) -> io::Result<()> { + if !lifetimes.is_empty() { + word(&mut self.s, "for<")?; + let mut comma = false; + for lifetime_def in lifetimes { + if comma { + self.word_space(",")? + } + self.print_lifetime_def(lifetime_def)?; + comma = true; + } + word(&mut self.s, ">")?; + } + Ok(()) + } + + fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> { + self.print_formal_lifetime_list(&t.bound_lifetimes)?; + self.print_trait_ref(&t.trait_ref) + } + + pub fn print_enum_def(&mut self, + enum_definition: &hir::EnumDef, + generics: &hir::Generics, + name: ast::Name, + span: codemap::Span, + visibility: hir::Visibility) + -> io::Result<()> { + self.head(&visibility_qualified(visibility, "enum"))?; + self.print_name(name)?; + self.print_generics(generics)?; + self.print_where_clause(&generics.where_clause)?; + space(&mut self.s)?; + self.print_variants(&enum_definition.variants, span) + } + + pub fn print_variants(&mut self, + variants: &[hir::Variant], + span: codemap::Span) + -> io::Result<()> { + self.bopen()?; + for v in variants { + self.space_if_not_bol()?; + self.maybe_print_comment(v.span.lo)?; + self.print_outer_attributes(&v.node.attrs)?; + self.ibox(indent_unit)?; + self.print_variant(v)?; + word(&mut self.s, ",")?; + self.end()?; + self.maybe_print_trailing_comment(v.span, None)?; + } + self.bclose(span) + } + + pub fn print_visibility(&mut self, vis: hir::Visibility) -> io::Result<()> { + match vis { + hir::Public => self.word_nbsp("pub"), + hir::Inherited => Ok(()), + } + } + + pub fn print_struct(&mut self, + struct_def: &hir::VariantData, + generics: &hir::Generics, + name: ast::Name, + span: codemap::Span, + print_finalizer: bool) + -> io::Result<()> { + self.print_name(name)?; + self.print_generics(generics)?; + if !struct_def.is_struct() { + if struct_def.is_tuple() { + self.popen()?; + self.commasep(Inconsistent, struct_def.fields(), |s, field| { + s.print_visibility(field.vis)?; + s.maybe_print_comment(field.span.lo)?; + s.print_type(&field.ty) + })?; + self.pclose()?; + } + self.print_where_clause(&generics.where_clause)?; + if print_finalizer { + word(&mut self.s, ";")?; + } + self.end()?; + self.end() // close the outer-box + } else { + self.print_where_clause(&generics.where_clause)?; + self.nbsp()?; + self.bopen()?; + self.hardbreak_if_not_bol()?; + + for field in struct_def.fields() { + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(field.span.lo)?; + self.print_outer_attributes(&field.attrs)?; + self.print_visibility(field.vis)?; + self.print_name(field.name)?; + self.word_nbsp(":")?; + self.print_type(&field.ty)?; + word(&mut self.s, ",")?; + } + + self.bclose(span) + } + } + + pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> { + self.head("")?; + let generics = hir::util::empty_generics(); + self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; + match v.node.disr_expr { + Some(ref d) => { + space(&mut self.s)?; + self.word_space("=")?; + self.print_expr(&d) + } + _ => Ok(()), + } + } + pub fn print_method_sig(&mut self, + name: ast::Name, + m: &hir::MethodSig, + vis: hir::Visibility) + -> io::Result<()> { + self.print_fn(&m.decl, + m.unsafety, + m.constness, + m.abi, + Some(name), + &m.generics, + Some(&m.explicit_self.node), + vis) + } + + pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> { + self.ann.pre(self, NodeSubItem(ti.id))?; + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(ti.span.lo)?; + self.print_outer_attributes(&ti.attrs)?; + match ti.node { + hir::ConstTraitItem(ref ty, ref default) => { + self.print_associated_const(ti.name, + &ty, + default.as_ref().map(|expr| &**expr), + hir::Inherited)?; + } + hir::MethodTraitItem(ref sig, ref body) => { + if body.is_some() { + self.head("")?; + } + self.print_method_sig(ti.name, sig, hir::Inherited)?; + if let Some(ref body) = *body { + self.nbsp()?; + self.print_block_with_attrs(body, &ti.attrs)?; + } else { + word(&mut self.s, ";")?; + } + } + hir::TypeTraitItem(ref bounds, ref default) => { + self.print_associated_type(ti.name, + Some(bounds), + default.as_ref().map(|ty| &**ty))?; + } + } + self.ann.post(self, NodeSubItem(ti.id)) + } + + pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> { + self.ann.pre(self, NodeSubItem(ii.id))?; + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(ii.span.lo)?; + self.print_outer_attributes(&ii.attrs)?; + + if let hir::Defaultness::Default = ii.defaultness { + self.word_nbsp("default")?; + } + + match ii.node { + hir::ImplItemKind::Const(ref ty, ref expr) => { + self.print_associated_const(ii.name, &ty, Some(&expr), ii.vis)?; + } + hir::ImplItemKind::Method(ref sig, ref body) => { + self.head("")?; + self.print_method_sig(ii.name, sig, ii.vis)?; + self.nbsp()?; + self.print_block_with_attrs(body, &ii.attrs)?; + } + hir::ImplItemKind::Type(ref ty) => { + self.print_associated_type(ii.name, None, Some(ty))?; + } + } + self.ann.post(self, NodeSubItem(ii.id)) + } + + pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> { + self.maybe_print_comment(st.span.lo)?; + match st.node { + hir::StmtDecl(ref decl, _) => { + self.print_decl(&decl)?; + } + hir::StmtExpr(ref expr, _) => { + self.space_if_not_bol()?; + self.print_expr(&expr)?; + } + hir::StmtSemi(ref expr, _) => { + self.space_if_not_bol()?; + self.print_expr(&expr)?; + word(&mut self.s, ";")?; + } + } + if stmt_ends_with_semi(&st.node) { + word(&mut self.s, ";")?; + } + self.maybe_print_trailing_comment(st.span, None) + } + + pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> { + self.print_block_with_attrs(blk, &[]) + } + + pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> { + self.print_block_unclosed_indent(blk, indent_unit) + } + + pub fn print_block_unclosed_indent(&mut self, + blk: &hir::Block, + indented: usize) + -> io::Result<()> { + self.print_block_maybe_unclosed(blk, indented, &[], false) + } + + pub fn print_block_with_attrs(&mut self, + blk: &hir::Block, + attrs: &[ast::Attribute]) + -> io::Result<()> { + self.print_block_maybe_unclosed(blk, indent_unit, attrs, true) + } + + pub fn print_block_maybe_unclosed(&mut self, + blk: &hir::Block, + indented: usize, + attrs: &[ast::Attribute], + close_box: bool) + -> io::Result<()> { + match blk.rules { + hir::UnsafeBlock(..) => self.word_space("unsafe")?, + hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?, + hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?, + hir::PushUnstableBlock => self.word_space("push_unstable")?, + hir::PopUnstableBlock => self.word_space("pop_unstable")?, + hir::DefaultBlock => (), + } + self.maybe_print_comment(blk.span.lo)?; + self.ann.pre(self, NodeBlock(blk))?; + self.bopen()?; + + self.print_inner_attributes(attrs)?; + + for st in &blk.stmts { + self.print_stmt(st)?; + } + match blk.expr { + Some(ref expr) => { + self.space_if_not_bol()?; + self.print_expr(&expr)?; + self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?; + } + _ => (), + } + self.bclose_maybe_open(blk.span, indented, close_box)?; + self.ann.post(self, NodeBlock(blk)) + } + + fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> { + match els { + Some(_else) => { + match _else.node { + // "another else-if" + hir::ExprIf(ref i, ref then, ref e) => { + self.cbox(indent_unit - 1)?; + self.ibox(0)?; + word(&mut self.s, " else if ")?; + self.print_expr(&i)?; + space(&mut self.s)?; + self.print_block(&then)?; + self.print_else(e.as_ref().map(|e| &**e)) + } + // "final else" + hir::ExprBlock(ref b) => { + self.cbox(indent_unit - 1)?; + self.ibox(0)?; + word(&mut self.s, " else ")?; + self.print_block(&b) + } + // BLEAH, constraints would be great here + _ => { + panic!("print_if saw if with weird alternative"); + } + } + } + _ => Ok(()), + } + } + + pub fn print_if(&mut self, + test: &hir::Expr, + blk: &hir::Block, + elseopt: Option<&hir::Expr>) + -> io::Result<()> { + self.head("if")?; + self.print_expr(test)?; + space(&mut self.s)?; + self.print_block(blk)?; + self.print_else(elseopt) + } + + pub fn print_if_let(&mut self, + pat: &hir::Pat, + expr: &hir::Expr, + blk: &hir::Block, + elseopt: Option<&hir::Expr>) + -> io::Result<()> { + self.head("if let")?; + self.print_pat(pat)?; + space(&mut self.s)?; + self.word_space("=")?; + self.print_expr(expr)?; + space(&mut self.s)?; + self.print_block(blk)?; + self.print_else(elseopt) + } + + + fn print_call_post(&mut self, args: &[P]) -> io::Result<()> { + self.popen()?; + self.commasep_exprs(Inconsistent, args)?; + self.pclose() + } + + pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr) -> io::Result<()> { + let needs_par = needs_parentheses(expr); + if needs_par { + self.popen()?; + } + self.print_expr(expr)?; + if needs_par { + self.pclose()?; + } + Ok(()) + } + + fn print_expr_vec(&mut self, exprs: &[P]) -> io::Result<()> { + self.ibox(indent_unit)?; + word(&mut self.s, "[")?; + self.commasep_exprs(Inconsistent, &exprs[..])?; + word(&mut self.s, "]")?; + self.end() + } + + fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::Expr) -> io::Result<()> { + self.ibox(indent_unit)?; + word(&mut self.s, "[")?; + self.print_expr(element)?; + self.word_space(";")?; + self.print_expr(count)?; + word(&mut self.s, "]")?; + self.end() + } + + fn print_expr_struct(&mut self, + path: &hir::Path, + fields: &[hir::Field], + wth: &Option>) + -> io::Result<()> { + self.print_path(path, true, 0)?; + word(&mut self.s, "{")?; + self.commasep_cmnt(Consistent, + &fields[..], + |s, field| { + s.ibox(indent_unit)?; + s.print_name(field.name.node)?; + s.word_space(":")?; + s.print_expr(&field.expr)?; + s.end() + }, + |f| f.span)?; + match *wth { + Some(ref expr) => { + self.ibox(indent_unit)?; + if !fields.is_empty() { + word(&mut self.s, ",")?; + space(&mut self.s)?; + } + word(&mut self.s, "..")?; + self.print_expr(&expr)?; + self.end()?; + } + _ => if !fields.is_empty() { + word(&mut self.s, ",")? + }, + } + word(&mut self.s, "}")?; + Ok(()) + } + + fn print_expr_tup(&mut self, exprs: &[P]) -> io::Result<()> { + self.popen()?; + self.commasep_exprs(Inconsistent, &exprs[..])?; + if exprs.len() == 1 { + word(&mut self.s, ",")?; + } + self.pclose() + } + + fn print_expr_call(&mut self, func: &hir::Expr, args: &[P]) -> io::Result<()> { + self.print_expr_maybe_paren(func)?; + self.print_call_post(args) + } + + fn print_expr_method_call(&mut self, + name: Spanned, + tys: &[P], + args: &[P]) + -> io::Result<()> { + let base_args = &args[1..]; + self.print_expr(&args[0])?; + word(&mut self.s, ".")?; + self.print_name(name.node)?; + if !tys.is_empty() { + word(&mut self.s, "::<")?; + self.commasep(Inconsistent, tys, |s, ty| s.print_type(&ty))?; + word(&mut self.s, ">")?; + } + self.print_call_post(base_args) + } + + fn print_expr_binary(&mut self, + op: hir::BinOp, + lhs: &hir::Expr, + rhs: &hir::Expr) + -> io::Result<()> { + self.print_expr(lhs)?; + space(&mut self.s)?; + self.word_space(hir::util::binop_to_string(op.node))?; + self.print_expr(rhs) + } + + fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> { + word(&mut self.s, hir::util::unop_to_string(op))?; + self.print_expr_maybe_paren(expr) + } + + fn print_expr_addr_of(&mut self, + mutability: hir::Mutability, + expr: &hir::Expr) + -> io::Result<()> { + word(&mut self.s, "&")?; + self.print_mutability(mutability)?; + self.print_expr_maybe_paren(expr) + } + + pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> { + self.maybe_print_comment(expr.span.lo)?; + self.ibox(indent_unit)?; + self.ann.pre(self, NodeExpr(expr))?; + match expr.node { + hir::ExprBox(ref expr) => { + self.word_space("box")?; + self.print_expr(expr)?; + } + hir::ExprVec(ref exprs) => { + self.print_expr_vec(&exprs[..])?; + } + hir::ExprRepeat(ref element, ref count) => { + self.print_expr_repeat(&element, &count)?; + } + hir::ExprStruct(ref path, ref fields, ref wth) => { + self.print_expr_struct(path, &fields[..], wth)?; + } + hir::ExprTup(ref exprs) => { + self.print_expr_tup(&exprs[..])?; + } + hir::ExprCall(ref func, ref args) => { + self.print_expr_call(&func, &args[..])?; + } + hir::ExprMethodCall(name, ref tys, ref args) => { + self.print_expr_method_call(name, &tys[..], &args[..])?; + } + hir::ExprBinary(op, ref lhs, ref rhs) => { + self.print_expr_binary(op, &lhs, &rhs)?; + } + hir::ExprUnary(op, ref expr) => { + self.print_expr_unary(op, &expr)?; + } + hir::ExprAddrOf(m, ref expr) => { + self.print_expr_addr_of(m, &expr)?; + } + hir::ExprLit(ref lit) => { + self.print_literal(&lit)?; + } + hir::ExprCast(ref expr, ref ty) => { + self.print_expr(&expr)?; + space(&mut self.s)?; + self.word_space("as")?; + self.print_type(&ty)?; + } + hir::ExprType(ref expr, ref ty) => { + self.print_expr(&expr)?; + self.word_space(":")?; + self.print_type(&ty)?; + } + hir::ExprIf(ref test, ref blk, ref elseopt) => { + self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; + } + hir::ExprWhile(ref test, ref blk, opt_ident) => { + if let Some(ident) = opt_ident { + self.print_name(ident.name)?; + self.word_space(":")?; + } + self.head("while")?; + self.print_expr(&test)?; + space(&mut self.s)?; + self.print_block(&blk)?; + } + hir::ExprLoop(ref blk, opt_ident) => { + if let Some(ident) = opt_ident { + self.print_name(ident.name)?; + self.word_space(":")?; + } + self.head("loop")?; + space(&mut self.s)?; + self.print_block(&blk)?; + } + hir::ExprMatch(ref expr, ref arms, _) => { + self.cbox(indent_unit)?; + self.ibox(4)?; + self.word_nbsp("match")?; + self.print_expr(&expr)?; + space(&mut self.s)?; + self.bopen()?; + for arm in arms { + self.print_arm(arm)?; + } + self.bclose_(expr.span, indent_unit)?; + } + hir::ExprClosure(capture_clause, ref decl, ref body) => { + self.print_capture_clause(capture_clause)?; + + self.print_fn_block_args(&decl)?; + space(&mut self.s)?; + + let default_return = match decl.output { + hir::DefaultReturn(..) => true, + _ => false, + }; + + if !default_return || !body.stmts.is_empty() || body.expr.is_none() { + self.print_block_unclosed(&body)?; + } else { + // we extract the block, so as not to create another set of boxes + match body.expr.as_ref().unwrap().node { + hir::ExprBlock(ref blk) => { + self.print_block_unclosed(&blk)?; + } + _ => { + // this is a bare expression + self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap())?; + self.end()?; // need to close a box + } + } + } + // a box will be closed by print_expr, but we didn't want an overall + // wrapper so we closed the corresponding opening. so create an + // empty box to satisfy the close. + self.ibox(0)?; + } + hir::ExprBlock(ref blk) => { + // containing cbox, will be closed by print-block at } + self.cbox(indent_unit)?; + // head-box, will be closed by print-block after { + self.ibox(0)?; + self.print_block(&blk)?; + } + hir::ExprAssign(ref lhs, ref rhs) => { + self.print_expr(&lhs)?; + space(&mut self.s)?; + self.word_space("=")?; + self.print_expr(&rhs)?; + } + hir::ExprAssignOp(op, ref lhs, ref rhs) => { + self.print_expr(&lhs)?; + space(&mut self.s)?; + word(&mut self.s, hir::util::binop_to_string(op.node))?; + self.word_space("=")?; + self.print_expr(&rhs)?; + } + hir::ExprField(ref expr, name) => { + self.print_expr(&expr)?; + word(&mut self.s, ".")?; + self.print_name(name.node)?; + } + hir::ExprTupField(ref expr, id) => { + self.print_expr(&expr)?; + word(&mut self.s, ".")?; + self.print_usize(id.node)?; + } + hir::ExprIndex(ref expr, ref index) => { + self.print_expr(&expr)?; + word(&mut self.s, "[")?; + self.print_expr(&index)?; + word(&mut self.s, "]")?; + } + hir::ExprPath(None, ref path) => { + self.print_path(path, true, 0)? + } + hir::ExprPath(Some(ref qself), ref path) => { + self.print_qpath(path, qself, true)? + } + hir::ExprBreak(opt_ident) => { + word(&mut self.s, "break")?; + space(&mut self.s)?; + if let Some(ident) = opt_ident { + self.print_name(ident.node.name)?; + space(&mut self.s)?; + } + } + hir::ExprAgain(opt_ident) => { + word(&mut self.s, "continue")?; + space(&mut self.s)?; + if let Some(ident) = opt_ident { + self.print_name(ident.node.name)?; + space(&mut self.s)? + } + } + hir::ExprRet(ref result) => { + word(&mut self.s, "return")?; + match *result { + Some(ref expr) => { + word(&mut self.s, " ")?; + self.print_expr(&expr)?; + } + _ => (), + } + } + hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => { + word(&mut self.s, "asm!")?; + self.popen()?; + self.print_string(&a.asm, a.asm_str_style)?; + self.word_space(":")?; + + let mut out_idx = 0; + self.commasep(Inconsistent, &a.outputs, |s, out| { + match out.constraint.slice_shift_char() { + Some(('=', operand)) if out.is_rw => { + s.print_string(&format!("+{}", operand), ast::StrStyle::Cooked)? + } + _ => s.print_string(&out.constraint, ast::StrStyle::Cooked)?, + } + s.popen()?; + s.print_expr(&outputs[out_idx])?; + s.pclose()?; + out_idx += 1; + Ok(()) + })?; + space(&mut self.s)?; + self.word_space(":")?; + + let mut in_idx = 0; + self.commasep(Inconsistent, &a.inputs, |s, co| { + s.print_string(&co, ast::StrStyle::Cooked)?; + s.popen()?; + s.print_expr(&inputs[in_idx])?; + s.pclose()?; + in_idx += 1; + Ok(()) + })?; + space(&mut self.s)?; + self.word_space(":")?; + + self.commasep(Inconsistent, &a.clobbers, |s, co| { + s.print_string(&co, ast::StrStyle::Cooked)?; + Ok(()) + })?; + + let mut options = vec![]; + if a.volatile { + options.push("volatile"); + } + if a.alignstack { + options.push("alignstack"); + } + if a.dialect == ast::AsmDialect::Intel { + options.push("intel"); + } + + if !options.is_empty() { + space(&mut self.s)?; + self.word_space(":")?; + self.commasep(Inconsistent, &options, |s, &co| { + s.print_string(co, ast::StrStyle::Cooked)?; + Ok(()) + })?; + } + + self.pclose()?; + } + } + self.ann.post(self, NodeExpr(expr))?; + self.end() + } + + pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> { + self.print_pat(&loc.pat)?; + if let Some(ref ty) = loc.ty { + self.word_space(":")?; + self.print_type(&ty)?; + } + Ok(()) + } + + pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> { + self.maybe_print_comment(decl.span.lo)?; + match decl.node { + hir::DeclLocal(ref loc) => { + self.space_if_not_bol()?; + self.ibox(indent_unit)?; + self.word_nbsp("let")?; + + self.ibox(indent_unit)?; + self.print_local_decl(&loc)?; + self.end()?; + if let Some(ref init) = loc.init { + self.nbsp()?; + self.word_space("=")?; + self.print_expr(&init)?; + } + self.end() + } + hir::DeclItem(ref item) => { + self.print_item_id(item) + } + } + } + + pub fn print_usize(&mut self, i: usize) -> io::Result<()> { + word(&mut self.s, &i.to_string()) + } + + pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { + word(&mut self.s, &name.as_str())?; + self.ann.post(self, NodeName(&name)) + } + + pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> { + self.print_local_decl(loc)?; + space(&mut self.s)?; + self.word_space("in")?; + self.print_expr(coll) + } + + fn print_path(&mut self, + path: &hir::Path, + colons_before_params: bool, + depth: usize) + -> io::Result<()> { + self.maybe_print_comment(path.span.lo)?; + + let mut first = !path.global; + for segment in &path.segments[..path.segments.len() - depth] { + if first { + first = false + } else { + word(&mut self.s, "::")? + } + + self.print_name(segment.identifier.name)?; + + self.print_path_parameters(&segment.parameters, colons_before_params)?; + } + + Ok(()) + } + + fn print_qpath(&mut self, + path: &hir::Path, + qself: &hir::QSelf, + colons_before_params: bool) + -> io::Result<()> { + word(&mut self.s, "<")?; + self.print_type(&qself.ty)?; + if qself.position > 0 { + space(&mut self.s)?; + self.word_space("as")?; + let depth = path.segments.len() - qself.position; + self.print_path(&path, false, depth)?; + } + word(&mut self.s, ">")?; + word(&mut self.s, "::")?; + let item_segment = path.segments.last().unwrap(); + self.print_name(item_segment.identifier.name)?; + self.print_path_parameters(&item_segment.parameters, colons_before_params) + } + + fn print_path_parameters(&mut self, + parameters: &hir::PathParameters, + colons_before_params: bool) + -> io::Result<()> { + if parameters.is_empty() { + return Ok(()); + } + + if colons_before_params { + word(&mut self.s, "::")? + } + + match *parameters { + hir::AngleBracketedParameters(ref data) => { + word(&mut self.s, "<")?; + + let mut comma = false; + for lifetime in &data.lifetimes { + if comma { + self.word_space(",")? + } + self.print_lifetime(lifetime)?; + comma = true; + } + + if !data.types.is_empty() { + if comma { + self.word_space(",")? + } + self.commasep(Inconsistent, &data.types, |s, ty| s.print_type(&ty))?; + comma = true; + } + + for binding in data.bindings.iter() { + if comma { + self.word_space(",")? + } + self.print_name(binding.name)?; + space(&mut self.s)?; + self.word_space("=")?; + self.print_type(&binding.ty)?; + comma = true; + } + + word(&mut self.s, ">")? + } + + hir::ParenthesizedParameters(ref data) => { + word(&mut self.s, "(")?; + self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(&ty))?; + word(&mut self.s, ")")?; + + match data.output { + None => {} + Some(ref ty) => { + self.space_if_not_bol()?; + self.word_space("->")?; + self.print_type(&ty)?; + } + } + } + } + + Ok(()) + } + + pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> { + self.maybe_print_comment(pat.span.lo)?; + self.ann.pre(self, NodePat(pat))?; + // Pat isn't normalized, but the beauty of it + // is that it doesn't matter + match pat.node { + PatKind::Wild => word(&mut self.s, "_")?, + PatKind::Ident(binding_mode, ref path1, ref sub) => { + match binding_mode { + hir::BindByRef(mutbl) => { + self.word_nbsp("ref")?; + self.print_mutability(mutbl)?; + } + hir::BindByValue(hir::MutImmutable) => {} + hir::BindByValue(hir::MutMutable) => { + self.word_nbsp("mut")?; + } + } + self.print_name(path1.node.name)?; + match *sub { + Some(ref p) => { + word(&mut self.s, "@")?; + self.print_pat(&p)?; + } + None => (), + } + } + PatKind::TupleStruct(ref path, ref args_) => { + self.print_path(path, true, 0)?; + match *args_ { + None => word(&mut self.s, "(..)")?, + Some(ref args) => { + self.popen()?; + self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p))?; + self.pclose()?; + } + } + } + PatKind::Path(ref path) => { + self.print_path(path, true, 0)?; + } + PatKind::QPath(ref qself, ref path) => { + self.print_qpath(path, qself, false)?; + } + PatKind::Struct(ref path, ref fields, etc) => { + self.print_path(path, true, 0)?; + self.nbsp()?; + self.word_space("{")?; + self.commasep_cmnt(Consistent, + &fields[..], + |s, f| { + s.cbox(indent_unit)?; + if !f.node.is_shorthand { + s.print_name(f.node.name)?; + s.word_nbsp(":")?; + } + s.print_pat(&f.node.pat)?; + s.end() + }, + |f| f.node.pat.span)?; + if etc { + if !fields.is_empty() { + self.word_space(",")?; + } + word(&mut self.s, "..")?; + } + space(&mut self.s)?; + word(&mut self.s, "}")?; + } + PatKind::Tup(ref elts) => { + self.popen()?; + self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; + if elts.len() == 1 { + word(&mut self.s, ",")?; + } + self.pclose()?; + } + PatKind::Box(ref inner) => { + word(&mut self.s, "box ")?; + self.print_pat(&inner)?; + } + PatKind::Ref(ref inner, mutbl) => { + word(&mut self.s, "&")?; + if mutbl == hir::MutMutable { + word(&mut self.s, "mut ")?; + } + self.print_pat(&inner)?; + } + PatKind::Lit(ref e) => self.print_expr(&e)?, + PatKind::Range(ref begin, ref end) => { + self.print_expr(&begin)?; + space(&mut self.s)?; + word(&mut self.s, "...")?; + self.print_expr(&end)?; + } + PatKind::Vec(ref before, ref slice, ref after) => { + word(&mut self.s, "[")?; + self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?; + if let Some(ref p) = *slice { + if !before.is_empty() { + self.word_space(",")?; + } + if p.node != PatKind::Wild { + self.print_pat(&p)?; + } + word(&mut self.s, "..")?; + if !after.is_empty() { + self.word_space(",")?; + } + } + self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?; + word(&mut self.s, "]")?; + } + } + self.ann.post(self, NodePat(pat)) + } + + fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> { + // I have no idea why this check is necessary, but here it + // is :( + if arm.attrs.is_empty() { + space(&mut self.s)?; + } + self.cbox(indent_unit)?; + self.ibox(0)?; + self.print_outer_attributes(&arm.attrs)?; + let mut first = true; + for p in &arm.pats { + if first { + first = false; + } else { + space(&mut self.s)?; + self.word_space("|")?; + } + self.print_pat(&p)?; + } + space(&mut self.s)?; + if let Some(ref e) = arm.guard { + self.word_space("if")?; + self.print_expr(&e)?; + space(&mut self.s)?; + } + self.word_space("=>")?; + + match arm.body.node { + hir::ExprBlock(ref blk) => { + // the block will close the pattern's ibox + self.print_block_unclosed_indent(&blk, indent_unit)?; + + // If it is a user-provided unsafe block, print a comma after it + if let hir::UnsafeBlock(hir::UserProvided) = blk.rules { + word(&mut self.s, ",")?; + } + } + _ => { + self.end()?; // close the ibox for the pattern + self.print_expr(&arm.body)?; + word(&mut self.s, ",")?; + } + } + self.end() // close enclosing cbox + } + + // Returns whether it printed anything + fn print_explicit_self(&mut self, + explicit_self: &hir::ExplicitSelf_, + mutbl: hir::Mutability) + -> io::Result { + self.print_mutability(mutbl)?; + match *explicit_self { + hir::SelfStatic => { + return Ok(false); + } + hir::SelfValue(_) => { + word(&mut self.s, "self")?; + } + hir::SelfRegion(ref lt, m, _) => { + word(&mut self.s, "&")?; + self.print_opt_lifetime(lt)?; + self.print_mutability(m)?; + word(&mut self.s, "self")?; + } + hir::SelfExplicit(ref typ, _) => { + word(&mut self.s, "self")?; + self.word_space(":")?; + self.print_type(&typ)?; + } + } + return Ok(true); + } + + pub fn print_fn(&mut self, + decl: &hir::FnDecl, + unsafety: hir::Unsafety, + constness: hir::Constness, + abi: Abi, + name: Option, + generics: &hir::Generics, + opt_explicit_self: Option<&hir::ExplicitSelf_>, + vis: hir::Visibility) + -> io::Result<()> { + self.print_fn_header_info(unsafety, constness, abi, vis)?; + + if let Some(name) = name { + self.nbsp()?; + self.print_name(name)?; + } + self.print_generics(generics)?; + self.print_fn_args_and_ret(decl, opt_explicit_self)?; + self.print_where_clause(&generics.where_clause) + } + + pub fn print_fn_args(&mut self, + decl: &hir::FnDecl, + opt_explicit_self: Option<&hir::ExplicitSelf_>, + is_closure: bool) + -> io::Result<()> { + // It is unfortunate to duplicate the commasep logic, but we want the + // self type and the args all in the same box. + self.rbox(0, Inconsistent)?; + let mut first = true; + if let Some(explicit_self) = opt_explicit_self { + let m = match explicit_self { + &hir::SelfStatic => hir::MutImmutable, + _ => match decl.inputs[0].pat.node { + PatKind::Ident(hir::BindByValue(m), _, _) => m, + _ => hir::MutImmutable, + }, + }; + first = !self.print_explicit_self(explicit_self, m)?; + } + + // HACK(eddyb) ignore the separately printed self argument. + let args = if first { + &decl.inputs[..] + } else { + &decl.inputs[1..] + }; + + for arg in args { + if first { + first = false; + } else { + self.word_space(",")?; + } + self.print_arg(arg, is_closure)?; + } + + self.end() + } + + pub fn print_fn_args_and_ret(&mut self, + decl: &hir::FnDecl, + opt_explicit_self: Option<&hir::ExplicitSelf_>) + -> io::Result<()> { + self.popen()?; + self.print_fn_args(decl, opt_explicit_self, false)?; + if decl.variadic { + word(&mut self.s, ", ...")?; + } + self.pclose()?; + + self.print_fn_output(decl) + } + + pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> { + word(&mut self.s, "|")?; + self.print_fn_args(decl, None, true)?; + word(&mut self.s, "|")?; + + if let hir::DefaultReturn(..) = decl.output { + return Ok(()); + } + + self.space_if_not_bol()?; + self.word_space("->")?; + match decl.output { + hir::Return(ref ty) => { + self.print_type(&ty)?; + self.maybe_print_comment(ty.span.lo) + } + hir::DefaultReturn(..) => unreachable!(), + hir::NoReturn(span) => { + self.word_nbsp("!")?; + self.maybe_print_comment(span.lo) + } + } + } + + pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> { + match capture_clause { + hir::CaptureByValue => self.word_space("move"), + hir::CaptureByRef => Ok(()), + } + } + + pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> { + if !bounds.is_empty() { + word(&mut self.s, prefix)?; + let mut first = true; + for bound in bounds { + self.nbsp()?; + if first { + first = false; + } else { + self.word_space("+")?; + } + + match *bound { + TraitTyParamBound(ref tref, TraitBoundModifier::None) => { + self.print_poly_trait_ref(tref) + } + TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => { + word(&mut self.s, "?")?; + self.print_poly_trait_ref(tref) + } + RegionTyParamBound(ref lt) => { + self.print_lifetime(lt) + } + }? + } + Ok(()) + } else { + Ok(()) + } + } + + pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { + self.print_name(lifetime.name) + } + + pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> { + self.print_lifetime(&lifetime.lifetime)?; + let mut sep = ":"; + for v in &lifetime.bounds { + word(&mut self.s, sep)?; + self.print_lifetime(v)?; + sep = "+"; + } + Ok(()) + } + + pub fn print_generics(&mut self, generics: &hir::Generics) -> io::Result<()> { + let total = generics.lifetimes.len() + generics.ty_params.len(); + if total == 0 { + return Ok(()); + } + + word(&mut self.s, "<")?; + + let mut ints = Vec::new(); + for i in 0..total { + ints.push(i); + } + + self.commasep(Inconsistent, &ints[..], |s, &idx| { + if idx < generics.lifetimes.len() { + let lifetime = &generics.lifetimes[idx]; + s.print_lifetime_def(lifetime) + } else { + let idx = idx - generics.lifetimes.len(); + let param = &generics.ty_params[idx]; + s.print_ty_param(param) + } + })?; + + word(&mut self.s, ">")?; + Ok(()) + } + + pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> { + self.print_name(param.name)?; + self.print_bounds(":", ¶m.bounds)?; + match param.default { + Some(ref default) => { + space(&mut self.s)?; + self.word_space("=")?; + self.print_type(&default) + } + _ => Ok(()), + } + } + + pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> { + if where_clause.predicates.is_empty() { + return Ok(()); + } + + space(&mut self.s)?; + self.word_space("where")?; + + for (i, predicate) in where_clause.predicates.iter().enumerate() { + if i != 0 { + self.word_space(",")?; + } + + match predicate { + &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bound_lifetimes, + ref bounded_ty, + ref bounds, + ..}) => { + self.print_formal_lifetime_list(bound_lifetimes)?; + self.print_type(&bounded_ty)?; + self.print_bounds(":", bounds)?; + } + &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime, + ref bounds, + ..}) => { + self.print_lifetime(lifetime)?; + word(&mut self.s, ":")?; + + for (i, bound) in bounds.iter().enumerate() { + self.print_lifetime(bound)?; + + if i != 0 { + word(&mut self.s, ":")?; + } + } + } + &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref path, ref ty, ..}) => { + self.print_path(path, false, 0)?; + space(&mut self.s)?; + self.word_space("=")?; + self.print_type(&ty)?; + } + } + } + + Ok(()) + } + + pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> { + match vp.node { + hir::ViewPathSimple(name, ref path) => { + self.print_path(path, false, 0)?; + + if path.segments.last().unwrap().identifier.name != name { + space(&mut self.s)?; + self.word_space("as")?; + self.print_name(name)?; + } + + Ok(()) + } + + hir::ViewPathGlob(ref path) => { + self.print_path(path, false, 0)?; + word(&mut self.s, "::*") + } + + hir::ViewPathList(ref path, ref segments) => { + if path.segments.is_empty() { + word(&mut self.s, "{")?; + } else { + self.print_path(path, false, 0)?; + word(&mut self.s, "::{")?; + } + self.commasep(Inconsistent, &segments[..], |s, w| { + match w.node { + hir::PathListIdent { name, .. } => { + s.print_name(name) + } + hir::PathListMod { .. } => { + word(&mut s.s, "self") + } + } + })?; + word(&mut self.s, "}") + } + } + } + + pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> { + match mutbl { + hir::MutMutable => self.word_nbsp("mut"), + hir::MutImmutable => Ok(()), + } + } + + pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> { + self.print_mutability(mt.mutbl)?; + self.print_type(&mt.ty) + } + + pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()> { + self.ibox(indent_unit)?; + match input.ty.node { + hir::TyInfer if is_closure => self.print_pat(&input.pat)?, + _ => { + match input.pat.node { + PatKind::Ident(_, ref path1, _) if + path1.node.name == + parse::token::special_idents::invalid.name => { + // Do nothing. + } + _ => { + self.print_pat(&input.pat)?; + word(&mut self.s, ":")?; + space(&mut self.s)?; + } + } + self.print_type(&input.ty)?; + } + } + self.end() + } + + pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> { + if let hir::DefaultReturn(..) = decl.output { + return Ok(()); + } + + self.space_if_not_bol()?; + self.ibox(indent_unit)?; + self.word_space("->")?; + match decl.output { + hir::NoReturn(_) => self.word_nbsp("!")?, + hir::DefaultReturn(..) => unreachable!(), + hir::Return(ref ty) => self.print_type(&ty)?, + } + self.end()?; + + match decl.output { + hir::Return(ref output) => self.maybe_print_comment(output.span.lo), + _ => Ok(()), + } + } + + pub fn print_ty_fn(&mut self, + abi: Abi, + unsafety: hir::Unsafety, + decl: &hir::FnDecl, + name: Option, + generics: &hir::Generics, + opt_explicit_self: Option<&hir::ExplicitSelf_>) + -> io::Result<()> { + self.ibox(indent_unit)?; + if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { + word(&mut self.s, "for")?; + self.print_generics(generics)?; + } + let generics = hir::Generics { + lifetimes: hir::HirVec::new(), + ty_params: hir::HirVec::new(), + where_clause: hir::WhereClause { + id: ast::DUMMY_NODE_ID, + predicates: hir::HirVec::new(), + }, + }; + self.print_fn(decl, + unsafety, + hir::Constness::NotConst, + abi, + name, + &generics, + opt_explicit_self, + hir::Inherited)?; + self.end() + } + + pub fn maybe_print_trailing_comment(&mut self, + span: codemap::Span, + next_pos: Option) + -> io::Result<()> { + let cm = match self.cm { + Some(cm) => cm, + _ => return Ok(()), + }; + match self.next_comment() { + Some(ref cmnt) => { + if (*cmnt).style != comments::Trailing { + return Ok(()); + } + let span_line = cm.lookup_char_pos(span.hi); + let comment_line = cm.lookup_char_pos((*cmnt).pos); + let mut next = (*cmnt).pos + BytePos(1); + match next_pos { + None => (), + Some(p) => next = p, + } + if span.hi < (*cmnt).pos && (*cmnt).pos < next && + span_line.line == comment_line.line { + self.print_comment(cmnt)?; + self.cur_cmnt_and_lit.cur_cmnt += 1; + } + } + _ => (), + } + Ok(()) + } + + pub fn print_remaining_comments(&mut self) -> io::Result<()> { + // If there aren't any remaining comments, then we need to manually + // make sure there is a line break at the end. + if self.next_comment().is_none() { + hardbreak(&mut self.s)?; + } + loop { + match self.next_comment() { + Some(ref cmnt) => { + self.print_comment(cmnt)?; + self.cur_cmnt_and_lit.cur_cmnt += 1; + } + _ => break, + } + } + Ok(()) + } + + pub fn print_opt_abi_and_extern_if_nondefault(&mut self, + opt_abi: Option) + -> io::Result<()> { + match opt_abi { + Some(Abi::Rust) => Ok(()), + Some(abi) => { + self.word_nbsp("extern")?; + self.word_nbsp(&abi.to_string()) + } + None => Ok(()), + } + } + + pub fn print_extern_opt_abi(&mut self, opt_abi: Option) -> io::Result<()> { + match opt_abi { + Some(abi) => { + self.word_nbsp("extern")?; + self.word_nbsp(&abi.to_string()) + } + None => Ok(()), + } + } + + pub fn print_fn_header_info(&mut self, + unsafety: hir::Unsafety, + constness: hir::Constness, + abi: Abi, + vis: hir::Visibility) + -> io::Result<()> { + word(&mut self.s, &visibility_qualified(vis, ""))?; + self.print_unsafety(unsafety)?; + + match constness { + hir::Constness::NotConst => {} + hir::Constness::Const => self.word_nbsp("const")?, + } + + if abi != Abi::Rust { + self.word_nbsp("extern")?; + self.word_nbsp(&abi.to_string())?; + } + + word(&mut self.s, "fn") + } + + pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> { + match s { + hir::Unsafety::Normal => Ok(()), + hir::Unsafety::Unsafe => self.word_nbsp("unsafe"), + } + } +} + +// Dup'ed from parse::classify, but adapted for the HIR. +/// Does this expression require a semicolon to be treated +/// as a statement? The negation of this: 'can this expression +/// be used as a statement without a semicolon' -- is used +/// as an early-bail-out in the parser so that, for instance, +/// if true {...} else {...} +/// |x| 5 +/// isn't parsed as (if true {...} else {...} | x) | 5 +fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { + match e.node { + hir::ExprIf(..) | + hir::ExprMatch(..) | + hir::ExprBlock(_) | + hir::ExprWhile(..) | + hir::ExprLoop(..) => false, + _ => true, + } +} + +/// this statement requires a semicolon after it. +/// note that in one case (stmt_semi), we've already +/// seen the semicolon, and thus don't need another. +fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool { + match *stmt { + hir::StmtDecl(ref d, _) => { + match d.node { + hir::DeclLocal(_) => true, + hir::DeclItem(_) => false, + } + } + hir::StmtExpr(ref e, _) => { + expr_requires_semi_to_be_stmt(&e) + } + hir::StmtSemi(..) => { + false + } + } +} diff --git a/src/librustc/hir/svh.rs b/src/librustc/hir/svh.rs new file mode 100644 index 00000000000..7ae20f68ad0 --- /dev/null +++ b/src/librustc/hir/svh.rs @@ -0,0 +1,439 @@ +// Copyright 2012-2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Calculation and management of a Strict Version Hash for crates +//! +//! # Today's ABI problem +//! +//! In today's implementation of rustc, it is incredibly difficult to achieve +//! forward binary compatibility without resorting to C-like interfaces. Within +//! rust code itself, abi details such as symbol names suffer from a variety of +//! unrelated factors to code changing such as the "def id drift" problem. This +//! ends up yielding confusing error messages about metadata mismatches and +//! such. +//! +//! The core of this problem is when an upstream dependency changes and +//! downstream dependents are not recompiled. This causes compile errors because +//! the upstream crate's metadata has changed but the downstream crates are +//! still referencing the older crate's metadata. +//! +//! This problem exists for many reasons, the primary of which is that rust does +//! not currently support forwards ABI compatibility (in place upgrades of a +//! crate). +//! +//! # SVH and how it alleviates the problem +//! +//! With all of this knowledge on hand, this module contains the implementation +//! of a notion of a "Strict Version Hash" for a crate. This is essentially a +//! hash of all contents of a crate which can somehow be exposed to downstream +//! crates. +//! +//! This hash is currently calculated by just hashing the AST, but this is +//! obviously wrong (doc changes should not result in an incompatible ABI). +//! Implementation-wise, this is required at this moment in time. +//! +//! By encoding this strict version hash into all crate's metadata, stale crates +//! can be detected immediately and error'd about by rustc itself. +//! +//! # Relevant links +//! +//! Original issue: https://github.com/rust-lang/rust/issues/10207 + +use std::fmt; +use std::hash::{Hash, SipHasher, Hasher}; +use hir; +use hir::intravisit as visit; + +#[derive(Clone, PartialEq, Debug)] +pub struct Svh { + hash: String, +} + +impl Svh { + pub fn new(hash: &str) -> Svh { + assert!(hash.len() == 16); + Svh { hash: hash.to_string() } + } + + pub fn as_str<'a>(&'a self) -> &'a str { + &self.hash + } + + pub fn calculate(crate_disambiguator: &str, krate: &hir::Crate) -> Svh { + // FIXME (#14132): This is better than it used to be, but it still not + // ideal. We now attempt to hash only the relevant portions of the + // Crate AST as well as the top-level crate attributes. (However, + // the hashing of the crate attributes should be double-checked + // to ensure it is not incorporating implementation artifacts into + // the hash that are not otherwise visible.) + + // FIXME: this should use SHA1, not SipHash. SipHash is not built to + // avoid collisions. + let mut state = SipHasher::new(); + + "crate_disambiguator".hash(&mut state); + crate_disambiguator.len().hash(&mut state); + crate_disambiguator.hash(&mut state); + + { + let mut visit = svh_visitor::make(&mut state, krate); + visit::walk_crate(&mut visit, krate); + } + + // FIXME (#14132): This hash is still sensitive to e.g. the + // spans of the crate Attributes and their underlying + // MetaItems; we should make ContentHashable impl for those + // types and then use hash_content. But, since all crate + // attributes should appear near beginning of the file, it is + // not such a big deal to be sensitive to their spans for now. + // + // We hash only the MetaItems instead of the entire Attribute + // to avoid hashing the AttrId + for attr in &krate.attrs { + attr.node.value.hash(&mut state); + } + + let hash = state.finish(); + return Svh { + hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect() + }; + + fn hex(b: u64) -> char { + let b = (b & 0xf) as u8; + let b = match b { + 0 ... 9 => '0' as u8 + b, + _ => 'a' as u8 + b - 10, + }; + b as char + } + } +} + +impl fmt::Display for Svh { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad(self.as_str()) + } +} + +// FIXME (#14132): Even this SVH computation still has implementation +// artifacts: namely, the order of item declaration will affect the +// hash computation, but for many kinds of items the order of +// declaration should be irrelevant to the ABI. + +mod svh_visitor { + pub use self::SawExprComponent::*; + pub use self::SawStmtComponent::*; + use self::SawAbiComponent::*; + use syntax::ast::{self, Name, NodeId}; + use syntax::codemap::Span; + use syntax::parse::token; + use hir::intravisit as visit; + use hir::intravisit::{Visitor, FnKind}; + use hir::*; + use hir; + + use std::hash::{Hash, SipHasher}; + + pub struct StrictVersionHashVisitor<'a> { + pub krate: &'a Crate, + pub st: &'a mut SipHasher, + } + + pub fn make<'a>(st: &'a mut SipHasher, krate: &'a Crate) -> StrictVersionHashVisitor<'a> { + StrictVersionHashVisitor { st: st, krate: krate } + } + + // To off-load the bulk of the hash-computation on #[derive(Hash)], + // we define a set of enums corresponding to the content that our + // crate visitor will encounter as it traverses the ast. + // + // The important invariant is that all of the Saw*Component enums + // do not carry any Spans, Names, or Idents. + // + // Not carrying any Names/Idents is the important fix for problem + // noted on PR #13948: using the ident.name as the basis for a + // hash leads to unstable SVH, because ident.name is just an index + // into intern table (i.e. essentially a random address), not + // computed from the name content. + // + // With the below enums, the SVH computation is not sensitive to + // artifacts of how rustc was invoked nor of how the source code + // was laid out. (Or at least it is *less* sensitive.) + + // This enum represents the different potential bits of code the + // visitor could encounter that could affect the ABI for the crate, + // and assigns each a distinct tag to feed into the hash computation. + #[derive(Hash)] + enum SawAbiComponent<'a> { + + // FIXME (#14132): should we include (some function of) + // ident.ctxt as well? + SawIdent(token::InternedString), + SawStructDef(token::InternedString), + + SawLifetime(token::InternedString), + SawLifetimeDef(token::InternedString), + + SawMod, + SawForeignItem, + SawItem, + SawDecl, + SawTy, + SawGenerics, + SawFn, + SawTraitItem, + SawImplItem, + SawStructField, + SawVariant, + SawExplicitSelf, + SawPath, + SawBlock, + SawPat, + SawLocal, + SawArm, + SawExpr(SawExprComponent<'a>), + SawStmt(SawStmtComponent), + } + + /// SawExprComponent carries all of the information that we want + /// to include in the hash that *won't* be covered by the + /// subsequent recursive traversal of the expression's + /// substructure by the visitor. + /// + /// We know every Expr_ variant is covered by a variant because + /// `fn saw_expr` maps each to some case below. Ensuring that + /// each variant carries an appropriate payload has to be verified + /// by hand. + /// + /// (However, getting that *exactly* right is not so important + /// because the SVH is just a developer convenience; there is no + /// guarantee of collision-freedom, hash collisions are just + /// (hopefully) unlikely.) + #[derive(Hash)] + pub enum SawExprComponent<'a> { + + SawExprLoop(Option), + SawExprField(token::InternedString), + SawExprTupField(usize), + SawExprBreak(Option), + SawExprAgain(Option), + + SawExprBox, + SawExprVec, + SawExprCall, + SawExprMethodCall, + SawExprTup, + SawExprBinary(hir::BinOp_), + SawExprUnary(hir::UnOp), + SawExprLit(ast::LitKind), + SawExprCast, + SawExprType, + SawExprIf, + SawExprWhile, + SawExprMatch, + SawExprClosure, + SawExprBlock, + SawExprAssign, + SawExprAssignOp(hir::BinOp_), + SawExprIndex, + SawExprPath(Option), + SawExprAddrOf(hir::Mutability), + SawExprRet, + SawExprInlineAsm(&'a hir::InlineAsm), + SawExprStruct, + SawExprRepeat, + } + + fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> { + match *node { + ExprBox(..) => SawExprBox, + ExprVec(..) => SawExprVec, + ExprCall(..) => SawExprCall, + ExprMethodCall(..) => SawExprMethodCall, + ExprTup(..) => SawExprTup, + ExprBinary(op, _, _) => SawExprBinary(op.node), + ExprUnary(op, _) => SawExprUnary(op), + ExprLit(ref lit) => SawExprLit(lit.node.clone()), + ExprCast(..) => SawExprCast, + ExprType(..) => SawExprType, + ExprIf(..) => SawExprIf, + ExprWhile(..) => SawExprWhile, + ExprLoop(_, id) => SawExprLoop(id.map(|id| id.name.as_str())), + ExprMatch(..) => SawExprMatch, + ExprClosure(..) => SawExprClosure, + ExprBlock(..) => SawExprBlock, + ExprAssign(..) => SawExprAssign, + ExprAssignOp(op, _, _) => SawExprAssignOp(op.node), + ExprField(_, name) => SawExprField(name.node.as_str()), + ExprTupField(_, id) => SawExprTupField(id.node), + ExprIndex(..) => SawExprIndex, + ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)), + ExprAddrOf(m, _) => SawExprAddrOf(m), + ExprBreak(id) => SawExprBreak(id.map(|id| id.node.name.as_str())), + ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())), + ExprRet(..) => SawExprRet, + ExprInlineAsm(ref a,_,_) => SawExprInlineAsm(a), + ExprStruct(..) => SawExprStruct, + ExprRepeat(..) => SawExprRepeat, + } + } + + /// SawStmtComponent is analogous to SawExprComponent, but for statements. + #[derive(Hash)] + pub enum SawStmtComponent { + SawStmtDecl, + SawStmtExpr, + SawStmtSemi, + } + + fn saw_stmt(node: &Stmt_) -> SawStmtComponent { + match *node { + StmtDecl(..) => SawStmtDecl, + StmtExpr(..) => SawStmtExpr, + StmtSemi(..) => SawStmtSemi, + } + } + + impl<'a> Visitor<'a> for StrictVersionHashVisitor<'a> { + fn visit_nested_item(&mut self, item: ItemId) { + self.visit_item(self.krate.item(item.id)) + } + + fn visit_variant_data(&mut self, s: &'a VariantData, name: Name, + g: &'a Generics, _: NodeId, _: Span) { + SawStructDef(name.as_str()).hash(self.st); + visit::walk_generics(self, g); + visit::walk_struct_def(self, s) + } + + fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) { + SawVariant.hash(self.st); + // walk_variant does not call walk_generics, so do it here. + visit::walk_generics(self, g); + visit::walk_variant(self, v, g, item_id) + } + + // All of the remaining methods just record (in the hash + // SipHasher) that the visitor saw that particular variant + // (with its payload), and continue walking as the default + // visitor would. + // + // Some of the implementations have some notes as to how one + // might try to make their SVH computation less discerning + // (e.g. by incorporating reachability analysis). But + // currently all of their implementations are uniform and + // uninteresting. + // + // (If you edit a method such that it deviates from the + // pattern, please move that method up above this comment.) + + fn visit_name(&mut self, _: Span, name: Name) { + SawIdent(name.as_str()).hash(self.st); + } + + fn visit_lifetime(&mut self, l: &'a Lifetime) { + SawLifetime(l.name.as_str()).hash(self.st); + } + + fn visit_lifetime_def(&mut self, l: &'a LifetimeDef) { + SawLifetimeDef(l.lifetime.name.as_str()).hash(self.st); + } + + // We do recursively walk the bodies of functions/methods + // (rather than omitting their bodies from the hash) since + // monomorphization and cross-crate inlining generally implies + // that a change to a crate body will require downstream + // crates to be recompiled. + fn visit_expr(&mut self, ex: &'a Expr) { + SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex) + } + + fn visit_stmt(&mut self, s: &'a Stmt) { + SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s) + } + + fn visit_foreign_item(&mut self, i: &'a ForeignItem) { + // FIXME (#14132) ideally we would incorporate privacy (or + // perhaps reachability) somewhere here, so foreign items + // that do not leak into downstream crates would not be + // part of the ABI. + SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i) + } + + fn visit_item(&mut self, i: &'a Item) { + // FIXME (#14132) ideally would incorporate reachability + // analysis somewhere here, so items that never leak into + // downstream crates (e.g. via monomorphisation or + // inlining) would not be part of the ABI. + SawItem.hash(self.st); visit::walk_item(self, i) + } + + fn visit_mod(&mut self, m: &'a Mod, _s: Span, _n: NodeId) { + SawMod.hash(self.st); visit::walk_mod(self, m) + } + + fn visit_decl(&mut self, d: &'a Decl) { + SawDecl.hash(self.st); visit::walk_decl(self, d) + } + + fn visit_ty(&mut self, t: &'a Ty) { + SawTy.hash(self.st); visit::walk_ty(self, t) + } + + fn visit_generics(&mut self, g: &'a Generics) { + SawGenerics.hash(self.st); visit::walk_generics(self, g) + } + + fn visit_fn(&mut self, fk: FnKind<'a>, fd: &'a FnDecl, + b: &'a Block, s: Span, _: NodeId) { + SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) + } + + fn visit_trait_item(&mut self, ti: &'a TraitItem) { + SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti) + } + + fn visit_impl_item(&mut self, ii: &'a ImplItem) { + SawImplItem.hash(self.st); visit::walk_impl_item(self, ii) + } + + fn visit_struct_field(&mut self, s: &'a StructField) { + SawStructField.hash(self.st); visit::walk_struct_field(self, s) + } + + fn visit_explicit_self(&mut self, es: &'a ExplicitSelf) { + SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es) + } + + fn visit_path(&mut self, path: &'a Path, _: ast::NodeId) { + SawPath.hash(self.st); visit::walk_path(self, path) + } + + fn visit_path_list_item(&mut self, prefix: &'a Path, item: &'a PathListItem) { + SawPath.hash(self.st); visit::walk_path_list_item(self, prefix, item) + } + + fn visit_block(&mut self, b: &'a Block) { + SawBlock.hash(self.st); visit::walk_block(self, b) + } + + fn visit_pat(&mut self, p: &'a Pat) { + SawPat.hash(self.st); visit::walk_pat(self, p) + } + + fn visit_local(&mut self, l: &'a Local) { + SawLocal.hash(self.st); visit::walk_local(self, l) + } + + fn visit_arm(&mut self, a: &'a Arm) { + SawArm.hash(self.st); visit::walk_arm(self, a) + } + } +} diff --git a/src/librustc/hir/util.rs b/src/librustc/hir/util.rs new file mode 100644 index 00000000000..7745c320e76 --- /dev/null +++ b/src/librustc/hir/util.rs @@ -0,0 +1,362 @@ +// Copyright 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use hir; +use hir::*; +use hir::intravisit::{Visitor, FnKind}; +use syntax::ast_util; +use syntax::ast::{Name, NodeId, DUMMY_NODE_ID}; +use syntax::codemap::Span; +use syntax::ptr::P; + +pub fn walk_pat(pat: &Pat, mut it: F) -> bool + where F: FnMut(&Pat) -> bool +{ + // FIXME(#19596) this is a workaround, but there should be a better way + fn walk_pat_(pat: &Pat, it: &mut G) -> bool + where G: FnMut(&Pat) -> bool + { + if !it(pat) { + return false; + } + + match pat.node { + PatKind::Ident(_, _, Some(ref p)) => walk_pat_(&p, it), + PatKind::Struct(_, ref fields, _) => { + fields.iter().all(|field| walk_pat_(&field.node.pat, it)) + } + PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { + s.iter().all(|p| walk_pat_(&p, it)) + } + PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { + walk_pat_(&s, it) + } + PatKind::Vec(ref before, ref slice, ref after) => { + before.iter().all(|p| walk_pat_(&p, it)) && + slice.iter().all(|p| walk_pat_(&p, it)) && + after.iter().all(|p| walk_pat_(&p, it)) + } + PatKind::Wild | + PatKind::Lit(_) | + PatKind::Range(_, _) | + PatKind::Ident(_, _, _) | + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::QPath(_, _) => { + true + } + } + } + + walk_pat_(pat, &mut it) +} + +pub fn binop_to_string(op: BinOp_) -> &'static str { + match op { + BiAdd => "+", + BiSub => "-", + BiMul => "*", + BiDiv => "/", + BiRem => "%", + BiAnd => "&&", + BiOr => "||", + BiBitXor => "^", + BiBitAnd => "&", + BiBitOr => "|", + BiShl => "<<", + BiShr => ">>", + BiEq => "==", + BiLt => "<", + BiLe => "<=", + BiNe => "!=", + BiGe => ">=", + BiGt => ">", + } +} + +pub fn stmt_id(s: &Stmt) -> NodeId { + match s.node { + StmtDecl(_, id) => id, + StmtExpr(_, id) => id, + StmtSemi(_, id) => id, + } +} + +pub fn lazy_binop(b: BinOp_) -> bool { + match b { + BiAnd => true, + BiOr => true, + _ => false, + } +} + +pub fn is_shift_binop(b: BinOp_) -> bool { + match b { + BiShl => true, + BiShr => true, + _ => false, + } +} + +pub fn is_comparison_binop(b: BinOp_) -> bool { + match b { + BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true, + BiAnd | + BiOr | + BiAdd | + BiSub | + BiMul | + BiDiv | + BiRem | + BiBitXor | + BiBitAnd | + BiBitOr | + BiShl | + BiShr => false, + } +} + +/// Returns `true` if the binary operator takes its arguments by value +pub fn is_by_value_binop(b: BinOp_) -> bool { + !is_comparison_binop(b) +} + +/// Returns `true` if the unary operator takes its argument by value +pub fn is_by_value_unop(u: UnOp) -> bool { + match u { + UnNeg | UnNot => true, + _ => false, + } +} + +pub fn unop_to_string(op: UnOp) -> &'static str { + match op { + UnDeref => "*", + UnNot => "!", + UnNeg => "-", + } +} + +pub struct IdVisitor<'a, O: 'a> { + operation: &'a mut O, + + // In general, the id visitor visits the contents of an item, but + // not including nested trait/impl items, nor other nested items. + // The base visitor itself always skips nested items, but not + // trait/impl items. This means in particular that if you start by + // visiting a trait or an impl, you should not visit the + // trait/impl items respectively. This is handled by setting + // `skip_members` to true when `visit_item` is on the stack. This + // way, if the user begins by calling `visit_trait_item`, we will + // visit the trait item, but if they begin with `visit_item`, we + // won't visit the (nested) trait items. + skip_members: bool, +} + +impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { + pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { + IdVisitor { operation: operation, skip_members: false } + } + + fn visit_generics_helper(&mut self, generics: &Generics) { + for type_parameter in generics.ty_params.iter() { + self.operation.visit_id(type_parameter.id) + } + for lifetime in &generics.lifetimes { + self.operation.visit_id(lifetime.lifetime.id) + } + } +} + +impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { + fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { + self.operation.visit_id(node_id); + intravisit::walk_mod(self, module) + } + + fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { + self.operation.visit_id(foreign_item.id); + intravisit::walk_foreign_item(self, foreign_item) + } + + fn visit_item(&mut self, item: &Item) { + assert!(!self.skip_members); + self.skip_members = true; + + self.operation.visit_id(item.id); + match item.node { + ItemUse(ref view_path) => { + match view_path.node { + ViewPathSimple(_, _) | + ViewPathGlob(_) => {} + ViewPathList(_, ref paths) => { + for path in paths { + self.operation.visit_id(path.node.id()) + } + } + } + } + _ => {} + } + intravisit::walk_item(self, item); + + self.skip_members = false; + } + + fn visit_local(&mut self, local: &Local) { + self.operation.visit_id(local.id); + intravisit::walk_local(self, local) + } + + fn visit_block(&mut self, block: &Block) { + self.operation.visit_id(block.id); + intravisit::walk_block(self, block) + } + + fn visit_stmt(&mut self, statement: &Stmt) { + self.operation.visit_id(stmt_id(statement)); + intravisit::walk_stmt(self, statement) + } + + fn visit_pat(&mut self, pattern: &Pat) { + self.operation.visit_id(pattern.id); + intravisit::walk_pat(self, pattern) + } + + fn visit_expr(&mut self, expression: &Expr) { + self.operation.visit_id(expression.id); + intravisit::walk_expr(self, expression) + } + + fn visit_ty(&mut self, typ: &Ty) { + self.operation.visit_id(typ.id); + intravisit::walk_ty(self, typ) + } + + fn visit_generics(&mut self, generics: &Generics) { + self.visit_generics_helper(generics); + intravisit::walk_generics(self, generics) + } + + fn visit_fn(&mut self, + function_kind: FnKind<'v>, + function_declaration: &'v FnDecl, + block: &'v Block, + span: Span, + node_id: NodeId) { + self.operation.visit_id(node_id); + + match function_kind { + FnKind::ItemFn(_, generics, _, _, _, _, _) => { + self.visit_generics_helper(generics) + } + FnKind::Method(_, sig, _, _) => { + self.visit_generics_helper(&sig.generics) + } + FnKind::Closure(_) => {} + } + + for argument in &function_declaration.inputs { + self.operation.visit_id(argument.id) + } + + intravisit::walk_fn(self, function_kind, function_declaration, block, span); + } + + fn visit_struct_field(&mut self, struct_field: &StructField) { + self.operation.visit_id(struct_field.id); + intravisit::walk_struct_field(self, struct_field) + } + + fn visit_variant_data(&mut self, + struct_def: &VariantData, + _: Name, + _: &hir::Generics, + _: NodeId, + _: Span) { + self.operation.visit_id(struct_def.id()); + intravisit::walk_struct_def(self, struct_def); + } + + fn visit_trait_item(&mut self, ti: &hir::TraitItem) { + if !self.skip_members { + self.operation.visit_id(ti.id); + intravisit::walk_trait_item(self, ti); + } + } + + fn visit_impl_item(&mut self, ii: &hir::ImplItem) { + if !self.skip_members { + self.operation.visit_id(ii.id); + intravisit::walk_impl_item(self, ii); + } + } + + fn visit_lifetime(&mut self, lifetime: &Lifetime) { + self.operation.visit_id(lifetime.id); + } + + fn visit_lifetime_def(&mut self, def: &LifetimeDef) { + self.visit_lifetime(&def.lifetime); + } + + fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { + self.operation.visit_id(trait_ref.ref_id); + intravisit::walk_trait_ref(self, trait_ref); + } +} + +/// Computes the id range for a single fn body, ignoring nested items. +pub fn compute_id_range_for_fn_body(fk: FnKind, + decl: &FnDecl, + body: &Block, + sp: Span, + id: NodeId) + -> ast_util::IdRange { + let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; + let mut id_visitor = IdVisitor::new(&mut visitor); + id_visitor.visit_fn(fk, decl, body, sp, id); + id_visitor.operation.result +} + +pub fn is_path(e: P) -> bool { + match e.node { + ExprPath(..) => true, + _ => false, + } +} + +pub fn empty_generics() -> Generics { + Generics { + lifetimes: HirVec::new(), + ty_params: HirVec::new(), + where_clause: WhereClause { + id: DUMMY_NODE_ID, + predicates: HirVec::new(), + }, + } +} + +// convert a span and an identifier to the corresponding +// 1-segment path +pub fn ident_to_path(s: Span, ident: Ident) -> Path { + hir::Path { + span: s, + global: false, + segments: hir_vec![hir::PathSegment { + identifier: ident, + parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { + lifetimes: HirVec::new(), + types: HirVec::new(), + bindings: HirVec::new(), + }), + }], + } +} diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 8079a6d1bbc..c0c63ac5042 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -73,9 +73,9 @@ use super::region_inference::SameRegions; use std::collections::HashSet; -use front::map as ast_map; -use rustc_front::hir; -use rustc_front::print::pprust; +use hir::map as ast_map; +use hir; +use hir::print as pprust; use middle::cstore::CrateStore; use middle::def::Def; diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index e22fb988904..427ff88b8f2 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -19,7 +19,7 @@ pub use self::freshen::TypeFreshener; pub use self::region_inference::{GenericKind, VerifyBound}; use middle::def_id::DefId; -use rustc_front::hir; +use hir; use middle::free_region::FreeRegionMap; use middle::mem_categorization as mc; use middle::mem_categorization::McResult; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 03a08231c74..291eab30dec 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -38,6 +38,7 @@ #![feature(rustc_private)] #![feature(slice_patterns)] #![feature(staged_api)] +#![feature(step_by)] #![feature(str_char)] #![feature(question_mark)] #![cfg_attr(test, feature(test))] @@ -51,7 +52,6 @@ extern crate graphviz; extern crate libc; extern crate rbml; extern crate rustc_back; -extern crate rustc_front; extern crate rustc_data_structures; extern crate serialize; extern crate collections; @@ -72,19 +72,9 @@ mod macros; // registered before they are used. pub mod diagnostics; -pub mod back { - pub use rustc_back::rpath; - pub use rustc_back::svh; -} - pub mod cfg; pub mod dep_graph; - -pub mod front { - pub mod check_attr; - pub mod map; -} - +pub mod hir; pub mod infer; pub mod lint; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e78ff513ac4..83244352769 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -46,9 +46,9 @@ use syntax::errors::DiagnosticBuilder; use syntax::parse::token::InternedString; use syntax::ast; use syntax::attr::ThinAttributesExt; -use rustc_front::hir; -use rustc_front::util; -use rustc_front::intravisit as hir_visit; +use hir; +use hir::util; +use hir::intravisit as hir_visit; use syntax::visit as ast_visit; /// Information about the registered lints. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 133d0163a8c..28994e1a7c4 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -34,10 +34,10 @@ pub use self::LintSource::*; use std::hash; use std::ascii::AsciiExt; use syntax::codemap::Span; -use rustc_front::intravisit::FnKind; +use hir::intravisit::FnKind; use syntax::visit as ast_visit; use syntax::ast; -use rustc_front::hir; +use hir; pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore, raw_emit_lint, check_crate, check_ast_crate, gather_attrs, diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index b86d74545cb..871440a7e54 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -18,7 +18,7 @@ use middle::def::Def; use ty::{Ty, TyCtxt}; use syntax::codemap::Span; -use rustc_front::hir as ast; +use hir as ast; pub fn prohibit_type_params(tcx: &TyCtxt, segments: &[ast::PathSegment]) { for segment in segments { diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 4efb40abdb0..59a3ab44645 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -22,8 +22,8 @@ // are *mostly* used as a part of that interface, but these should // probably get a better home if someone can find one. -use back::svh::Svh; -use front::map as hir_map; +use hir::svh::Svh; +use hir::map as hir_map; use middle::def::{self, Def}; use middle::lang_items; use ty::{self, Ty, TyCtxt, VariantKind}; @@ -44,9 +44,9 @@ use syntax::codemap::Span; use syntax::ptr::P; use syntax::parse::token::InternedString; use rustc_back::target::Target; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; -use rustc_front::util::IdVisitor; +use hir; +use hir::intravisit::Visitor; +use hir::util::IdVisitor; pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 6468187e219..99b512141a4 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -25,9 +25,9 @@ use syntax::ast_util::IdRange; use syntax::print::pp; use syntax::print::pprust::PrintState; use util::nodemap::NodeMap; -use rustc_front::hir; -use rustc_front::intravisit; -use rustc_front::print::pprust; +use hir; +use hir::intravisit; +use hir::print as pprust; #[derive(Copy, Clone, Debug)] diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 18bea745858..b7b6279270c 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -13,9 +13,9 @@ // from live codes are live, and everything else is dead. use dep_graph::DepNode; -use front::map as ast_map; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit::{self, Visitor}; +use hir::map as ast_map; +use hir::{self, PatKind}; +use hir::intravisit::{self, Visitor}; use middle::{pat_util, privacy}; use ty::{self, TyCtxt}; diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index e6ea000936c..ee6e747a855 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -12,7 +12,7 @@ use middle::def_id::DefId; use ty::subst::ParamSpace; use util::nodemap::NodeMap; use syntax::ast; -use rustc_front::hir; +use hir; #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum Def { diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index fa949073f4e..e4c93dfdb93 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -19,9 +19,9 @@ use ty::MethodCall; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; -use rustc_front::intravisit; -use rustc_front::intravisit::{FnKind, Visitor}; +use hir; +use hir::intravisit; +use hir::intravisit::{FnKind, Visitor}; #[derive(Copy, Clone)] struct UnsafeContext { diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 67e96816abf..4a64980fcdd 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -10,15 +10,15 @@ use dep_graph::DepNode; -use front::map as ast_map; +use hir::map as ast_map; use middle::def_id::{CRATE_DEF_INDEX}; use session::{config, Session}; use syntax::ast::NodeId; use syntax::attr; use syntax::codemap::Span; use syntax::entry::EntryPointType; -use rustc_front::hir::{Item, ItemFn}; -use rustc_front::intravisit::Visitor; +use hir::{Item, ItemFn}; +use hir::intravisit::Visitor; struct EntryContext<'a, 'tcx: 'a> { session: &'a Session, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index bfc96005bc8..47ec7ab5ff0 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -26,7 +26,7 @@ use infer; use middle::mem_categorization as mc; use ty::{self, TyCtxt, adjustment}; -use rustc_front::hir::{self, PatKind}; +use hir::{self, PatKind}; use syntax::ast; use syntax::ptr::P; @@ -479,7 +479,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } hir::ExprUnary(op, ref lhs) => { - let pass_args = if ::rustc_front::util::is_by_value_unop(op) { + let pass_args = if hir::util::is_by_value_unop(op) { PassArgs::ByValue } else { PassArgs::ByRef @@ -491,7 +491,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } hir::ExprBinary(op, ref lhs, ref rhs) => { - let pass_args = if ::rustc_front::util::is_by_value_binop(op.node) { + let pass_args = if hir::util::is_by_value_binop(op.node) { PassArgs::ByValue } else { PassArgs::ByRef @@ -524,7 +524,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { hir::ExprAssignOp(op, ref lhs, ref rhs) => { // NB All our assignment operations take the RHS by value - assert!(::rustc_front::util::is_by_value_binop(op.node)); + assert!(hir::util::is_by_value_binop(op.node)); if !self.walk_overloaded_operator(expr, lhs, vec![rhs], PassArgs::ByValue) { self.mutate_expr(expr, &lhs, MutateMode::WriteAndRead); diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index fd74ccac975..354a6c5e13b 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -20,8 +20,8 @@ use std::fmt; use syntax::abi::Abi::RustIntrinsic; use syntax::ast; use syntax::codemap::Span; -use rustc_front::intravisit::{self, Visitor, FnKind}; -use rustc_front::hir; +use hir::intravisit::{self, Visitor, FnKind}; +use hir; pub fn check_crate(tcx: &TyCtxt) { let mut visitor = IntrinsicCheckingVisitor { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index bb0b8ed91df..7aad106c4ed 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -22,7 +22,7 @@ pub use self::LangItem::*; use dep_graph::DepNode; -use front::map as hir_map; +use hir::map as hir_map; use session::Session; use middle::cstore::CrateStore; use middle::def_id::DefId; @@ -33,8 +33,8 @@ use util::nodemap::FnvHashMap; use syntax::ast; use syntax::attr::AttrMetaMethods; use syntax::parse::token::InternedString; -use rustc_front::intravisit::Visitor; -use rustc_front::hir; +use hir::intravisit::Visitor; +use hir; // The actual lang items defined come at the end of this file in one handy table. // So you probably just want to nip down to the end. diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 4451e7ac472..8d429ff2384 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -128,10 +128,10 @@ use syntax::codemap::{BytePos, original_sp, Span}; use syntax::parse::token::special_idents; use syntax::ptr::P; -use rustc_front::hir::Expr; -use rustc_front::hir; -use rustc_front::print::pprust::{expr_to_string, block_to_string}; -use rustc_front::intravisit::{self, Visitor, FnKind}; +use hir::Expr; +use hir; +use hir::print::{expr_to_string, block_to_string}; +use hir::intravisit::{self, Visitor, FnKind}; /// For use with `propagate_through_loop`. enum LoopKind<'a> { @@ -484,7 +484,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); } - hir::ExprBinary(op, _, _) if ::rustc_front::util::lazy_binop(op.node) => { + hir::ExprBinary(op, _, _) if hir::util::lazy_binop(op.node) => { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); } @@ -1142,7 +1142,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_exprs(&exprs[..], succ) } - hir::ExprBinary(op, ref l, ref r) if ::rustc_front::util::lazy_binop(op.node) => { + hir::ExprBinary(op, ref l, ref r) if hir::util::lazy_binop(op.node) => { let r_succ = self.propagate_through_expr(&r, succ); let ln = self.live_node(expr.id, expr.span); diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ef031ad13f1..7260bdde3ee 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -72,15 +72,15 @@ pub use self::deref_kind::*; use self::Aliasability::*; use middle::def_id::DefId; -use front::map as ast_map; +use hir::map as ast_map; use infer; use middle::const_qualif::ConstQualif; use middle::def::Def; use ty::adjustment; use ty::{self, Ty, TyCtxt}; -use rustc_front::hir::{MutImmutable, MutMutable, PatKind}; -use rustc_front::hir; +use hir::{MutImmutable, MutMutable, PatKind}; +use hir; use syntax::ast; use syntax::codemap::Span; diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index b2b1344c4bb..3cd69603b5b 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -14,8 +14,8 @@ use ty::TyCtxt; use util::nodemap::FnvHashMap; use syntax::ast; -use rustc_front::hir::{self, PatKind}; -use rustc_front::util::walk_pat; +use hir::{self, PatKind}; +use hir::util::walk_pat; use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; use std::cell::RefCell; diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 149e895717c..8c44594c1f7 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -16,7 +16,7 @@ // reachable as well. use dep_graph::DepNode; -use front::map as ast_map; +use hir::map as ast_map; use middle::def::Def; use middle::def_id::DefId; use ty::{self, TyCtxt}; @@ -28,9 +28,9 @@ use std::collections::HashSet; use syntax::abi::Abi; use syntax::ast; use syntax::attr; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; -use rustc_front::intravisit; +use hir; +use hir::intravisit::Visitor; +use hir::intravisit; // Returns true if the given set of generics implies that the item it's // associated with must be inlined. diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 2cde6ce9320..99ebf5ccb84 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -17,7 +17,7 @@ //! `middle/infer/region_inference/README.md` use dep_graph::DepNode; -use front::map as ast_map; +use hir::map as ast_map; use session::Session; use util::nodemap::{FnvHashMap, NodeMap, NodeSet}; use middle::cstore::InlinedItem; @@ -30,10 +30,10 @@ use std::mem; use syntax::codemap::{self, Span}; use syntax::ast::{self, NodeId}; -use rustc_front::hir; -use rustc_front::intravisit::{self, Visitor, FnKind}; -use rustc_front::hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; -use rustc_front::util::stmt_id; +use hir; +use hir::intravisit::{self, Visitor, FnKind}; +use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; +use hir::util::stmt_id; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)] diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d3757629d30..1275753a340 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -19,7 +19,7 @@ pub use self::DefRegion::*; use self::ScopeChain::*; use dep_graph::DepNode; -use front::map::Map; +use hir::map::Map; use session::Session; use middle::def::{Def, DefMap}; use middle::region; @@ -32,9 +32,9 @@ use syntax::codemap::Span; use syntax::parse::token::special_idents; use util::nodemap::NodeMap; -use rustc_front::hir; -use rustc_front::print::pprust::lifetime_to_string; -use rustc_front::intravisit::{self, Visitor, FnKind}; +use hir; +use hir::print::lifetime_to_string; +use hir::intravisit::{self, Visitor, FnKind}; #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] pub enum DefRegion { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index e589743222b..ffb4a791363 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -14,7 +14,7 @@ pub use self::StabilityLevel::*; use dep_graph::DepNode; -use front::map as hir_map; +use hir::map as hir_map; use session::Session; use lint; use middle::cstore::{CrateStore, LOCAL_CRATE}; @@ -30,9 +30,9 @@ use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::attr::{self, Stability, Deprecation, AttrMetaMethods}; use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; -use rustc_front::hir; -use rustc_front::hir::{Item, Generics, StructField, Variant, PatKind}; -use rustc_front::intravisit::{self, Visitor}; +use hir; +use hir::{Item, Generics, StructField, Variant, PatKind}; +use hir::intravisit::{self, Visitor}; use std::mem::replace; use std::cmp::Ordering; diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index 6059d7ee74e..74bb41785cb 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -18,9 +18,9 @@ use middle::lang_items; use syntax::ast; use syntax::codemap::Span; use syntax::parse::token::InternedString; -use rustc_front::intravisit::Visitor; -use rustc_front::intravisit; -use rustc_front::hir; +use hir::intravisit::Visitor; +use hir::intravisit; +use hir; use std::collections::HashSet; diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index a33ee6bd204..1b24b4f6210 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -16,7 +16,7 @@ use ty::subst::Substs; use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty}; use util::ppaux; use rustc_back::slice; -use rustc_front::hir::InlineAsm; +use hir::InlineAsm; use std::ascii; use std::borrow::{Cow}; use std::fmt::{self, Debug, Formatter, Write}; diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index ecac5d2f73f..d710417bf20 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -17,7 +17,7 @@ use mir::repr::*; use ty::subst::{Subst, Substs}; use ty::{self, AdtDef, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; -use rustc_front::hir; +use hir; #[derive(Copy, Clone, Debug)] pub enum LvalueTy<'tcx> { diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index f68386feddb..97c9caadd52 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -49,7 +49,7 @@ use std::cell::RefCell; use std::fmt; use std::rc::Rc; use syntax::abi::Abi; -use rustc_front::hir; +use hir; use util::common::ErrorReported; use util::nodemap::FnvHashMap; diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 90ccdeea928..41008823c85 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -17,7 +17,7 @@ use ty::LvaluePreference::{NoPreference}; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; +use hir; #[derive(Copy, Clone)] pub enum AutoAdjustment<'tcx> { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 2074339f2e6..fa5a7f3ca69 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -11,7 +11,7 @@ //! type context book-keeping use dep_graph::{DepGraph, DepTrackingMap}; -use front::map as ast_map; +use hir::map as ast_map; use session::Session; use lint; use middle; @@ -45,7 +45,7 @@ use syntax::ast::{self, Name, NodeId}; use syntax::attr; use syntax::parse::token::{self, special_idents}; -use rustc_front::hir; +use hir; /// Internal storage pub struct CtxtArenas<'tcx> { diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 9ab48505828..e6b7b49ea57 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -19,7 +19,7 @@ use syntax::ast::{self, Name}; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; -use rustc_front::hir; +use hir; #[derive(Clone, Copy, Debug)] pub struct ExpectedFound { diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index caf7e6fe629..0648450d833 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use front::map::DefPathData; +use hir::map::DefPathData; use middle::cstore::LOCAL_CRATE; use middle::def_id::{DefId, CRATE_DEF_INDEX}; use ty::{self, Ty, TyCtxt}; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index edfad09ae1f..69a6a6aa920 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -19,8 +19,8 @@ pub use self::LvaluePreference::*; pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; -use front::map as ast_map; -use front::map::LinkedPath; +use hir::map as ast_map; +use hir::map::LinkedPath; use middle; use middle::cstore::{self, CrateStore, LOCAL_CRATE}; use middle::def::{self, Def, ExportMap}; @@ -52,9 +52,9 @@ use syntax::parse::token::InternedString; use rustc_const_math::ConstInt; -use rustc_front::hir; -use rustc_front::hir::{ItemImpl, ItemTrait, PatKind}; -use rustc_front::intravisit::Visitor; +use hir; +use hir::{ItemImpl, ItemTrait, PatKind}; +use hir::intravisit::Visitor; pub use self::sty::{Binder, DebruijnIndex}; pub use self::sty::{BuiltinBound, BuiltinBounds, ExistentialBounds}; diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index b39cb5ef939..b1bff9b43cc 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -19,7 +19,7 @@ use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; use std::rc::Rc; use syntax::abi; -use rustc_front::hir as ast; +use hir as ast; pub type RelateResult<'tcx, T> = Result>; diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 82cc9e7f2e3..bbf6d0329b4 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -17,7 +17,7 @@ use std::rc::Rc; use syntax::abi; use syntax::ptr::P; -use rustc_front::hir; +use hir; /////////////////////////////////////////////////////////////////////////// // Lift implementations diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index fee0aaff445..101c8501bd3 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -28,7 +28,7 @@ use syntax::parse::token::special_idents; use serialize::{Decodable, Decoder}; -use rustc_front::hir; +use hir; use self::FnOutput::*; use self::InferTy::*; diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 3ebf2ba4c84..0eb70f93bed 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -17,7 +17,7 @@ use ty::{Ty, TyCtxt, TraitRef}; use std::borrow::{Borrow}; use std::cell::{Cell, Ref, RefCell}; use syntax::ast::Name; -use rustc_front::hir; +use hir; use util::nodemap::FnvHashMap; /// As `TypeScheme` but for a trait ref. diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 6e8363f629b..710cd2e301c 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -10,7 +10,7 @@ //! misc. type-system utilities too small to deserve their own file -use back::svh::Svh; +use hir::svh::Svh; use middle::def_id::DefId; use ty::subst; use infer; @@ -28,7 +28,7 @@ use syntax::ast::{self, Name}; use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt}; use syntax::codemap::Span; -use rustc_front::hir; +use hir; pub trait IntTypeExt { fn to_ty<'tcx>(&self, cx: &TyCtxt<'tcx>) -> Ty<'tcx>; diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 888a623b24a..bdfb97549d5 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -19,9 +19,9 @@ use std::iter::repeat; use std::path::Path; use std::time::Instant; -use rustc_front::hir; -use rustc_front::intravisit; -use rustc_front::intravisit::Visitor; +use hir; +use hir::intravisit; +use hir::intravisit::Visitor; // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &'static str = "Output"; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 20f16a1d255..c386a670ba2 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -23,7 +23,7 @@ use std::fmt; use syntax::abi::Abi; use syntax::parse::token; use syntax::ast::CRATE_NODE_ID; -use rustc_front::hir; +use hir; pub fn verbose() -> bool { ty::tls::with(|tcx| tcx.sess.verbose()) diff --git a/src/librustc_back/Cargo.toml b/src/librustc_back/Cargo.toml index 2cf6cbc4bcf..85e861b405a 100644 --- a/src/librustc_back/Cargo.toml +++ b/src/librustc_back/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["dylib"] [dependencies] syntax = { path = "../libsyntax" } serialize = { path = "../libserialize" } -rustc_front = { path = "../librustc_front" } log = { path = "../liblog" } [features] diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 80dec2cd281..25edaf4b8e4 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -45,13 +45,11 @@ extern crate syntax; extern crate libc; extern crate serialize; -extern crate rustc_front; #[macro_use] extern crate log; pub mod tempdir; pub mod rpath; pub mod sha2; -pub mod svh; pub mod target; pub mod slice; pub mod dynamic_lib; diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs deleted file mode 100644 index ec607314f45..00000000000 --- a/src/librustc_back/svh.rs +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Calculation and management of a Strict Version Hash for crates -//! -//! # Today's ABI problem -//! -//! In today's implementation of rustc, it is incredibly difficult to achieve -//! forward binary compatibility without resorting to C-like interfaces. Within -//! rust code itself, abi details such as symbol names suffer from a variety of -//! unrelated factors to code changing such as the "def id drift" problem. This -//! ends up yielding confusing error messages about metadata mismatches and -//! such. -//! -//! The core of this problem is when an upstream dependency changes and -//! downstream dependents are not recompiled. This causes compile errors because -//! the upstream crate's metadata has changed but the downstream crates are -//! still referencing the older crate's metadata. -//! -//! This problem exists for many reasons, the primary of which is that rust does -//! not currently support forwards ABI compatibility (in place upgrades of a -//! crate). -//! -//! # SVH and how it alleviates the problem -//! -//! With all of this knowledge on hand, this module contains the implementation -//! of a notion of a "Strict Version Hash" for a crate. This is essentially a -//! hash of all contents of a crate which can somehow be exposed to downstream -//! crates. -//! -//! This hash is currently calculated by just hashing the AST, but this is -//! obviously wrong (doc changes should not result in an incompatible ABI). -//! Implementation-wise, this is required at this moment in time. -//! -//! By encoding this strict version hash into all crate's metadata, stale crates -//! can be detected immediately and error'd about by rustc itself. -//! -//! # Relevant links -//! -//! Original issue: https://github.com/rust-lang/rust/issues/10207 - -use std::fmt; -use std::hash::{Hash, SipHasher, Hasher}; -use rustc_front::hir; -use rustc_front::intravisit as visit; - -#[derive(Clone, PartialEq, Debug)] -pub struct Svh { - hash: String, -} - -impl Svh { - pub fn new(hash: &str) -> Svh { - assert!(hash.len() == 16); - Svh { hash: hash.to_string() } - } - - pub fn as_str<'a>(&'a self) -> &'a str { - &self.hash - } - - pub fn calculate(crate_disambiguator: &str, krate: &hir::Crate) -> Svh { - // FIXME (#14132): This is better than it used to be, but it still not - // ideal. We now attempt to hash only the relevant portions of the - // Crate AST as well as the top-level crate attributes. (However, - // the hashing of the crate attributes should be double-checked - // to ensure it is not incorporating implementation artifacts into - // the hash that are not otherwise visible.) - - // FIXME: this should use SHA1, not SipHash. SipHash is not built to - // avoid collisions. - let mut state = SipHasher::new(); - - "crate_disambiguator".hash(&mut state); - crate_disambiguator.len().hash(&mut state); - crate_disambiguator.hash(&mut state); - - { - let mut visit = svh_visitor::make(&mut state, krate); - visit::walk_crate(&mut visit, krate); - } - - // FIXME (#14132): This hash is still sensitive to e.g. the - // spans of the crate Attributes and their underlying - // MetaItems; we should make ContentHashable impl for those - // types and then use hash_content. But, since all crate - // attributes should appear near beginning of the file, it is - // not such a big deal to be sensitive to their spans for now. - // - // We hash only the MetaItems instead of the entire Attribute - // to avoid hashing the AttrId - for attr in &krate.attrs { - attr.node.value.hash(&mut state); - } - - let hash = state.finish(); - return Svh { - hash: (0..64).step_by(4).map(|i| hex(hash >> i)).collect() - }; - - fn hex(b: u64) -> char { - let b = (b & 0xf) as u8; - let b = match b { - 0 ... 9 => '0' as u8 + b, - _ => 'a' as u8 + b - 10, - }; - b as char - } - } -} - -impl fmt::Display for Svh { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad(self.as_str()) - } -} - -// FIXME (#14132): Even this SVH computation still has implementation -// artifacts: namely, the order of item declaration will affect the -// hash computation, but for many kinds of items the order of -// declaration should be irrelevant to the ABI. - -mod svh_visitor { - pub use self::SawExprComponent::*; - pub use self::SawStmtComponent::*; - use self::SawAbiComponent::*; - use syntax::ast::{self, Name, NodeId}; - use syntax::codemap::Span; - use syntax::parse::token; - use rustc_front::intravisit as visit; - use rustc_front::intravisit::{Visitor, FnKind}; - use rustc_front::hir::*; - use rustc_front::hir; - - use std::hash::{Hash, SipHasher}; - - pub struct StrictVersionHashVisitor<'a> { - pub krate: &'a Crate, - pub st: &'a mut SipHasher, - } - - pub fn make<'a>(st: &'a mut SipHasher, krate: &'a Crate) -> StrictVersionHashVisitor<'a> { - StrictVersionHashVisitor { st: st, krate: krate } - } - - // To off-load the bulk of the hash-computation on #[derive(Hash)], - // we define a set of enums corresponding to the content that our - // crate visitor will encounter as it traverses the ast. - // - // The important invariant is that all of the Saw*Component enums - // do not carry any Spans, Names, or Idents. - // - // Not carrying any Names/Idents is the important fix for problem - // noted on PR #13948: using the ident.name as the basis for a - // hash leads to unstable SVH, because ident.name is just an index - // into intern table (i.e. essentially a random address), not - // computed from the name content. - // - // With the below enums, the SVH computation is not sensitive to - // artifacts of how rustc was invoked nor of how the source code - // was laid out. (Or at least it is *less* sensitive.) - - // This enum represents the different potential bits of code the - // visitor could encounter that could affect the ABI for the crate, - // and assigns each a distinct tag to feed into the hash computation. - #[derive(Hash)] - enum SawAbiComponent<'a> { - - // FIXME (#14132): should we include (some function of) - // ident.ctxt as well? - SawIdent(token::InternedString), - SawStructDef(token::InternedString), - - SawLifetime(token::InternedString), - SawLifetimeDef(token::InternedString), - - SawMod, - SawForeignItem, - SawItem, - SawDecl, - SawTy, - SawGenerics, - SawFn, - SawTraitItem, - SawImplItem, - SawStructField, - SawVariant, - SawExplicitSelf, - SawPath, - SawBlock, - SawPat, - SawLocal, - SawArm, - SawExpr(SawExprComponent<'a>), - SawStmt(SawStmtComponent), - } - - /// SawExprComponent carries all of the information that we want - /// to include in the hash that *won't* be covered by the - /// subsequent recursive traversal of the expression's - /// substructure by the visitor. - /// - /// We know every Expr_ variant is covered by a variant because - /// `fn saw_expr` maps each to some case below. Ensuring that - /// each variant carries an appropriate payload has to be verified - /// by hand. - /// - /// (However, getting that *exactly* right is not so important - /// because the SVH is just a developer convenience; there is no - /// guarantee of collision-freedom, hash collisions are just - /// (hopefully) unlikely.) - #[derive(Hash)] - pub enum SawExprComponent<'a> { - - SawExprLoop(Option), - SawExprField(token::InternedString), - SawExprTupField(usize), - SawExprBreak(Option), - SawExprAgain(Option), - - SawExprBox, - SawExprVec, - SawExprCall, - SawExprMethodCall, - SawExprTup, - SawExprBinary(hir::BinOp_), - SawExprUnary(hir::UnOp), - SawExprLit(ast::LitKind), - SawExprCast, - SawExprType, - SawExprIf, - SawExprWhile, - SawExprMatch, - SawExprClosure, - SawExprBlock, - SawExprAssign, - SawExprAssignOp(hir::BinOp_), - SawExprIndex, - SawExprPath(Option), - SawExprAddrOf(hir::Mutability), - SawExprRet, - SawExprInlineAsm(&'a hir::InlineAsm), - SawExprStruct, - SawExprRepeat, - } - - fn saw_expr<'a>(node: &'a Expr_) -> SawExprComponent<'a> { - match *node { - ExprBox(..) => SawExprBox, - ExprVec(..) => SawExprVec, - ExprCall(..) => SawExprCall, - ExprMethodCall(..) => SawExprMethodCall, - ExprTup(..) => SawExprTup, - ExprBinary(op, _, _) => SawExprBinary(op.node), - ExprUnary(op, _) => SawExprUnary(op), - ExprLit(ref lit) => SawExprLit(lit.node.clone()), - ExprCast(..) => SawExprCast, - ExprType(..) => SawExprType, - ExprIf(..) => SawExprIf, - ExprWhile(..) => SawExprWhile, - ExprLoop(_, id) => SawExprLoop(id.map(|id| id.name.as_str())), - ExprMatch(..) => SawExprMatch, - ExprClosure(..) => SawExprClosure, - ExprBlock(..) => SawExprBlock, - ExprAssign(..) => SawExprAssign, - ExprAssignOp(op, _, _) => SawExprAssignOp(op.node), - ExprField(_, name) => SawExprField(name.node.as_str()), - ExprTupField(_, id) => SawExprTupField(id.node), - ExprIndex(..) => SawExprIndex, - ExprPath(ref qself, _) => SawExprPath(qself.as_ref().map(|q| q.position)), - ExprAddrOf(m, _) => SawExprAddrOf(m), - ExprBreak(id) => SawExprBreak(id.map(|id| id.node.name.as_str())), - ExprAgain(id) => SawExprAgain(id.map(|id| id.node.name.as_str())), - ExprRet(..) => SawExprRet, - ExprInlineAsm(ref a,_,_) => SawExprInlineAsm(a), - ExprStruct(..) => SawExprStruct, - ExprRepeat(..) => SawExprRepeat, - } - } - - /// SawStmtComponent is analogous to SawExprComponent, but for statements. - #[derive(Hash)] - pub enum SawStmtComponent { - SawStmtDecl, - SawStmtExpr, - SawStmtSemi, - } - - fn saw_stmt(node: &Stmt_) -> SawStmtComponent { - match *node { - StmtDecl(..) => SawStmtDecl, - StmtExpr(..) => SawStmtExpr, - StmtSemi(..) => SawStmtSemi, - } - } - - impl<'a> Visitor<'a> for StrictVersionHashVisitor<'a> { - fn visit_nested_item(&mut self, item: ItemId) { - self.visit_item(self.krate.item(item.id)) - } - - fn visit_variant_data(&mut self, s: &'a VariantData, name: Name, - g: &'a Generics, _: NodeId, _: Span) { - SawStructDef(name.as_str()).hash(self.st); - visit::walk_generics(self, g); - visit::walk_struct_def(self, s) - } - - fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) { - SawVariant.hash(self.st); - // walk_variant does not call walk_generics, so do it here. - visit::walk_generics(self, g); - visit::walk_variant(self, v, g, item_id) - } - - // All of the remaining methods just record (in the hash - // SipHasher) that the visitor saw that particular variant - // (with its payload), and continue walking as the default - // visitor would. - // - // Some of the implementations have some notes as to how one - // might try to make their SVH computation less discerning - // (e.g. by incorporating reachability analysis). But - // currently all of their implementations are uniform and - // uninteresting. - // - // (If you edit a method such that it deviates from the - // pattern, please move that method up above this comment.) - - fn visit_name(&mut self, _: Span, name: Name) { - SawIdent(name.as_str()).hash(self.st); - } - - fn visit_lifetime(&mut self, l: &'a Lifetime) { - SawLifetime(l.name.as_str()).hash(self.st); - } - - fn visit_lifetime_def(&mut self, l: &'a LifetimeDef) { - SawLifetimeDef(l.lifetime.name.as_str()).hash(self.st); - } - - // We do recursively walk the bodies of functions/methods - // (rather than omitting their bodies from the hash) since - // monomorphization and cross-crate inlining generally implies - // that a change to a crate body will require downstream - // crates to be recompiled. - fn visit_expr(&mut self, ex: &'a Expr) { - SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex) - } - - fn visit_stmt(&mut self, s: &'a Stmt) { - SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s) - } - - fn visit_foreign_item(&mut self, i: &'a ForeignItem) { - // FIXME (#14132) ideally we would incorporate privacy (or - // perhaps reachability) somewhere here, so foreign items - // that do not leak into downstream crates would not be - // part of the ABI. - SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i) - } - - fn visit_item(&mut self, i: &'a Item) { - // FIXME (#14132) ideally would incorporate reachability - // analysis somewhere here, so items that never leak into - // downstream crates (e.g. via monomorphisation or - // inlining) would not be part of the ABI. - SawItem.hash(self.st); visit::walk_item(self, i) - } - - fn visit_mod(&mut self, m: &'a Mod, _s: Span, _n: NodeId) { - SawMod.hash(self.st); visit::walk_mod(self, m) - } - - fn visit_decl(&mut self, d: &'a Decl) { - SawDecl.hash(self.st); visit::walk_decl(self, d) - } - - fn visit_ty(&mut self, t: &'a Ty) { - SawTy.hash(self.st); visit::walk_ty(self, t) - } - - fn visit_generics(&mut self, g: &'a Generics) { - SawGenerics.hash(self.st); visit::walk_generics(self, g) - } - - fn visit_fn(&mut self, fk: FnKind<'a>, fd: &'a FnDecl, - b: &'a Block, s: Span, _: NodeId) { - SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s) - } - - fn visit_trait_item(&mut self, ti: &'a TraitItem) { - SawTraitItem.hash(self.st); visit::walk_trait_item(self, ti) - } - - fn visit_impl_item(&mut self, ii: &'a ImplItem) { - SawImplItem.hash(self.st); visit::walk_impl_item(self, ii) - } - - fn visit_struct_field(&mut self, s: &'a StructField) { - SawStructField.hash(self.st); visit::walk_struct_field(self, s) - } - - fn visit_explicit_self(&mut self, es: &'a ExplicitSelf) { - SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es) - } - - fn visit_path(&mut self, path: &'a Path, _: ast::NodeId) { - SawPath.hash(self.st); visit::walk_path(self, path) - } - - fn visit_path_list_item(&mut self, prefix: &'a Path, item: &'a PathListItem) { - SawPath.hash(self.st); visit::walk_path_list_item(self, prefix, item) - } - - fn visit_block(&mut self, b: &'a Block) { - SawBlock.hash(self.st); visit::walk_block(self, b) - } - - fn visit_pat(&mut self, p: &'a Pat) { - SawPat.hash(self.st); visit::walk_pat(self, p) - } - - fn visit_local(&mut self, l: &'a Local) { - SawLocal.hash(self.st); visit::walk_local(self, l) - } - - fn visit_arm(&mut self, a: &'a Arm) { - SawArm.hash(self.st); visit::walk_arm(self, a) - } - } -} diff --git a/src/librustc_borrowck/Cargo.toml b/src/librustc_borrowck/Cargo.toml index fdb97bd8d2d..6da87f97fb7 100644 --- a/src/librustc_borrowck/Cargo.toml +++ b/src/librustc_borrowck/Cargo.toml @@ -13,5 +13,4 @@ log = { path = "../liblog" } syntax = { path = "../libsyntax" } graphviz = { path = "../libgraphviz" } rustc = { path = "../librustc" } -rustc_front = { path = "../librustc_front" } rustc_mir = { path = "../librustc_mir" } diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index aa2b7ed2cde..d79ba213aca 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -30,7 +30,7 @@ use rustc::ty::{self, TyCtxt}; use rustc::traits::ProjectionMode; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; use std::rc::Rc; diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 489c8be4e38..c85d69fa8a6 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -23,7 +23,7 @@ use rustc::ty; use std::rc::Rc; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::{self, PatKind}; struct GatherMoveInfo<'tcx> { id: ast::NodeId, diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index c759722c24b..893c27f0ede 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -29,10 +29,10 @@ use rustc::traits::ProjectionMode; use syntax::ast; use syntax::codemap::Span; use syntax::ast::NodeId; -use rustc_front::hir; -use rustc_front::hir::Expr; -use rustc_front::intravisit; -use rustc_front::intravisit::Visitor; +use rustc::hir; +use rustc::hir::Expr; +use rustc::hir::intravisit; +use rustc::hir::intravisit::Visitor; use self::restrictions::RestrictionResult; diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs index f5e3bc4f6fb..3d94f5b186f 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs @@ -16,7 +16,7 @@ use rustc::ty; use syntax::ast; use syntax::codemap; use syntax::errors::DiagnosticBuilder; -use rustc_front::hir; +use rustc::hir; pub struct MoveErrorCollector<'tcx> { errors: Vec> diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index d1335811858..672faea58f5 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -13,8 +13,8 @@ use borrowck::BorrowckCtxt; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; -use rustc_front::intravisit::{FnKind}; +use rustc::hir; +use rustc::hir::intravisit::{FnKind}; use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator}; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 1dfa4da46aa..fec327f4aa0 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -21,8 +21,8 @@ pub use self::MovedValueUseKind::*; use self::InteriorKind::*; use rustc::dep_graph::DepNode; -use rustc::front::map as hir_map; -use rustc::front::map::blocks::FnParts; +use rustc::hir::map as hir_map; +use rustc::hir::map::blocks::FnParts; use rustc::cfg; use rustc::middle::dataflow::DataFlowContext; use rustc::middle::dataflow::BitwiseOperator; @@ -44,11 +44,11 @@ use syntax::attr::AttrMetaMethods; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; -use rustc_front::hir; -use rustc_front::hir::{FnDecl, Block}; -use rustc_front::intravisit; -use rustc_front::intravisit::{Visitor, FnKind}; -use rustc_front::util as hir_util; +use rustc::hir; +use rustc::hir::{FnDecl, Block}; +use rustc::hir::intravisit; +use rustc::hir::intravisit::{Visitor, FnKind}; +use rustc::hir::util as hir_util; use rustc::mir::mir_map::MirMap; diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index b31f74c6476..292cfcfeac1 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -30,7 +30,7 @@ use std::usize; use syntax::ast; use syntax::ast_util; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; #[path="fragments.rs"] pub mod fragments; diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 6f21fcd9230..e38677de662 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -34,7 +34,6 @@ extern crate graphviz as dot; #[macro_use] extern crate rustc; -extern crate rustc_front; extern crate rustc_mir; extern crate core; // for NonZero diff --git a/src/librustc_const_eval/Cargo.toml b/src/librustc_const_eval/Cargo.toml index f38c60cd1fa..c572284a6bb 100644 --- a/src/librustc_const_eval/Cargo.toml +++ b/src/librustc_const_eval/Cargo.toml @@ -12,7 +12,6 @@ crate-type = ["dylib"] log = { path = "../liblog" } serialize = { path = "../libserialize" } rustc = { path = "../librustc" } -rustc_front = { path = "../librustc_front" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index a46d72840b7..70781184f74 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -32,17 +32,17 @@ use std::cmp::Ordering; use std::fmt; use std::iter::{FromIterator, IntoIterator, repeat}; -use rustc_front::hir; -use rustc_front::hir::{Pat, PatKind}; -use rustc_front::intravisit::{self, Visitor, FnKind}; -use rustc_front::util as front_util; +use rustc::hir; +use rustc::hir::{Pat, PatKind}; +use rustc::hir::intravisit::{self, Visitor, FnKind}; +use rustc::hir::util as front_util; use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; use syntax::ast_util; use syntax::codemap::{Span, Spanned, DUMMY_SP}; -use rustc_front::fold::{Folder, noop_fold_pat}; -use rustc_front::print::pprust::pat_to_string; +use rustc::hir::fold::{Folder, noop_fold_pat}; +use rustc::hir::print::pat_to_string; use syntax::ptr::P; use rustc::util::nodemap::FnvHashMap; diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 5a00b4573de..dba31ddef95 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -15,8 +15,8 @@ use rustc::middle::const_val::ConstVal; use self::ErrKind::*; use self::EvalHint::*; -use rustc::front::map as ast_map; -use rustc::front::map::blocks::FnLikeNode; +use rustc::hir::map as ast_map; +use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::{self, CrateStore, InlinedItem}; use rustc::{infer, traits}; use rustc::middle::def::Def; @@ -31,9 +31,9 @@ use rustc::lint; use graphviz::IntoCow; use syntax::ast; -use rustc_front::hir::{Expr, PatKind}; -use rustc_front::hir; -use rustc_front::intravisit::FnKind; +use rustc::hir::{Expr, PatKind}; +use rustc::hir; +use rustc::hir::intravisit::FnKind; use syntax::codemap::Span; use syntax::ptr::P; use syntax::codemap; diff --git a/src/librustc_const_eval/lib.rs b/src/librustc_const_eval/lib.rs index b74fc121e39..085888dc21f 100644 --- a/src/librustc_const_eval/lib.rs +++ b/src/librustc_const_eval/lib.rs @@ -33,7 +33,6 @@ #[macro_use] extern crate syntax; #[macro_use] extern crate log; #[macro_use] extern crate rustc; -extern crate rustc_front; extern crate rustc_back; extern crate rustc_const_math; extern crate graphviz; diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 0d2ae14d7d1..bac5900f3ed 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -17,7 +17,6 @@ rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_borrowck = { path = "../librustc_borrowck" } rustc_const_eval = { path = "../librustc_const_eval" } -rustc_front = { path = "../librustc_front" } rustc_lint = { path = "../librustc_lint" } rustc_llvm = { path = "../librustc_llvm" } rustc_mir = { path = "../librustc_mir" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 4255d4fc8b0..f661b2a38b6 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -9,8 +9,8 @@ // except according to those terms. use rustc::dep_graph::DepGraph; -use rustc::front; -use rustc::front::map as hir_map; +use rustc::hir; +use rustc::hir::map as hir_map; use rustc_mir as mir; use rustc::mir::mir_map::MirMap; use rustc::session::{Session, CompileResult, compile_result_from_err_count}; @@ -35,8 +35,7 @@ use rustc_typeck as typeck; use rustc_privacy; use rustc_plugin::registry::Registry; use rustc_plugin as plugin; -use rustc_front::hir; -use rustc_front::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_passes::{no_asm, loops, consts, const_fn, rvalues, static_recursion}; use rustc_const_eval::check_match; use super::Compilation; @@ -155,7 +154,7 @@ pub fn compile_input(sess: &Session, } time(sess.time_passes(), "attribute checking", || { - front::check_attr::check_crate(sess, &expanded_crate); + hir::check_attr::check_crate(sess, &expanded_crate); }); time(sess.time_passes(), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3444b770cc8..b4b53d30e3c 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -42,7 +42,6 @@ extern crate rustc_back; extern crate rustc_borrowck; extern crate rustc_const_eval; extern crate rustc_passes; -extern crate rustc_front; extern crate rustc_lint; extern crate rustc_plugin; extern crate rustc_privacy; diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 31345cfdc41..cda5595c102 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -50,11 +50,11 @@ use std::option; use std::path::PathBuf; use std::str::FromStr; -use rustc::front::map as hir_map; -use rustc::front::map::{blocks, NodePrinter}; -use rustc_front::hir; -use rustc_front::lowering::{lower_crate, LoweringContext}; -use rustc_front::print::pprust as pprust_hir; +use rustc::hir::map as hir_map; +use rustc::hir::map::{blocks, NodePrinter}; +use rustc::hir; +use rustc::hir::lowering::{lower_crate, LoweringContext}; +use rustc::hir::print as pprust_hir; use rustc::mir::mir_map::MirMap; diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index ce0d42203b9..fc12d546288 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -27,7 +27,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::relate::TypeRelation; use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc_metadata::cstore::CStore; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::session::{self, config}; use std::rc::Rc; use syntax::ast; @@ -39,8 +39,8 @@ use syntax::errors::{Level, RenderSpan}; use syntax::parse::token; use syntax::feature_gate::UnstableFeatures; -use rustc_front::lowering::{lower_crate, LoweringContext}; -use rustc_front::hir; +use rustc::hir::lowering::{lower_crate, LoweringContext}; +use rustc::hir; struct Env<'a, 'tcx: 'a> { infcx: &'a infer::InferCtxt<'a, 'tcx>, diff --git a/src/librustc_front/Cargo.toml b/src/librustc_front/Cargo.toml deleted file mode 100644 index bf40cdbd330..00000000000 --- a/src/librustc_front/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_front" -version = "0.0.0" - -[lib] -name = "rustc_front" -path = "lib.rs" -crate-type = ["dylib"] - -[dependencies] -log = { path = "../liblog" } -syntax = { path = "../libsyntax" } -serialize = { path = "../libserialize" } -rustc_bitflags = { path = "../librustc_bitflags" } diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs deleted file mode 100644 index e65f2fc37de..00000000000 --- a/src/librustc_front/fold.rs +++ /dev/null @@ -1,1151 +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 or the MIT license -// , 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_, MetaItem}; -use syntax::ast::MetaItemKind; -use syntax::attr::ThinAttributesExt; -use hir; -use syntax::codemap::{respan, Span, Spanned}; -use syntax::ptr::P; -use syntax::parse::token; -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>) -> HirVec> { - noop_fold_meta_items(meta_items, self) - } - - fn fold_meta_item(&mut self, meta_item: P) -> P { - noop_fold_meta_item(meta_item, self) - } - - fn fold_view_path(&mut self, view_path: P) -> P { - 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) -> P { - noop_fold_fn_decl(d, self) - } - - fn fold_block(&mut self, b: P) -> P { - 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) -> P { - noop_fold_pat(p, self) - } - - fn fold_decl(&mut self, d: P) -> P { - noop_fold_decl(d, self) - } - - fn fold_expr(&mut self, e: P) -> P { - e.map(|e| noop_fold_expr(e, self)) - } - - fn fold_ty(&mut self, t: P) -> P { - 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_ident(&mut self, i: Ident) -> Ident { - noop_fold_ident(i, 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) -> P { - noop_fold_local(l, self) - } - - fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf { - noop_fold_explicit_self(es, self) - } - - fn fold_explicit_self_underscore(&mut self, es: ExplicitSelf_) -> ExplicitSelf_ { - noop_fold_explicit_self_underscore(es, 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 { - 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) -> HirVec { - noop_fold_lifetimes(lts, self) - } - - fn fold_lifetime_defs(&mut self, lts: HirVec) -> HirVec { - 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) -> HirVec { - noop_fold_ty_params(tps, self) - } - - fn fold_opt_lifetime(&mut self, o_lt: Option) -> Option { - noop_fold_opt_lifetime(o_lt, self) - } - - fn fold_opt_bounds(&mut self, - b: Option) - -> Option { - 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(meta_items: HirVec>, - fld: &mut T) - -> HirVec> { - meta_items.move_map(|x| fld.fold_meta_item(x)) -} - -pub fn noop_fold_view_path(view_path: P, fld: &mut T) -> P { - 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: match path_list_ident.node { - PathListIdent { id, name, rename } => PathListIdent { - id: fld.new_id(id), - name: name, - rename: rename, - }, - PathListMod { id, rename } => PathListMod { - id: fld.new_id(id), - rename: rename, - }, - }, - span: fld.new_span(path_list_ident.span), - } - })) - } - }, - span: fld.new_span(span), - } - }) -} - -pub fn fold_attrs(attrs: HirVec, fld: &mut T) -> HirVec { - attrs.move_flat_map(|x| fld.fold_attribute(x)) -} - -pub fn noop_fold_arm(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(d: P, fld: &mut T) -> P { - 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(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: P, fld: &mut T) -> P { - 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), - } - })) - } - 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))) - } - }, - span: fld.new_span(span), - } - }) -} - -pub fn noop_fold_foreign_mod(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(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(n: Name, _: &mut T) -> Name { - n -} - -pub fn noop_fold_ident(i: Ident, _: &mut T) -> Ident { - i -} - -pub fn noop_fold_usize(i: usize, _: &mut T) -> usize { - i -} - -pub fn noop_fold_path(Path { global, segments, span }: Path, fld: &mut T) -> Path { - Path { - global: global, - segments: segments.move_map(|PathSegment { identifier, parameters }| { - PathSegment { - identifier: fld.fold_ident(identifier), - parameters: fld.fold_path_parameters(parameters), - } - }), - span: fld.new_span(span), - } -} - -pub fn noop_fold_path_parameters(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(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(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(l: P, fld: &mut T) -> P { - 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: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), fld).into()), - } - }) -} - -pub fn noop_fold_attribute(at: Attribute, fld: &mut T) -> Option { - 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_explicit_self_underscore(es: ExplicitSelf_, - fld: &mut T) - -> ExplicitSelf_ { - match es { - SelfStatic | SelfValue(_) => es, - SelfRegion(lifetime, m, name) => { - SelfRegion(fld.fold_opt_lifetime(lifetime), m, name) - } - SelfExplicit(typ, name) => { - SelfExplicit(fld.fold_ty(typ), name) - } - } -} - -pub fn noop_fold_explicit_self(Spanned { span, node }: ExplicitSelf, - fld: &mut T) - -> ExplicitSelf { - Spanned { - node: fld.fold_explicit_self_underscore(node), - span: fld.new_span(span), - } -} - -pub fn noop_fold_meta_item(mi: P, fld: &mut T) -> P { - 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_item(e))) - } - MetaItemKind::NameValue(id, s) => MetaItemKind::NameValue(id, s), - }, - span: fld.new_span(span), - } - }) -} - -pub fn noop_fold_arg(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(decl: P, fld: &mut T) -> P { - 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), - NoReturn(span) => NoReturn(span), - }, - variadic: variadic, - } - }) -} - -pub fn noop_fold_ty_param_bound(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(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(tps: HirVec, - fld: &mut T) - -> HirVec { - tps.move_map(|tp| fld.fold_ty_param(tp)) -} - -pub fn noop_fold_lifetime(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(l: LifetimeDef, fld: &mut T) -> LifetimeDef { - LifetimeDef { - lifetime: fld.fold_lifetime(l.lifetime), - bounds: fld.fold_lifetimes(l.bounds), - } -} - -pub fn noop_fold_lifetimes(lts: HirVec, fld: &mut T) -> HirVec { - lts.move_map(|l| fld.fold_lifetime(l)) -} - -pub fn noop_fold_lifetime_defs(lts: HirVec, - fld: &mut T) - -> HirVec { - lts.move_map(|l| fld.fold_lifetime_def(l)) -} - -pub fn noop_fold_opt_lifetime(o_lt: Option, fld: &mut T) -> Option { - o_lt.map(|lt| fld.fold_lifetime(lt)) -} - -pub fn noop_fold_generics(Generics { ty_params, lifetimes, where_clause }: 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), - } -} - -pub fn noop_fold_where_clause(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(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(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(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(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(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(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(MutTy { ty, mutbl }: MutTy, folder: &mut T) -> MutTy { - MutTy { - ty: folder.fold_ty(ty), - mutbl: mutbl, - } -} - -pub fn noop_fold_opt_bounds(b: Option, - folder: &mut T) - -> Option { - b.map(|bounds| folder.fold_bounds(bounds)) -} - -fn noop_fold_bounds(bounds: TyParamBounds, folder: &mut T) -> TyParamBounds { - bounds.move_map(|bound| folder.fold_ty_param_bound(bound)) -} - -pub fn noop_fold_block(b: P, folder: &mut T) -> P { - 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(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)) - } - 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(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(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(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(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: token::special_idents::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(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(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); - // FIXME: we should update the impl_pretty_name, but it uses pretty printing. - // let ident = match node { - // // The node may have changed, recompute the "pretty" impl name. - // ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => { - // impl_pretty_name(maybe_trait, Some(&**ty)) - // } - // _ => ident - // }; - - 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(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(sig: MethodSig, folder: &mut T) -> MethodSig { - MethodSig { - generics: folder.fold_generics(sig.generics), - abi: sig.abi, - explicit_self: folder.fold_explicit_self(sig.explicit_self), - unsafety: sig.unsafety, - constness: sig.constness, - decl: folder.fold_fn_decl(sig.decl), - } -} - -pub fn noop_fold_pat(p: P, folder: &mut T) -> P { - p.map(|Pat { id, node, span }| { - Pat { - id: folder.new_id(id), - node: match node { - PatKind::Wild => PatKind::Wild, - PatKind::Ident(binding_mode, pth1, sub) => { - PatKind::Ident(binding_mode, - Spanned { - span: folder.new_span(pth1.span), - node: folder.fold_ident(pth1.node), - }, - sub.map(|x| folder.fold_pat(x))) - } - PatKind::Lit(e) => PatKind::Lit(folder.fold_expr(e)), - PatKind::TupleStruct(pth, pats) => { - PatKind::TupleStruct(folder.fold_path(pth), - pats.map(|pats| pats.move_map(|x| folder.fold_pat(x)))) - } - PatKind::Path(pth) => { - PatKind::Path(folder.fold_path(pth)) - } - PatKind::QPath(qself, pth) => { - let qself = QSelf { ty: folder.fold_ty(qself.ty), ..qself }; - PatKind::QPath(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::Tup(elts) => PatKind::Tup(elts.move_map(|x| folder.fold_pat(x))), - 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(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_ident) => { - ExprWhile(folder.fold_expr(cond), - folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) - } - ExprLoop(body, opt_ident) => { - ExprLoop(folder.fold_block(body), - opt_ident.map(|i| folder.fold_ident(i))) - } - ExprMatch(expr, arms, source) => { - ExprMatch(folder.fold_expr(expr), - arms.move_map(|x| folder.fold_arm(x)), - source) - } - ExprClosure(capture_clause, decl, body) => { - ExprClosure(capture_clause, - folder.fold_fn_decl(decl), - folder.fold_block(body)) - } - 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_ident) => ExprBreak(opt_ident.map(|label| { - respan(folder.new_span(label.span), folder.fold_ident(label.node)) - })), - ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|label| { - respan(folder.new_span(label.span), folder.fold_ident(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: attrs.map_thin_attrs(|attrs| fold_attrs(attrs.into(), folder).into()), - } -} - -pub fn noop_fold_stmt(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_front/hir.rs b/src/librustc_front/hir.rs deleted file mode 100644 index 86f8635f58d..00000000000 --- a/src/librustc_front/hir.rs +++ /dev/null @@ -1,1458 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// The Rust HIR. - -pub use self::BindingMode::*; -pub use self::BinOp_::*; -pub use self::BlockCheckMode::*; -pub use self::CaptureClause::*; -pub use self::Decl_::*; -pub use self::ExplicitSelf_::*; -pub use self::Expr_::*; -pub use self::FunctionRetTy::*; -pub use self::ForeignItem_::*; -pub use self::Item_::*; -pub use self::Mutability::*; -pub use self::PathListItem_::*; -pub use self::PrimTy::*; -pub use self::Stmt_::*; -pub use self::TraitItem_::*; -pub use self::Ty_::*; -pub use self::TyParamBound::*; -pub use self::UnOp::*; -pub use self::UnsafeSource::*; -pub use self::ViewPath_::*; -pub use self::Visibility::*; -pub use self::PathParameters::*; - -use intravisit::Visitor; -use std::collections::BTreeMap; -use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; -use syntax::abi::Abi; -use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; -use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, MetaItem}; -use syntax::attr::{ThinAttributes, ThinAttributesExt}; -use syntax::parse::token::InternedString; -use syntax::ptr::P; - -use print::pprust; -use util; - -use std::fmt; -use std::hash::{Hash, Hasher}; -use serialize::{Encodable, Decodable, Encoder, Decoder}; - -/// HIR doesn't commit to a concrete storage type and have its own alias for a vector. -/// It can be `Vec`, `P<[T]>` or potentially `Box<[T]>`, or some other container with similar -/// behavior. Unlike AST, HIR is mostly a static structure, so we can use an owned slice instead -/// of `Vec` to avoid keeping extra capacity. -pub type HirVec = P<[T]>; - -macro_rules! hir_vec { - ($elem:expr; $n:expr) => ( - $crate::hir::HirVec::from(vec![$elem; $n]) - ); - ($($x:expr),*) => ( - $crate::hir::HirVec::from(vec![$($x),*]) - ); - ($($x:expr,)*) => (vec![$($x),*]) -} - -/// Identifier in HIR -#[derive(Clone, Copy, Eq)] -pub struct Ident { - /// Hygienic name (renamed), should be used by default - pub name: Name, - /// Unhygienic name (original, not renamed), needed in few places in name resolution - pub unhygienic_name: Name, -} - -impl Ident { - /// Creates a HIR identifier with both `name` and `unhygienic_name` initialized with - /// the argument. Hygiene properties of the created identifier depend entirely on this - /// argument. If the argument is a plain interned string `intern("iter")`, then the result - /// is unhygienic and can interfere with other entities named "iter". If the argument is - /// a "fresh" name created with `gensym("iter")`, then the result is hygienic and can't - /// interfere with other entities having the same string as a name. - pub fn from_name(name: Name) -> Ident { - Ident { name: name, unhygienic_name: name } - } -} - -impl PartialEq for Ident { - fn eq(&self, other: &Ident) -> bool { - self.name == other.name - } -} - -impl Hash for Ident { - fn hash(&self, state: &mut H) { - self.name.hash(state) - } -} - -impl fmt::Debug for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Debug::fmt(&self.name, f) - } -} - -impl fmt::Display for Ident { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(&self.name, f) - } -} - -impl Encodable for Ident { - fn encode(&self, s: &mut S) -> Result<(), S::Error> { - self.name.encode(s) - } -} - -impl Decodable for Ident { - fn decode(d: &mut D) -> Result { - Ok(Ident::from_name(Name::decode(d)?)) - } -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Copy)] -pub struct Lifetime { - pub id: NodeId, - pub span: Span, - pub name: Name, -} - -impl fmt::Debug for Lifetime { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, - "lifetime({}: {})", - self.id, - pprust::lifetime_to_string(self)) - } -} - -/// A lifetime definition, eg `'a: 'b+'c+'d` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct LifetimeDef { - pub lifetime: Lifetime, - pub bounds: HirVec, -} - -/// A "Path" is essentially Rust's notion of a name; for instance: -/// std::cmp::PartialEq . It's represented as a sequence of identifiers, -/// along with a bunch of supporting information. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub struct Path { - pub span: Span, - /// A `::foo` path, is relative to the crate root rather than current - /// module (like paths in an import). - pub global: bool, - /// The segments in the path: the things separated by `::`. - pub segments: HirVec, -} - -impl fmt::Debug for Path { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "path({})", pprust::path_to_string(self)) - } -} - -impl fmt::Display for Path { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", pprust::path_to_string(self)) - } -} - -/// A segment of a path: an identifier, an optional lifetime, and a set of -/// types. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct PathSegment { - /// The identifier portion of this path segment. - /// - /// Hygiene properties of this identifier are worth noting. - /// Most path segments are not hygienic and they are not renamed during - /// lowering from AST to HIR (see comments to `fn lower_path`). However segments from - /// unqualified paths with one segment originating from `ExprPath` (local-variable-like paths) - /// can be hygienic, so they are renamed. You should not normally care about this peculiarity - /// and just use `identifier.name` unless you modify identifier resolution code - /// (`fn resolve_identifier` and other functions called by it in `rustc_resolve`). - pub identifier: Ident, - - /// Type/lifetime parameters attached to this path. They come in - /// two flavors: `Path` and `Path(A,B) -> C`. Note that - /// this is more than just simple syntactic sugar; the use of - /// parens affects the region binding rules, so we preserve the - /// distinction. - pub parameters: PathParameters, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum PathParameters { - /// The `<'a, A,B,C>` in `foo::bar::baz::<'a, A,B,C>` - AngleBracketedParameters(AngleBracketedParameterData), - /// The `(A,B)` and `C` in `Foo(A,B) -> C` - ParenthesizedParameters(ParenthesizedParameterData), -} - -impl PathParameters { - pub fn none() -> PathParameters { - AngleBracketedParameters(AngleBracketedParameterData { - lifetimes: HirVec::new(), - types: HirVec::new(), - bindings: HirVec::new(), - }) - } - - pub fn is_empty(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => data.is_empty(), - - // Even if the user supplied no types, something like - // `X()` is equivalent to `X<(),()>`. - ParenthesizedParameters(..) => false, - } - } - - pub fn has_lifetimes(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => !data.lifetimes.is_empty(), - ParenthesizedParameters(_) => false, - } - } - - pub fn has_types(&self) -> bool { - match *self { - AngleBracketedParameters(ref data) => !data.types.is_empty(), - ParenthesizedParameters(..) => true, - } - } - - /// Returns the types that the user wrote. Note that these do not necessarily map to the type - /// parameters in the parenthesized case. - pub fn types(&self) -> HirVec<&P> { - match *self { - AngleBracketedParameters(ref data) => { - data.types.iter().collect() - } - ParenthesizedParameters(ref data) => { - data.inputs - .iter() - .chain(data.output.iter()) - .collect() - } - } - } - - pub fn lifetimes(&self) -> HirVec<&Lifetime> { - match *self { - AngleBracketedParameters(ref data) => { - data.lifetimes.iter().collect() - } - ParenthesizedParameters(_) => { - HirVec::new() - } - } - } - - pub fn bindings(&self) -> HirVec<&TypeBinding> { - match *self { - AngleBracketedParameters(ref data) => { - data.bindings.iter().collect() - } - ParenthesizedParameters(_) => { - HirVec::new() - } - } - } -} - -/// A path like `Foo<'a, T>` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct AngleBracketedParameterData { - /// The lifetime parameters for this path segment. - pub lifetimes: HirVec, - /// The type parameters for this path segment, if present. - pub types: HirVec>, - /// Bindings (equality constraints) on associated types, if present. - /// E.g., `Foo`. - pub bindings: HirVec, -} - -impl AngleBracketedParameterData { - fn is_empty(&self) -> bool { - self.lifetimes.is_empty() && self.types.is_empty() && self.bindings.is_empty() - } -} - -/// A path like `Foo(A,B) -> C` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ParenthesizedParameterData { - /// Overall span - pub span: Span, - - /// `(A,B)` - pub inputs: HirVec>, - - /// `C` - pub output: Option>, -} - -/// The AST represents all type param bounds as types. -/// typeck::collect::compute_bounds matches these against -/// the "special" built-in traits (see middle::lang_items) and -/// detects Copy, Send and Sync. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum TyParamBound { - TraitTyParamBound(PolyTraitRef, TraitBoundModifier), - RegionTyParamBound(Lifetime), -} - -/// A modifier on a bound, currently this is only used for `?Sized`, where the -/// modifier is `Maybe`. Negative bounds should also be handled here. -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum TraitBoundModifier { - None, - Maybe, -} - -pub type TyParamBounds = HirVec; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TyParam { - pub name: Name, - pub id: NodeId, - pub bounds: TyParamBounds, - pub default: Option>, - pub span: Span, -} - -/// Represents lifetimes and type parameters attached to a declaration -/// of a function, enum, trait, etc. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Generics { - pub lifetimes: HirVec, - pub ty_params: HirVec, - pub where_clause: WhereClause, -} - -impl Generics { - pub fn is_lt_parameterized(&self) -> bool { - !self.lifetimes.is_empty() - } - pub fn is_type_parameterized(&self) -> bool { - !self.ty_params.is_empty() - } - pub fn is_parameterized(&self) -> bool { - self.is_lt_parameterized() || self.is_type_parameterized() - } -} - -/// A `where` clause in a definition -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct WhereClause { - pub id: NodeId, - pub predicates: HirVec, -} - -/// A single predicate in a `where` clause -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum WherePredicate { - /// A type binding, eg `for<'c> Foo: Send+Clone+'c` - BoundPredicate(WhereBoundPredicate), - /// A lifetime predicate, e.g. `'a: 'b+'c` - RegionPredicate(WhereRegionPredicate), - /// An equality predicate (unsupported) - EqPredicate(WhereEqPredicate), -} - -/// A type bound, eg `for<'c> Foo: Send+Clone+'c` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct WhereBoundPredicate { - pub span: Span, - /// Any lifetimes from a `for` binding - pub bound_lifetimes: HirVec, - /// The type being bounded - pub bounded_ty: P, - /// Trait and lifetime bounds (`Clone+Send+'static`) - pub bounds: TyParamBounds, -} - -/// A lifetime predicate, e.g. `'a: 'b+'c` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct WhereRegionPredicate { - pub span: Span, - pub lifetime: Lifetime, - pub bounds: HirVec, -} - -/// An equality predicate (unsupported), e.g. `T=int` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct WhereEqPredicate { - pub id: NodeId, - pub span: Span, - pub path: Path, - pub ty: P, -} - -pub type CrateConfig = HirVec>; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] -pub struct Crate { - pub module: Mod, - pub attrs: HirVec, - pub config: CrateConfig, - pub span: Span, - pub exported_macros: HirVec, - - // NB: We use a BTreeMap here so that `visit_all_items` iterates - // over the ids in increasing order. In principle it should not - // matter what order we visit things in, but in *practice* it - // does, because it can affect the order in which errors are - // detected, which in turn can make compile-fail tests yield - // slightly different results. - pub items: BTreeMap, -} - -impl Crate { - pub fn item(&self, id: NodeId) -> &Item { - &self.items[&id] - } - - /// Visits all items in the crate in some determinstic (but - /// unspecified) order. If you just need to process every item, - /// but don't care about nesting, this method is the best choice. - /// - /// If you do care about nesting -- usually because your algorithm - /// follows lexical scoping rules -- then you want a different - /// approach. You should override `visit_nested_item` in your - /// visitor and then call `intravisit::walk_crate` instead. - pub fn visit_all_items<'hir, V:Visitor<'hir>>(&'hir self, visitor: &mut V) { - for (_, item) in &self.items { - visitor.visit_item(item); - } - } -} - -/// A macro definition, in this crate or imported from another. -/// -/// Not parsed directly, but created on macro import or `macro_rules!` expansion. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct MacroDef { - pub name: Name, - pub attrs: HirVec, - pub id: NodeId, - pub span: Span, - pub imported_from: Option, - pub export: bool, - pub use_locally: bool, - pub allow_internal_unstable: bool, - pub body: HirVec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Block { - /// Statements in a block - pub stmts: HirVec, - /// An expression at the end of the block - /// without a semicolon, if any - pub expr: Option>, - pub id: NodeId, - /// Distinguishes between `unsafe { ... }` and `{ ... }` - pub rules: BlockCheckMode, - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub struct Pat { - pub id: NodeId, - pub node: PatKind, - pub span: Span, -} - -impl fmt::Debug for Pat { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "pat({}: {})", self.id, pprust::pat_to_string(self)) - } -} - -/// A single field in a struct pattern -/// -/// Patterns like the fields of Foo `{ x, ref y, ref mut z }` -/// are treated the same as` x: x, y: ref y, z: ref mut z`, -/// except is_shorthand is true -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct FieldPat { - /// The identifier for the field - pub name: Name, - /// The pattern the field is destructured to - pub pat: P, - pub is_shorthand: bool, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum BindingMode { - BindByRef(Mutability), - BindByValue(Mutability), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum PatKind { - /// Represents a wildcard pattern (`_`) - Wild, - - /// A `PatKind::Ident` may either be a new bound variable, - /// or a unit struct/variant pattern, or a const pattern (in the last two cases - /// the third field must be `None`). - /// - /// In the unit or const pattern case, the parser can't determine - /// which it is. The resolver determines this, and - /// records this pattern's `NodeId` in an auxiliary - /// set (of "PatIdents that refer to unit patterns or constants"). - Ident(BindingMode, Spanned, Option>), - - /// A struct or struct variant pattern, e.g. `Variant {x, y, ..}`. - /// The `bool` is `true` in the presence of a `..`. - Struct(Path, HirVec>, bool), - - /// A tuple struct/variant pattern `Variant(x, y, z)`. - /// "None" means a `Variant(..)` pattern where we don't bind the fields to names. - TupleStruct(Path, Option>>), - - /// A path pattern. - /// Such pattern can be resolved to a unit struct/variant or a constant. - Path(Path), - - /// An associated const named using the qualified path `::CONST` or - /// `::CONST`. Associated consts from inherent impls can be - /// referred to as simply `T::CONST`, in which case they will end up as - /// PatKind::Path, and the resolver will have to sort that out. - QPath(QSelf, Path), - - /// A tuple pattern `(a, b)` - Tup(HirVec>), - /// A `box` pattern - Box(P), - /// A reference pattern, e.g. `&mut (a, b)` - Ref(P, Mutability), - /// A literal - Lit(P), - /// A range pattern, e.g. `1...2` - Range(P, P), - /// `[a, b, ..i, y, z]` is represented as: - /// `PatKind::Vec(box [a, b], Some(i), box [y, z])` - Vec(HirVec>, Option>, HirVec>), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum Mutability { - MutMutable, - MutImmutable, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum BinOp_ { - /// The `+` operator (addition) - BiAdd, - /// The `-` operator (subtraction) - BiSub, - /// The `*` operator (multiplication) - BiMul, - /// The `/` operator (division) - BiDiv, - /// The `%` operator (modulus) - BiRem, - /// The `&&` operator (logical and) - BiAnd, - /// The `||` operator (logical or) - BiOr, - /// The `^` operator (bitwise xor) - BiBitXor, - /// The `&` operator (bitwise and) - BiBitAnd, - /// The `|` operator (bitwise or) - BiBitOr, - /// The `<<` operator (shift left) - BiShl, - /// The `>>` operator (shift right) - BiShr, - /// The `==` operator (equality) - BiEq, - /// The `<` operator (less than) - BiLt, - /// The `<=` operator (less than or equal to) - BiLe, - /// The `!=` operator (not equal to) - BiNe, - /// The `>=` operator (greater than or equal to) - BiGe, - /// The `>` operator (greater than) - BiGt, -} - -pub type BinOp = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum UnOp { - /// The `*` operator for dereferencing - UnDeref, - /// The `!` operator for logical inversion - UnNot, - /// The `-` operator for negation - UnNeg, -} - -/// A statement -pub type Stmt = Spanned; - -impl fmt::Debug for Stmt_ { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Sadness. - let spanned = codemap::dummy_spanned(self.clone()); - write!(f, - "stmt({}: {})", - util::stmt_id(&spanned), - pprust::stmt_to_string(&spanned)) - } -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub enum Stmt_ { - /// Could be an item or a local (let) binding: - StmtDecl(P, NodeId), - - /// Expr without trailing semi-colon (must have unit type): - StmtExpr(P, NodeId), - - /// Expr with trailing semi-colon (may have any type): - StmtSemi(P, NodeId), -} - -impl Stmt_ { - pub fn attrs(&self) -> &[Attribute] { - match *self { - StmtDecl(ref d, _) => d.node.attrs(), - StmtExpr(ref e, _) | - StmtSemi(ref e, _) => e.attrs.as_attr_slice(), - } - } -} - -// FIXME (pending discussion of #1697, #2178...): local should really be -// a refinement on pat. -/// Local represents a `let` statement, e.g., `let : = ;` -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Local { - pub pat: P, - pub ty: Option>, - /// Initializer expression to set the value, if any - pub init: Option>, - pub id: NodeId, - pub span: Span, - pub attrs: ThinAttributes, -} - -pub type Decl = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Decl_ { - /// A local (let) binding: - DeclLocal(P), - /// An item binding: - DeclItem(ItemId), -} - -impl Decl_ { - pub fn attrs(&self) -> &[Attribute] { - match *self { - DeclLocal(ref l) => l.attrs.as_attr_slice(), - DeclItem(_) => &[] - } - } -} - -/// represents one arm of a 'match' -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Arm { - pub attrs: HirVec, - pub pats: HirVec>, - pub guard: Option>, - pub body: P, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Field { - pub name: Spanned, - pub expr: P, - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum BlockCheckMode { - DefaultBlock, - UnsafeBlock(UnsafeSource), - PushUnsafeBlock(UnsafeSource), - PopUnsafeBlock(UnsafeSource), - // Within this block (but outside a PopUnstableBlock), we suspend checking of stability. - PushUnstableBlock, - PopUnstableBlock, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum UnsafeSource { - CompilerGenerated, - UserProvided, -} - -/// An expression -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub struct Expr { - pub id: NodeId, - pub node: Expr_, - pub span: Span, - pub attrs: ThinAttributes, -} - -impl fmt::Debug for Expr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "expr({}: {})", self.id, pprust::expr_to_string(self)) - } -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Expr_ { - /// A `box x` expression. - ExprBox(P), - /// An array (`[a, b, c, d]`) - ExprVec(HirVec>), - /// A function call - /// - /// The first field resolves to the function itself, - /// and the second field is the list of arguments - ExprCall(P, HirVec>), - /// A method call (`x.foo::(a, b, c, d)`) - /// - /// The `Spanned` is the identifier for the method name. - /// The vector of `Ty`s are the ascripted type parameters for the method - /// (within the angle brackets). - /// - /// The first element of the vector of `Expr`s is the expression that evaluates - /// to the object on which the method is being called on (the receiver), - /// and the remaining elements are the rest of the arguments. - /// - /// Thus, `x.foo::(a, b, c, d)` is represented as - /// `ExprMethodCall(foo, [Bar, Baz], [x, a, b, c, d])`. - ExprMethodCall(Spanned, HirVec>, HirVec>), - /// A tuple (`(a, b, c ,d)`) - ExprTup(HirVec>), - /// A binary operation (For example: `a + b`, `a * b`) - ExprBinary(BinOp, P, P), - /// A unary operation (For example: `!x`, `*x`) - ExprUnary(UnOp, P), - /// A literal (For example: `1`, `"foo"`) - ExprLit(P), - /// A cast (`foo as f64`) - ExprCast(P, P), - ExprType(P, P), - /// An `if` block, with an optional else block - /// - /// `if expr { block } else { expr }` - ExprIf(P, P, Option>), - /// A while loop, with an optional label - /// - /// `'label: while expr { block }` - ExprWhile(P, P, Option), - /// Conditionless loop (can be exited with break, continue, or return) - /// - /// `'label: loop { block }` - ExprLoop(P, Option), - /// A `match` block, with a source that indicates whether or not it is - /// the result of a desugaring, and if so, which kind. - ExprMatch(P, HirVec, MatchSource), - /// A closure (for example, `move |a, b, c| {a + b + c}`) - ExprClosure(CaptureClause, P, P), - /// A block (`{ ... }`) - ExprBlock(P), - - /// An assignment (`a = foo()`) - ExprAssign(P, P), - /// An assignment with an operator - /// - /// For example, `a += 1`. - ExprAssignOp(BinOp, P, P), - /// Access of a named struct field (`obj.foo`) - ExprField(P, Spanned), - /// Access of an unnamed field of a struct or tuple-struct - /// - /// For example, `foo.0`. - ExprTupField(P, Spanned), - /// An indexing operation (`foo[2]`) - ExprIndex(P, P), - - /// Variable reference, possibly containing `::` and/or type - /// parameters, e.g. foo::bar::. - /// - /// Optionally "qualified", - /// e.g. ` as SomeTrait>::SomeType`. - ExprPath(Option, Path), - - /// A referencing operation (`&a` or `&mut a`) - ExprAddrOf(Mutability, P), - /// A `break`, with an optional label to break - ExprBreak(Option>), - /// A `continue`, with an optional label - ExprAgain(Option>), - /// A `return`, with an optional value to be returned - ExprRet(Option>), - - /// Inline assembly (from `asm!`), with its outputs and inputs. - ExprInlineAsm(InlineAsm, Vec>, Vec>), - - /// A struct literal expression. - /// - /// For example, `Foo {x: 1, y: 2}`, or - /// `Foo {x: 1, .. base}`, where `base` is the `Option`. - ExprStruct(Path, HirVec, Option>), - - /// A vector literal constructed from one repeated element. - /// - /// For example, `[1; 5]`. The first expression is the element - /// to be repeated; the second is the number of times to repeat it. - ExprRepeat(P, P), -} - -/// The explicit Self type in a "qualified path". The actual -/// path, including the trait and the associated item, is stored -/// separately. `position` represents the index of the associated -/// item qualified with this Self type. -/// -/// as a::b::Trait>::AssociatedItem -/// ^~~~~ ~~~~~~~~~~~~~~^ -/// ty position = 3 -/// -/// >::AssociatedItem -/// ^~~~~ ^ -/// ty position = 0 -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct QSelf { - pub ty: P, - pub position: usize, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum MatchSource { - Normal, - IfLetDesugar { - contains_else_clause: bool, - }, - WhileLetDesugar, - ForLoopDesugar, - TryDesugar, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum CaptureClause { - CaptureByValue, - CaptureByRef, -} - -// NB: If you change this, you'll probably want to change the corresponding -// type structure in middle/ty.rs as well. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct MutTy { - pub ty: P, - pub mutbl: Mutability, -} - -/// Represents a method's signature in a trait declaration, -/// or in an implementation. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct MethodSig { - pub unsafety: Unsafety, - pub constness: Constness, - pub abi: Abi, - pub decl: P, - pub generics: Generics, - pub explicit_self: ExplicitSelf, -} - -/// Represents an item declaration within a trait declaration, -/// possibly including a default implementation. A trait item is -/// either required (meaning it doesn't have an implementation, just a -/// signature) or provided (meaning it has a default implementation). -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TraitItem { - pub id: NodeId, - pub name: Name, - pub attrs: HirVec, - pub node: TraitItem_, - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum TraitItem_ { - ConstTraitItem(P, Option>), - MethodTraitItem(MethodSig, Option>), - TypeTraitItem(TyParamBounds, Option>), -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ImplItem { - pub id: NodeId, - pub name: Name, - pub vis: Visibility, - pub defaultness: Defaultness, - pub attrs: HirVec, - pub node: ImplItemKind, - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ImplItemKind { - Const(P, P), - Method(MethodSig, P), - Type(P), -} - -// Bind a type to an associated type: `A=Foo`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TypeBinding { - pub id: NodeId, - pub name: Name, - pub ty: P, - pub span: Span, -} - - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub struct Ty { - pub id: NodeId, - pub node: Ty_, - pub span: Span, -} - -impl fmt::Debug for Ty { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "type({})", pprust::ty_to_string(self)) - } -} - -/// Not represented directly in the AST, referred to by name through a ty_path. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum PrimTy { - TyInt(IntTy), - TyUint(UintTy), - TyFloat(FloatTy), - TyStr, - TyBool, - TyChar, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct BareFnTy { - pub unsafety: Unsafety, - pub abi: Abi, - pub lifetimes: HirVec, - pub decl: P, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -/// The different kinds of types recognized by the compiler -pub enum Ty_ { - TyVec(P), - /// A fixed length array (`[T; n]`) - TyFixedLengthVec(P, P), - /// A raw pointer (`*const T` or `*mut T`) - TyPtr(MutTy), - /// A reference (`&'a T` or `&'a mut T`) - TyRptr(Option, MutTy), - /// A bare function (e.g. `fn(usize) -> bool`) - TyBareFn(P), - /// A tuple (`(A, B, C, D,...)`) - TyTup(HirVec>), - /// A path (`module::module::...::Type`), optionally - /// "qualified", e.g. ` as SomeTrait>::SomeType`. - /// - /// Type parameters are stored in the Path itself - TyPath(Option, Path), - /// Something like `A+B`. Note that `B` must always be a path. - TyObjectSum(P, TyParamBounds), - /// A type like `for<'a> Foo<&'a Bar>` - TyPolyTraitRef(TyParamBounds), - /// Unused for now - TyTypeof(P), - /// TyInfer means the type should be inferred instead of it having been - /// specified. This can appear anywhere in a type. - TyInfer, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct InlineAsmOutput { - pub constraint: InternedString, - pub is_rw: bool, - pub is_indirect: bool, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct InlineAsm { - pub asm: InternedString, - pub asm_str_style: StrStyle, - pub outputs: HirVec, - pub inputs: HirVec, - pub clobbers: HirVec, - pub volatile: bool, - pub alignstack: bool, - pub dialect: AsmDialect, - pub expn_id: ExpnId, -} - -/// represents an argument in a function header -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Arg { - pub ty: P, - pub pat: P, - pub id: NodeId, -} - -impl Arg { - pub fn new_self(span: Span, mutability: Mutability, self_ident: Ident) -> Arg { - let path = Spanned { - span: span, - node: self_ident, - }; - Arg { - // HACK(eddyb) fake type for the self argument. - ty: P(Ty { - id: DUMMY_NODE_ID, - node: TyInfer, - span: DUMMY_SP, - }), - pat: P(Pat { - id: DUMMY_NODE_ID, - node: PatKind::Ident(BindByValue(mutability), path, None), - span: span, - }), - id: DUMMY_NODE_ID, - } - } -} - -/// Represents the header (not the body) of a function declaration -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct FnDecl { - pub inputs: HirVec, - pub output: FunctionRetTy, - pub variadic: bool, -} - -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Unsafety { - Unsafe, - Normal, -} - -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Constness { - Const, - NotConst, -} - -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Defaultness { - Default, - Final, -} - -impl Defaultness { - pub fn is_final(&self) -> bool { - *self == Defaultness::Final - } - - pub fn is_default(&self) -> bool { - *self == Defaultness::Default - } -} - -impl fmt::Display for Unsafety { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::Display::fmt(match *self { - Unsafety::Normal => "normal", - Unsafety::Unsafe => "unsafe", - }, - f) - } -} - -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)] -pub enum ImplPolarity { - /// `impl Trait for Type` - Positive, - /// `impl !Trait for Type` - Negative, -} - -impl fmt::Debug for ImplPolarity { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - ImplPolarity::Positive => "positive".fmt(f), - ImplPolarity::Negative => "negative".fmt(f), - } - } -} - - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum FunctionRetTy { - /// Functions with return type `!`that always - /// raise an error or exit (i.e. never return to the caller) - NoReturn(Span), - /// Return type is not specified. - /// - /// Functions default to `()` and - /// closures default to inference. Span points to where return - /// type would be inserted. - DefaultReturn(Span), - /// Everything else - Return(P), -} - -impl FunctionRetTy { - pub fn span(&self) -> Span { - match *self { - NoReturn(span) => span, - DefaultReturn(span) => span, - Return(ref ty) => ty.span, - } - } -} - -/// Represents the kind of 'self' associated with a method -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ExplicitSelf_ { - /// No self - SelfStatic, - /// `self` - SelfValue(Name), - /// `&'lt self`, `&'lt mut self` - SelfRegion(Option, Mutability, Name), - /// `self: TYPE` - SelfExplicit(P, Name), -} - -pub type ExplicitSelf = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Mod { - /// A span from the first token past `{` to the last token until `}`. - /// For `mod foo;`, the inner span ranges from the first token - /// to the last token in the external file. - pub inner: Span, - pub item_ids: HirVec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ForeignMod { - pub abi: Abi, - pub items: HirVec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct EnumDef { - pub variants: HirVec, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Variant_ { - pub name: Name, - pub attrs: HirVec, - pub data: VariantData, - /// Explicit discriminant, eg `Foo = 1` - pub disr_expr: Option>, -} - -pub type Variant = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum PathListItem_ { - PathListIdent { - name: Name, - /// renamed in list, eg `use foo::{bar as baz};` - rename: Option, - id: NodeId, - }, - PathListMod { - /// renamed in list, eg `use foo::{self as baz};` - rename: Option, - id: NodeId, - }, -} - -impl PathListItem_ { - pub fn id(&self) -> NodeId { - match *self { - PathListIdent { id, .. } | PathListMod { id, .. } => id, - } - } - - pub fn name(&self) -> Option { - match *self { - PathListIdent { name, .. } => Some(name), - PathListMod { .. } => None, - } - } - - pub fn rename(&self) -> Option { - match *self { - PathListIdent { rename, .. } | PathListMod { rename, .. } => rename, - } - } -} - -pub type PathListItem = Spanned; - -pub type ViewPath = Spanned; - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ViewPath_ { - /// `foo::bar::baz as quux` - /// - /// or just - /// - /// `foo::bar::baz` (with `as baz` implicitly on the right) - ViewPathSimple(Name, Path), - - /// `foo::bar::*` - ViewPathGlob(Path), - - /// `foo::bar::{a,b,c}` - ViewPathList(Path, HirVec), -} - -/// TraitRef's appear in impls. -/// -/// resolve maps each TraitRef's ref_id to its defining trait; that's all -/// that the ref_id is for. The impl_id maps to the "self type" of this impl. -/// If this impl is an ItemImpl, the impl_id is redundant (it could be the -/// same as the impl's node id). -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct TraitRef { - pub path: Path, - pub ref_id: NodeId, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct PolyTraitRef { - /// The `'a` in `<'a> Foo<&'a T>` - pub bound_lifetimes: HirVec, - - /// The `Foo<&'a T>` in `<'a> Foo<&'a T>` - pub trait_ref: TraitRef, - - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] -pub enum Visibility { - Public, - Inherited, -} - -impl Visibility { - pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility { - match self { - &Inherited => parent_visibility, - &Public => *self, - } - } -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct StructField { - pub span: Span, - pub name: Name, - pub vis: Visibility, - pub id: NodeId, - pub ty: P, - pub attrs: HirVec, -} - -impl StructField { - // Still necessary in couple of places - pub fn is_positional(&self) -> bool { - let first = self.name.as_str().as_bytes()[0]; - first >= b'0' && first <= b'9' - } -} - -/// Fields and Ids of enum variants and structs -/// -/// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all -/// variant kinds) and an Id of the variant's constructor (not relevant for `Struct`-variants). -/// One shared Id can be successfully used for these two purposes. -/// Id of the whole enum lives in `Item`. -/// -/// For structs: `NodeId` represents an Id of the structure's constructor, so it is not actually -/// used for `Struct`-structs (but still presents). Structures don't have an analogue of "Id of -/// the variant itself" from enum variants. -/// Id of the whole struct lives in `Item`. -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum VariantData { - Struct(HirVec, NodeId), - Tuple(HirVec, NodeId), - Unit(NodeId), -} - -impl VariantData { - pub fn fields(&self) -> &[StructField] { - match *self { - VariantData::Struct(ref fields, _) | VariantData::Tuple(ref fields, _) => fields, - _ => &[], - } - } - pub fn id(&self) -> NodeId { - match *self { - VariantData::Struct(_, id) | VariantData::Tuple(_, id) | VariantData::Unit(id) => id, - } - } - pub fn is_struct(&self) -> bool { - if let VariantData::Struct(..) = *self { - true - } else { - false - } - } - pub fn is_tuple(&self) -> bool { - if let VariantData::Tuple(..) = *self { - true - } else { - false - } - } - pub fn is_unit(&self) -> bool { - if let VariantData::Unit(..) = *self { - true - } else { - false - } - } -} - -// The bodies for items are stored "out of line", in a separate -// hashmap in the `Crate`. Here we just record the node-id of the item -// so it can fetched later. -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ItemId { - pub id: NodeId, -} - -// FIXME (#3300): Should allow items to be anonymous. Right now -// we just use dummy names for anon items. -/// An item -/// -/// The name might be a dummy name in case of anonymous items -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct Item { - pub name: Name, - pub attrs: HirVec, - pub id: NodeId, - pub node: Item_, - pub vis: Visibility, - pub span: Span, -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Item_ { - /// An`extern crate` item, with optional original crate name, - /// - /// e.g. `extern crate foo` or `extern crate foo_bar as foo` - ItemExternCrate(Option), - /// A `use` or `pub use` item - ItemUse(P), - - /// A `static` item - ItemStatic(P, Mutability, P), - /// A `const` item - ItemConst(P, P), - /// A function declaration - ItemFn(P, Unsafety, Constness, Abi, Generics, P), - /// A module - ItemMod(Mod), - /// An external module - ItemForeignMod(ForeignMod), - /// A type alias, e.g. `type Foo = Bar` - ItemTy(P, Generics), - /// An enum definition, e.g. `enum Foo {C, D}` - ItemEnum(EnumDef, Generics), - /// A struct definition, e.g. `struct Foo {x: A}` - ItemStruct(VariantData, Generics), - /// Represents a Trait Declaration - ItemTrait(Unsafety, Generics, TyParamBounds, HirVec), - - // Default trait implementations - /// - /// `impl Trait for .. {}` - ItemDefaultImpl(Unsafety, TraitRef), - /// An implementation, eg `impl Trait for Foo { .. }` - ItemImpl(Unsafety, - ImplPolarity, - Generics, - Option, // (optional) trait this impl implements - P, // self - HirVec), -} - -impl Item_ { - pub fn descriptive_variant(&self) -> &str { - match *self { - ItemExternCrate(..) => "extern crate", - ItemUse(..) => "use", - ItemStatic(..) => "static item", - ItemConst(..) => "constant item", - ItemFn(..) => "function", - ItemMod(..) => "module", - ItemForeignMod(..) => "foreign module", - ItemTy(..) => "type alias", - ItemEnum(..) => "enum", - ItemStruct(..) => "struct", - ItemTrait(..) => "trait", - ItemImpl(..) | - ItemDefaultImpl(..) => "item", - } - } -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct ForeignItem { - pub name: Name, - pub attrs: HirVec, - pub node: ForeignItem_, - pub id: NodeId, - pub span: Span, - pub vis: Visibility, -} - -/// An item within an `extern` block -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum ForeignItem_ { - /// A foreign function - ForeignItemFn(P, Generics), - /// A foreign static item (`static ext: u8`), with optional mutability - /// (the boolean is true when mutable) - ForeignItemStatic(P, bool), -} - -impl ForeignItem_ { - pub fn descriptive_variant(&self) -> &str { - match *self { - ForeignItemFn(..) => "foreign function", - ForeignItemStatic(..) => "foreign static item", - } - } -} diff --git a/src/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs deleted file mode 100644 index be1cc528d88..00000000000 --- a/src/librustc_front/intravisit.rs +++ /dev/null @@ -1,837 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! HIR walker. Each overridden visit method has full control over what -//! happens with its node, it can do its own traversal of the node's children, -//! call `intravisit::walk_*` to apply the default traversal algorithm, or prevent -//! deeper traversal by doing nothing. -//! -//! When visiting the HIR, the contents of nested items are NOT visited -//! by default. This is different from the AST visitor, which does a deep walk. -//! Hence this module is called `intravisit`; see the method `visit_nested_item` -//! for more details. -//! -//! Note: it is an important invariant that the default visitor walks -//! the body of a function in "execution order" (more concretely, -//! reverse post-order with respect to the CFG implied by the AST), -//! meaning that if AST node A may execute before AST node B, then A -//! is visited first. The borrow checker in particular relies on this -//! property. - -use syntax::abi::Abi; -use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; -use syntax::attr::ThinAttributesExt; -use syntax::codemap::Span; -use hir::*; - -#[derive(Copy, Clone, PartialEq, Eq)] -pub enum FnKind<'a> { - /// fn foo() or extern "Abi" fn foo() - ItemFn(Name, &'a Generics, Unsafety, Constness, Abi, Visibility, &'a [Attribute]), - - /// fn foo(&self) - Method(Name, &'a MethodSig, Option, &'a [Attribute]), - - /// |x, y| {} - Closure(&'a [Attribute]), -} - -impl<'a> FnKind<'a> { - pub fn attrs(&self) -> &'a [Attribute] { - match *self { - FnKind::ItemFn(_, _, _, _, _, _, attrs) => attrs, - FnKind::Method(_, _, _, attrs) => attrs, - FnKind::Closure(attrs) => attrs, - } - } -} - -/// Each method of the Visitor trait is a hook to be potentially -/// overridden. Each method's default implementation recursively visits -/// the substructure of the input via the corresponding `walk` method; -/// e.g. the `visit_mod` method by default calls `intravisit::walk_mod`. -/// -/// Note that this visitor does NOT visit nested items by default -/// (this is why the module is called `intravisit`, to distinguish it -/// from the AST's `visit` module, which acts differently). If you -/// simply want to visit all items in the crate in some order, you -/// should call `Crate::visit_all_items`. Otherwise, see the comment -/// on `visit_nested_item` for details on how to visit nested items. -/// -/// If you want to ensure that your code handles every variant -/// explicitly, you need to override each method. (And you also need -/// to monitor future changes to `Visitor` in case a new method with a -/// new default implementation gets introduced.) -pub trait Visitor<'v> : Sized { - /////////////////////////////////////////////////////////////////////////// - // Nested items. - - /// Invoked when a nested item is encountered. By default, does - /// nothing. If you want a deep walk, you need to override to - /// fetch the item contents. But most of the time, it is easier - /// (and better) to invoke `Crate::visit_all_items`, which visits - /// all items in the crate in some order (but doesn't respect - /// nesting). - #[allow(unused_variables)] - fn visit_nested_item(&mut self, id: ItemId) { - } - - /// Visit the top-level item and (optionally) nested items. See - /// `visit_nested_item` for details. - fn visit_item(&mut self, i: &'v Item) { - walk_item(self, i) - } - - /////////////////////////////////////////////////////////////////////////// - - fn visit_name(&mut self, _span: Span, _name: Name) { - // Nothing to do. - } - fn visit_ident(&mut self, span: Span, ident: Ident) { - walk_ident(self, span, ident); - } - fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { - walk_mod(self, m) - } - fn visit_foreign_item(&mut self, i: &'v ForeignItem) { - walk_foreign_item(self, i) - } - fn visit_local(&mut self, l: &'v Local) { - walk_local(self, l) - } - fn visit_block(&mut self, b: &'v Block) { - walk_block(self, b) - } - fn visit_stmt(&mut self, s: &'v Stmt) { - walk_stmt(self, s) - } - fn visit_arm(&mut self, a: &'v Arm) { - walk_arm(self, a) - } - fn visit_pat(&mut self, p: &'v Pat) { - walk_pat(self, p) - } - fn visit_decl(&mut self, d: &'v Decl) { - walk_decl(self, d) - } - fn visit_expr(&mut self, ex: &'v Expr) { - walk_expr(self, ex) - } - fn visit_expr_post(&mut self, _ex: &'v Expr) { - } - fn visit_ty(&mut self, t: &'v Ty) { - walk_ty(self, t) - } - fn visit_generics(&mut self, g: &'v Generics) { - walk_generics(self, g) - } - fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, _: NodeId) { - walk_fn(self, fk, fd, b, s) - } - fn visit_trait_item(&mut self, ti: &'v TraitItem) { - walk_trait_item(self, ti) - } - fn visit_impl_item(&mut self, ii: &'v ImplItem) { - walk_impl_item(self, ii) - } - fn visit_trait_ref(&mut self, t: &'v TraitRef) { - walk_trait_ref(self, t) - } - fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) { - walk_ty_param_bound(self, bounds) - } - fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: &'v TraitBoundModifier) { - walk_poly_trait_ref(self, t, m) - } - fn visit_variant_data(&mut self, - s: &'v VariantData, - _: Name, - _: &'v Generics, - _: NodeId, - _: Span) { - walk_struct_def(self, s) - } - fn visit_struct_field(&mut self, s: &'v StructField) { - walk_struct_field(self, s) - } - fn visit_enum_def(&mut self, - enum_definition: &'v EnumDef, - generics: &'v Generics, - item_id: NodeId, - _: Span) { - walk_enum_def(self, enum_definition, generics, item_id) - } - fn visit_variant(&mut self, v: &'v Variant, g: &'v Generics, item_id: NodeId) { - walk_variant(self, v, g, item_id) - } - fn visit_lifetime(&mut self, lifetime: &'v Lifetime) { - walk_lifetime(self, lifetime) - } - fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) { - walk_lifetime_def(self, lifetime) - } - fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) { - walk_explicit_self(self, es) - } - fn visit_path(&mut self, path: &'v Path, _id: NodeId) { - walk_path(self, path) - } - fn visit_path_list_item(&mut self, prefix: &'v Path, item: &'v PathListItem) { - walk_path_list_item(self, prefix, item) - } - fn visit_path_segment(&mut self, path_span: Span, path_segment: &'v PathSegment) { - walk_path_segment(self, path_span, path_segment) - } - fn visit_path_parameters(&mut self, path_span: Span, path_parameters: &'v PathParameters) { - walk_path_parameters(self, path_span, path_parameters) - } - fn visit_assoc_type_binding(&mut self, type_binding: &'v TypeBinding) { - walk_assoc_type_binding(self, type_binding) - } - fn visit_attribute(&mut self, _attr: &'v Attribute) { - } - fn visit_macro_def(&mut self, macro_def: &'v MacroDef) { - walk_macro_def(self, macro_def) - } -} - -pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option) { - for name in opt_name { - visitor.visit_name(span, name); - } -} - -pub fn walk_opt_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_ident: Option) { - for ident in opt_ident { - visitor.visit_ident(span, ident); - } -} - -pub fn walk_ident<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, ident: Ident) { - visitor.visit_name(span, ident.name); -} - -/// Walks the contents of a crate. See also `Crate::visit_all_items`. -pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) { - visitor.visit_mod(&krate.module, krate.span, CRATE_NODE_ID); - walk_list!(visitor, visit_attribute, &krate.attrs); - walk_list!(visitor, visit_macro_def, &krate.exported_macros); -} - -pub fn walk_macro_def<'v, V: Visitor<'v>>(visitor: &mut V, macro_def: &'v MacroDef) { - visitor.visit_name(macro_def.span, macro_def.name); - walk_opt_name(visitor, macro_def.span, macro_def.imported_from); - walk_list!(visitor, visit_attribute, ¯o_def.attrs); -} - -pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) { - for &item_id in &module.item_ids { - visitor.visit_nested_item(item_id); - } -} - -pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) { - visitor.visit_pat(&local.pat); - walk_list!(visitor, visit_ty, &local.ty); - walk_list!(visitor, visit_expr, &local.init); -} - -pub fn walk_lifetime<'v, V: Visitor<'v>>(visitor: &mut V, lifetime: &'v Lifetime) { - visitor.visit_name(lifetime.span, lifetime.name); -} - -pub fn walk_lifetime_def<'v, V: Visitor<'v>>(visitor: &mut V, lifetime_def: &'v LifetimeDef) { - visitor.visit_lifetime(&lifetime_def.lifetime); - walk_list!(visitor, visit_lifetime, &lifetime_def.bounds); -} - -pub fn walk_explicit_self<'v, V: Visitor<'v>>(visitor: &mut V, explicit_self: &'v ExplicitSelf) { - match explicit_self.node { - SelfStatic => {} - SelfValue(name) => { - visitor.visit_name(explicit_self.span, name) - } - SelfRegion(ref opt_lifetime, _, name) => { - visitor.visit_name(explicit_self.span, name); - walk_list!(visitor, visit_lifetime, opt_lifetime); - } - SelfExplicit(ref typ, name) => { - visitor.visit_name(explicit_self.span, name); - visitor.visit_ty(typ) - } - } -} - -pub fn walk_poly_trait_ref<'v, V>(visitor: &mut V, - trait_ref: &'v PolyTraitRef, - _modifier: &'v TraitBoundModifier) - where V: Visitor<'v> -{ - walk_list!(visitor, visit_lifetime_def, &trait_ref.bound_lifetimes); - visitor.visit_trait_ref(&trait_ref.trait_ref); -} - -pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) - where V: Visitor<'v> -{ - visitor.visit_path(&trait_ref.path, trait_ref.ref_id) -} - -pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { - visitor.visit_name(item.span, item.name); - match item.node { - ItemExternCrate(opt_name) => { - walk_opt_name(visitor, item.span, opt_name) - } - ItemUse(ref vp) => { - match vp.node { - ViewPathSimple(name, ref path) => { - visitor.visit_name(vp.span, name); - visitor.visit_path(path, item.id); - } - ViewPathGlob(ref path) => { - visitor.visit_path(path, item.id); - } - ViewPathList(ref prefix, ref list) => { - if !list.is_empty() { - for item in list { - visitor.visit_path_list_item(prefix, item) - } - } else { - visitor.visit_path(prefix, item.id); - } - } - } - } - ItemStatic(ref typ, _, ref expr) | - ItemConst(ref typ, ref expr) => { - visitor.visit_ty(typ); - visitor.visit_expr(expr); - } - ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => { - visitor.visit_fn(FnKind::ItemFn(item.name, - generics, - unsafety, - constness, - abi, - item.vis, - &item.attrs), - declaration, - body, - item.span, - item.id) - } - ItemMod(ref module) => { - visitor.visit_mod(module, item.span, item.id) - } - ItemForeignMod(ref foreign_module) => { - walk_list!(visitor, visit_foreign_item, &foreign_module.items); - } - ItemTy(ref typ, ref type_parameters) => { - visitor.visit_ty(typ); - visitor.visit_generics(type_parameters) - } - ItemEnum(ref enum_definition, ref type_parameters) => { - visitor.visit_generics(type_parameters); - visitor.visit_enum_def(enum_definition, type_parameters, item.id, item.span) - } - ItemDefaultImpl(_, ref trait_ref) => { - visitor.visit_trait_ref(trait_ref) - } - ItemImpl(_, _, ref type_parameters, ref opt_trait_reference, ref typ, ref impl_items) => { - visitor.visit_generics(type_parameters); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item, impl_items); - } - ItemStruct(ref struct_definition, ref generics) => { - visitor.visit_generics(generics); - visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); - } - ItemTrait(_, ref generics, ref bounds, ref methods) => { - visitor.visit_generics(generics); - walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_trait_item, methods); - } - } - walk_list!(visitor, visit_attribute, &item.attrs); -} - -pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, - enum_definition: &'v EnumDef, - generics: &'v Generics, - item_id: NodeId) { - walk_list!(visitor, - visit_variant, - &enum_definition.variants, - generics, - item_id); -} - -pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, - variant: &'v Variant, - generics: &'v Generics, - item_id: NodeId) { - visitor.visit_name(variant.span, variant.node.name); - visitor.visit_variant_data(&variant.node.data, - variant.node.name, - generics, - item_id, - variant.span); - walk_list!(visitor, visit_expr, &variant.node.disr_expr); - walk_list!(visitor, visit_attribute, &variant.node.attrs); -} - -pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { - match typ.node { - TyVec(ref ty) => { - visitor.visit_ty(ty) - } - TyPtr(ref mutable_type) => { - visitor.visit_ty(&mutable_type.ty) - } - TyRptr(ref opt_lifetime, ref mutable_type) => { - walk_list!(visitor, visit_lifetime, opt_lifetime); - visitor.visit_ty(&mutable_type.ty) - } - TyTup(ref tuple_element_types) => { - walk_list!(visitor, visit_ty, tuple_element_types); - } - TyBareFn(ref function_declaration) => { - walk_fn_decl(visitor, &function_declaration.decl); - walk_list!(visitor, visit_lifetime_def, &function_declaration.lifetimes); - } - TyPath(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { - visitor.visit_ty(&qself.ty); - } - visitor.visit_path(path, typ.id); - } - TyObjectSum(ref ty, ref bounds) => { - visitor.visit_ty(ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - } - TyFixedLengthVec(ref ty, ref expression) => { - visitor.visit_ty(ty); - visitor.visit_expr(expression) - } - TyPolyTraitRef(ref bounds) => { - walk_list!(visitor, visit_ty_param_bound, bounds); - } - TyTypeof(ref expression) => { - visitor.visit_expr(expression) - } - TyInfer => {} - } -} - -pub fn walk_path<'v, V: Visitor<'v>>(visitor: &mut V, path: &'v Path) { - for segment in &path.segments { - visitor.visit_path_segment(path.span, segment); - } -} - -pub fn walk_path_list_item<'v, V: Visitor<'v>>(visitor: &mut V, - prefix: &'v Path, - item: &'v PathListItem) { - for segment in &prefix.segments { - visitor.visit_path_segment(prefix.span, segment); - } - - walk_opt_name(visitor, item.span, item.node.name()); - walk_opt_name(visitor, item.span, item.node.rename()); -} - -pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, - path_span: Span, - segment: &'v PathSegment) { - visitor.visit_ident(path_span, segment.identifier); - visitor.visit_path_parameters(path_span, &segment.parameters); -} - -pub fn walk_path_parameters<'v, V: Visitor<'v>>(visitor: &mut V, - _path_span: Span, - path_parameters: &'v PathParameters) { - match *path_parameters { - AngleBracketedParameters(ref data) => { - walk_list!(visitor, visit_ty, &data.types); - walk_list!(visitor, visit_lifetime, &data.lifetimes); - walk_list!(visitor, visit_assoc_type_binding, &data.bindings); - } - ParenthesizedParameters(ref data) => { - walk_list!(visitor, visit_ty, &data.inputs); - walk_list!(visitor, visit_ty, &data.output); - } - } -} - -pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, - type_binding: &'v TypeBinding) { - visitor.visit_name(type_binding.span, type_binding.name); - visitor.visit_ty(&type_binding.ty); -} - -pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { - match pattern.node { - PatKind::TupleStruct(ref path, ref opt_children) => { - visitor.visit_path(path, pattern.id); - if let Some(ref children) = *opt_children { - walk_list!(visitor, visit_pat, children); - } - } - PatKind::Path(ref path) => { - visitor.visit_path(path, pattern.id); - } - PatKind::QPath(ref qself, ref path) => { - visitor.visit_ty(&qself.ty); - visitor.visit_path(path, pattern.id) - } - PatKind::Struct(ref path, ref fields, _) => { - visitor.visit_path(path, pattern.id); - for field in fields { - visitor.visit_name(field.span, field.node.name); - visitor.visit_pat(&field.node.pat) - } - } - PatKind::Tup(ref tuple_elements) => { - walk_list!(visitor, visit_pat, tuple_elements); - } - PatKind::Box(ref subpattern) | - PatKind::Ref(ref subpattern, _) => { - visitor.visit_pat(subpattern) - } - PatKind::Ident(_, ref pth1, ref optional_subpattern) => { - visitor.visit_ident(pth1.span, pth1.node); - walk_list!(visitor, visit_pat, optional_subpattern); - } - PatKind::Lit(ref expression) => visitor.visit_expr(expression), - PatKind::Range(ref lower_bound, ref upper_bound) => { - visitor.visit_expr(lower_bound); - visitor.visit_expr(upper_bound) - } - PatKind::Wild => (), - PatKind::Vec(ref prepatterns, ref slice_pattern, ref postpatterns) => { - walk_list!(visitor, visit_pat, prepatterns); - walk_list!(visitor, visit_pat, slice_pattern); - walk_list!(visitor, visit_pat, postpatterns); - } - } -} - -pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { - visitor.visit_name(foreign_item.span, foreign_item.name); - - match foreign_item.node { - ForeignItemFn(ref function_declaration, ref generics) => { - walk_fn_decl(visitor, function_declaration); - visitor.visit_generics(generics) - } - ForeignItemStatic(ref typ, _) => visitor.visit_ty(typ), - } - - walk_list!(visitor, visit_attribute, &foreign_item.attrs); -} - -pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) { - match *bound { - TraitTyParamBound(ref typ, ref modifier) => { - visitor.visit_poly_trait_ref(typ, modifier); - } - RegionTyParamBound(ref lifetime) => { - visitor.visit_lifetime(lifetime); - } - } -} - -pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) { - for param in &generics.ty_params { - visitor.visit_name(param.span, param.name); - walk_list!(visitor, visit_ty_param_bound, ¶m.bounds); - walk_list!(visitor, visit_ty, ¶m.default); - } - walk_list!(visitor, visit_lifetime_def, &generics.lifetimes); - for predicate in &generics.where_clause.predicates { - match predicate { - &WherePredicate::BoundPredicate(WhereBoundPredicate{ref bounded_ty, - ref bounds, - ref bound_lifetimes, - ..}) => { - visitor.visit_ty(bounded_ty); - walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_lifetime_def, bound_lifetimes); - } - &WherePredicate::RegionPredicate(WhereRegionPredicate{ref lifetime, - ref bounds, - ..}) => { - visitor.visit_lifetime(lifetime); - walk_list!(visitor, visit_lifetime, bounds); - } - &WherePredicate::EqPredicate(WhereEqPredicate{id, - ref path, - ref ty, - ..}) => { - visitor.visit_path(path, id); - visitor.visit_ty(ty); - } - } - } -} - -pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy) { - if let Return(ref output_ty) = *ret_ty { - visitor.visit_ty(output_ty) - } -} - -pub fn walk_fn_decl<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { - for argument in &function_declaration.inputs { - visitor.visit_pat(&argument.pat); - visitor.visit_ty(&argument.ty) - } - walk_fn_ret_ty(visitor, &function_declaration.output) -} - -pub fn walk_fn_decl_nopat<'v, V: Visitor<'v>>(visitor: &mut V, function_declaration: &'v FnDecl) { - for argument in &function_declaration.inputs { - visitor.visit_ty(&argument.ty) - } - walk_fn_ret_ty(visitor, &function_declaration.output) -} - -pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'v>) { - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { - visitor.visit_generics(generics); - } - FnKind::Method(_, sig, _, _) => { - visitor.visit_generics(&sig.generics); - visitor.visit_explicit_self(&sig.explicit_self); - } - FnKind::Closure(_) => {} - } -} - -pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - function_body: &'v Block, - _span: Span) { - walk_fn_decl(visitor, function_declaration); - walk_fn_kind(visitor, function_kind); - visitor.visit_block(function_body) -} - -pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) { - visitor.visit_name(trait_item.span, trait_item.name); - walk_list!(visitor, visit_attribute, &trait_item.attrs); - match trait_item.node { - ConstTraitItem(ref ty, ref default) => { - visitor.visit_ty(ty); - walk_list!(visitor, visit_expr, default); - } - MethodTraitItem(ref sig, None) => { - visitor.visit_explicit_self(&sig.explicit_self); - visitor.visit_generics(&sig.generics); - walk_fn_decl(visitor, &sig.decl); - } - MethodTraitItem(ref sig, Some(ref body)) => { - visitor.visit_fn(FnKind::Method(trait_item.name, - sig, - None, - &trait_item.attrs), - &sig.decl, - body, - trait_item.span, - trait_item.id); - } - TypeTraitItem(ref bounds, ref default) => { - walk_list!(visitor, visit_ty_param_bound, bounds); - walk_list!(visitor, visit_ty, default); - } - } -} - -pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem) { - visitor.visit_name(impl_item.span, impl_item.name); - walk_list!(visitor, visit_attribute, &impl_item.attrs); - match impl_item.node { - ImplItemKind::Const(ref ty, ref expr) => { - visitor.visit_ty(ty); - visitor.visit_expr(expr); - } - ImplItemKind::Method(ref sig, ref body) => { - visitor.visit_fn(FnKind::Method(impl_item.name, - sig, - Some(impl_item.vis), - &impl_item.attrs), - &sig.decl, - body, - impl_item.span, - impl_item.id); - } - ImplItemKind::Type(ref ty) => { - visitor.visit_ty(ty); - } - } -} - -pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { - walk_list!(visitor, visit_struct_field, struct_definition.fields()); -} - -pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { - visitor.visit_name(struct_field.span, struct_field.name); - visitor.visit_ty(&struct_field.ty); - walk_list!(visitor, visit_attribute, &struct_field.attrs); -} - -pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { - walk_list!(visitor, visit_stmt, &block.stmts); - walk_list!(visitor, visit_expr, &block.expr); -} - -pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { - match statement.node { - StmtDecl(ref declaration, _) => visitor.visit_decl(declaration), - StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => { - visitor.visit_expr(expression) - } - } -} - -pub fn walk_decl<'v, V: Visitor<'v>>(visitor: &mut V, declaration: &'v Decl) { - match declaration.node { - DeclLocal(ref local) => visitor.visit_local(local), - DeclItem(item) => visitor.visit_nested_item(item), - } -} - -pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { - match expression.node { - ExprBox(ref subexpression) => { - visitor.visit_expr(subexpression) - } - ExprVec(ref subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprRepeat(ref element, ref count) => { - visitor.visit_expr(element); - visitor.visit_expr(count) - } - ExprStruct(ref path, ref fields, ref optional_base) => { - visitor.visit_path(path, expression.id); - for field in fields { - visitor.visit_name(field.name.span, field.name.node); - visitor.visit_expr(&field.expr) - } - walk_list!(visitor, visit_expr, optional_base); - } - ExprTup(ref subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprCall(ref callee_expression, ref arguments) => { - walk_list!(visitor, visit_expr, arguments); - visitor.visit_expr(callee_expression) - } - ExprMethodCall(ref name, ref types, ref arguments) => { - visitor.visit_name(name.span, name.node); - walk_list!(visitor, visit_expr, arguments); - walk_list!(visitor, visit_ty, types); - } - ExprBinary(_, ref left_expression, ref right_expression) => { - visitor.visit_expr(left_expression); - visitor.visit_expr(right_expression) - } - ExprAddrOf(_, ref subexpression) | ExprUnary(_, ref subexpression) => { - visitor.visit_expr(subexpression) - } - ExprLit(_) => {} - ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => { - visitor.visit_expr(subexpression); - visitor.visit_ty(typ) - } - ExprIf(ref head_expression, ref if_block, ref optional_else) => { - visitor.visit_expr(head_expression); - visitor.visit_block(if_block); - walk_list!(visitor, visit_expr, optional_else); - } - ExprWhile(ref subexpression, ref block, opt_ident) => { - visitor.visit_expr(subexpression); - visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) - } - ExprLoop(ref block, opt_ident) => { - visitor.visit_block(block); - walk_opt_ident(visitor, expression.span, opt_ident) - } - ExprMatch(ref subexpression, ref arms, _) => { - visitor.visit_expr(subexpression); - walk_list!(visitor, visit_arm, arms); - } - ExprClosure(_, ref function_declaration, ref body) => { - visitor.visit_fn(FnKind::Closure(expression.attrs.as_attr_slice()), - function_declaration, - body, - expression.span, - expression.id) - } - ExprBlock(ref block) => visitor.visit_block(block), - ExprAssign(ref left_hand_expression, ref right_hand_expression) => { - visitor.visit_expr(right_hand_expression); - visitor.visit_expr(left_hand_expression) - } - ExprAssignOp(_, ref left_expression, ref right_expression) => { - visitor.visit_expr(right_expression); - visitor.visit_expr(left_expression) - } - ExprField(ref subexpression, ref name) => { - visitor.visit_expr(subexpression); - visitor.visit_name(name.span, name.node); - } - ExprTupField(ref subexpression, _) => { - visitor.visit_expr(subexpression); - } - ExprIndex(ref main_expression, ref index_expression) => { - visitor.visit_expr(main_expression); - visitor.visit_expr(index_expression) - } - ExprPath(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { - visitor.visit_ty(&qself.ty); - } - visitor.visit_path(path, expression.id) - } - ExprBreak(ref opt_sp_ident) | ExprAgain(ref opt_sp_ident) => { - for sp_ident in opt_sp_ident { - visitor.visit_ident(sp_ident.span, sp_ident.node); - } - } - ExprRet(ref optional_expression) => { - walk_list!(visitor, visit_expr, optional_expression); - } - ExprInlineAsm(_, ref outputs, ref inputs) => { - for output in outputs { - visitor.visit_expr(output) - } - for input in inputs { - visitor.visit_expr(input) - } - } - } - - visitor.visit_expr_post(expression) -} - -pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { - walk_list!(visitor, visit_pat, &arm.pats); - walk_list!(visitor, visit_expr, &arm.guard); - visitor.visit_expr(&arm.body); - walk_list!(visitor, visit_attribute, &arm.attrs); -} diff --git a/src/librustc_front/lib.rs b/src/librustc_front/lib.rs deleted file mode 100644 index b9e3b71cf1a..00000000000 --- a/src/librustc_front/lib.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! The Rust compiler. -//! -//! # Note -//! -//! This API is completely unstable and subject to change. - -#![crate_name = "rustc_front"] -#![unstable(feature = "rustc_private", issue = "27812")] -#![crate_type = "dylib"] -#![crate_type = "rlib"] -#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "http://doc.rust-lang.org/nightly/")] -#![cfg_attr(not(stage0), deny(warnings))] - -#![feature(associated_consts)] -#![feature(box_patterns)] -#![feature(box_syntax)] -#![feature(const_fn)] -#![feature(quote)] -#![feature(rustc_diagnostic_macros)] -#![feature(rustc_private)] -#![feature(slice_patterns)] -#![feature(staged_api)] -#![feature(str_char)] -#![feature(question_mark)] - -extern crate serialize; -#[macro_use] -extern crate log; -#[macro_use] -extern crate syntax; -#[macro_use] -#[no_link] -extern crate rustc_bitflags; - -extern crate serialize as rustc_serialize; // used by deriving - -#[macro_use] -pub mod hir; -pub mod lowering; -pub mod fold; -pub mod intravisit; -pub mod util; - -pub mod print { - pub mod pprust; -} diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs deleted file mode 100644 index 66b9e217bd3..00000000000 --- a/src/librustc_front/lowering.rs +++ /dev/null @@ -1,2149 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Lowers the AST to the HIR. -// -// Since the AST and HIR are fairly similar, this is mostly a simple procedure, -// much like a fold. Where lowering involves a bit more work things get more -// interesting and there are some invariants you should know about. These mostly -// concern spans and ids. -// -// Spans are assigned to AST nodes during parsing and then are modified during -// expansion to indicate the origin of a node and the process it went through -// being expanded. Ids are assigned to AST nodes just before lowering. -// -// For the simpler lowering steps, ids and spans should be preserved. Unlike -// expansion we do not preserve the process of lowering in the spans, so spans -// should not be modified here. When creating a new node (as opposed to -// 'folding' an existing one), then you create a new id using `next_id()`. -// -// You must ensure that ids are unique. That means that you should only use the -// id from an AST node in a single HIR node (you can assume that AST node ids -// are unique). Every new node must have a unique id. Avoid cloning HIR nodes. -// If you do, you must then set the new node's id to a fresh one. -// -// Lowering must be reproducable (the compiler only lowers once, but tools and -// custom lints may lower an AST node to a HIR node to interact with the -// compiler). The most interesting bit of this is ids - if you lower an AST node -// and create new HIR nodes with fresh ids, when re-lowering the same node, you -// must ensure you get the same ids! To do this, we keep track of the next id -// when we translate a node which requires new ids. By checking this cache and -// using node ids starting with the cached id, we ensure ids are reproducible. -// To use this system, you just need to hold on to a CachedIdSetter object -// whilst lowering. This is an RAII object that takes care of setting and -// restoring the cached id, etc. -// -// This whole system relies on node ids being incremented one at a time and -// all increments being for lowering. This means that you should not call any -// non-lowering function which will use new node ids. -// -// We must also cache gensym'ed Idents to ensure that we get the same Ident -// every time we lower a node with gensym'ed names. One consequence of this is -// that you can only gensym a name once in a lowering (you don't need to worry -// about nested lowering though). That's because we cache based on the name and -// the currently cached node id, which is unique per lowered node. -// -// Spans are used for error messages and for tools to map semantics back to -// source code. It is therefore not as important with spans as ids to be strict -// about use (you can't break the compiler by screwing up a span). Obviously, a -// HIR node can only have a single span. But multiple nodes can have the same -// span and spans don't need to be kept in order, etc. Where code is preserved -// by lowering, it should have the same span as in the AST. Where HIR nodes are -// new it is probably best to give a span for the whole AST node being lowered. -// All nodes should have real spans, don't use dummy spans. Tools are likely to -// get confused if the spans from leaf AST nodes occur in multiple places -// in the HIR, especially for multiple identifiers. - -use hir; - -use std::collections::BTreeMap; -use std::collections::HashMap; -use std::iter; -use syntax::ast::*; -use syntax::attr::{ThinAttributes, ThinAttributesExt}; -use syntax::errors::Handler; -use syntax::ext::mtwt; -use syntax::ptr::P; -use syntax::codemap::{respan, Spanned, Span}; -use syntax::parse::token; -use syntax::std_inject; -use syntax::visit::{self, Visitor}; - -use std::cell::{Cell, RefCell}; - -pub struct LoweringContext<'a> { - crate_root: Option<&'static str>, - // Map AST ids to ids used for expanded nodes. - id_cache: RefCell>, - // Use if there are no cached ids for the current node. - id_assigner: &'a NodeIdAssigner, - // 0 == no cached id. Must be incremented to align with previous id - // incrementing. - cached_id: Cell, - // Keep track of gensym'ed idents. - gensym_cache: RefCell>, - // A copy of cached_id, but is also set to an id while a node is lowered for - // the first time. - gensym_key: Cell, -} - -impl<'a, 'hir> LoweringContext<'a> { - pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> { - let crate_root = c.and_then(|c| { - if std_inject::no_core(c) { - None - } else if std_inject::no_std(c) { - Some("core") - } else { - Some("std") - } - }); - - LoweringContext { - crate_root: crate_root, - id_cache: RefCell::new(HashMap::new()), - id_assigner: id_assigner, - cached_id: Cell::new(0), - gensym_cache: RefCell::new(HashMap::new()), - gensym_key: Cell::new(0), - } - } - - fn next_id(&self) -> NodeId { - let cached_id = self.cached_id.get(); - if cached_id == 0 { - return self.id_assigner.next_node_id(); - } - - self.cached_id.set(cached_id + 1); - cached_id - } - - fn str_to_ident(&self, s: &'static str) -> hir::Ident { - let gensym_key = self.gensym_key.get(); - if gensym_key == 0 { - return hir::Ident::from_name(token::gensym(s)); - } - - let cached = self.gensym_cache.borrow().contains_key(&(gensym_key, s)); - if cached { - self.gensym_cache.borrow()[&(gensym_key, s)] - } else { - let result = hir::Ident::from_name(token::gensym(s)); - self.gensym_cache.borrow_mut().insert((gensym_key, s), result); - result - } - } - - // Panics if this LoweringContext's NodeIdAssigner is not able to emit diagnostics. - fn diagnostic(&self) -> &Handler { - self.id_assigner.diagnostic() - } -} - -// Utility fn for setting and unsetting the cached id. -fn cache_ids<'a, OP, R>(lctx: &LoweringContext, expr_id: NodeId, op: OP) -> R - where OP: FnOnce(&LoweringContext) -> R -{ - // Only reset the id if it was previously 0, i.e., was not cached. - // If it was cached, we are in a nested node, but our id count will - // still count towards the parent's count. - let reset_cached_id = lctx.cached_id.get() == 0; - // We always reset gensym_key so that if we use the same name in a nested - // node and after that node, they get different values. - let old_gensym_key = lctx.gensym_key.get(); - - { - let id_cache: &mut HashMap<_, _> = &mut lctx.id_cache.borrow_mut(); - - if id_cache.contains_key(&expr_id) { - let cached_id = lctx.cached_id.get(); - if cached_id == 0 { - // We're entering a node where we need to track ids, but are not - // yet tracking. - lctx.cached_id.set(id_cache[&expr_id]); - } else { - // We're already tracking - check that the tracked id is the same - // as the expected id. - assert!(cached_id == id_cache[&expr_id], "id mismatch"); - } - lctx.gensym_key.set(id_cache[&expr_id]); - } else { - // We've never lowered this node before, remember it for next time. - let next_id = lctx.id_assigner.peek_node_id(); - id_cache.insert(expr_id, next_id); - lctx.gensym_key.set(next_id); - // self.cached_id is not set when we lower a node for the first time, - // only on re-lowering. - } - } - - let result = op(lctx); - - if reset_cached_id { - lctx.cached_id.set(0); - } - lctx.gensym_key.set(old_gensym_key); - - result -} - -pub fn lower_ident(_lctx: &LoweringContext, ident: Ident) -> hir::Ident { - hir::Ident { - name: mtwt::resolve(ident), - unhygienic_name: ident.name, - } -} - -pub fn lower_attrs(_lctx: &LoweringContext, attrs: &Vec) -> hir::HirVec { - attrs.clone().into() -} - -pub fn lower_view_path(lctx: &LoweringContext, view_path: &ViewPath) -> P { - P(Spanned { - node: match view_path.node { - ViewPathSimple(ident, ref path) => { - hir::ViewPathSimple(ident.name, lower_path(lctx, path)) - } - ViewPathGlob(ref path) => { - hir::ViewPathGlob(lower_path(lctx, path)) - } - ViewPathList(ref path, ref path_list_idents) => { - hir::ViewPathList(lower_path(lctx, path), - path_list_idents.iter() - .map(lower_path_list_item) - .collect()) - } - }, - span: view_path.span, - }) -} - -fn lower_path_list_item(path_list_ident: &PathListItem) -> hir::PathListItem { - Spanned { - node: match path_list_ident.node { - PathListItemKind::Ident { id, name, rename } => hir::PathListIdent { - id: id, - name: name.name, - rename: rename.map(|x| x.name), - }, - PathListItemKind::Mod { id, rename } => hir::PathListMod { - id: id, - rename: rename.map(|x| x.name), - }, - }, - span: path_list_ident.span, - } -} - -pub fn lower_arm(lctx: &LoweringContext, arm: &Arm) -> hir::Arm { - hir::Arm { - attrs: lower_attrs(lctx, &arm.attrs), - pats: arm.pats.iter().map(|x| lower_pat(lctx, x)).collect(), - guard: arm.guard.as_ref().map(|ref x| lower_expr(lctx, x)), - body: lower_expr(lctx, &arm.body), - } -} - -pub fn lower_decl(lctx: &LoweringContext, d: &Decl) -> P { - match d.node { - DeclKind::Local(ref l) => P(Spanned { - node: hir::DeclLocal(lower_local(lctx, l)), - span: d.span, - }), - DeclKind::Item(ref it) => P(Spanned { - node: hir::DeclItem(lower_item_id(lctx, it)), - span: d.span, - }), - } -} - -pub fn lower_ty_binding(lctx: &LoweringContext, b: &TypeBinding) -> hir::TypeBinding { - hir::TypeBinding { - id: b.id, - name: b.ident.name, - ty: lower_ty(lctx, &b.ty), - span: b.span, - } -} - -pub fn lower_ty(lctx: &LoweringContext, t: &Ty) -> P { - use syntax::ast::TyKind::*; - P(hir::Ty { - id: t.id, - node: match t.node { - Infer => hir::TyInfer, - Vec(ref ty) => hir::TyVec(lower_ty(lctx, ty)), - Ptr(ref mt) => hir::TyPtr(lower_mt(lctx, mt)), - Rptr(ref region, ref mt) => { - hir::TyRptr(lower_opt_lifetime(lctx, region), lower_mt(lctx, mt)) - } - BareFn(ref f) => { - hir::TyBareFn(P(hir::BareFnTy { - lifetimes: lower_lifetime_defs(lctx, &f.lifetimes), - unsafety: lower_unsafety(lctx, f.unsafety), - abi: f.abi, - decl: lower_fn_decl(lctx, &f.decl), - })) - } - Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| lower_ty(lctx, ty)).collect()), - Paren(ref ty) => { - return lower_ty(lctx, ty); - } - Path(ref qself, ref path) => { - let qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, - } - }); - hir::TyPath(qself, lower_path(lctx, path)) - } - ObjectSum(ref ty, ref bounds) => { - hir::TyObjectSum(lower_ty(lctx, ty), lower_bounds(lctx, bounds)) - } - FixedLengthVec(ref ty, ref e) => { - hir::TyFixedLengthVec(lower_ty(lctx, ty), lower_expr(lctx, e)) - } - Typeof(ref expr) => { - hir::TyTypeof(lower_expr(lctx, expr)) - } - PolyTraitRef(ref bounds) => { - hir::TyPolyTraitRef(bounds.iter().map(|b| lower_ty_param_bound(lctx, b)).collect()) - } - Mac(_) => panic!("TyMac should have been expanded by now."), - }, - span: t.span, - }) -} - -pub fn lower_foreign_mod(lctx: &LoweringContext, fm: &ForeignMod) -> hir::ForeignMod { - hir::ForeignMod { - abi: fm.abi, - items: fm.items.iter().map(|x| lower_foreign_item(lctx, x)).collect(), - } -} - -pub fn lower_variant(lctx: &LoweringContext, v: &Variant) -> hir::Variant { - Spanned { - node: hir::Variant_ { - name: v.node.name.name, - attrs: lower_attrs(lctx, &v.node.attrs), - data: lower_variant_data(lctx, &v.node.data), - disr_expr: v.node.disr_expr.as_ref().map(|e| lower_expr(lctx, e)), - }, - span: v.span, - } -} - -// Path segments are usually unhygienic, hygienic path segments can occur only in -// identifier-like paths originating from `ExprPath`. -// Make life simpler for rustc_resolve by renaming only such segments. -pub fn lower_path_full(lctx: &LoweringContext, p: &Path, maybe_hygienic: bool) -> hir::Path { - let maybe_hygienic = maybe_hygienic && !p.global && p.segments.len() == 1; - hir::Path { - global: p.global, - segments: p.segments - .iter() - .map(|&PathSegment { identifier, ref parameters }| { - hir::PathSegment { - identifier: if maybe_hygienic { - lower_ident(lctx, identifier) - } else { - hir::Ident::from_name(identifier.name) - }, - parameters: lower_path_parameters(lctx, parameters), - } - }) - .collect(), - span: p.span, - } -} - -pub fn lower_path(lctx: &LoweringContext, p: &Path) -> hir::Path { - lower_path_full(lctx, p, false) -} - -pub fn lower_path_parameters(lctx: &LoweringContext, - path_parameters: &PathParameters) - -> hir::PathParameters { - match *path_parameters { - PathParameters::AngleBracketed(ref data) => - hir::AngleBracketedParameters(lower_angle_bracketed_parameter_data(lctx, data)), - PathParameters::Parenthesized(ref data) => - hir::ParenthesizedParameters(lower_parenthesized_parameter_data(lctx, data)), - } -} - -pub fn lower_angle_bracketed_parameter_data(lctx: &LoweringContext, - data: &AngleBracketedParameterData) - -> hir::AngleBracketedParameterData { - let &AngleBracketedParameterData { ref lifetimes, ref types, ref bindings } = data; - hir::AngleBracketedParameterData { - lifetimes: lower_lifetimes(lctx, lifetimes), - types: types.iter().map(|ty| lower_ty(lctx, ty)).collect(), - bindings: bindings.iter().map(|b| lower_ty_binding(lctx, b)).collect(), - } -} - -pub fn lower_parenthesized_parameter_data(lctx: &LoweringContext, - data: &ParenthesizedParameterData) - -> hir::ParenthesizedParameterData { - let &ParenthesizedParameterData { ref inputs, ref output, span } = data; - hir::ParenthesizedParameterData { - inputs: inputs.iter().map(|ty| lower_ty(lctx, ty)).collect(), - output: output.as_ref().map(|ty| lower_ty(lctx, ty)), - span: span, - } -} - -pub fn lower_local(lctx: &LoweringContext, l: &Local) -> P { - P(hir::Local { - id: l.id, - ty: l.ty.as_ref().map(|t| lower_ty(lctx, t)), - pat: lower_pat(lctx, &l.pat), - init: l.init.as_ref().map(|e| lower_expr(lctx, e)), - span: l.span, - attrs: l.attrs.clone(), - }) -} - -pub fn lower_explicit_self_underscore(lctx: &LoweringContext, - es: &SelfKind) - -> hir::ExplicitSelf_ { - match *es { - SelfKind::Static => hir::SelfStatic, - SelfKind::Value(v) => hir::SelfValue(v.name), - SelfKind::Region(ref lifetime, m, ident) => { - hir::SelfRegion(lower_opt_lifetime(lctx, lifetime), - lower_mutability(lctx, m), - ident.name) - } - SelfKind::Explicit(ref typ, ident) => { - hir::SelfExplicit(lower_ty(lctx, typ), ident.name) - } - } -} - -pub fn lower_mutability(_lctx: &LoweringContext, m: Mutability) -> hir::Mutability { - match m { - Mutability::Mutable => hir::MutMutable, - Mutability::Immutable => hir::MutImmutable, - } -} - -pub fn lower_explicit_self(lctx: &LoweringContext, s: &ExplicitSelf) -> hir::ExplicitSelf { - Spanned { - node: lower_explicit_self_underscore(lctx, &s.node), - span: s.span, - } -} - -pub fn lower_arg(lctx: &LoweringContext, arg: &Arg) -> hir::Arg { - hir::Arg { - id: arg.id, - pat: lower_pat(lctx, &arg.pat), - ty: lower_ty(lctx, &arg.ty), - } -} - -pub fn lower_fn_decl(lctx: &LoweringContext, decl: &FnDecl) -> P { - P(hir::FnDecl { - inputs: decl.inputs.iter().map(|x| lower_arg(lctx, x)).collect(), - output: match decl.output { - FunctionRetTy::Ty(ref ty) => hir::Return(lower_ty(lctx, ty)), - FunctionRetTy::Default(span) => hir::DefaultReturn(span), - FunctionRetTy::None(span) => hir::NoReturn(span), - }, - variadic: decl.variadic, - }) -} - -pub fn lower_ty_param_bound(lctx: &LoweringContext, tpb: &TyParamBound) -> hir::TyParamBound { - match *tpb { - TraitTyParamBound(ref ty, modifier) => { - hir::TraitTyParamBound(lower_poly_trait_ref(lctx, ty), - lower_trait_bound_modifier(lctx, modifier)) - } - RegionTyParamBound(ref lifetime) => { - hir::RegionTyParamBound(lower_lifetime(lctx, lifetime)) - } - } -} - -pub fn lower_ty_param(lctx: &LoweringContext, tp: &TyParam) -> hir::TyParam { - hir::TyParam { - id: tp.id, - name: tp.ident.name, - bounds: lower_bounds(lctx, &tp.bounds), - default: tp.default.as_ref().map(|x| lower_ty(lctx, x)), - span: tp.span, - } -} - -pub fn lower_ty_params(lctx: &LoweringContext, - tps: &P<[TyParam]>) - -> hir::HirVec { - tps.iter().map(|tp| lower_ty_param(lctx, tp)).collect() -} - -pub fn lower_lifetime(_lctx: &LoweringContext, l: &Lifetime) -> hir::Lifetime { - hir::Lifetime { - id: l.id, - name: l.name, - span: l.span, - } -} - -pub fn lower_lifetime_def(lctx: &LoweringContext, l: &LifetimeDef) -> hir::LifetimeDef { - hir::LifetimeDef { - lifetime: lower_lifetime(lctx, &l.lifetime), - bounds: lower_lifetimes(lctx, &l.bounds), - } -} - -pub fn lower_lifetimes(lctx: &LoweringContext, lts: &Vec) -> hir::HirVec { - lts.iter().map(|l| lower_lifetime(lctx, l)).collect() -} - -pub fn lower_lifetime_defs(lctx: &LoweringContext, - lts: &Vec) - -> hir::HirVec { - lts.iter().map(|l| lower_lifetime_def(lctx, l)).collect() -} - -pub fn lower_opt_lifetime(lctx: &LoweringContext, - o_lt: &Option) - -> Option { - o_lt.as_ref().map(|lt| lower_lifetime(lctx, lt)) -} - -pub fn lower_generics(lctx: &LoweringContext, g: &Generics) -> hir::Generics { - hir::Generics { - ty_params: lower_ty_params(lctx, &g.ty_params), - lifetimes: lower_lifetime_defs(lctx, &g.lifetimes), - where_clause: lower_where_clause(lctx, &g.where_clause), - } -} - -pub fn lower_where_clause(lctx: &LoweringContext, wc: &WhereClause) -> hir::WhereClause { - hir::WhereClause { - id: wc.id, - predicates: wc.predicates - .iter() - .map(|predicate| lower_where_predicate(lctx, predicate)) - .collect(), - } -} - -pub fn lower_where_predicate(lctx: &LoweringContext, - pred: &WherePredicate) - -> hir::WherePredicate { - match *pred { - WherePredicate::BoundPredicate(WhereBoundPredicate{ ref bound_lifetimes, - ref bounded_ty, - ref bounds, - span}) => { - hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { - bound_lifetimes: lower_lifetime_defs(lctx, bound_lifetimes), - bounded_ty: lower_ty(lctx, bounded_ty), - bounds: bounds.iter().map(|x| lower_ty_param_bound(lctx, x)).collect(), - span: span, - }) - } - WherePredicate::RegionPredicate(WhereRegionPredicate{ ref lifetime, - ref bounds, - span}) => { - hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate { - span: span, - lifetime: lower_lifetime(lctx, lifetime), - bounds: bounds.iter().map(|bound| lower_lifetime(lctx, bound)).collect(), - }) - } - WherePredicate::EqPredicate(WhereEqPredicate{ id, - ref path, - ref ty, - span}) => { - hir::WherePredicate::EqPredicate(hir::WhereEqPredicate { - id: id, - path: lower_path(lctx, path), - ty: lower_ty(lctx, ty), - span: span, - }) - } - } -} - -pub fn lower_variant_data(lctx: &LoweringContext, vdata: &VariantData) -> hir::VariantData { - match *vdata { - VariantData::Struct(ref fields, id) => { - hir::VariantData::Struct(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) - } - VariantData::Tuple(ref fields, id) => { - hir::VariantData::Tuple(fields.iter() - .enumerate() - .map(|f| lower_struct_field(lctx, f)) - .collect(), - id) - } - VariantData::Unit(id) => hir::VariantData::Unit(id), - } -} - -pub fn lower_trait_ref(lctx: &LoweringContext, p: &TraitRef) -> hir::TraitRef { - hir::TraitRef { - path: lower_path(lctx, &p.path), - ref_id: p.ref_id, - } -} - -pub fn lower_poly_trait_ref(lctx: &LoweringContext, p: &PolyTraitRef) -> hir::PolyTraitRef { - hir::PolyTraitRef { - bound_lifetimes: lower_lifetime_defs(lctx, &p.bound_lifetimes), - trait_ref: lower_trait_ref(lctx, &p.trait_ref), - span: p.span, - } -} - -pub fn lower_struct_field(lctx: &LoweringContext, - (index, f): (usize, &StructField)) - -> hir::StructField { - hir::StructField { - span: f.span, - id: f.node.id, - name: f.node.ident().map(|ident| ident.name) - .unwrap_or(token::intern(&index.to_string())), - vis: lower_visibility(lctx, f.node.kind.visibility()), - ty: lower_ty(lctx, &f.node.ty), - attrs: lower_attrs(lctx, &f.node.attrs), - } -} - -pub fn lower_field(lctx: &LoweringContext, f: &Field) -> hir::Field { - hir::Field { - name: respan(f.ident.span, f.ident.node.name), - expr: lower_expr(lctx, &f.expr), - span: f.span, - } -} - -pub fn lower_mt(lctx: &LoweringContext, mt: &MutTy) -> hir::MutTy { - hir::MutTy { - ty: lower_ty(lctx, &mt.ty), - mutbl: lower_mutability(lctx, mt.mutbl), - } -} - -pub fn lower_opt_bounds(lctx: &LoweringContext, - b: &Option) - -> Option { - b.as_ref().map(|ref bounds| lower_bounds(lctx, bounds)) -} - -fn lower_bounds(lctx: &LoweringContext, bounds: &TyParamBounds) -> hir::TyParamBounds { - bounds.iter().map(|bound| lower_ty_param_bound(lctx, bound)).collect() -} - -pub fn lower_block(lctx: &LoweringContext, b: &Block) -> P { - P(hir::Block { - id: b.id, - stmts: b.stmts.iter().map(|s| lower_stmt(lctx, s)).collect(), - expr: b.expr.as_ref().map(|ref x| lower_expr(lctx, x)), - rules: lower_block_check_mode(lctx, &b.rules), - span: b.span, - }) -} - -pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { - match *i { - ItemKind::ExternCrate(string) => hir::ItemExternCrate(string), - ItemKind::Use(ref view_path) => { - hir::ItemUse(lower_view_path(lctx, view_path)) - } - ItemKind::Static(ref t, m, ref e) => { - hir::ItemStatic(lower_ty(lctx, t), - lower_mutability(lctx, m), - lower_expr(lctx, e)) - } - ItemKind::Const(ref t, ref e) => { - hir::ItemConst(lower_ty(lctx, t), lower_expr(lctx, e)) - } - ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => { - hir::ItemFn(lower_fn_decl(lctx, decl), - lower_unsafety(lctx, unsafety), - lower_constness(lctx, constness), - abi, - lower_generics(lctx, generics), - lower_block(lctx, body)) - } - ItemKind::Mod(ref m) => hir::ItemMod(lower_mod(lctx, m)), - ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(lower_foreign_mod(lctx, nm)), - ItemKind::Ty(ref t, ref generics) => { - hir::ItemTy(lower_ty(lctx, t), lower_generics(lctx, generics)) - } - ItemKind::Enum(ref enum_definition, ref generics) => { - hir::ItemEnum(hir::EnumDef { - variants: enum_definition.variants - .iter() - .map(|x| lower_variant(lctx, x)) - .collect(), - }, - lower_generics(lctx, generics)) - } - ItemKind::Struct(ref struct_def, ref generics) => { - let struct_def = lower_variant_data(lctx, struct_def); - hir::ItemStruct(struct_def, lower_generics(lctx, generics)) - } - ItemKind::DefaultImpl(unsafety, ref trait_ref) => { - hir::ItemDefaultImpl(lower_unsafety(lctx, unsafety), - lower_trait_ref(lctx, trait_ref)) - } - ItemKind::Impl(unsafety, polarity, ref generics, ref ifce, ref ty, ref impl_items) => { - let new_impl_items = impl_items.iter() - .map(|item| lower_impl_item(lctx, item)) - .collect(); - let ifce = ifce.as_ref().map(|trait_ref| lower_trait_ref(lctx, trait_ref)); - hir::ItemImpl(lower_unsafety(lctx, unsafety), - lower_impl_polarity(lctx, polarity), - lower_generics(lctx, generics), - ifce, - lower_ty(lctx, ty), - new_impl_items) - } - ItemKind::Trait(unsafety, ref generics, ref bounds, ref items) => { - let bounds = lower_bounds(lctx, bounds); - let items = items.iter().map(|item| lower_trait_item(lctx, item)).collect(); - hir::ItemTrait(lower_unsafety(lctx, unsafety), - lower_generics(lctx, generics), - bounds, - items) - } - ItemKind::Mac(_) => panic!("Shouldn't still be around"), - } -} - -pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { - hir::TraitItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(lctx, ty), - default.as_ref().map(|x| lower_expr(lctx, x))) - } - TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(lctx, sig), - body.as_ref().map(|x| lower_block(lctx, x))) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(lctx, bounds), - default.as_ref().map(|x| lower_ty(lctx, x))) - } - }, - span: i.span, - } -} - -pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { - hir::ImplItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - vis: lower_visibility(lctx, &i.vis), - defaultness: lower_defaultness(lctx, i.defaultness), - node: match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) - } - ImplItemKind::Method(ref sig, ref body) => { - hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) - } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, - span: i.span, - } -} - -pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { - hir::Mod { - inner: m.inner, - item_ids: m.items.iter().map(|x| lower_item_id(lctx, x)).collect(), - } -} - -struct ItemLowerer<'lcx, 'interner: 'lcx> { - items: BTreeMap, - lctx: &'lcx LoweringContext<'interner>, -} - -impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> { - fn visit_item(&mut self, item: &'lcx Item) { - self.items.insert(item.id, lower_item(self.lctx, item)); - visit::walk_item(self, item); - } -} - -pub fn lower_crate(lctx: &LoweringContext, c: &Crate) -> hir::Crate { - let items = { - let mut item_lowerer = ItemLowerer { items: BTreeMap::new(), lctx: lctx }; - visit::walk_crate(&mut item_lowerer, c); - item_lowerer.items - }; - - hir::Crate { - module: lower_mod(lctx, &c.module), - attrs: lower_attrs(lctx, &c.attrs), - config: c.config.clone().into(), - span: c.span, - exported_macros: c.exported_macros.iter().map(|m| lower_macro_def(lctx, m)).collect(), - items: items, - } -} - -pub fn lower_macro_def(lctx: &LoweringContext, m: &MacroDef) -> hir::MacroDef { - hir::MacroDef { - name: m.ident.name, - attrs: lower_attrs(lctx, &m.attrs), - id: m.id, - span: m.span, - imported_from: m.imported_from.map(|x| x.name), - export: m.export, - use_locally: m.use_locally, - allow_internal_unstable: m.allow_internal_unstable, - body: m.body.clone().into(), - } -} - -pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { - hir::ItemId { id: i.id } -} - -pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lower_item_kind(lctx, &i.node); - - hir::Item { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: node, - vis: lower_visibility(lctx, &i.vis), - span: i.span, - } -} - -pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - hir::ForeignItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - ForeignItemKind::Fn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) - } - ForeignItemKind::Static(ref t, m) => { - hir::ForeignItemStatic(lower_ty(lctx, t), m) - } - }, - vis: lower_visibility(lctx, &i.vis), - span: i.span, - } -} - -pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { - hir::MethodSig { - generics: lower_generics(lctx, &sig.generics), - abi: sig.abi, - explicit_self: lower_explicit_self(lctx, &sig.explicit_self), - unsafety: lower_unsafety(lctx, sig.unsafety), - constness: lower_constness(lctx, sig.constness), - decl: lower_fn_decl(lctx, &sig.decl), - } -} - -pub fn lower_unsafety(_lctx: &LoweringContext, u: Unsafety) -> hir::Unsafety { - match u { - Unsafety::Unsafe => hir::Unsafety::Unsafe, - Unsafety::Normal => hir::Unsafety::Normal, - } -} - -pub fn lower_constness(_lctx: &LoweringContext, c: Constness) -> hir::Constness { - match c { - Constness::Const => hir::Constness::Const, - Constness::NotConst => hir::Constness::NotConst, - } -} - -pub fn lower_unop(_lctx: &LoweringContext, u: UnOp) -> hir::UnOp { - match u { - UnOp::Deref => hir::UnDeref, - UnOp::Not => hir::UnNot, - UnOp::Neg => hir::UnNeg, - } -} - -pub fn lower_binop(_lctx: &LoweringContext, b: BinOp) -> hir::BinOp { - Spanned { - node: match b.node { - BinOpKind::Add => hir::BiAdd, - BinOpKind::Sub => hir::BiSub, - BinOpKind::Mul => hir::BiMul, - BinOpKind::Div => hir::BiDiv, - BinOpKind::Rem => hir::BiRem, - BinOpKind::And => hir::BiAnd, - BinOpKind::Or => hir::BiOr, - BinOpKind::BitXor => hir::BiBitXor, - BinOpKind::BitAnd => hir::BiBitAnd, - BinOpKind::BitOr => hir::BiBitOr, - BinOpKind::Shl => hir::BiShl, - BinOpKind::Shr => hir::BiShr, - BinOpKind::Eq => hir::BiEq, - BinOpKind::Lt => hir::BiLt, - BinOpKind::Le => hir::BiLe, - BinOpKind::Ne => hir::BiNe, - BinOpKind::Ge => hir::BiGe, - BinOpKind::Gt => hir::BiGt, - }, - span: b.span, - } -} - -pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { - P(hir::Pat { - id: p.id, - node: match p.node { - PatKind::Wild => hir::PatKind::Wild, - PatKind::Ident(ref binding_mode, pth1, ref sub) => { - hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), - respan(pth1.span, lower_ident(lctx, pth1.node)), - sub.as_ref().map(|x| lower_pat(lctx, x))) - } - PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), - PatKind::TupleStruct(ref pth, ref pats) => { - hir::PatKind::TupleStruct(lower_path(lctx, pth), - pats.as_ref() - .map(|pats| pats.iter().map(|x| lower_pat(lctx, x)).collect())) - } - PatKind::Path(ref pth) => { - hir::PatKind::Path(lower_path(lctx, pth)) - } - PatKind::QPath(ref qself, ref pth) => { - let qself = hir::QSelf { - ty: lower_ty(lctx, &qself.ty), - position: qself.position, - }; - hir::PatKind::QPath(qself, lower_path(lctx, pth)) - } - PatKind::Struct(ref pth, ref fields, etc) => { - let pth = lower_path(lctx, pth); - let fs = fields.iter() - .map(|f| { - Spanned { - span: f.span, - node: hir::FieldPat { - name: f.node.ident.name, - pat: lower_pat(lctx, &f.node.pat), - is_shorthand: f.node.is_shorthand, - }, - } - }) - .collect(); - hir::PatKind::Struct(pth, fs, etc) - } - PatKind::Tup(ref elts) => { - hir::PatKind::Tup(elts.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Box(ref inner) => hir::PatKind::Box(lower_pat(lctx, inner)), - PatKind::Ref(ref inner, mutbl) => { - hir::PatKind::Ref(lower_pat(lctx, inner), lower_mutability(lctx, mutbl)) - } - PatKind::Range(ref e1, ref e2) => { - hir::PatKind::Range(lower_expr(lctx, e1), lower_expr(lctx, e2)) - } - PatKind::Vec(ref before, ref slice, ref after) => { - hir::PatKind::Vec(before.iter().map(|x| lower_pat(lctx, x)).collect(), - slice.as_ref().map(|x| lower_pat(lctx, x)), - after.iter().map(|x| lower_pat(lctx, x)).collect()) - } - PatKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: p.span, - }) -} - -pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { - P(hir::Expr { - id: e.id, - node: match e.node { - // Issue #22181: - // Eventually a desugaring for `box EXPR` - // (similar to the desugaring above for `in PLACE BLOCK`) - // should go here, desugaring - // - // to: - // - // let mut place = BoxPlace::make_place(); - // let raw_place = Place::pointer(&mut place); - // let value = $value; - // unsafe { - // ::std::ptr::write(raw_place, value); - // Boxed::finalize(place) - // } - // - // But for now there are type-inference issues doing that. - ExprKind::Box(ref e) => { - hir::ExprBox(lower_expr(lctx, e)) - } - - // Desugar ExprBox: `in (PLACE) EXPR` - ExprKind::InPlace(ref placer, ref value_expr) => { - // to: - // - // let p = PLACE; - // let mut place = Placer::make_place(p); - // let raw_place = Place::pointer(&mut place); - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - return cache_ids(lctx, e.id, |lctx| { - let placer_expr = lower_expr(lctx, placer); - let value_expr = lower_expr(lctx, value_expr); - - let placer_ident = lctx.str_to_ident("placer"); - let place_ident = lctx.str_to_ident("place"); - let p_ptr_ident = lctx.str_to_ident("p_ptr"); - - let make_place = ["ops", "Placer", "make_place"]; - let place_pointer = ["ops", "Place", "pointer"]; - let move_val_init = ["intrinsics", "move_val_init"]; - let inplace_finalize = ["ops", "InPlace", "finalize"]; - - let make_call = |lctx: &LoweringContext, p, args| { - let path = core_path(lctx, e.span, p); - let path = expr_path(lctx, path, None); - expr_call(lctx, e.span, path, args, None) - }; - - let mk_stmt_let = |lctx: &LoweringContext, bind, expr| { - stmt_let(lctx, e.span, false, bind, expr, None) - }; - - let mk_stmt_let_mut = |lctx: &LoweringContext, bind, expr| { - stmt_let(lctx, e.span, true, bind, expr, None) - }; - - // let placer = ; - let s1 = { - let placer_expr = signal_block_expr(lctx, - hir_vec![], - placer_expr, - e.span, - hir::PopUnstableBlock, - None); - mk_stmt_let(lctx, placer_ident, placer_expr) - }; - - // let mut place = Placer::make_place(placer); - let s2 = { - let placer = expr_ident(lctx, e.span, placer_ident, None); - let call = make_call(lctx, &make_place, hir_vec![placer]); - mk_stmt_let_mut(lctx, place_ident, call) - }; - - // let p_ptr = Place::pointer(&mut place); - let s3 = { - let agent = expr_ident(lctx, e.span, place_ident, None); - let args = hir_vec![expr_mut_addr_of(lctx, e.span, agent, None)]; - let call = make_call(lctx, &place_pointer, args); - mk_stmt_let(lctx, p_ptr_ident, call) - }; - - // pop_unsafe!(EXPR)); - let pop_unsafe_expr = { - let value_expr = signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnstableBlock, - None); - signal_block_expr(lctx, - hir_vec![], - value_expr, - e.span, - hir::PopUnsafeBlock(hir::CompilerGenerated), None) - }; - - // push_unsafe!({ - // std::intrinsics::move_val_init(raw_place, pop_unsafe!( EXPR )); - // InPlace::finalize(place) - // }) - let expr = { - let ptr = expr_ident(lctx, e.span, p_ptr_ident, None); - let call_move_val_init = - hir::StmtSemi( - make_call(lctx, &move_val_init, hir_vec![ptr, pop_unsafe_expr]), - lctx.next_id()); - let call_move_val_init = respan(e.span, call_move_val_init); - - let place = expr_ident(lctx, e.span, place_ident, None); - let call = make_call(lctx, &inplace_finalize, hir_vec![place]); - signal_block_expr(lctx, - hir_vec![call_move_val_init], - call, - e.span, - hir::PushUnsafeBlock(hir::CompilerGenerated), None) - }; - - signal_block_expr(lctx, - hir_vec![s1, s2, s3], - expr, - e.span, - hir::PushUnstableBlock, - e.attrs.clone()) - }); - } - - ExprKind::Vec(ref exprs) => { - hir::ExprVec(exprs.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Repeat(ref expr, ref count) => { - let expr = lower_expr(lctx, expr); - let count = lower_expr(lctx, count); - hir::ExprRepeat(expr, count) - } - ExprKind::Tup(ref elts) => { - hir::ExprTup(elts.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::Call(ref f, ref args) => { - let f = lower_expr(lctx, f); - hir::ExprCall(f, args.iter().map(|x| lower_expr(lctx, x)).collect()) - } - ExprKind::MethodCall(i, ref tps, ref args) => { - let tps = tps.iter().map(|x| lower_ty(lctx, x)).collect(); - let args = args.iter().map(|x| lower_expr(lctx, x)).collect(); - hir::ExprMethodCall(respan(i.span, i.node.name), tps, args) - } - ExprKind::Binary(binop, ref lhs, ref rhs) => { - let binop = lower_binop(lctx, binop); - let lhs = lower_expr(lctx, lhs); - let rhs = lower_expr(lctx, rhs); - hir::ExprBinary(binop, lhs, rhs) - } - ExprKind::Unary(op, ref ohs) => { - let op = lower_unop(lctx, op); - let ohs = lower_expr(lctx, ohs); - hir::ExprUnary(op, ohs) - } - ExprKind::Lit(ref l) => hir::ExprLit(P((**l).clone())), - ExprKind::Cast(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprCast(expr, lower_ty(lctx, ty)) - } - ExprKind::Type(ref expr, ref ty) => { - let expr = lower_expr(lctx, expr); - hir::ExprType(expr, lower_ty(lctx, ty)) - } - ExprKind::AddrOf(m, ref ohs) => { - let m = lower_mutability(lctx, m); - let ohs = lower_expr(lctx, ohs); - hir::ExprAddrOf(m, ohs) - } - // More complicated than you might expect because the else branch - // might be `if let`. - ExprKind::If(ref cond, ref blk, ref else_opt) => { - let else_opt = else_opt.as_ref().map(|els| { - match els.node { - ExprKind::IfLet(..) => { - cache_ids(lctx, e.id, |lctx| { - // wrap the if-let expr in a block - let span = els.span; - let els = lower_expr(lctx, els); - let id = lctx.next_id(); - let blk = P(hir::Block { - stmts: hir_vec![], - expr: Some(els), - id: id, - rules: hir::DefaultBlock, - span: span, - }); - expr_block(lctx, blk, None) - }) - } - _ => lower_expr(lctx, els), - } - }); - - hir::ExprIf(lower_expr(lctx, cond), lower_block(lctx, blk), else_opt) - } - ExprKind::While(ref cond, ref body, opt_ident) => { - hir::ExprWhile(lower_expr(lctx, cond), lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Loop(ref body, opt_ident) => { - hir::ExprLoop(lower_block(lctx, body), - opt_ident.map(|ident| lower_ident(lctx, ident))) - } - ExprKind::Match(ref expr, ref arms) => { - hir::ExprMatch(lower_expr(lctx, expr), - arms.iter().map(|x| lower_arm(lctx, x)).collect(), - hir::MatchSource::Normal) - } - ExprKind::Closure(capture_clause, ref decl, ref body) => { - hir::ExprClosure(lower_capture_clause(lctx, capture_clause), - lower_fn_decl(lctx, decl), - lower_block(lctx, body)) - } - ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), - ExprKind::Assign(ref el, ref er) => { - hir::ExprAssign(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::AssignOp(op, ref el, ref er) => { - hir::ExprAssignOp(lower_binop(lctx, op), - lower_expr(lctx, el), - lower_expr(lctx, er)) - } - ExprKind::Field(ref el, ident) => { - hir::ExprField(lower_expr(lctx, el), respan(ident.span, ident.node.name)) - } - ExprKind::TupField(ref el, ident) => { - hir::ExprTupField(lower_expr(lctx, el), ident) - } - ExprKind::Index(ref el, ref er) => { - hir::ExprIndex(lower_expr(lctx, el), lower_expr(lctx, er)) - } - ExprKind::Range(ref e1, ref e2, lims) => { - fn make_struct(lctx: &LoweringContext, - ast_expr: &Expr, - path: &[&str], - fields: &[(&str, &P)]) -> P { - let strs = std_path(lctx, &iter::once(&"ops") - .chain(path) - .map(|s| *s) - .collect::>()); - - let structpath = path_global(ast_expr.span, strs); - - let hir_expr = if fields.len() == 0 { - expr_path(lctx, - structpath, - ast_expr.attrs.clone()) - } else { - expr_struct(lctx, - ast_expr.span, - structpath, - fields.into_iter().map(|&(s, e)| { - field(token::intern(s), - signal_block_expr(lctx, - hir_vec![], - lower_expr(lctx, &**e), - e.span, - hir::PopUnstableBlock, - None), - ast_expr.span) - }).collect(), - None, - ast_expr.attrs.clone()) - }; - - signal_block_expr(lctx, - hir_vec![], - hir_expr, - ast_expr.span, - hir::PushUnstableBlock, - None) - } - - return cache_ids(lctx, e.id, |lctx| { - use syntax::ast::RangeLimits::*; - - match (e1, e2, lims) { - (&None, &None, HalfOpen) => - make_struct(lctx, e, &["RangeFull"], - &[]), - - (&Some(ref e1), &None, HalfOpen) => - make_struct(lctx, e, &["RangeFrom"], - &[("start", e1)]), - - (&None, &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["RangeTo"], - &[("end", e2)]), - - (&Some(ref e1), &Some(ref e2), HalfOpen) => - make_struct(lctx, e, &["Range"], - &[("start", e1), ("end", e2)]), - - (&None, &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeToInclusive"], - &[("end", e2)]), - - (&Some(ref e1), &Some(ref e2), Closed) => - make_struct(lctx, e, &["RangeInclusive", "NonEmpty"], - &[("start", e1), ("end", e2)]), - - _ => panic!(lctx.diagnostic().span_fatal(e.span, - "inclusive range with no end")) - } - }); - } - ExprKind::Path(ref qself, ref path) => { - let hir_qself = qself.as_ref().map(|&QSelf { ref ty, position }| { - hir::QSelf { - ty: lower_ty(lctx, ty), - position: position, - } - }); - hir::ExprPath(hir_qself, lower_path_full(lctx, path, qself.is_none())) - } - ExprKind::Break(opt_ident) => hir::ExprBreak(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Again(opt_ident) => hir::ExprAgain(opt_ident.map(|sp_ident| { - respan(sp_ident.span, lower_ident(lctx, sp_ident.node)) - })), - ExprKind::Ret(ref e) => hir::ExprRet(e.as_ref().map(|x| lower_expr(lctx, x))), - ExprKind::InlineAsm(InlineAsm { - ref inputs, - ref outputs, - ref asm, - asm_str_style, - ref clobbers, - volatile, - alignstack, - dialect, - expn_id, - }) => hir::ExprInlineAsm(hir::InlineAsm { - inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(), - outputs: outputs.iter() - .map(|out| { - hir::InlineAsmOutput { - constraint: out.constraint.clone(), - is_rw: out.is_rw, - is_indirect: out.is_indirect, - } - }) - .collect(), - asm: asm.clone(), - asm_str_style: asm_str_style, - clobbers: clobbers.clone().into(), - volatile: volatile, - alignstack: alignstack, - dialect: dialect, - expn_id: expn_id, - }, outputs.iter().map(|out| lower_expr(lctx, &out.expr)).collect(), - inputs.iter().map(|&(_, ref input)| lower_expr(lctx, input)).collect()), - ExprKind::Struct(ref path, ref fields, ref maybe_expr) => { - hir::ExprStruct(lower_path(lctx, path), - fields.iter().map(|x| lower_field(lctx, x)).collect(), - maybe_expr.as_ref().map(|x| lower_expr(lctx, x))) - } - ExprKind::Paren(ref ex) => { - // merge attributes into the inner expression. - return lower_expr(lctx, ex).map(|mut ex| { - ex.attrs.update(|attrs| { - attrs.prepend(e.attrs.clone()) - }); - ex - }); - } - - // Desugar ExprIfLet - // From: `if let = []` - ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => { - // to: - // - // match { - // => , - // [_ if => ,] - // _ => [ | ()] - // } - - return cache_ids(lctx, e.id, |lctx| { - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `[_ if => ,]` - let mut else_opt = else_opt.as_ref().map(|e| lower_expr(lctx, e)); - let else_if_arms = { - let mut arms = vec![]; - loop { - let else_opt_continue = else_opt.and_then(|els| { - els.and_then(|els| { - match els.node { - // else if - hir::ExprIf(cond, then, else_opt) => { - let pat_under = pat_wild(lctx, e.span); - arms.push(hir::Arm { - attrs: hir_vec![], - pats: hir_vec![pat_under], - guard: Some(cond), - body: expr_block(lctx, then, None), - }); - else_opt.map(|else_opt| (else_opt, true)) - } - _ => Some((P(els), false)), - } - }) - }); - match else_opt_continue { - Some((e, true)) => { - else_opt = Some(e); - } - Some((e, false)) => { - else_opt = Some(e); - break; - } - None => { - else_opt = None; - break; - } - } - } - arms - }; - - let contains_else_clause = else_opt.is_some(); - - // `_ => [ | ()]` - let else_arm = { - let pat_under = pat_wild(lctx, e.span); - let else_expr = - else_opt.unwrap_or_else( - || expr_tuple(lctx, e.span, hir_vec![], None)); - arm(hir_vec![pat_under], else_expr) - }; - - let mut arms = Vec::with_capacity(else_if_arms.len() + 2); - arms.push(pat_arm); - arms.extend(else_if_arms); - arms.push(else_arm); - - let sub_expr = lower_expr(lctx, sub_expr); - // add attributes to the outer returned expr node - expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms.into(), - hir::MatchSource::IfLetDesugar { - contains_else_clause: contains_else_clause, - }), - e.attrs.clone()) - }); - } - - // Desugar ExprWhileLet - // From: `[opt_ident]: while let = ` - ExprKind::WhileLet(ref pat, ref sub_expr, ref body, opt_ident) => { - // to: - // - // [opt_ident]: loop { - // match { - // => , - // _ => break - // } - // } - - return cache_ids(lctx, e.id, |lctx| { - // ` => ` - let pat_arm = { - let body = lower_block(lctx, body); - let body_expr = expr_block(lctx, body, None); - arm(hir_vec![lower_pat(lctx, pat)], body_expr) - }; - - // `_ => break` - let break_arm = { - let pat_under = pat_wild(lctx, e.span); - let break_expr = expr_break(lctx, e.span, None); - arm(hir_vec![pat_under], break_expr) - }; - - // `match { ... }` - let arms = hir_vec![pat_arm, break_arm]; - let sub_expr = lower_expr(lctx, sub_expr); - let match_expr = expr(lctx, - e.span, - hir::ExprMatch(sub_expr, - arms, - hir::MatchSource::WhileLetDesugar), - None); - - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - // add attributes to the outer returned expr node - expr(lctx, e.span, loop_expr, e.attrs.clone()) - }); - } - - // Desugar ExprForLoop - // From: `[opt_ident]: for in ` - ExprKind::ForLoop(ref pat, ref head, ref body, opt_ident) => { - // to: - // - // { - // let result = match ::std::iter::IntoIterator::into_iter() { - // mut iter => { - // [opt_ident]: loop { - // match ::std::iter::Iterator::next(&mut iter) { - // ::std::option::Option::Some() => , - // ::std::option::Option::None => break - // } - // } - // } - // }; - // result - // } - - return cache_ids(lctx, e.id, |lctx| { - // expand - let head = lower_expr(lctx, head); - - let iter = lctx.str_to_ident("iter"); - - // `::std::option::Option::Some() => ` - let pat_arm = { - let body_block = lower_block(lctx, body); - let body_span = body_block.span; - let body_expr = P(hir::Expr { - id: lctx.next_id(), - node: hir::ExprBlock(body_block), - span: body_span, - attrs: None, - }); - let pat = lower_pat(lctx, pat); - let some_pat = pat_some(lctx, e.span, pat); - - arm(hir_vec![some_pat], body_expr) - }; - - // `::std::option::Option::None => break` - let break_arm = { - let break_expr = expr_break(lctx, e.span, None); - - arm(hir_vec![pat_none(lctx, e.span)], break_expr) - }; - - // `match ::std::iter::Iterator::next(&mut iter) { ... }` - let match_expr = { - let next_path = { - let strs = std_path(lctx, &["iter", "Iterator", "next"]); - - path_global(e.span, strs) - }; - let iter = expr_ident(lctx, e.span, iter, None); - let ref_mut_iter = expr_mut_addr_of(lctx, e.span, iter, None); - let next_path = expr_path(lctx, next_path, None); - let next_expr = expr_call(lctx, - e.span, - next_path, - hir_vec![ref_mut_iter], - None); - let arms = hir_vec![pat_arm, break_arm]; - - expr(lctx, - e.span, - hir::ExprMatch(next_expr, arms, hir::MatchSource::ForLoopDesugar), - None) - }; - - // `[opt_ident]: loop { ... }` - let loop_block = block_expr(lctx, match_expr); - let loop_expr = hir::ExprLoop(loop_block, - opt_ident.map(|ident| lower_ident(lctx, ident))); - let loop_expr = expr(lctx, e.span, loop_expr, None); - - // `mut iter => { ... }` - let iter_arm = { - let iter_pat = pat_ident_binding_mode(lctx, - e.span, - iter, - hir::BindByValue(hir::MutMutable)); - arm(hir_vec![iter_pat], loop_expr) - }; - - // `match ::std::iter::IntoIterator::into_iter() { ... }` - let into_iter_expr = { - let into_iter_path = { - let strs = std_path(lctx, &["iter", "IntoIterator", "into_iter"]); - - path_global(e.span, strs) - }; - - let into_iter = expr_path(lctx, into_iter_path, None); - expr_call(lctx, e.span, into_iter, hir_vec![head], None) - }; - - let match_expr = expr_match(lctx, - e.span, - into_iter_expr, - hir_vec![iter_arm], - hir::MatchSource::ForLoopDesugar, - None); - - // `{ let _result = ...; _result }` - // underscore prevents an unused_variables lint if the head diverges - let result_ident = lctx.str_to_ident("_result"); - let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None); - let result = expr_ident(lctx, e.span, result_ident, None); - let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); - // add the attributes to the outer returned expr node - expr_block(lctx, block, e.attrs.clone()) - }); - } - - // Desugar ExprKind::Try - // From: `?` - ExprKind::Try(ref sub_expr) => { - // to: - // - // { - // match { - // Ok(val) => val, - // Err(err) => { - // return Err(From::from(err)) - // } - // } - // } - - return cache_ids(lctx, e.id, |lctx| { - // expand - let sub_expr = lower_expr(lctx, sub_expr); - - // Ok(val) => val - let ok_arm = { - let val_ident = lctx.str_to_ident("val"); - let val_pat = pat_ident(lctx, e.span, val_ident); - let val_expr = expr_ident(lctx, e.span, val_ident, None); - let ok_pat = pat_ok(lctx, e.span, val_pat); - - arm(hir_vec![ok_pat], val_expr) - }; - - // Err(err) => return Err(From::from(err)) - let err_arm = { - let err_ident = lctx.str_to_ident("err"); - let from_expr = { - let path = std_path(lctx, &["convert", "From", "from"]); - let path = path_global(e.span, path); - let from = expr_path(lctx, path, None); - let err_expr = expr_ident(lctx, e.span, err_ident, None); - - expr_call(lctx, e.span, from, hir_vec![err_expr], None) - }; - let err_expr = { - let path = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(e.span, path); - let err_ctor = expr_path(lctx, path, None); - expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) - }; - let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident)); - let ret_expr = expr(lctx, e.span, - hir::Expr_::ExprRet(Some(err_expr)), None); - - arm(hir_vec![err_pat], ret_expr) - }; - - expr_match(lctx, e.span, sub_expr, hir_vec![err_arm, ok_arm], - hir::MatchSource::TryDesugar, None) - }) - } - - ExprKind::Mac(_) => panic!("Shouldn't exist here"), - }, - span: e.span, - attrs: e.attrs.clone(), - }) -} - -pub fn lower_stmt(lctx: &LoweringContext, s: &Stmt) -> hir::Stmt { - match s.node { - StmtKind::Decl(ref d, id) => { - Spanned { - node: hir::StmtDecl(lower_decl(lctx, d), id), - span: s.span, - } - } - StmtKind::Expr(ref e, id) => { - Spanned { - node: hir::StmtExpr(lower_expr(lctx, e), id), - span: s.span, - } - } - StmtKind::Semi(ref e, id) => { - Spanned { - node: hir::StmtSemi(lower_expr(lctx, e), id), - span: s.span, - } - } - StmtKind::Mac(..) => panic!("Shouldn't exist here"), - } -} - -pub fn lower_capture_clause(_lctx: &LoweringContext, c: CaptureBy) -> hir::CaptureClause { - match c { - CaptureBy::Value => hir::CaptureByValue, - CaptureBy::Ref => hir::CaptureByRef, - } -} - -pub fn lower_visibility(lctx: &LoweringContext, v: &Visibility) -> hir::Visibility { - match *v { - Visibility::Public => hir::Public, - Visibility::Inherited => hir::Inherited, - _ => panic!(lctx.diagnostic().fatal("pub(restricted) is not implemented yet!")) - } -} - -pub fn lower_defaultness(_lctx: &LoweringContext, d: Defaultness) -> hir::Defaultness { - match d { - Defaultness::Default => hir::Defaultness::Default, - Defaultness::Final => hir::Defaultness::Final, - } -} - -pub fn lower_block_check_mode(lctx: &LoweringContext, b: &BlockCheckMode) -> hir::BlockCheckMode { - match *b { - BlockCheckMode::Default => hir::DefaultBlock, - BlockCheckMode::Unsafe(u) => hir::UnsafeBlock(lower_unsafe_source(lctx, u)), - } -} - -pub fn lower_binding_mode(lctx: &LoweringContext, b: &BindingMode) -> hir::BindingMode { - match *b { - BindingMode::ByRef(m) => hir::BindByRef(lower_mutability(lctx, m)), - BindingMode::ByValue(m) => hir::BindByValue(lower_mutability(lctx, m)), - } -} - -pub fn lower_unsafe_source(_lctx: &LoweringContext, u: UnsafeSource) -> hir::UnsafeSource { - match u { - CompilerGenerated => hir::CompilerGenerated, - UserProvided => hir::UserProvided, - } -} - -pub fn lower_impl_polarity(_lctx: &LoweringContext, i: ImplPolarity) -> hir::ImplPolarity { - match i { - ImplPolarity::Positive => hir::ImplPolarity::Positive, - ImplPolarity::Negative => hir::ImplPolarity::Negative, - } -} - -pub fn lower_trait_bound_modifier(_lctx: &LoweringContext, - f: TraitBoundModifier) - -> hir::TraitBoundModifier { - match f { - TraitBoundModifier::None => hir::TraitBoundModifier::None, - TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe, - } -} - -// Helper methods for building HIR. - -fn arm(pats: hir::HirVec>, expr: P) -> hir::Arm { - hir::Arm { - attrs: hir_vec![], - pats: pats, - guard: None, - body: expr, - } -} - -fn field(name: Name, expr: P, span: Span) -> hir::Field { - hir::Field { - name: Spanned { - node: name, - span: span, - }, - span: span, - expr: expr, - } -} - -fn expr_break(lctx: &LoweringContext, span: Span, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprBreak(None), attrs) -} - -fn expr_call(lctx: &LoweringContext, - span: Span, - e: P, - args: hir::HirVec>, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprCall(e, args), attrs) -} - -fn expr_ident(lctx: &LoweringContext, span: Span, id: hir::Ident, - attrs: ThinAttributes) -> P { - expr_path(lctx, path_ident(span, id), attrs) -} - -fn expr_mut_addr_of(lctx: &LoweringContext, span: Span, e: P, - attrs: ThinAttributes) -> P { - expr(lctx, span, hir::ExprAddrOf(hir::MutMutable, e), attrs) -} - -fn expr_path(lctx: &LoweringContext, path: hir::Path, - attrs: ThinAttributes) -> P { - expr(lctx, path.span, hir::ExprPath(None, path), attrs) -} - -fn expr_match(lctx: &LoweringContext, - span: Span, - arg: P, - arms: hir::HirVec, - source: hir::MatchSource, - attrs: ThinAttributes) - -> P { - expr(lctx, span, hir::ExprMatch(arg, arms, source), attrs) -} - -fn expr_block(lctx: &LoweringContext, b: P, - attrs: ThinAttributes) -> P { - expr(lctx, b.span, hir::ExprBlock(b), attrs) -} - -fn expr_tuple(lctx: &LoweringContext, sp: Span, exprs: hir::HirVec>, - attrs: ThinAttributes) -> P { - expr(lctx, sp, hir::ExprTup(exprs), attrs) -} - -fn expr_struct(lctx: &LoweringContext, - sp: Span, - path: hir::Path, - fields: hir::HirVec, - e: Option>, - attrs: ThinAttributes) -> P { - expr(lctx, sp, hir::ExprStruct(path, fields, e), attrs) -} - -fn expr(lctx: &LoweringContext, span: Span, node: hir::Expr_, - attrs: ThinAttributes) -> P { - P(hir::Expr { - id: lctx.next_id(), - node: node, - span: span, - attrs: attrs, - }) -} - -fn stmt_let(lctx: &LoweringContext, - sp: Span, - mutbl: bool, - ident: hir::Ident, - ex: P, - attrs: ThinAttributes) - -> hir::Stmt { - let pat = if mutbl { - pat_ident_binding_mode(lctx, sp, ident, hir::BindByValue(hir::MutMutable)) - } else { - pat_ident(lctx, sp, ident) - }; - let local = P(hir::Local { - pat: pat, - ty: None, - init: Some(ex), - id: lctx.next_id(), - span: sp, - attrs: attrs, - }); - let decl = respan(sp, hir::DeclLocal(local)); - respan(sp, hir::StmtDecl(P(decl), lctx.next_id())) -} - -fn block_expr(lctx: &LoweringContext, expr: P) -> P { - block_all(lctx, expr.span, hir::HirVec::new(), Some(expr)) -} - -fn block_all(lctx: &LoweringContext, - span: Span, - stmts: hir::HirVec, - expr: Option>) - -> P { - P(hir::Block { - stmts: stmts, - expr: expr, - id: lctx.next_id(), - rules: hir::DefaultBlock, - span: span, - }) -} - -fn pat_ok(lctx: &LoweringContext, span: Span, pat: P) -> P { - let ok = std_path(lctx, &["result", "Result", "Ok"]); - let path = path_global(span, ok); - pat_enum(lctx, span, path, hir_vec![pat]) -} - -fn pat_err(lctx: &LoweringContext, span: Span, pat: P) -> P { - let err = std_path(lctx, &["result", "Result", "Err"]); - let path = path_global(span, err); - pat_enum(lctx, span, path, hir_vec![pat]) -} - -fn pat_some(lctx: &LoweringContext, span: Span, pat: P) -> P { - let some = std_path(lctx, &["option", "Option", "Some"]); - let path = path_global(span, some); - pat_enum(lctx, span, path, hir_vec![pat]) -} - -fn pat_none(lctx: &LoweringContext, span: Span) -> P { - let none = std_path(lctx, &["option", "Option", "None"]); - let path = path_global(span, none); - pat_enum(lctx, span, path, hir_vec![]) -} - -fn pat_enum(lctx: &LoweringContext, - span: Span, - path: hir::Path, - subpats: hir::HirVec>) - -> P { - let pt = if subpats.is_empty() { - hir::PatKind::Path(path) - } else { - hir::PatKind::TupleStruct(path, Some(subpats)) - }; - pat(lctx, span, pt) -} - -fn pat_ident(lctx: &LoweringContext, span: Span, ident: hir::Ident) -> P { - pat_ident_binding_mode(lctx, span, ident, hir::BindByValue(hir::MutImmutable)) -} - -fn pat_ident_binding_mode(lctx: &LoweringContext, - span: Span, - ident: hir::Ident, - bm: hir::BindingMode) - -> P { - let pat_ident = hir::PatKind::Ident(bm, - Spanned { - span: span, - node: ident, - }, - None); - pat(lctx, span, pat_ident) -} - -fn pat_wild(lctx: &LoweringContext, span: Span) -> P { - pat(lctx, span, hir::PatKind::Wild) -} - -fn pat(lctx: &LoweringContext, span: Span, pat: hir::PatKind) -> P { - P(hir::Pat { - id: lctx.next_id(), - node: pat, - span: span, - }) -} - -fn path_ident(span: Span, id: hir::Ident) -> hir::Path { - path(span, vec![id]) -} - -fn path(span: Span, strs: Vec) -> hir::Path { - path_all(span, false, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} - -fn path_global(span: Span, strs: Vec) -> hir::Path { - path_all(span, true, strs, hir::HirVec::new(), hir::HirVec::new(), hir::HirVec::new()) -} - -fn path_all(sp: Span, - global: bool, - mut idents: Vec, - lifetimes: hir::HirVec, - types: hir::HirVec>, - bindings: hir::HirVec) - -> hir::Path { - let last_identifier = idents.pop().unwrap(); - let mut segments: Vec = idents.into_iter() - .map(|ident| { - hir::PathSegment { - identifier: ident, - parameters: hir::PathParameters::none(), - } - }) - .collect(); - segments.push(hir::PathSegment { - identifier: last_identifier, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: lifetimes, - types: types, - bindings: bindings, - }), - }); - hir::Path { - span: sp, - global: global, - segments: segments.into(), - } -} - -fn std_path(lctx: &LoweringContext, components: &[&str]) -> Vec { - let mut v = Vec::new(); - if let Some(s) = lctx.crate_root { - v.push(hir::Ident::from_name(token::intern(s))); - } - v.extend(components.iter().map(|s| hir::Ident::from_name(token::intern(s)))); - return v; -} - -// Given suffix ["b","c","d"], returns path `::std::b::c::d` when -// `fld.cx.use_std`, and `::core::b::c::d` otherwise. -fn core_path(lctx: &LoweringContext, span: Span, components: &[&str]) -> hir::Path { - let idents = std_path(lctx, components); - path_global(span, idents) -} - -fn signal_block_expr(lctx: &LoweringContext, - stmts: hir::HirVec, - expr: P, - span: Span, - rule: hir::BlockCheckMode, - attrs: ThinAttributes) - -> P { - let id = lctx.next_id(); - expr_block(lctx, - P(hir::Block { - rules: rule, - span: span, - id: id, - stmts: stmts, - expr: Some(expr), - }), - attrs) -} - - - -#[cfg(test)] -mod test { - use super::*; - use syntax::ast::{self, NodeId, NodeIdAssigner}; - use syntax::{parse, codemap}; - use syntax::fold::Folder; - use std::cell::Cell; - - struct MockAssigner { - next_id: Cell, - } - - impl MockAssigner { - fn new() -> MockAssigner { - MockAssigner { next_id: Cell::new(0) } - } - } - - trait FakeExtCtxt { - fn call_site(&self) -> codemap::Span; - fn cfg(&self) -> ast::CrateConfig; - fn ident_of(&self, st: &str) -> ast::Ident; - fn name_of(&self, st: &str) -> ast::Name; - fn parse_sess(&self) -> &parse::ParseSess; - } - - impl FakeExtCtxt for parse::ParseSess { - fn call_site(&self) -> codemap::Span { - codemap::Span { - lo: codemap::BytePos(0), - hi: codemap::BytePos(0), - expn_id: codemap::NO_EXPANSION, - } - } - fn cfg(&self) -> ast::CrateConfig { - Vec::new() - } - fn ident_of(&self, st: &str) -> ast::Ident { - parse::token::str_to_ident(st) - } - fn name_of(&self, st: &str) -> ast::Name { - parse::token::intern(st) - } - fn parse_sess(&self) -> &parse::ParseSess { - self - } - } - - impl NodeIdAssigner for MockAssigner { - fn next_node_id(&self) -> NodeId { - let result = self.next_id.get(); - self.next_id.set(result + 1); - result - } - - fn peek_node_id(&self) -> NodeId { - self.next_id.get() - } - } - - impl Folder for MockAssigner { - fn new_id(&mut self, old_id: NodeId) -> NodeId { - assert_eq!(old_id, ast::DUMMY_NODE_ID); - self.next_node_id() - } - } - - #[test] - fn test_preserves_ids() { - let cx = parse::ParseSess::new(); - let mut assigner = MockAssigner::new(); - - let ast_if_let = quote_expr!(&cx, - if let Some(foo) = baz { - bar(foo); - }); - let ast_if_let = assigner.fold_expr(ast_if_let); - let ast_while_let = quote_expr!(&cx, - while let Some(foo) = baz { - bar(foo); - }); - let ast_while_let = assigner.fold_expr(ast_while_let); - let ast_for = quote_expr!(&cx, - for i in 0..10 { - for j in 0..10 { - foo(i, j); - } - }); - let ast_for = assigner.fold_expr(ast_for); - let ast_in = quote_expr!(&cx, in HEAP { foo() }); - let ast_in = assigner.fold_expr(ast_in); - - let lctx = LoweringContext::new(&assigner, None); - let hir1 = lower_expr(&lctx, &ast_if_let); - let hir2 = lower_expr(&lctx, &ast_if_let); - assert!(hir1 == hir2); - - let hir1 = lower_expr(&lctx, &ast_while_let); - let hir2 = lower_expr(&lctx, &ast_while_let); - assert!(hir1 == hir2); - - let hir1 = lower_expr(&lctx, &ast_for); - let hir2 = lower_expr(&lctx, &ast_for); - assert!(hir1 == hir2); - - let hir1 = lower_expr(&lctx, &ast_in); - let hir2 = lower_expr(&lctx, &ast_in); - assert!(hir1 == hir2); - } -} diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs deleted file mode 100644 index 3b8e6763de0..00000000000 --- a/src/librustc_front/print/pprust.rs +++ /dev/null @@ -1,2413 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use self::AnnNode::*; - -use syntax::abi::Abi; -use syntax::ast; -use syntax::codemap::{self, CodeMap, BytePos, Spanned}; -use syntax::errors; -use syntax::parse::token::{self, BinOpToken}; -use syntax::parse::lexer::comments; -use syntax::parse; -use syntax::print::pp::{self, break_offset, word, space, hardbreak}; -use syntax::print::pp::{Breaks, eof}; -use syntax::print::pp::Breaks::{Consistent, Inconsistent}; -use syntax::print::pprust::{self as ast_pp, PrintState}; -use syntax::ptr::P; - -use hir; -use hir::{Crate, PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; - -use std::io::{self, Write, Read}; - -pub enum AnnNode<'a> { - NodeName(&'a ast::Name), - NodeBlock(&'a hir::Block), - NodeItem(&'a hir::Item), - NodeSubItem(ast::NodeId), - NodeExpr(&'a hir::Expr), - NodePat(&'a hir::Pat), -} - -pub trait PpAnn { - fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { - Ok(()) - } - fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { - Ok(()) - } -} - -#[derive(Copy, Clone)] -pub struct NoAnn; - -impl PpAnn for NoAnn {} - - -pub struct State<'a> { - krate: Option<&'a Crate>, - pub s: pp::Printer<'a>, - cm: Option<&'a CodeMap>, - comments: Option>, - literals: Option>, - cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral, - boxes: Vec, - ann: &'a (PpAnn + 'a), -} - -impl<'a> PrintState<'a> for State<'a> { - fn writer(&mut self) -> &mut pp::Printer<'a> { - &mut self.s - } - - fn boxes(&mut self) -> &mut Vec { - &mut self.boxes - } - - fn comments(&mut self) -> &mut Option> { - &mut self.comments - } - - fn cur_cmnt_and_lit(&mut self) -> &mut ast_pp::CurrentCommentAndLiteral { - &mut self.cur_cmnt_and_lit - } - - fn literals(&self) -> &Option> { - &self.literals - } -} - -pub fn rust_printer<'a>(writer: Box, krate: Option<&'a Crate>) -> State<'a> { - static NO_ANN: NoAnn = NoAnn; - rust_printer_annotated(writer, &NO_ANN, krate) -} - -pub fn rust_printer_annotated<'a>(writer: Box, - ann: &'a PpAnn, - krate: Option<&'a Crate>) - -> State<'a> { - State { - krate: krate, - s: pp::mk_printer(writer, default_columns), - cm: None, - comments: None, - literals: None, - cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral { - cur_cmnt: 0, - cur_lit: 0, - }, - boxes: Vec::new(), - ann: ann, - } -} - -#[allow(non_upper_case_globals)] -pub const indent_unit: usize = 4; - -#[allow(non_upper_case_globals)] -pub const default_columns: usize = 78; - - -/// Requires you to pass an input filename and reader so that -/// it can scan the input text for comments and literals to -/// copy forward. -pub fn print_crate<'a>(cm: &'a CodeMap, - span_diagnostic: &errors::Handler, - krate: &hir::Crate, - filename: String, - input: &mut Read, - out: Box, - ann: &'a PpAnn, - is_expanded: bool) - -> io::Result<()> { - let mut s = State::new_from_input(cm, span_diagnostic, filename, input, - out, ann, is_expanded, Some(krate)); - - // When printing the AST, we sometimes need to inject `#[no_std]` here. - // Since you can't compile the HIR, it's not necessary. - - s.print_mod(&krate.module, &krate.attrs)?; - s.print_remaining_comments()?; - eof(&mut s.s) -} - -impl<'a> State<'a> { - pub fn new_from_input(cm: &'a CodeMap, - span_diagnostic: &errors::Handler, - filename: String, - input: &mut Read, - out: Box, - ann: &'a PpAnn, - is_expanded: bool, - krate: Option<&'a Crate>) - -> State<'a> { - let (cmnts, lits) = comments::gather_comments_and_literals(span_diagnostic, - filename, - input); - - State::new(cm, - out, - ann, - Some(cmnts), - // If the code is post expansion, don't use the table of - // literals, since it doesn't correspond with the literals - // in the AST anymore. - if is_expanded { - None - } else { - Some(lits) - }, - krate) - } - - pub fn new(cm: &'a CodeMap, - out: Box, - ann: &'a PpAnn, - comments: Option>, - literals: Option>, - krate: Option<&'a Crate>) - -> State<'a> { - State { - krate: krate, - s: pp::mk_printer(out, default_columns), - cm: Some(cm), - comments: comments.clone(), - literals: literals.clone(), - cur_cmnt_and_lit: ast_pp::CurrentCommentAndLiteral { - cur_cmnt: 0, - cur_lit: 0, - }, - boxes: Vec::new(), - ann: ann, - } - } -} - -pub fn to_string(f: F) -> String - where F: FnOnce(&mut State) -> io::Result<()> -{ - let mut wr = Vec::new(); - { - let mut printer = rust_printer(Box::new(&mut wr), None); - f(&mut printer).unwrap(); - eof(&mut printer.s).unwrap(); - } - String::from_utf8(wr).unwrap() -} - -pub fn binop_to_string(op: BinOpToken) -> &'static str { - match op { - token::Plus => "+", - token::Minus => "-", - token::Star => "*", - token::Slash => "/", - token::Percent => "%", - token::Caret => "^", - token::And => "&", - token::Or => "|", - token::Shl => "<<", - token::Shr => ">>", - } -} - -pub fn ty_to_string(ty: &hir::Ty) -> String { - to_string(|s| s.print_type(ty)) -} - -pub fn bounds_to_string(bounds: &[hir::TyParamBound]) -> String { - to_string(|s| s.print_bounds("", bounds)) -} - -pub fn pat_to_string(pat: &hir::Pat) -> String { - to_string(|s| s.print_pat(pat)) -} - -pub fn arm_to_string(arm: &hir::Arm) -> String { - to_string(|s| s.print_arm(arm)) -} - -pub fn expr_to_string(e: &hir::Expr) -> String { - to_string(|s| s.print_expr(e)) -} - -pub fn lifetime_to_string(e: &hir::Lifetime) -> String { - to_string(|s| s.print_lifetime(e)) -} - -pub fn stmt_to_string(stmt: &hir::Stmt) -> String { - to_string(|s| s.print_stmt(stmt)) -} - -pub fn item_to_string(i: &hir::Item) -> String { - to_string(|s| s.print_item(i)) -} - -pub fn impl_item_to_string(i: &hir::ImplItem) -> String { - to_string(|s| s.print_impl_item(i)) -} - -pub fn trait_item_to_string(i: &hir::TraitItem) -> String { - to_string(|s| s.print_trait_item(i)) -} - -pub fn generics_to_string(generics: &hir::Generics) -> String { - to_string(|s| s.print_generics(generics)) -} - -pub fn where_clause_to_string(i: &hir::WhereClause) -> String { - to_string(|s| s.print_where_clause(i)) -} - -pub fn fn_block_to_string(p: &hir::FnDecl) -> String { - to_string(|s| s.print_fn_block_args(p)) -} - -pub fn path_to_string(p: &hir::Path) -> String { - to_string(|s| s.print_path(p, false, 0)) -} - -pub fn name_to_string(name: ast::Name) -> String { - to_string(|s| s.print_name(name)) -} - -pub fn fun_to_string(decl: &hir::FnDecl, - unsafety: hir::Unsafety, - constness: hir::Constness, - name: ast::Name, - opt_explicit_self: Option<&hir::ExplicitSelf_>, - generics: &hir::Generics) - -> String { - to_string(|s| { - s.head("")?; - s.print_fn(decl, - unsafety, - constness, - Abi::Rust, - Some(name), - generics, - opt_explicit_self, - hir::Inherited)?; - s.end()?; // Close the head box - s.end() // Close the outer box - }) -} - -pub fn block_to_string(blk: &hir::Block) -> String { - to_string(|s| { - // containing cbox, will be closed by print-block at } - s.cbox(indent_unit)?; - // head-ibox, will be closed by print-block after { - s.ibox(0)?; - s.print_block(blk) - }) -} - -pub fn explicit_self_to_string(explicit_self: &hir::ExplicitSelf_) -> String { - to_string(|s| s.print_explicit_self(explicit_self, hir::MutImmutable).map(|_| {})) -} - -pub fn variant_to_string(var: &hir::Variant) -> String { - to_string(|s| s.print_variant(var)) -} - -pub fn arg_to_string(arg: &hir::Arg) -> String { - to_string(|s| s.print_arg(arg, false)) -} - -pub fn visibility_qualified(vis: hir::Visibility, s: &str) -> String { - match vis { - hir::Public => format!("pub {}", s), - hir::Inherited => s.to_string(), - } -} - -fn needs_parentheses(expr: &hir::Expr) -> bool { - match expr.node { - hir::ExprAssign(..) | - hir::ExprBinary(..) | - hir::ExprClosure(..) | - hir::ExprAssignOp(..) | - hir::ExprCast(..) | - hir::ExprType(..) => true, - _ => false, - } -} - -impl<'a> State<'a> { - pub fn cbox(&mut self, u: usize) -> io::Result<()> { - self.boxes.push(pp::Breaks::Consistent); - pp::cbox(&mut self.s, u) - } - - pub fn nbsp(&mut self) -> io::Result<()> { - word(&mut self.s, " ") - } - - pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> { - word(&mut self.s, w)?; - self.nbsp() - } - - pub fn head(&mut self, w: &str) -> io::Result<()> { - // outer-box is consistent - self.cbox(indent_unit)?; - // head-box is inconsistent - self.ibox(w.len() + 1)?; - // keyword that starts the head - if !w.is_empty() { - self.word_nbsp(w)?; - } - Ok(()) - } - - pub fn bopen(&mut self) -> io::Result<()> { - word(&mut self.s, "{")?; - self.end() // close the head-box - } - - pub fn bclose_(&mut self, span: codemap::Span, indented: usize) -> io::Result<()> { - self.bclose_maybe_open(span, indented, true) - } - pub fn bclose_maybe_open(&mut self, - span: codemap::Span, - indented: usize, - close_box: bool) - -> io::Result<()> { - self.maybe_print_comment(span.hi)?; - self.break_offset_if_not_bol(1, -(indented as isize))?; - word(&mut self.s, "}")?; - if close_box { - self.end()?; // close the outer-box - } - Ok(()) - } - pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> { - self.bclose_(span, indent_unit) - } - - pub fn in_cbox(&self) -> bool { - match self.boxes.last() { - Some(&last_box) => last_box == pp::Breaks::Consistent, - None => false, - } - } - pub fn space_if_not_bol(&mut self) -> io::Result<()> { - if !self.is_bol() { - space(&mut self.s)?; - } - Ok(()) - } - pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) -> io::Result<()> { - if !self.is_bol() { - break_offset(&mut self.s, n, off) - } else { - if off != 0 && self.s.last_token().is_hardbreak_tok() { - // We do something pretty sketchy here: tuck the nonzero - // offset-adjustment we were going to deposit along with the - // break into the previous hardbreak. - self.s.replace_last_token(pp::hardbreak_tok_offset(off)); - } - Ok(()) - } - } - - // Synthesizes a comment that was not textually present in the original source - // file. - pub fn synth_comment(&mut self, text: String) -> io::Result<()> { - word(&mut self.s, "/*")?; - space(&mut self.s)?; - word(&mut self.s, &text[..])?; - space(&mut self.s)?; - word(&mut self.s, "*/") - } - - - pub fn commasep_cmnt(&mut self, - b: Breaks, - elts: &[T], - mut op: F, - mut get_span: G) - -> io::Result<()> - where F: FnMut(&mut State, &T) -> io::Result<()>, - G: FnMut(&T) -> codemap::Span - { - self.rbox(0, b)?; - let len = elts.len(); - let mut i = 0; - for elt in elts { - self.maybe_print_comment(get_span(elt).hi)?; - op(self, elt)?; - i += 1; - if i < len { - word(&mut self.s, ",")?; - self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi))?; - self.space_if_not_bol()?; - } - } - self.end() - } - - pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[P]) -> io::Result<()> { - self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span) - } - - pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) -> io::Result<()> { - self.print_inner_attributes(attrs)?; - for item_id in &_mod.item_ids { - self.print_item_id(item_id)?; - } - Ok(()) - } - - pub fn print_foreign_mod(&mut self, - nmod: &hir::ForeignMod, - attrs: &[ast::Attribute]) - -> io::Result<()> { - self.print_inner_attributes(attrs)?; - for item in &nmod.items { - self.print_foreign_item(item)?; - } - Ok(()) - } - - pub fn print_opt_lifetime(&mut self, lifetime: &Option) -> io::Result<()> { - if let Some(l) = *lifetime { - self.print_lifetime(&l)?; - self.nbsp()?; - } - Ok(()) - } - - pub fn print_type(&mut self, ty: &hir::Ty) -> io::Result<()> { - self.maybe_print_comment(ty.span.lo)?; - self.ibox(0)?; - match ty.node { - hir::TyVec(ref ty) => { - word(&mut self.s, "[")?; - self.print_type(&ty)?; - word(&mut self.s, "]")?; - } - hir::TyPtr(ref mt) => { - word(&mut self.s, "*")?; - match mt.mutbl { - hir::MutMutable => self.word_nbsp("mut")?, - hir::MutImmutable => self.word_nbsp("const")?, - } - self.print_type(&mt.ty)?; - } - hir::TyRptr(ref lifetime, ref mt) => { - word(&mut self.s, "&")?; - self.print_opt_lifetime(lifetime)?; - self.print_mt(mt)?; - } - hir::TyTup(ref elts) => { - self.popen()?; - self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?; - if elts.len() == 1 { - word(&mut self.s, ",")?; - } - self.pclose()?; - } - hir::TyBareFn(ref f) => { - let generics = hir::Generics { - lifetimes: f.lifetimes.clone(), - ty_params: hir::HirVec::new(), - where_clause: hir::WhereClause { - id: ast::DUMMY_NODE_ID, - predicates: hir::HirVec::new(), - }, - }; - self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &generics, None)?; - } - hir::TyPath(None, ref path) => { - self.print_path(path, false, 0)?; - } - hir::TyPath(Some(ref qself), ref path) => { - self.print_qpath(path, qself, false)? - } - hir::TyObjectSum(ref ty, ref bounds) => { - self.print_type(&ty)?; - self.print_bounds("+", &bounds[..])?; - } - hir::TyPolyTraitRef(ref bounds) => { - self.print_bounds("", &bounds[..])?; - } - hir::TyFixedLengthVec(ref ty, ref v) => { - word(&mut self.s, "[")?; - self.print_type(&ty)?; - word(&mut self.s, "; ")?; - self.print_expr(&v)?; - word(&mut self.s, "]")?; - } - hir::TyTypeof(ref e) => { - word(&mut self.s, "typeof(")?; - self.print_expr(&e)?; - word(&mut self.s, ")")?; - } - hir::TyInfer => { - word(&mut self.s, "_")?; - } - } - self.end() - } - - pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo)?; - self.print_outer_attributes(&item.attrs)?; - match item.node { - hir::ForeignItemFn(ref decl, ref generics) => { - self.head("")?; - self.print_fn(decl, - hir::Unsafety::Normal, - hir::Constness::NotConst, - Abi::Rust, - Some(item.name), - generics, - None, - item.vis)?; - self.end()?; // end head-ibox - word(&mut self.s, ";")?; - self.end() // end the outer fn box - } - hir::ForeignItemStatic(ref t, m) => { - self.head(&visibility_qualified(item.vis, "static"))?; - if m { - self.word_space("mut")?; - } - self.print_name(item.name)?; - self.word_space(":")?; - self.print_type(&t)?; - word(&mut self.s, ";")?; - self.end()?; // end the head-ibox - self.end() // end the outer cbox - } - } - } - - fn print_associated_const(&mut self, - name: ast::Name, - ty: &hir::Ty, - default: Option<&hir::Expr>, - vis: hir::Visibility) - -> io::Result<()> { - word(&mut self.s, &visibility_qualified(vis, ""))?; - self.word_space("const")?; - self.print_name(name)?; - self.word_space(":")?; - self.print_type(ty)?; - if let Some(expr) = default { - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(expr)?; - } - word(&mut self.s, ";") - } - - fn print_associated_type(&mut self, - name: ast::Name, - bounds: Option<&hir::TyParamBounds>, - ty: Option<&hir::Ty>) - -> io::Result<()> { - self.word_space("type")?; - self.print_name(name)?; - if let Some(bounds) = bounds { - self.print_bounds(":", bounds)?; - } - if let Some(ty) = ty { - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(ty)?; - } - word(&mut self.s, ";") - } - - pub fn print_item_id(&mut self, item_id: &hir::ItemId) -> io::Result<()> { - if let Some(krate) = self.krate { - // skip nested items if krate context was not provided - let item = &krate.items[&item_id.id]; - self.print_item(item) - } else { - Ok(()) - } - } - - /// Pretty-print an item - pub fn print_item(&mut self, item: &hir::Item) -> io::Result<()> { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(item.span.lo)?; - self.print_outer_attributes(&item.attrs)?; - self.ann.pre(self, NodeItem(item))?; - match item.node { - hir::ItemExternCrate(ref optional_path) => { - self.head(&visibility_qualified(item.vis, "extern crate"))?; - if let Some(p) = *optional_path { - let val = p.as_str(); - if val.contains("-") { - self.print_string(&val, ast::StrStyle::Cooked)?; - } else { - self.print_name(p)?; - } - space(&mut self.s)?; - word(&mut self.s, "as")?; - space(&mut self.s)?; - } - self.print_name(item.name)?; - word(&mut self.s, ";")?; - self.end()?; // end inner head-block - self.end()?; // end outer head-block - } - hir::ItemUse(ref vp) => { - self.head(&visibility_qualified(item.vis, "use"))?; - self.print_view_path(&vp)?; - word(&mut self.s, ";")?; - self.end()?; // end inner head-block - self.end()?; // end outer head-block - } - hir::ItemStatic(ref ty, m, ref expr) => { - self.head(&visibility_qualified(item.vis, "static"))?; - if m == hir::MutMutable { - self.word_space("mut")?; - } - self.print_name(item.name)?; - self.word_space(":")?; - self.print_type(&ty)?; - space(&mut self.s)?; - self.end()?; // end the head-ibox - - self.word_space("=")?; - self.print_expr(&expr)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer cbox - } - hir::ItemConst(ref ty, ref expr) => { - self.head(&visibility_qualified(item.vis, "const"))?; - self.print_name(item.name)?; - self.word_space(":")?; - self.print_type(&ty)?; - space(&mut self.s)?; - self.end()?; // end the head-ibox - - self.word_space("=")?; - self.print_expr(&expr)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer cbox - } - hir::ItemFn(ref decl, unsafety, constness, abi, ref typarams, ref body) => { - self.head("")?; - self.print_fn(decl, - unsafety, - constness, - abi, - Some(item.name), - typarams, - None, - item.vis)?; - word(&mut self.s, " ")?; - self.print_block_with_attrs(&body, &item.attrs)?; - } - hir::ItemMod(ref _mod) => { - self.head(&visibility_qualified(item.vis, "mod"))?; - self.print_name(item.name)?; - self.nbsp()?; - self.bopen()?; - self.print_mod(_mod, &item.attrs)?; - self.bclose(item.span)?; - } - hir::ItemForeignMod(ref nmod) => { - self.head("extern")?; - self.word_nbsp(&nmod.abi.to_string())?; - self.bopen()?; - self.print_foreign_mod(nmod, &item.attrs)?; - self.bclose(item.span)?; - } - hir::ItemTy(ref ty, ref params) => { - self.ibox(indent_unit)?; - self.ibox(0)?; - self.word_nbsp(&visibility_qualified(item.vis, "type"))?; - self.print_name(item.name)?; - self.print_generics(params)?; - self.end()?; // end the inner ibox - - self.print_where_clause(¶ms.where_clause)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&ty)?; - word(&mut self.s, ";")?; - self.end()?; // end the outer ibox - } - hir::ItemEnum(ref enum_definition, ref params) => { - self.print_enum_def(enum_definition, params, item.name, item.span, item.vis)?; - } - hir::ItemStruct(ref struct_def, ref generics) => { - self.head(&visibility_qualified(item.vis, "struct"))?; - self.print_struct(struct_def, generics, item.name, item.span, true)?; - } - - hir::ItemDefaultImpl(unsafety, ref trait_ref) => { - self.head("")?; - self.print_visibility(item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("impl")?; - self.print_trait_ref(trait_ref)?; - space(&mut self.s)?; - self.word_space("for")?; - self.word_space("..")?; - self.bopen()?; - self.bclose(item.span)?; - } - hir::ItemImpl(unsafety, - polarity, - ref generics, - ref opt_trait, - ref ty, - ref impl_items) => { - self.head("")?; - self.print_visibility(item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("impl")?; - - if generics.is_parameterized() { - self.print_generics(generics)?; - space(&mut self.s)?; - } - - match polarity { - hir::ImplPolarity::Negative => { - word(&mut self.s, "!")?; - } - _ => {} - } - - match opt_trait { - &Some(ref t) => { - self.print_trait_ref(t)?; - space(&mut self.s)?; - self.word_space("for")?; - } - &None => {} - } - - self.print_type(&ty)?; - self.print_where_clause(&generics.where_clause)?; - - space(&mut self.s)?; - self.bopen()?; - self.print_inner_attributes(&item.attrs)?; - for impl_item in impl_items { - self.print_impl_item(impl_item)?; - } - self.bclose(item.span)?; - } - hir::ItemTrait(unsafety, ref generics, ref bounds, ref trait_items) => { - self.head("")?; - self.print_visibility(item.vis)?; - self.print_unsafety(unsafety)?; - self.word_nbsp("trait")?; - self.print_name(item.name)?; - self.print_generics(generics)?; - let mut real_bounds = Vec::with_capacity(bounds.len()); - for b in bounds.iter() { - if let TraitTyParamBound(ref ptr, hir::TraitBoundModifier::Maybe) = *b { - space(&mut self.s)?; - self.word_space("for ?")?; - self.print_trait_ref(&ptr.trait_ref)?; - } else { - real_bounds.push(b.clone()); - } - } - self.print_bounds(":", &real_bounds[..])?; - self.print_where_clause(&generics.where_clause)?; - word(&mut self.s, " ")?; - self.bopen()?; - for trait_item in trait_items { - self.print_trait_item(trait_item)?; - } - self.bclose(item.span)?; - } - } - self.ann.post(self, NodeItem(item)) - } - - fn print_trait_ref(&mut self, t: &hir::TraitRef) -> io::Result<()> { - self.print_path(&t.path, false, 0) - } - - fn print_formal_lifetime_list(&mut self, lifetimes: &[hir::LifetimeDef]) -> io::Result<()> { - if !lifetimes.is_empty() { - word(&mut self.s, "for<")?; - let mut comma = false; - for lifetime_def in lifetimes { - if comma { - self.word_space(",")? - } - self.print_lifetime_def(lifetime_def)?; - comma = true; - } - word(&mut self.s, ">")?; - } - Ok(()) - } - - fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) -> io::Result<()> { - self.print_formal_lifetime_list(&t.bound_lifetimes)?; - self.print_trait_ref(&t.trait_ref) - } - - pub fn print_enum_def(&mut self, - enum_definition: &hir::EnumDef, - generics: &hir::Generics, - name: ast::Name, - span: codemap::Span, - visibility: hir::Visibility) - -> io::Result<()> { - self.head(&visibility_qualified(visibility, "enum"))?; - self.print_name(name)?; - self.print_generics(generics)?; - self.print_where_clause(&generics.where_clause)?; - space(&mut self.s)?; - self.print_variants(&enum_definition.variants, span) - } - - pub fn print_variants(&mut self, - variants: &[hir::Variant], - span: codemap::Span) - -> io::Result<()> { - self.bopen()?; - for v in variants { - self.space_if_not_bol()?; - self.maybe_print_comment(v.span.lo)?; - self.print_outer_attributes(&v.node.attrs)?; - self.ibox(indent_unit)?; - self.print_variant(v)?; - word(&mut self.s, ",")?; - self.end()?; - self.maybe_print_trailing_comment(v.span, None)?; - } - self.bclose(span) - } - - pub fn print_visibility(&mut self, vis: hir::Visibility) -> io::Result<()> { - match vis { - hir::Public => self.word_nbsp("pub"), - hir::Inherited => Ok(()), - } - } - - pub fn print_struct(&mut self, - struct_def: &hir::VariantData, - generics: &hir::Generics, - name: ast::Name, - span: codemap::Span, - print_finalizer: bool) - -> io::Result<()> { - self.print_name(name)?; - self.print_generics(generics)?; - if !struct_def.is_struct() { - if struct_def.is_tuple() { - self.popen()?; - self.commasep(Inconsistent, struct_def.fields(), |s, field| { - s.print_visibility(field.vis)?; - s.maybe_print_comment(field.span.lo)?; - s.print_type(&field.ty) - })?; - self.pclose()?; - } - self.print_where_clause(&generics.where_clause)?; - if print_finalizer { - word(&mut self.s, ";")?; - } - self.end()?; - self.end() // close the outer-box - } else { - self.print_where_clause(&generics.where_clause)?; - self.nbsp()?; - self.bopen()?; - self.hardbreak_if_not_bol()?; - - for field in struct_def.fields() { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(field.span.lo)?; - self.print_outer_attributes(&field.attrs)?; - self.print_visibility(field.vis)?; - self.print_name(field.name)?; - self.word_nbsp(":")?; - self.print_type(&field.ty)?; - word(&mut self.s, ",")?; - } - - self.bclose(span) - } - } - - pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> { - self.head("")?; - let generics = ::util::empty_generics(); - self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; - match v.node.disr_expr { - Some(ref d) => { - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&d) - } - _ => Ok(()), - } - } - pub fn print_method_sig(&mut self, - name: ast::Name, - m: &hir::MethodSig, - vis: hir::Visibility) - -> io::Result<()> { - self.print_fn(&m.decl, - m.unsafety, - m.constness, - m.abi, - Some(name), - &m.generics, - Some(&m.explicit_self.node), - vis) - } - - pub fn print_trait_item(&mut self, ti: &hir::TraitItem) -> io::Result<()> { - self.ann.pre(self, NodeSubItem(ti.id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ti.span.lo)?; - self.print_outer_attributes(&ti.attrs)?; - match ti.node { - hir::ConstTraitItem(ref ty, ref default) => { - self.print_associated_const(ti.name, - &ty, - default.as_ref().map(|expr| &**expr), - hir::Inherited)?; - } - hir::MethodTraitItem(ref sig, ref body) => { - if body.is_some() { - self.head("")?; - } - self.print_method_sig(ti.name, sig, hir::Inherited)?; - if let Some(ref body) = *body { - self.nbsp()?; - self.print_block_with_attrs(body, &ti.attrs)?; - } else { - word(&mut self.s, ";")?; - } - } - hir::TypeTraitItem(ref bounds, ref default) => { - self.print_associated_type(ti.name, - Some(bounds), - default.as_ref().map(|ty| &**ty))?; - } - } - self.ann.post(self, NodeSubItem(ti.id)) - } - - pub fn print_impl_item(&mut self, ii: &hir::ImplItem) -> io::Result<()> { - self.ann.pre(self, NodeSubItem(ii.id))?; - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(ii.span.lo)?; - self.print_outer_attributes(&ii.attrs)?; - - if let hir::Defaultness::Default = ii.defaultness { - self.word_nbsp("default")?; - } - - match ii.node { - hir::ImplItemKind::Const(ref ty, ref expr) => { - self.print_associated_const(ii.name, &ty, Some(&expr), ii.vis)?; - } - hir::ImplItemKind::Method(ref sig, ref body) => { - self.head("")?; - self.print_method_sig(ii.name, sig, ii.vis)?; - self.nbsp()?; - self.print_block_with_attrs(body, &ii.attrs)?; - } - hir::ImplItemKind::Type(ref ty) => { - self.print_associated_type(ii.name, None, Some(ty))?; - } - } - self.ann.post(self, NodeSubItem(ii.id)) - } - - pub fn print_stmt(&mut self, st: &hir::Stmt) -> io::Result<()> { - self.maybe_print_comment(st.span.lo)?; - match st.node { - hir::StmtDecl(ref decl, _) => { - self.print_decl(&decl)?; - } - hir::StmtExpr(ref expr, _) => { - self.space_if_not_bol()?; - self.print_expr(&expr)?; - } - hir::StmtSemi(ref expr, _) => { - self.space_if_not_bol()?; - self.print_expr(&expr)?; - word(&mut self.s, ";")?; - } - } - if stmt_ends_with_semi(&st.node) { - word(&mut self.s, ";")?; - } - self.maybe_print_trailing_comment(st.span, None) - } - - pub fn print_block(&mut self, blk: &hir::Block) -> io::Result<()> { - self.print_block_with_attrs(blk, &[]) - } - - pub fn print_block_unclosed(&mut self, blk: &hir::Block) -> io::Result<()> { - self.print_block_unclosed_indent(blk, indent_unit) - } - - pub fn print_block_unclosed_indent(&mut self, - blk: &hir::Block, - indented: usize) - -> io::Result<()> { - self.print_block_maybe_unclosed(blk, indented, &[], false) - } - - pub fn print_block_with_attrs(&mut self, - blk: &hir::Block, - attrs: &[ast::Attribute]) - -> io::Result<()> { - self.print_block_maybe_unclosed(blk, indent_unit, attrs, true) - } - - pub fn print_block_maybe_unclosed(&mut self, - blk: &hir::Block, - indented: usize, - attrs: &[ast::Attribute], - close_box: bool) - -> io::Result<()> { - match blk.rules { - hir::UnsafeBlock(..) => self.word_space("unsafe")?, - hir::PushUnsafeBlock(..) => self.word_space("push_unsafe")?, - hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe")?, - hir::PushUnstableBlock => self.word_space("push_unstable")?, - hir::PopUnstableBlock => self.word_space("pop_unstable")?, - hir::DefaultBlock => (), - } - self.maybe_print_comment(blk.span.lo)?; - self.ann.pre(self, NodeBlock(blk))?; - self.bopen()?; - - self.print_inner_attributes(attrs)?; - - for st in &blk.stmts { - self.print_stmt(st)?; - } - match blk.expr { - Some(ref expr) => { - self.space_if_not_bol()?; - self.print_expr(&expr)?; - self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi))?; - } - _ => (), - } - self.bclose_maybe_open(blk.span, indented, close_box)?; - self.ann.post(self, NodeBlock(blk)) - } - - fn print_else(&mut self, els: Option<&hir::Expr>) -> io::Result<()> { - match els { - Some(_else) => { - match _else.node { - // "another else-if" - hir::ExprIf(ref i, ref then, ref e) => { - self.cbox(indent_unit - 1)?; - self.ibox(0)?; - word(&mut self.s, " else if ")?; - self.print_expr(&i)?; - space(&mut self.s)?; - self.print_block(&then)?; - self.print_else(e.as_ref().map(|e| &**e)) - } - // "final else" - hir::ExprBlock(ref b) => { - self.cbox(indent_unit - 1)?; - self.ibox(0)?; - word(&mut self.s, " else ")?; - self.print_block(&b) - } - // BLEAH, constraints would be great here - _ => { - panic!("print_if saw if with weird alternative"); - } - } - } - _ => Ok(()), - } - } - - pub fn print_if(&mut self, - test: &hir::Expr, - blk: &hir::Block, - elseopt: Option<&hir::Expr>) - -> io::Result<()> { - self.head("if")?; - self.print_expr(test)?; - space(&mut self.s)?; - self.print_block(blk)?; - self.print_else(elseopt) - } - - pub fn print_if_let(&mut self, - pat: &hir::Pat, - expr: &hir::Expr, - blk: &hir::Block, - elseopt: Option<&hir::Expr>) - -> io::Result<()> { - self.head("if let")?; - self.print_pat(pat)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(expr)?; - space(&mut self.s)?; - self.print_block(blk)?; - self.print_else(elseopt) - } - - - fn print_call_post(&mut self, args: &[P]) -> io::Result<()> { - self.popen()?; - self.commasep_exprs(Inconsistent, args)?; - self.pclose() - } - - pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr) -> io::Result<()> { - let needs_par = needs_parentheses(expr); - if needs_par { - self.popen()?; - } - self.print_expr(expr)?; - if needs_par { - self.pclose()?; - } - Ok(()) - } - - fn print_expr_vec(&mut self, exprs: &[P]) -> io::Result<()> { - self.ibox(indent_unit)?; - word(&mut self.s, "[")?; - self.commasep_exprs(Inconsistent, &exprs[..])?; - word(&mut self.s, "]")?; - self.end() - } - - fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::Expr) -> io::Result<()> { - self.ibox(indent_unit)?; - word(&mut self.s, "[")?; - self.print_expr(element)?; - self.word_space(";")?; - self.print_expr(count)?; - word(&mut self.s, "]")?; - self.end() - } - - fn print_expr_struct(&mut self, - path: &hir::Path, - fields: &[hir::Field], - wth: &Option>) - -> io::Result<()> { - self.print_path(path, true, 0)?; - word(&mut self.s, "{")?; - self.commasep_cmnt(Consistent, - &fields[..], - |s, field| { - s.ibox(indent_unit)?; - s.print_name(field.name.node)?; - s.word_space(":")?; - s.print_expr(&field.expr)?; - s.end() - }, - |f| f.span)?; - match *wth { - Some(ref expr) => { - self.ibox(indent_unit)?; - if !fields.is_empty() { - word(&mut self.s, ",")?; - space(&mut self.s)?; - } - word(&mut self.s, "..")?; - self.print_expr(&expr)?; - self.end()?; - } - _ => if !fields.is_empty() { - word(&mut self.s, ",")? - }, - } - word(&mut self.s, "}")?; - Ok(()) - } - - fn print_expr_tup(&mut self, exprs: &[P]) -> io::Result<()> { - self.popen()?; - self.commasep_exprs(Inconsistent, &exprs[..])?; - if exprs.len() == 1 { - word(&mut self.s, ",")?; - } - self.pclose() - } - - fn print_expr_call(&mut self, func: &hir::Expr, args: &[P]) -> io::Result<()> { - self.print_expr_maybe_paren(func)?; - self.print_call_post(args) - } - - fn print_expr_method_call(&mut self, - name: Spanned, - tys: &[P], - args: &[P]) - -> io::Result<()> { - let base_args = &args[1..]; - self.print_expr(&args[0])?; - word(&mut self.s, ".")?; - self.print_name(name.node)?; - if !tys.is_empty() { - word(&mut self.s, "::<")?; - self.commasep(Inconsistent, tys, |s, ty| s.print_type(&ty))?; - word(&mut self.s, ">")?; - } - self.print_call_post(base_args) - } - - fn print_expr_binary(&mut self, - op: hir::BinOp, - lhs: &hir::Expr, - rhs: &hir::Expr) - -> io::Result<()> { - self.print_expr(lhs)?; - space(&mut self.s)?; - self.word_space(::util::binop_to_string(op.node))?; - self.print_expr(rhs) - } - - fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> { - word(&mut self.s, ::util::unop_to_string(op))?; - self.print_expr_maybe_paren(expr) - } - - fn print_expr_addr_of(&mut self, - mutability: hir::Mutability, - expr: &hir::Expr) - -> io::Result<()> { - word(&mut self.s, "&")?; - self.print_mutability(mutability)?; - self.print_expr_maybe_paren(expr) - } - - pub fn print_expr(&mut self, expr: &hir::Expr) -> io::Result<()> { - self.maybe_print_comment(expr.span.lo)?; - self.ibox(indent_unit)?; - self.ann.pre(self, NodeExpr(expr))?; - match expr.node { - hir::ExprBox(ref expr) => { - self.word_space("box")?; - self.print_expr(expr)?; - } - hir::ExprVec(ref exprs) => { - self.print_expr_vec(&exprs[..])?; - } - hir::ExprRepeat(ref element, ref count) => { - self.print_expr_repeat(&element, &count)?; - } - hir::ExprStruct(ref path, ref fields, ref wth) => { - self.print_expr_struct(path, &fields[..], wth)?; - } - hir::ExprTup(ref exprs) => { - self.print_expr_tup(&exprs[..])?; - } - hir::ExprCall(ref func, ref args) => { - self.print_expr_call(&func, &args[..])?; - } - hir::ExprMethodCall(name, ref tys, ref args) => { - self.print_expr_method_call(name, &tys[..], &args[..])?; - } - hir::ExprBinary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, &lhs, &rhs)?; - } - hir::ExprUnary(op, ref expr) => { - self.print_expr_unary(op, &expr)?; - } - hir::ExprAddrOf(m, ref expr) => { - self.print_expr_addr_of(m, &expr)?; - } - hir::ExprLit(ref lit) => { - self.print_literal(&lit)?; - } - hir::ExprCast(ref expr, ref ty) => { - self.print_expr(&expr)?; - space(&mut self.s)?; - self.word_space("as")?; - self.print_type(&ty)?; - } - hir::ExprType(ref expr, ref ty) => { - self.print_expr(&expr)?; - self.word_space(":")?; - self.print_type(&ty)?; - } - hir::ExprIf(ref test, ref blk, ref elseopt) => { - self.print_if(&test, &blk, elseopt.as_ref().map(|e| &**e))?; - } - hir::ExprWhile(ref test, ref blk, opt_ident) => { - if let Some(ident) = opt_ident { - self.print_name(ident.name)?; - self.word_space(":")?; - } - self.head("while")?; - self.print_expr(&test)?; - space(&mut self.s)?; - self.print_block(&blk)?; - } - hir::ExprLoop(ref blk, opt_ident) => { - if let Some(ident) = opt_ident { - self.print_name(ident.name)?; - self.word_space(":")?; - } - self.head("loop")?; - space(&mut self.s)?; - self.print_block(&blk)?; - } - hir::ExprMatch(ref expr, ref arms, _) => { - self.cbox(indent_unit)?; - self.ibox(4)?; - self.word_nbsp("match")?; - self.print_expr(&expr)?; - space(&mut self.s)?; - self.bopen()?; - for arm in arms { - self.print_arm(arm)?; - } - self.bclose_(expr.span, indent_unit)?; - } - hir::ExprClosure(capture_clause, ref decl, ref body) => { - self.print_capture_clause(capture_clause)?; - - self.print_fn_block_args(&decl)?; - space(&mut self.s)?; - - let default_return = match decl.output { - hir::DefaultReturn(..) => true, - _ => false, - }; - - if !default_return || !body.stmts.is_empty() || body.expr.is_none() { - self.print_block_unclosed(&body)?; - } else { - // we extract the block, so as not to create another set of boxes - match body.expr.as_ref().unwrap().node { - hir::ExprBlock(ref blk) => { - self.print_block_unclosed(&blk)?; - } - _ => { - // this is a bare expression - self.print_expr(body.expr.as_ref().map(|e| &**e).unwrap())?; - self.end()?; // need to close a box - } - } - } - // a box will be closed by print_expr, but we didn't want an overall - // wrapper so we closed the corresponding opening. so create an - // empty box to satisfy the close. - self.ibox(0)?; - } - hir::ExprBlock(ref blk) => { - // containing cbox, will be closed by print-block at } - self.cbox(indent_unit)?; - // head-box, will be closed by print-block after { - self.ibox(0)?; - self.print_block(&blk)?; - } - hir::ExprAssign(ref lhs, ref rhs) => { - self.print_expr(&lhs)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_expr(&rhs)?; - } - hir::ExprAssignOp(op, ref lhs, ref rhs) => { - self.print_expr(&lhs)?; - space(&mut self.s)?; - word(&mut self.s, ::util::binop_to_string(op.node))?; - self.word_space("=")?; - self.print_expr(&rhs)?; - } - hir::ExprField(ref expr, name) => { - self.print_expr(&expr)?; - word(&mut self.s, ".")?; - self.print_name(name.node)?; - } - hir::ExprTupField(ref expr, id) => { - self.print_expr(&expr)?; - word(&mut self.s, ".")?; - self.print_usize(id.node)?; - } - hir::ExprIndex(ref expr, ref index) => { - self.print_expr(&expr)?; - word(&mut self.s, "[")?; - self.print_expr(&index)?; - word(&mut self.s, "]")?; - } - hir::ExprPath(None, ref path) => { - self.print_path(path, true, 0)? - } - hir::ExprPath(Some(ref qself), ref path) => { - self.print_qpath(path, qself, true)? - } - hir::ExprBreak(opt_ident) => { - word(&mut self.s, "break")?; - space(&mut self.s)?; - if let Some(ident) = opt_ident { - self.print_name(ident.node.name)?; - space(&mut self.s)?; - } - } - hir::ExprAgain(opt_ident) => { - word(&mut self.s, "continue")?; - space(&mut self.s)?; - if let Some(ident) = opt_ident { - self.print_name(ident.node.name)?; - space(&mut self.s)? - } - } - hir::ExprRet(ref result) => { - word(&mut self.s, "return")?; - match *result { - Some(ref expr) => { - word(&mut self.s, " ")?; - self.print_expr(&expr)?; - } - _ => (), - } - } - hir::ExprInlineAsm(ref a, ref outputs, ref inputs) => { - word(&mut self.s, "asm!")?; - self.popen()?; - self.print_string(&a.asm, a.asm_str_style)?; - self.word_space(":")?; - - let mut out_idx = 0; - self.commasep(Inconsistent, &a.outputs, |s, out| { - match out.constraint.slice_shift_char() { - Some(('=', operand)) if out.is_rw => { - s.print_string(&format!("+{}", operand), ast::StrStyle::Cooked)? - } - _ => s.print_string(&out.constraint, ast::StrStyle::Cooked)?, - } - s.popen()?; - s.print_expr(&outputs[out_idx])?; - s.pclose()?; - out_idx += 1; - Ok(()) - })?; - space(&mut self.s)?; - self.word_space(":")?; - - let mut in_idx = 0; - self.commasep(Inconsistent, &a.inputs, |s, co| { - s.print_string(&co, ast::StrStyle::Cooked)?; - s.popen()?; - s.print_expr(&inputs[in_idx])?; - s.pclose()?; - in_idx += 1; - Ok(()) - })?; - space(&mut self.s)?; - self.word_space(":")?; - - self.commasep(Inconsistent, &a.clobbers, |s, co| { - s.print_string(&co, ast::StrStyle::Cooked)?; - Ok(()) - })?; - - let mut options = vec![]; - if a.volatile { - options.push("volatile"); - } - if a.alignstack { - options.push("alignstack"); - } - if a.dialect == ast::AsmDialect::Intel { - options.push("intel"); - } - - if !options.is_empty() { - space(&mut self.s)?; - self.word_space(":")?; - self.commasep(Inconsistent, &options, |s, &co| { - s.print_string(co, ast::StrStyle::Cooked)?; - Ok(()) - })?; - } - - self.pclose()?; - } - } - self.ann.post(self, NodeExpr(expr))?; - self.end() - } - - pub fn print_local_decl(&mut self, loc: &hir::Local) -> io::Result<()> { - self.print_pat(&loc.pat)?; - if let Some(ref ty) = loc.ty { - self.word_space(":")?; - self.print_type(&ty)?; - } - Ok(()) - } - - pub fn print_decl(&mut self, decl: &hir::Decl) -> io::Result<()> { - self.maybe_print_comment(decl.span.lo)?; - match decl.node { - hir::DeclLocal(ref loc) => { - self.space_if_not_bol()?; - self.ibox(indent_unit)?; - self.word_nbsp("let")?; - - self.ibox(indent_unit)?; - self.print_local_decl(&loc)?; - self.end()?; - if let Some(ref init) = loc.init { - self.nbsp()?; - self.word_space("=")?; - self.print_expr(&init)?; - } - self.end() - } - hir::DeclItem(ref item) => { - self.print_item_id(item) - } - } - } - - pub fn print_usize(&mut self, i: usize) -> io::Result<()> { - word(&mut self.s, &i.to_string()) - } - - pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> { - word(&mut self.s, &name.as_str())?; - self.ann.post(self, NodeName(&name)) - } - - pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) -> io::Result<()> { - self.print_local_decl(loc)?; - space(&mut self.s)?; - self.word_space("in")?; - self.print_expr(coll) - } - - fn print_path(&mut self, - path: &hir::Path, - colons_before_params: bool, - depth: usize) - -> io::Result<()> { - self.maybe_print_comment(path.span.lo)?; - - let mut first = !path.global; - for segment in &path.segments[..path.segments.len() - depth] { - if first { - first = false - } else { - word(&mut self.s, "::")? - } - - self.print_name(segment.identifier.name)?; - - self.print_path_parameters(&segment.parameters, colons_before_params)?; - } - - Ok(()) - } - - fn print_qpath(&mut self, - path: &hir::Path, - qself: &hir::QSelf, - colons_before_params: bool) - -> io::Result<()> { - word(&mut self.s, "<")?; - self.print_type(&qself.ty)?; - if qself.position > 0 { - space(&mut self.s)?; - self.word_space("as")?; - let depth = path.segments.len() - qself.position; - self.print_path(&path, false, depth)?; - } - word(&mut self.s, ">")?; - word(&mut self.s, "::")?; - let item_segment = path.segments.last().unwrap(); - self.print_name(item_segment.identifier.name)?; - self.print_path_parameters(&item_segment.parameters, colons_before_params) - } - - fn print_path_parameters(&mut self, - parameters: &hir::PathParameters, - colons_before_params: bool) - -> io::Result<()> { - if parameters.is_empty() { - return Ok(()); - } - - if colons_before_params { - word(&mut self.s, "::")? - } - - match *parameters { - hir::AngleBracketedParameters(ref data) => { - word(&mut self.s, "<")?; - - let mut comma = false; - for lifetime in &data.lifetimes { - if comma { - self.word_space(",")? - } - self.print_lifetime(lifetime)?; - comma = true; - } - - if !data.types.is_empty() { - if comma { - self.word_space(",")? - } - self.commasep(Inconsistent, &data.types, |s, ty| s.print_type(&ty))?; - comma = true; - } - - for binding in data.bindings.iter() { - if comma { - self.word_space(",")? - } - self.print_name(binding.name)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&binding.ty)?; - comma = true; - } - - word(&mut self.s, ">")? - } - - hir::ParenthesizedParameters(ref data) => { - word(&mut self.s, "(")?; - self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(&ty))?; - word(&mut self.s, ")")?; - - match data.output { - None => {} - Some(ref ty) => { - self.space_if_not_bol()?; - self.word_space("->")?; - self.print_type(&ty)?; - } - } - } - } - - Ok(()) - } - - pub fn print_pat(&mut self, pat: &hir::Pat) -> io::Result<()> { - self.maybe_print_comment(pat.span.lo)?; - self.ann.pre(self, NodePat(pat))?; - // Pat isn't normalized, but the beauty of it - // is that it doesn't matter - match pat.node { - PatKind::Wild => word(&mut self.s, "_")?, - PatKind::Ident(binding_mode, ref path1, ref sub) => { - match binding_mode { - hir::BindByRef(mutbl) => { - self.word_nbsp("ref")?; - self.print_mutability(mutbl)?; - } - hir::BindByValue(hir::MutImmutable) => {} - hir::BindByValue(hir::MutMutable) => { - self.word_nbsp("mut")?; - } - } - self.print_name(path1.node.name)?; - match *sub { - Some(ref p) => { - word(&mut self.s, "@")?; - self.print_pat(&p)?; - } - None => (), - } - } - PatKind::TupleStruct(ref path, ref args_) => { - self.print_path(path, true, 0)?; - match *args_ { - None => word(&mut self.s, "(..)")?, - Some(ref args) => { - self.popen()?; - self.commasep(Inconsistent, &args[..], |s, p| s.print_pat(&p))?; - self.pclose()?; - } - } - } - PatKind::Path(ref path) => { - self.print_path(path, true, 0)?; - } - PatKind::QPath(ref qself, ref path) => { - self.print_qpath(path, qself, false)?; - } - PatKind::Struct(ref path, ref fields, etc) => { - self.print_path(path, true, 0)?; - self.nbsp()?; - self.word_space("{")?; - self.commasep_cmnt(Consistent, - &fields[..], - |s, f| { - s.cbox(indent_unit)?; - if !f.node.is_shorthand { - s.print_name(f.node.name)?; - s.word_nbsp(":")?; - } - s.print_pat(&f.node.pat)?; - s.end() - }, - |f| f.node.pat.span)?; - if etc { - if !fields.is_empty() { - self.word_space(",")?; - } - word(&mut self.s, "..")?; - } - space(&mut self.s)?; - word(&mut self.s, "}")?; - } - PatKind::Tup(ref elts) => { - self.popen()?; - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p))?; - if elts.len() == 1 { - word(&mut self.s, ",")?; - } - self.pclose()?; - } - PatKind::Box(ref inner) => { - word(&mut self.s, "box ")?; - self.print_pat(&inner)?; - } - PatKind::Ref(ref inner, mutbl) => { - word(&mut self.s, "&")?; - if mutbl == hir::MutMutable { - word(&mut self.s, "mut ")?; - } - self.print_pat(&inner)?; - } - PatKind::Lit(ref e) => self.print_expr(&e)?, - PatKind::Range(ref begin, ref end) => { - self.print_expr(&begin)?; - space(&mut self.s)?; - word(&mut self.s, "...")?; - self.print_expr(&end)?; - } - PatKind::Vec(ref before, ref slice, ref after) => { - word(&mut self.s, "[")?; - self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p))?; - if let Some(ref p) = *slice { - if !before.is_empty() { - self.word_space(",")?; - } - if p.node != PatKind::Wild { - self.print_pat(&p)?; - } - word(&mut self.s, "..")?; - if !after.is_empty() { - self.word_space(",")?; - } - } - self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p))?; - word(&mut self.s, "]")?; - } - } - self.ann.post(self, NodePat(pat)) - } - - fn print_arm(&mut self, arm: &hir::Arm) -> io::Result<()> { - // I have no idea why this check is necessary, but here it - // is :( - if arm.attrs.is_empty() { - space(&mut self.s)?; - } - self.cbox(indent_unit)?; - self.ibox(0)?; - self.print_outer_attributes(&arm.attrs)?; - let mut first = true; - for p in &arm.pats { - if first { - first = false; - } else { - space(&mut self.s)?; - self.word_space("|")?; - } - self.print_pat(&p)?; - } - space(&mut self.s)?; - if let Some(ref e) = arm.guard { - self.word_space("if")?; - self.print_expr(&e)?; - space(&mut self.s)?; - } - self.word_space("=>")?; - - match arm.body.node { - hir::ExprBlock(ref blk) => { - // the block will close the pattern's ibox - self.print_block_unclosed_indent(&blk, indent_unit)?; - - // If it is a user-provided unsafe block, print a comma after it - if let hir::UnsafeBlock(hir::UserProvided) = blk.rules { - word(&mut self.s, ",")?; - } - } - _ => { - self.end()?; // close the ibox for the pattern - self.print_expr(&arm.body)?; - word(&mut self.s, ",")?; - } - } - self.end() // close enclosing cbox - } - - // Returns whether it printed anything - fn print_explicit_self(&mut self, - explicit_self: &hir::ExplicitSelf_, - mutbl: hir::Mutability) - -> io::Result { - self.print_mutability(mutbl)?; - match *explicit_self { - hir::SelfStatic => { - return Ok(false); - } - hir::SelfValue(_) => { - word(&mut self.s, "self")?; - } - hir::SelfRegion(ref lt, m, _) => { - word(&mut self.s, "&")?; - self.print_opt_lifetime(lt)?; - self.print_mutability(m)?; - word(&mut self.s, "self")?; - } - hir::SelfExplicit(ref typ, _) => { - word(&mut self.s, "self")?; - self.word_space(":")?; - self.print_type(&typ)?; - } - } - return Ok(true); - } - - pub fn print_fn(&mut self, - decl: &hir::FnDecl, - unsafety: hir::Unsafety, - constness: hir::Constness, - abi: Abi, - name: Option, - generics: &hir::Generics, - opt_explicit_self: Option<&hir::ExplicitSelf_>, - vis: hir::Visibility) - -> io::Result<()> { - self.print_fn_header_info(unsafety, constness, abi, vis)?; - - if let Some(name) = name { - self.nbsp()?; - self.print_name(name)?; - } - self.print_generics(generics)?; - self.print_fn_args_and_ret(decl, opt_explicit_self)?; - self.print_where_clause(&generics.where_clause) - } - - pub fn print_fn_args(&mut self, - decl: &hir::FnDecl, - opt_explicit_self: Option<&hir::ExplicitSelf_>, - is_closure: bool) - -> io::Result<()> { - // It is unfortunate to duplicate the commasep logic, but we want the - // self type and the args all in the same box. - self.rbox(0, Inconsistent)?; - let mut first = true; - if let Some(explicit_self) = opt_explicit_self { - let m = match explicit_self { - &hir::SelfStatic => hir::MutImmutable, - _ => match decl.inputs[0].pat.node { - PatKind::Ident(hir::BindByValue(m), _, _) => m, - _ => hir::MutImmutable, - }, - }; - first = !self.print_explicit_self(explicit_self, m)?; - } - - // HACK(eddyb) ignore the separately printed self argument. - let args = if first { - &decl.inputs[..] - } else { - &decl.inputs[1..] - }; - - for arg in args { - if first { - first = false; - } else { - self.word_space(",")?; - } - self.print_arg(arg, is_closure)?; - } - - self.end() - } - - pub fn print_fn_args_and_ret(&mut self, - decl: &hir::FnDecl, - opt_explicit_self: Option<&hir::ExplicitSelf_>) - -> io::Result<()> { - self.popen()?; - self.print_fn_args(decl, opt_explicit_self, false)?; - if decl.variadic { - word(&mut self.s, ", ...")?; - } - self.pclose()?; - - self.print_fn_output(decl) - } - - pub fn print_fn_block_args(&mut self, decl: &hir::FnDecl) -> io::Result<()> { - word(&mut self.s, "|")?; - self.print_fn_args(decl, None, true)?; - word(&mut self.s, "|")?; - - if let hir::DefaultReturn(..) = decl.output { - return Ok(()); - } - - self.space_if_not_bol()?; - self.word_space("->")?; - match decl.output { - hir::Return(ref ty) => { - self.print_type(&ty)?; - self.maybe_print_comment(ty.span.lo) - } - hir::DefaultReturn(..) => unreachable!(), - hir::NoReturn(span) => { - self.word_nbsp("!")?; - self.maybe_print_comment(span.lo) - } - } - } - - pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureClause) -> io::Result<()> { - match capture_clause { - hir::CaptureByValue => self.word_space("move"), - hir::CaptureByRef => Ok(()), - } - } - - pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> { - if !bounds.is_empty() { - word(&mut self.s, prefix)?; - let mut first = true; - for bound in bounds { - self.nbsp()?; - if first { - first = false; - } else { - self.word_space("+")?; - } - - match *bound { - TraitTyParamBound(ref tref, TraitBoundModifier::None) => { - self.print_poly_trait_ref(tref) - } - TraitTyParamBound(ref tref, TraitBoundModifier::Maybe) => { - word(&mut self.s, "?")?; - self.print_poly_trait_ref(tref) - } - RegionTyParamBound(ref lt) => { - self.print_lifetime(lt) - } - }? - } - Ok(()) - } else { - Ok(()) - } - } - - pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) -> io::Result<()> { - self.print_name(lifetime.name) - } - - pub fn print_lifetime_def(&mut self, lifetime: &hir::LifetimeDef) -> io::Result<()> { - self.print_lifetime(&lifetime.lifetime)?; - let mut sep = ":"; - for v in &lifetime.bounds { - word(&mut self.s, sep)?; - self.print_lifetime(v)?; - sep = "+"; - } - Ok(()) - } - - pub fn print_generics(&mut self, generics: &hir::Generics) -> io::Result<()> { - let total = generics.lifetimes.len() + generics.ty_params.len(); - if total == 0 { - return Ok(()); - } - - word(&mut self.s, "<")?; - - let mut ints = Vec::new(); - for i in 0..total { - ints.push(i); - } - - self.commasep(Inconsistent, &ints[..], |s, &idx| { - if idx < generics.lifetimes.len() { - let lifetime = &generics.lifetimes[idx]; - s.print_lifetime_def(lifetime) - } else { - let idx = idx - generics.lifetimes.len(); - let param = &generics.ty_params[idx]; - s.print_ty_param(param) - } - })?; - - word(&mut self.s, ">")?; - Ok(()) - } - - pub fn print_ty_param(&mut self, param: &hir::TyParam) -> io::Result<()> { - self.print_name(param.name)?; - self.print_bounds(":", ¶m.bounds)?; - match param.default { - Some(ref default) => { - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&default) - } - _ => Ok(()), - } - } - - pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) -> io::Result<()> { - if where_clause.predicates.is_empty() { - return Ok(()); - } - - space(&mut self.s)?; - self.word_space("where")?; - - for (i, predicate) in where_clause.predicates.iter().enumerate() { - if i != 0 { - self.word_space(",")?; - } - - match predicate { - &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate{ref bound_lifetimes, - ref bounded_ty, - ref bounds, - ..}) => { - self.print_formal_lifetime_list(bound_lifetimes)?; - self.print_type(&bounded_ty)?; - self.print_bounds(":", bounds)?; - } - &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime, - ref bounds, - ..}) => { - self.print_lifetime(lifetime)?; - word(&mut self.s, ":")?; - - for (i, bound) in bounds.iter().enumerate() { - self.print_lifetime(bound)?; - - if i != 0 { - word(&mut self.s, ":")?; - } - } - } - &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref path, ref ty, ..}) => { - self.print_path(path, false, 0)?; - space(&mut self.s)?; - self.word_space("=")?; - self.print_type(&ty)?; - } - } - } - - Ok(()) - } - - pub fn print_view_path(&mut self, vp: &hir::ViewPath) -> io::Result<()> { - match vp.node { - hir::ViewPathSimple(name, ref path) => { - self.print_path(path, false, 0)?; - - if path.segments.last().unwrap().identifier.name != name { - space(&mut self.s)?; - self.word_space("as")?; - self.print_name(name)?; - } - - Ok(()) - } - - hir::ViewPathGlob(ref path) => { - self.print_path(path, false, 0)?; - word(&mut self.s, "::*") - } - - hir::ViewPathList(ref path, ref segments) => { - if path.segments.is_empty() { - word(&mut self.s, "{")?; - } else { - self.print_path(path, false, 0)?; - word(&mut self.s, "::{")?; - } - self.commasep(Inconsistent, &segments[..], |s, w| { - match w.node { - hir::PathListIdent { name, .. } => { - s.print_name(name) - } - hir::PathListMod { .. } => { - word(&mut s.s, "self") - } - } - })?; - word(&mut self.s, "}") - } - } - } - - pub fn print_mutability(&mut self, mutbl: hir::Mutability) -> io::Result<()> { - match mutbl { - hir::MutMutable => self.word_nbsp("mut"), - hir::MutImmutable => Ok(()), - } - } - - pub fn print_mt(&mut self, mt: &hir::MutTy) -> io::Result<()> { - self.print_mutability(mt.mutbl)?; - self.print_type(&mt.ty) - } - - pub fn print_arg(&mut self, input: &hir::Arg, is_closure: bool) -> io::Result<()> { - self.ibox(indent_unit)?; - match input.ty.node { - hir::TyInfer if is_closure => self.print_pat(&input.pat)?, - _ => { - match input.pat.node { - PatKind::Ident(_, ref path1, _) if - path1.node.name == - parse::token::special_idents::invalid.name => { - // Do nothing. - } - _ => { - self.print_pat(&input.pat)?; - word(&mut self.s, ":")?; - space(&mut self.s)?; - } - } - self.print_type(&input.ty)?; - } - } - self.end() - } - - pub fn print_fn_output(&mut self, decl: &hir::FnDecl) -> io::Result<()> { - if let hir::DefaultReturn(..) = decl.output { - return Ok(()); - } - - self.space_if_not_bol()?; - self.ibox(indent_unit)?; - self.word_space("->")?; - match decl.output { - hir::NoReturn(_) => self.word_nbsp("!")?, - hir::DefaultReturn(..) => unreachable!(), - hir::Return(ref ty) => self.print_type(&ty)?, - } - self.end()?; - - match decl.output { - hir::Return(ref output) => self.maybe_print_comment(output.span.lo), - _ => Ok(()), - } - } - - pub fn print_ty_fn(&mut self, - abi: Abi, - unsafety: hir::Unsafety, - decl: &hir::FnDecl, - name: Option, - generics: &hir::Generics, - opt_explicit_self: Option<&hir::ExplicitSelf_>) - -> io::Result<()> { - self.ibox(indent_unit)?; - if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() { - word(&mut self.s, "for")?; - self.print_generics(generics)?; - } - let generics = hir::Generics { - lifetimes: hir::HirVec::new(), - ty_params: hir::HirVec::new(), - where_clause: hir::WhereClause { - id: ast::DUMMY_NODE_ID, - predicates: hir::HirVec::new(), - }, - }; - self.print_fn(decl, - unsafety, - hir::Constness::NotConst, - abi, - name, - &generics, - opt_explicit_self, - hir::Inherited)?; - self.end() - } - - pub fn maybe_print_trailing_comment(&mut self, - span: codemap::Span, - next_pos: Option) - -> io::Result<()> { - let cm = match self.cm { - Some(cm) => cm, - _ => return Ok(()), - }; - match self.next_comment() { - Some(ref cmnt) => { - if (*cmnt).style != comments::Trailing { - return Ok(()); - } - let span_line = cm.lookup_char_pos(span.hi); - let comment_line = cm.lookup_char_pos((*cmnt).pos); - let mut next = (*cmnt).pos + BytePos(1); - match next_pos { - None => (), - Some(p) => next = p, - } - if span.hi < (*cmnt).pos && (*cmnt).pos < next && - span_line.line == comment_line.line { - self.print_comment(cmnt)?; - self.cur_cmnt_and_lit.cur_cmnt += 1; - } - } - _ => (), - } - Ok(()) - } - - pub fn print_remaining_comments(&mut self) -> io::Result<()> { - // If there aren't any remaining comments, then we need to manually - // make sure there is a line break at the end. - if self.next_comment().is_none() { - hardbreak(&mut self.s)?; - } - loop { - match self.next_comment() { - Some(ref cmnt) => { - self.print_comment(cmnt)?; - self.cur_cmnt_and_lit.cur_cmnt += 1; - } - _ => break, - } - } - Ok(()) - } - - pub fn print_opt_abi_and_extern_if_nondefault(&mut self, - opt_abi: Option) - -> io::Result<()> { - match opt_abi { - Some(Abi::Rust) => Ok(()), - Some(abi) => { - self.word_nbsp("extern")?; - self.word_nbsp(&abi.to_string()) - } - None => Ok(()), - } - } - - pub fn print_extern_opt_abi(&mut self, opt_abi: Option) -> io::Result<()> { - match opt_abi { - Some(abi) => { - self.word_nbsp("extern")?; - self.word_nbsp(&abi.to_string()) - } - None => Ok(()), - } - } - - pub fn print_fn_header_info(&mut self, - unsafety: hir::Unsafety, - constness: hir::Constness, - abi: Abi, - vis: hir::Visibility) - -> io::Result<()> { - word(&mut self.s, &visibility_qualified(vis, ""))?; - self.print_unsafety(unsafety)?; - - match constness { - hir::Constness::NotConst => {} - hir::Constness::Const => self.word_nbsp("const")?, - } - - if abi != Abi::Rust { - self.word_nbsp("extern")?; - self.word_nbsp(&abi.to_string())?; - } - - word(&mut self.s, "fn") - } - - pub fn print_unsafety(&mut self, s: hir::Unsafety) -> io::Result<()> { - match s { - hir::Unsafety::Normal => Ok(()), - hir::Unsafety::Unsafe => self.word_nbsp("unsafe"), - } - } -} - -// Dup'ed from parse::classify, but adapted for the HIR. -/// Does this expression require a semicolon to be treated -/// as a statement? The negation of this: 'can this expression -/// be used as a statement without a semicolon' -- is used -/// as an early-bail-out in the parser so that, for instance, -/// if true {...} else {...} -/// |x| 5 -/// isn't parsed as (if true {...} else {...} | x) | 5 -fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { - match e.node { - hir::ExprIf(..) | - hir::ExprMatch(..) | - hir::ExprBlock(_) | - hir::ExprWhile(..) | - hir::ExprLoop(..) => false, - _ => true, - } -} - -/// this statement requires a semicolon after it. -/// note that in one case (stmt_semi), we've already -/// seen the semicolon, and thus don't need another. -fn stmt_ends_with_semi(stmt: &hir::Stmt_) -> bool { - match *stmt { - hir::StmtDecl(ref d, _) => { - match d.node { - hir::DeclLocal(_) => true, - hir::DeclItem(_) => false, - } - } - hir::StmtExpr(ref e, _) => { - expr_requires_semi_to_be_stmt(&e) - } - hir::StmtSemi(..) => { - false - } - } -} diff --git a/src/librustc_front/util.rs b/src/librustc_front/util.rs deleted file mode 100644 index f4f9cb75eaf..00000000000 --- a/src/librustc_front/util.rs +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use hir; -use hir::*; -use intravisit::{self, Visitor, FnKind}; -use syntax::ast_util; -use syntax::ast::{Name, NodeId, DUMMY_NODE_ID}; -use syntax::codemap::Span; -use syntax::ptr::P; - -pub fn walk_pat(pat: &Pat, mut it: F) -> bool - where F: FnMut(&Pat) -> bool -{ - // FIXME(#19596) this is a workaround, but there should be a better way - fn walk_pat_(pat: &Pat, it: &mut G) -> bool - where G: FnMut(&Pat) -> bool - { - if !it(pat) { - return false; - } - - match pat.node { - PatKind::Ident(_, _, Some(ref p)) => walk_pat_(&p, it), - PatKind::Struct(_, ref fields, _) => { - fields.iter().all(|field| walk_pat_(&field.node.pat, it)) - } - PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { - s.iter().all(|p| walk_pat_(&p, it)) - } - PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { - walk_pat_(&s, it) - } - PatKind::Vec(ref before, ref slice, ref after) => { - before.iter().all(|p| walk_pat_(&p, it)) && - slice.iter().all(|p| walk_pat_(&p, it)) && - after.iter().all(|p| walk_pat_(&p, it)) - } - PatKind::Wild | - PatKind::Lit(_) | - PatKind::Range(_, _) | - PatKind::Ident(_, _, _) | - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::QPath(_, _) => { - true - } - } - } - - walk_pat_(pat, &mut it) -} - -pub fn binop_to_string(op: BinOp_) -> &'static str { - match op { - BiAdd => "+", - BiSub => "-", - BiMul => "*", - BiDiv => "/", - BiRem => "%", - BiAnd => "&&", - BiOr => "||", - BiBitXor => "^", - BiBitAnd => "&", - BiBitOr => "|", - BiShl => "<<", - BiShr => ">>", - BiEq => "==", - BiLt => "<", - BiLe => "<=", - BiNe => "!=", - BiGe => ">=", - BiGt => ">", - } -} - -pub fn stmt_id(s: &Stmt) -> NodeId { - match s.node { - StmtDecl(_, id) => id, - StmtExpr(_, id) => id, - StmtSemi(_, id) => id, - } -} - -pub fn lazy_binop(b: BinOp_) -> bool { - match b { - BiAnd => true, - BiOr => true, - _ => false, - } -} - -pub fn is_shift_binop(b: BinOp_) -> bool { - match b { - BiShl => true, - BiShr => true, - _ => false, - } -} - -pub fn is_comparison_binop(b: BinOp_) -> bool { - match b { - BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true, - BiAnd | - BiOr | - BiAdd | - BiSub | - BiMul | - BiDiv | - BiRem | - BiBitXor | - BiBitAnd | - BiBitOr | - BiShl | - BiShr => false, - } -} - -/// Returns `true` if the binary operator takes its arguments by value -pub fn is_by_value_binop(b: BinOp_) -> bool { - !is_comparison_binop(b) -} - -/// Returns `true` if the unary operator takes its argument by value -pub fn is_by_value_unop(u: UnOp) -> bool { - match u { - UnNeg | UnNot => true, - _ => false, - } -} - -pub fn unop_to_string(op: UnOp) -> &'static str { - match op { - UnDeref => "*", - UnNot => "!", - UnNeg => "-", - } -} - -pub struct IdVisitor<'a, O: 'a> { - operation: &'a mut O, - - // In general, the id visitor visits the contents of an item, but - // not including nested trait/impl items, nor other nested items. - // The base visitor itself always skips nested items, but not - // trait/impl items. This means in particular that if you start by - // visiting a trait or an impl, you should not visit the - // trait/impl items respectively. This is handled by setting - // `skip_members` to true when `visit_item` is on the stack. This - // way, if the user begins by calling `visit_trait_item`, we will - // visit the trait item, but if they begin with `visit_item`, we - // won't visit the (nested) trait items. - skip_members: bool, -} - -impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { - pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { - IdVisitor { operation: operation, skip_members: false } - } - - fn visit_generics_helper(&mut self, generics: &Generics) { - for type_parameter in generics.ty_params.iter() { - self.operation.visit_id(type_parameter.id) - } - for lifetime in &generics.lifetimes { - self.operation.visit_id(lifetime.lifetime.id) - } - } -} - -impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { - fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { - self.operation.visit_id(node_id); - intravisit::walk_mod(self, module) - } - - fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.operation.visit_id(foreign_item.id); - intravisit::walk_foreign_item(self, foreign_item) - } - - fn visit_item(&mut self, item: &Item) { - assert!(!self.skip_members); - self.skip_members = true; - - self.operation.visit_id(item.id); - match item.node { - ItemUse(ref view_path) => { - match view_path.node { - ViewPathSimple(_, _) | - ViewPathGlob(_) => {} - ViewPathList(_, ref paths) => { - for path in paths { - self.operation.visit_id(path.node.id()) - } - } - } - } - _ => {} - } - intravisit::walk_item(self, item); - - self.skip_members = false; - } - - fn visit_local(&mut self, local: &Local) { - self.operation.visit_id(local.id); - intravisit::walk_local(self, local) - } - - fn visit_block(&mut self, block: &Block) { - self.operation.visit_id(block.id); - intravisit::walk_block(self, block) - } - - fn visit_stmt(&mut self, statement: &Stmt) { - self.operation.visit_id(stmt_id(statement)); - intravisit::walk_stmt(self, statement) - } - - fn visit_pat(&mut self, pattern: &Pat) { - self.operation.visit_id(pattern.id); - intravisit::walk_pat(self, pattern) - } - - fn visit_expr(&mut self, expression: &Expr) { - self.operation.visit_id(expression.id); - intravisit::walk_expr(self, expression) - } - - fn visit_ty(&mut self, typ: &Ty) { - self.operation.visit_id(typ.id); - intravisit::walk_ty(self, typ) - } - - fn visit_generics(&mut self, generics: &Generics) { - self.visit_generics_helper(generics); - intravisit::walk_generics(self, generics) - } - - fn visit_fn(&mut self, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - block: &'v Block, - span: Span, - node_id: NodeId) { - self.operation.visit_id(node_id); - - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { - self.visit_generics_helper(generics) - } - FnKind::Method(_, sig, _, _) => { - self.visit_generics_helper(&sig.generics) - } - FnKind::Closure(_) => {} - } - - for argument in &function_declaration.inputs { - self.operation.visit_id(argument.id) - } - - intravisit::walk_fn(self, function_kind, function_declaration, block, span); - } - - fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.id); - intravisit::walk_struct_field(self, struct_field) - } - - fn visit_variant_data(&mut self, - struct_def: &VariantData, - _: Name, - _: &hir::Generics, - _: NodeId, - _: Span) { - self.operation.visit_id(struct_def.id()); - intravisit::walk_struct_def(self, struct_def); - } - - fn visit_trait_item(&mut self, ti: &hir::TraitItem) { - if !self.skip_members { - self.operation.visit_id(ti.id); - intravisit::walk_trait_item(self, ti); - } - } - - fn visit_impl_item(&mut self, ii: &hir::ImplItem) { - if !self.skip_members { - self.operation.visit_id(ii.id); - intravisit::walk_impl_item(self, ii); - } - } - - fn visit_lifetime(&mut self, lifetime: &Lifetime) { - self.operation.visit_id(lifetime.id); - } - - fn visit_lifetime_def(&mut self, def: &LifetimeDef) { - self.visit_lifetime(&def.lifetime); - } - - fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { - self.operation.visit_id(trait_ref.ref_id); - intravisit::walk_trait_ref(self, trait_ref); - } -} - -/// Computes the id range for a single fn body, ignoring nested items. -pub fn compute_id_range_for_fn_body(fk: FnKind, - decl: &FnDecl, - body: &Block, - sp: Span, - id: NodeId) - -> ast_util::IdRange { - let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; - let mut id_visitor = IdVisitor::new(&mut visitor); - id_visitor.visit_fn(fk, decl, body, sp, id); - id_visitor.operation.result -} - -pub fn is_path(e: P) -> bool { - match e.node { - ExprPath(..) => true, - _ => false, - } -} - -pub fn empty_generics() -> Generics { - Generics { - lifetimes: HirVec::new(), - ty_params: HirVec::new(), - where_clause: WhereClause { - id: DUMMY_NODE_ID, - predicates: HirVec::new(), - }, - } -} - -// convert a span and an identifier to the corresponding -// 1-segment path -pub fn ident_to_path(s: Span, ident: Ident) -> Path { - hir::Path { - span: s, - global: false, - segments: hir_vec![hir::PathSegment { - identifier: ident, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: HirVec::new(), - types: HirVec::new(), - bindings: HirVec::new(), - }), - }], - } -} diff --git a/src/librustc_lint/Cargo.toml b/src/librustc_lint/Cargo.toml index 4821a723279..3f0cd397e76 100644 --- a/src/librustc_lint/Cargo.toml +++ b/src/librustc_lint/Cargo.toml @@ -13,5 +13,4 @@ log = { path = "../liblog" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_eval = { path = "../librustc_const_eval" } -rustc_front = { path = "../librustc_front" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index ca189d0b519..ed9c66a1882 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -17,8 +17,8 @@ use syntax::ast; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::Span; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit::FnKind; +use rustc::hir::{self, PatKind}; +use rustc::hir::intravisit::FnKind; #[derive(PartialEq)] pub enum MethodLateContext { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 339c969b01f..6f11ebafa86 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -37,7 +37,7 @@ use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::adjustment; use rustc::traits::{self, ProjectionMode}; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use util::nodemap::{NodeSet}; use lint::{Level, LateContext, LintContext, LintArray, Lint}; use lint::{LintPass, LateLintPass}; @@ -48,8 +48,8 @@ use syntax::{ast}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit::FnKind; +use rustc::hir::{self, PatKind}; +use rustc::hir::intravisit::FnKind; use bad_style::{MethodLateContext, method_context}; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0780e4cd048..2075bd5edca 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -44,7 +44,6 @@ extern crate syntax; extern crate rustc; #[macro_use] extern crate log; -extern crate rustc_front; extern crate rustc_back; extern crate rustc_const_eval; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 6eeadc77698..b094bca8410 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -29,8 +29,8 @@ use syntax::abi::Abi; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; -use rustc_front::hir; -use rustc_front::util::is_shift_binop; +use rustc::hir; +use rustc::hir::util::is_shift_binop; register_long_diagnostics! { E0519: r##" diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 9840cd4256f..f531628601b 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -24,8 +24,8 @@ use syntax::feature_gate::{KNOWN_ATTRIBUTES, AttributeType}; use syntax::ptr::P; use rustc_back::slice; -use rustc_front::hir; -use rustc_front::intravisit::FnKind; +use rustc::hir; +use rustc::hir::intravisit::FnKind; declare_lint! { pub UNUSED_MUT, diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 65c2c2d1480..697cbe39c67 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -16,7 +16,6 @@ rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } rustc_const_math = { path = "../librustc_const_math" } -rustc_front = { path = "../librustc_front" } rustc_llvm = { path = "../librustc_llvm" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 505619d31d7..98e73f2902b 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -12,12 +12,12 @@ // FIXME: remove this after snapshot, and Results are handled #![allow(unused_must_use)] -use rustc::front::map as ast_map; +use rustc::hir::map as ast_map; use rustc::session::Session; -use rustc_front::hir; -use rustc_front::fold; -use rustc_front::fold::Folder; +use rustc::hir; +use rustc::hir::fold; +use rustc::hir::fold::Folder; use common as c; use cstore; @@ -55,8 +55,8 @@ use serialize::EncoderHelpers; #[cfg(test)] use std::io::Cursor; #[cfg(test)] use syntax::parse; #[cfg(test)] use syntax::ast::NodeId; -#[cfg(test)] use rustc_front::print::pprust; -#[cfg(test)] use rustc_front::lowering::{lower_item, LoweringContext}; +#[cfg(test)] use rustc::hir::print as pprust; +#[cfg(test)] use rustc::hir::lowering::{lower_item, LoweringContext}; struct DecodeContext<'a, 'b, 'tcx: 'a> { tcx: &'a TyCtxt<'tcx>, @@ -168,7 +168,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, copy_item_types(dcx, ii, orig_did); if let InlinedItem::Item(ref i) = *ii { debug!(">>> DECODED ITEM >>>\n{}\n<<< DECODED ITEM <<<", - ::rustc_front::print::pprust::item_to_string(&i)); + ::rustc::hir::print::item_to_string(&i)); } ii diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index edabf43a150..df9072835b9 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -17,13 +17,13 @@ use cstore::{self, CStore, CrateSource, MetadataBlob}; use decoder; use loader::{self, CratePaths}; -use rustc::back::svh::Svh; +use rustc::hir::svh::Svh; use rustc::dep_graph::DepNode; use rustc::session::{config, Session}; use rustc::session::search_paths::PathKind; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; use rustc::util::nodemap::FnvHashMap; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use std::cell::{RefCell, Cell}; use std::path::PathBuf; @@ -37,8 +37,8 @@ use syntax::parse; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::parse::token::InternedString; -use rustc_front::intravisit::Visitor; -use rustc_front::hir; +use rustc::hir::intravisit::Visitor; +use rustc::hir; use log; pub struct LocalCrateReader<'a, 'b:'a> { diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index c11d9865516..c9e661dec51 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -20,7 +20,7 @@ use middle::lang_items; use rustc::ty::{self, Ty, TyCtxt, VariantKind}; use middle::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::mir::repr::Mir; use rustc::mir::mir_map::MirMap; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; @@ -31,9 +31,9 @@ use std::path::PathBuf; use syntax::ast; use syntax::attr; use syntax::parse::token; -use rustc_back::svh::Svh; +use rustc::hir::svh::Svh; use rustc_back::target::Target; -use rustc_front::hir; +use rustc::hir; impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn stability(&self, def: DefId) -> Option @@ -552,7 +552,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { let mut visible_parent_map = self.visible_parent_map.borrow_mut(); if !visible_parent_map.is_empty() { return visible_parent_map; } - use rustc_front::hir; + use rustc::hir; use rustc::middle::cstore::{CrateStore, ChildItem}; use std::collections::vec_deque::VecDeque; use std::collections::hash_map::Entry; diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 5637301724b..3a6cd4d832b 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -20,7 +20,7 @@ use decoder; use index; use loader; -use rustc::back::svh::Svh; +use rustc::hir::svh::Svh; use rustc::middle::cstore::{ExternCrate}; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; use rustc::middle::def_id::DefId; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e85fdb05ca8..5aafd015f9a 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -22,10 +22,10 @@ use index; use tls_context; use tydecode::TyDecoder; -use rustc::back::svh::Svh; -use rustc::front::map as hir_map; +use rustc::hir::svh::Svh; +use rustc::hir::map as hir_map; use rustc::util::nodemap::FnvHashMap; -use rustc_front::hir; +use rustc::hir; use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference}; use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls}; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 30eabb7e8f3..dc21ebcbcfc 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -30,9 +30,9 @@ use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::util::IntTypeExt; -use rustc::back::svh::Svh; -use rustc::front::map::{LinkedPath, PathElem, PathElems}; -use rustc::front::map as ast_map; +use rustc::hir::svh::Svh; +use rustc::hir::map::{LinkedPath, PathElem, PathElems}; +use rustc::hir::map as ast_map; use rustc::mir::mir_map::MirMap; use rustc::session::config; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet}; @@ -52,9 +52,9 @@ use syntax::errors::Handler; use syntax; use rbml::writer::Encoder; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit::Visitor; -use rustc_front::intravisit; +use rustc::hir::{self, PatKind}; +use rustc::hir::intravisit::Visitor; +use rustc::hir::intravisit; pub struct EncodeContext<'a, 'tcx: 'a> { pub diag: &'a Handler, diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index c927f53eccd..139462d41bf 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -36,7 +36,6 @@ extern crate serialize; #[macro_use] extern crate rustc; extern crate rustc_back; -extern crate rustc_front; extern crate rustc_llvm; extern crate rustc_const_math; diff --git a/src/librustc_metadata/loader.rs b/src/librustc_metadata/loader.rs index 87e86e221f1..c7cd8ae2dd7 100644 --- a/src/librustc_metadata/loader.rs +++ b/src/librustc_metadata/loader.rs @@ -216,7 +216,7 @@ use cstore::{MetadataBlob, MetadataVec, MetadataArchive}; use decoder; use encoder; -use rustc::back::svh::Svh; +use rustc::hir::svh::Svh; use rustc::session::Session; use rustc::session::filesearch::{FileSearch, FileMatches, FileDoesntMatch}; use rustc::session::search_paths::PathKind; diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index 28985c75a91..cd63b58372b 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -16,7 +16,7 @@ #![allow(non_camel_case_types)] -use rustc_front::hir; +use rustc::hir; use middle::def_id::{DefId, DefIndex}; use middle::region; diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index ffaf7e2d465..b5079256487 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -25,7 +25,7 @@ use rustc::ty::ParamTy; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::nodemap::FnvHashMap; -use rustc_front::hir; +use rustc::hir; use syntax::abi::Abi; use syntax::ast; diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml index f136618b1c9..1c41ca6f416 100644 --- a/src/librustc_mir/Cargo.toml +++ b/src/librustc_mir/Cargo.toml @@ -16,5 +16,4 @@ rustc_back = { path = "../librustc_back" } rustc_const_eval = { path = "../librustc_const_eval" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_front = { path = "../librustc_front" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index ef48a408e79..8c98408e239 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -11,7 +11,7 @@ use build::{BlockAnd, BlockAndExtension, Builder}; use hair::*; use rustc::mir::repr::*; -use rustc_front::hir; +use rustc::hir; impl<'a,'tcx> Builder<'a,'tcx> { pub fn ast_block(&mut self, diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 51069c38857..2e5b6a952b7 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -13,7 +13,7 @@ use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::ty::{FnOutput, Ty}; use rustc::mir::repr::*; use rustc_data_structures::fnv::FnvHashMap; -use rustc_front::hir; +use rustc::hir; use std::ops::{Index, IndexMut}; use syntax::ast; use syntax::codemap::Span; diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index c7af42b776f..f0ed25902f7 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -12,7 +12,7 @@ use hair::*; use hair::cx::Cx; use hair::cx::to_ref::ToRef; use rustc::middle::region::{BlockRemainder, CodeExtentData}; -use rustc_front::hir; +use rustc::hir; use syntax::ast; impl<'tcx> Mirror<'tcx> for &'tcx hir::Block { diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 7e16883e754..475ae459fef 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -14,7 +14,7 @@ use rustc_const_math::ConstInt; use hair::cx::Cx; use hair::cx::block; use hair::cx::to_ref::ToRef; -use rustc::front::map; +use rustc::hir::map; use rustc::middle::def::Def; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; @@ -22,8 +22,8 @@ use rustc::middle::region::CodeExtent; use rustc::middle::pat_util; use rustc::ty::{self, VariantDef, Ty}; use rustc::mir::repr::*; -use rustc_front::hir; -use rustc_front::util as hir_util; +use rustc::hir; +use rustc::hir::util as hir_util; use syntax::ptr::P; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index 05448a7deab..f0c6887802d 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -25,7 +25,7 @@ use rustc::infer::InferCtxt; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt}; use syntax::parse::token; -use rustc_front::hir; +use rustc::hir; use rustc_const_math::{ConstInt, ConstUsize}; #[derive(Copy, Clone)] diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index 8ec8cd4bf81..673d12c3316 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -16,7 +16,7 @@ use rustc::middle::def::Def; use rustc::middle::pat_util::{pat_is_resolved_const, pat_is_binding}; use rustc::ty::{self, Ty}; use rustc::mir::repr::*; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::{self, PatKind}; use syntax::ast; use syntax::codemap::Span; use syntax::ptr::P; diff --git a/src/librustc_mir/hair/cx/to_ref.rs b/src/librustc_mir/hair/cx/to_ref.rs index 24fcc2f4fcd..63dbde47438 100644 --- a/src/librustc_mir/hair/cx/to_ref.rs +++ b/src/librustc_mir/hair/cx/to_ref.rs @@ -10,7 +10,7 @@ use hair::*; -use rustc_front::hir; +use rustc::hir; use syntax::ptr::P; pub trait ToRef { diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index affc1872987..0ea8dece47c 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -21,7 +21,7 @@ use rustc::middle::def_id::DefId; use rustc::middle::region::CodeExtent; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty}; -use rustc_front::hir; +use rustc::hir; use syntax::ast; use syntax::codemap::Span; use self::cx::Cx; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index dd81895ebec..ced73f34e0d 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -30,7 +30,6 @@ extern crate graphviz as dot; #[macro_use] extern crate rustc; extern crate rustc_data_structures; -extern crate rustc_front; extern crate rustc_back; extern crate syntax; extern crate rustc_const_math; diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs index 9ec88c1b59a..40334f652ee 100644 --- a/src/librustc_mir/mir_map.rs +++ b/src/librustc_mir/mir_map.rs @@ -17,7 +17,6 @@ //! - `#[rustc_mir(pretty="file.mir")]` extern crate syntax; -extern crate rustc_front; use build; use rustc::dep_graph::DepNode; @@ -31,8 +30,8 @@ use rustc::traits::ProjectionMode; use rustc::ty::{self, Ty, TyCtxt}; use rustc::util::common::ErrorReported; use rustc::util::nodemap::NodeMap; -use rustc_front::hir; -use rustc_front::intravisit::{self, Visitor}; +use rustc::hir; +use rustc::hir::intravisit::{self, Visitor}; use syntax::abi::Abi; use syntax::ast; use syntax::attr::AttrMetaMethods; diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml index 02303aa7130..fa6bd3dfb67 100644 --- a/src/librustc_passes/Cargo.toml +++ b/src/librustc_passes/Cargo.toml @@ -12,5 +12,4 @@ crate-type = ["dylib"] log = { path = "../liblog" } rustc = { path = "../librustc" } rustc_const_eval = { path = "../librustc_const_eval" } -rustc_front = { path = "../librustc_front" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index ba5d8ef45b6..38784191a78 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -42,11 +42,11 @@ use rustc::util::nodemap::NodeMap; use rustc::middle::const_qualif::ConstQualif; use rustc::lint::builtin::CONST_ERR; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::{self, PatKind}; use syntax::ast; use syntax::codemap::Span; use syntax::feature_gate::UnstableFeatures; -use rustc_front::intravisit::{self, FnKind, Visitor}; +use rustc::hir::intravisit::{self, FnKind, Visitor}; use std::collections::hash_map::Entry; use std::cmp::Ordering; diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 44bcdcdb364..53ae1b30f7c 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -29,7 +29,6 @@ extern crate core; #[macro_use] extern crate rustc; -extern crate rustc_front; extern crate rustc_const_eval; #[macro_use] extern crate log; diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index a89627aea82..9a58a704c52 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -12,9 +12,9 @@ use self::Context::*; use rustc::session::Session; use rustc::dep_graph::DepNode; -use rustc::front::map::Map; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir; +use rustc::hir::map::Map; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir; use syntax::codemap::Span; #[derive(Clone, Copy, PartialEq)] diff --git a/src/librustc_passes/rvalues.rs b/src/librustc_passes/rvalues.rs index 98502f5a16e..754d5ef8f52 100644 --- a/src/librustc_passes/rvalues.rs +++ b/src/librustc_passes/rvalues.rs @@ -18,8 +18,8 @@ use rustc::middle::mem_categorization as mc; use rustc::ty::{self, TyCtxt, ParameterEnvironment}; use rustc::traits::ProjectionMode; -use rustc_front::hir; -use rustc_front::intravisit; +use rustc::hir; +use rustc::hir::intravisit; use syntax::ast; use syntax::codemap::Span; diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 2230283c977..2766d13d7b8 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -12,7 +12,7 @@ // recursively. use rustc::dep_graph::DepNode; -use rustc::front::map as ast_map; +use rustc::hir::map as ast_map; use rustc::session::{Session, CompileResult}; use rustc::middle::def::{Def, DefMap}; use rustc::util::nodemap::NodeMap; @@ -20,8 +20,8 @@ use rustc::util::nodemap::NodeMap; use syntax::{ast}; use syntax::codemap::Span; use syntax::feature_gate::{GateIssue, emit_feature_err}; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir; use std::cell::RefCell; diff --git a/src/librustc_plugin/Cargo.toml b/src/librustc_plugin/Cargo.toml index 89fa0df0306..e9a32e53a9f 100644 --- a/src/librustc_plugin/Cargo.toml +++ b/src/librustc_plugin/Cargo.toml @@ -13,7 +13,6 @@ log = { path = "../liblog" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_bitflags = { path = "../librustc_bitflags" } -rustc_front = { path = "../librustc_front" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_plugin/build.rs b/src/librustc_plugin/build.rs index fe83b609334..4c7755b1b09 100644 --- a/src/librustc_plugin/build.rs +++ b/src/librustc_plugin/build.rs @@ -15,9 +15,9 @@ use syntax::attr; use syntax::codemap::Span; use syntax::errors; use rustc::dep_graph::DepNode; -use rustc::front::map::Map; -use rustc_front::intravisit::Visitor; -use rustc_front::hir; +use rustc::hir::map::Map; +use rustc::hir::intravisit::Visitor; +use rustc::hir; struct RegistrarFinder { registrars: Vec<(ast::NodeId, Span)> , diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs index 8de26083910..5fa29771c57 100644 --- a/src/librustc_plugin/lib.rs +++ b/src/librustc_plugin/lib.rs @@ -69,7 +69,6 @@ extern crate rustc; extern crate rustc_back; -extern crate rustc_front; extern crate rustc_metadata; extern crate rustc_mir; diff --git a/src/librustc_privacy/Cargo.toml b/src/librustc_privacy/Cargo.toml index 56d6ca5543a..0553e54e3aa 100644 --- a/src/librustc_privacy/Cargo.toml +++ b/src/librustc_privacy/Cargo.toml @@ -11,5 +11,4 @@ crate-type = ["dylib"] [dependencies] log = { path = "../liblog" } rustc = { path = "../librustc" } -rustc_front = { path = "../librustc_front" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 80df21e85f6..908a7869c42 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -25,13 +25,12 @@ #[macro_use] extern crate syntax; #[macro_use] extern crate rustc; -extern crate rustc_front; use std::cmp; use std::mem::replace; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit::{self, Visitor}; +use rustc::hir::{self, PatKind}; +use rustc::hir::intravisit::{self, Visitor}; use rustc::dep_graph::DepNode; use rustc::lint; @@ -41,7 +40,7 @@ use rustc::middle::def_id::DefId; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::NodeSet; -use rustc::front::map as ast_map; +use rustc::hir::map as ast_map; use syntax::ast; use syntax::codemap::Span; diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 82e952d2bee..cf477c2a956 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -13,5 +13,4 @@ log = { path = "../liblog" } syntax = { path = "../libsyntax" } rustc = { path = "../librustc" } rustc_bitflags = { path = "../librustc_bitflags" } -rustc_front = { path = "../librustc_front" } arena = { path = "../libarena" } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f36a8269dc0..470fd88025e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -33,15 +33,15 @@ use syntax::attr::AttrMetaMethods; use syntax::parse::token::{special_idents, SELF_KEYWORD_NAME, SUPER_KEYWORD_NAME}; use syntax::codemap::{Span, DUMMY_SP}; -use rustc_front::hir; -use rustc_front::hir::{Block, DeclItem}; -use rustc_front::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic}; -use rustc_front::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}; -use rustc_front::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; -use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use rustc_front::hir::{PathListIdent, PathListMod, StmtDecl}; -use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; -use rustc_front::intravisit::{self, Visitor}; +use rustc::hir; +use rustc::hir::{Block, DeclItem}; +use rustc::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic}; +use rustc::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}; +use rustc::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; +use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; +use rustc::hir::{PathListIdent, PathListMod, StmtDecl}; +use rustc::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; +use rustc::hir::intravisit::{self, Visitor}; trait ToNameBinding<'a> { fn to_name_binding(self) -> NameBinding<'a>; diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index ea197109cab..4046c8c7783 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -26,9 +26,9 @@ use rustc::lint; use syntax::ast; use syntax::codemap::{Span, DUMMY_SP}; -use rustc_front::hir; -use rustc_front::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; -use rustc_front::intravisit::Visitor; +use rustc::hir; +use rustc::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; +use rustc::hir::intravisit::Visitor; struct UnusedImportCheckVisitor<'a, 'b: 'a, 'tcx: 'b> { resolver: &'a mut Resolver<'b, 'tcx>, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 98e40d73133..bbf8796436e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -31,7 +31,6 @@ extern crate arena; #[macro_use] #[no_link] extern crate rustc_bitflags; -extern crate rustc_front; #[macro_use] extern crate rustc; @@ -49,7 +48,7 @@ use self::ParentLink::*; use self::FallbackChecks::*; use rustc::dep_graph::DepNode; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::session::Session; use rustc::lint; use rustc::middle::cstore::CrateStore; @@ -68,24 +67,24 @@ use syntax::errors::DiagnosticBuilder; use syntax::parse::token::{self, special_names, special_idents}; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_front::intravisit::{self, FnKind, Visitor}; -use rustc_front::hir; -use rustc_front::hir::{Arm, BindByRef, BindByValue, BindingMode, Block}; -use rustc_front::hir::Crate; -use rustc_front::hir::{Expr, ExprAgain, ExprBreak, ExprCall, ExprField}; -use rustc_front::hir::{ExprLoop, ExprWhile, ExprMethodCall}; -use rustc_front::hir::{ExprPath, ExprStruct, FnDecl}; -use rustc_front::hir::{ForeignItemFn, ForeignItemStatic, Generics}; -use rustc_front::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}; -use rustc_front::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; -use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use rustc_front::hir::Local; -use rustc_front::hir::{Pat, PatKind, Path, PrimTy}; -use rustc_front::hir::{PathSegment, PathParameters}; -use rustc_front::hir::HirVec; -use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt}; -use rustc_front::hir::{TyRptr, TyStr, TyUint, TyPath, TyPtr}; -use rustc_front::util::walk_pat; +use rustc::hir::intravisit::{self, FnKind, Visitor}; +use rustc::hir; +use rustc::hir::{Arm, BindByRef, BindByValue, BindingMode, Block}; +use rustc::hir::Crate; +use rustc::hir::{Expr, ExprAgain, ExprBreak, ExprCall, ExprField}; +use rustc::hir::{ExprLoop, ExprWhile, ExprMethodCall}; +use rustc::hir::{ExprPath, ExprStruct, FnDecl}; +use rustc::hir::{ForeignItemFn, ForeignItemStatic, Generics}; +use rustc::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}; +use rustc::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; +use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; +use rustc::hir::Local; +use rustc::hir::{Pat, PatKind, Path, PrimTy}; +use rustc::hir::{PathSegment, PathParameters}; +use rustc::hir::HirVec; +use rustc::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt}; +use rustc::hir::{TyRptr, TyStr, TyUint, TyPath, TyPtr}; +use rustc::hir::util::walk_pat; use std::collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index a0cf70b57a9..52fa9193472 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -11,5 +11,4 @@ crate-type = ["dylib"] [dependencies] log = { path = "../liblog" } rustc = { path = "../librustc" } -rustc_front = { path = "../librustc_front" } syntax = { path = "../libsyntax" } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 35ca2a9b014..310747c8991 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -42,7 +42,7 @@ use syntax::visit::{self, Visitor}; use syntax::print::pprust::{path_to_string, ty_to_string}; use syntax::ptr::P; -use rustc_front::lowering::{lower_expr, LoweringContext}; +use rustc::hir::lowering::{lower_expr, LoweringContext}; use super::{escape, generated_code, SaveContext, PathCollector}; use super::data::*; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 36b94731e45..e65bf5be256 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -23,13 +23,12 @@ #![feature(staged_api)] #[macro_use] extern crate rustc; -extern crate rustc_front; #[macro_use] extern crate log; #[macro_use] extern crate syntax; -use rustc_front::{hir, lowering}; -use rustc::front::map::NodeItem; +use rustc::hir::{self, lowering}; +use rustc::hir::map::NodeItem; use rustc::middle::def::Def; use rustc::middle::def_id::DefId; use rustc::session::config::CrateType::CrateTypeExecutable; @@ -278,7 +277,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { match item.node { hir::ItemImpl(_, _, _, _, ref ty, _) => { let mut result = String::from("<"); - result.push_str(&rustc_front::print::pprust::ty_to_string(&ty)); + result.push_str(&rustc::hir::print::ty_to_string(&ty)); match self.tcx.trait_of_item(self.tcx.map.local_def_id(id)) { Some(def_id) => { diff --git a/src/librustc_trans/Cargo.toml b/src/librustc_trans/Cargo.toml index fb5a8e4a90e..ea4cef03b70 100644 --- a/src/librustc_trans/Cargo.toml +++ b/src/librustc_trans/Cargo.toml @@ -18,7 +18,6 @@ rustc_back = { path = "../librustc_back" } rustc_const_eval = { path = "../librustc_const_eval" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_front = { path = "../librustc_front" } rustc_llvm = { path = "../librustc_llvm" } rustc_mir = { path = "../librustc_mir" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs index b27929c80c2..3bbead9847b 100644 --- a/src/librustc_trans/_match.rs +++ b/src/librustc_trans/_match.rs @@ -229,10 +229,10 @@ use std::cell::RefCell; use std::cmp::Ordering; use std::fmt; use std::rc::Rc; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::{self, PatKind}; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; use syntax::codemap::Span; -use rustc_front::fold::Folder; +use rustc::hir::fold::Folder; use syntax::ptr::P; #[derive(Copy, Clone, Debug)] diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index 6edc26c7009..961a32170d0 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -26,7 +26,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real}; use type_::Type; use type_of; -use rustc_front::hir; +use rustc::hir; use rustc::ty::{self, Ty}; use libc::c_uint; diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index 41f1f4ae5f8..e27bec68375 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -18,7 +18,7 @@ use datum::{Datum, Lvalue}; use type_of; use type_::Type; -use rustc_front::hir as ast; +use rustc::hir as ast; use std::ffi::CString; use syntax::ast::AsmDialect; use libc::{c_uint, c_char}; diff --git a/src/librustc_trans/assert_dep_graph.rs b/src/librustc_trans/assert_dep_graph.rs index bd98b3950d4..ecbb5049443 100644 --- a/src/librustc_trans/assert_dep_graph.rs +++ b/src/librustc_trans/assert_dep_graph.rs @@ -43,8 +43,8 @@ use rustc::middle::def_id::DefId; use rustc::ty::TyCtxt; use rustc_data_structures::fnv::{FnvHashMap, FnvHashSet}; use rustc_data_structures::graph::{Direction, INCOMING, OUTGOING, NodeIndex}; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; +use rustc::hir; +use rustc::hir::intravisit::Visitor; use graphviz::IntoCow; use std::env; use std::fs::File; diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 7aef1d912ec..130499603e7 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -43,7 +43,7 @@ use syntax::ast; use syntax::codemap::Span; use syntax::attr::AttrMetaMethods; -use rustc_front::hir; +use rustc::hir; // RLIB LLVM-BYTECODE OBJECT LAYOUT // Version 1 diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index a458307da40..949a10297c1 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -105,7 +105,7 @@ use rustc::middle::cstore; use rustc::middle::def_id::DefId; use rustc::ty::{self, TypeFoldable}; use rustc::ty::item_path::{ItemPathBuffer, RootMode}; -use rustc::front::map::definitions::{DefPath, DefPathData}; +use rustc::hir::map::definitions::{DefPath, DefPathData}; use std::fmt::Write; use syntax::parse::token::{self, InternedString}; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index e5667e06b44..d2fc20fd837 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -46,7 +46,7 @@ use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::adjustment::CustomCoerceUnsized; use rustc::dep_graph::DepNode; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::util::common::time; use rustc::mir::mir_map::MirMap; use session::config::{self, NoDebugInfo, FullDebugInfo}; @@ -106,9 +106,8 @@ use syntax::codemap::{Span, DUMMY_SP}; use syntax::parse::token::InternedString; use syntax::attr::AttrMetaMethods; use syntax::attr; -use rustc_front; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir; use syntax::ast; thread_local! { @@ -713,7 +712,7 @@ fn cast_shift_rhs(op: hir::BinOp_, G: FnOnce(ValueRef, Type) -> ValueRef { // Shifts may have any size int on the rhs - if rustc_front::util::is_shift_binop(op) { + if hir::util::is_shift_binop(op) { let mut rhs_llty = val_ty(rhs); let mut lhs_llty = val_ty(lhs); if rhs_llty.kind() == Vector { diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 6b0945b2bb2..2da9acf3250 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -26,7 +26,7 @@ use rustc::infer; use rustc::ty::subst; use rustc::ty::subst::{Substs}; use rustc::traits; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use abi::{Abi, FnType}; use adt; use attributes; @@ -54,7 +54,7 @@ use type_of; use value::Value; use Disr; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc_front::hir; +use rustc::hir; use syntax::codemap::DUMMY_SP; use syntax::errors; diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs index cb94c9dfeb8..579848919ec 100644 --- a/src/librustc_trans/closure.rs +++ b/src/librustc_trans/closure.rs @@ -35,7 +35,7 @@ use session::config::FullDebugInfo; use syntax::ast; -use rustc_front::hir; +use rustc::hir; use libc::c_uint; diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 1c18f3ca393..4f197dbee13 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -188,10 +188,10 @@ //! this is not implemented however: a translation item will be produced //! regardless of whether it is actually needed or not. -use rustc_front::hir; -use rustc_front::intravisit as hir_visit; +use rustc::hir; +use rustc::hir::intravisit as hir_visit; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::middle::def_id::DefId; use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem}; use rustc::traits; diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 589e6f3266e..1f48eb91603 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -40,7 +40,7 @@ use value::Value; use rustc::ty::{self, Ty, TyCtxt}; use rustc::traits::{self, SelectionContext, ProjectionMode}; use rustc::ty::fold::{TypeFolder, TypeFoldable}; -use rustc_front::hir; +use rustc::hir; use util::nodemap::NodeMap; use arena::TypedArena; diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 3e516c0eec4..7945639f86b 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -17,7 +17,7 @@ use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, use rustc_const_eval::eval_repeat_count; use middle::def::Def; use middle::def_id::DefId; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use {abi, adt, closure, debuginfo, expr, machine}; use base::{self, exported_name, imported_name, push_ctxt}; use callee::Callee; @@ -41,7 +41,7 @@ use rustc::ty::cast::{CastTy,IntTy}; use util::nodemap::NodeMap; use rustc_const_math::{ConstInt, ConstMathErr, ConstUsize, ConstIsize}; -use rustc_front::hir; +use rustc::hir; use std::ffi::{CStr, CString}; use std::borrow::Cow; diff --git a/src/librustc_trans/controlflow.rs b/src/librustc_trans/controlflow.rs index 6d4b02f076c..60ae91a8c5f 100644 --- a/src/librustc_trans/controlflow.rs +++ b/src/librustc_trans/controlflow.rs @@ -25,8 +25,8 @@ use debuginfo::{DebugLoc, ToDebugLoc}; use expr; use machine; -use rustc_front::hir; -use rustc_front::util as ast_util; +use rustc::hir; +use rustc::hir::util as ast_util; use syntax::ast; use syntax::parse::token::InternedString; diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index a7f2bf4a5fa..477dc0b4b52 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -21,8 +21,7 @@ use libc::c_uint; use syntax::codemap::{Span, Pos}; use syntax::{ast, codemap}; -use rustc_front; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::{self, PatKind}; // This procedure builds the *scope map* for a given function, which maps any // given ast::NodeId in the function's AST to the correct DIScope metadata instance. @@ -117,7 +116,7 @@ fn walk_block(cx: &CrateContext, // The interesting things here are statements and the concluding expression. for statement in &block.stmts { - scope_map.insert(rustc_front::util::stmt_id(statement), + scope_map.insert(hir::util::stmt_id(statement), scope_stack.last().unwrap().scope_metadata); match statement.node { diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 5690b18bc8e..acfafc6e329 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -27,8 +27,8 @@ use middle::def_id::DefId; use rustc::infer; use middle::pat_util; use rustc::ty::subst; -use rustc::front::map as hir_map; -use rustc_front::hir::{self, PatKind}; +use rustc::hir::map as hir_map; +use rustc::hir::{self, PatKind}; use {type_of, adt, machine, monomorphize}; use common::{self, CrateContext, FunctionContext, Block}; use _match::{BindingInfo, TransBindingMode}; diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 6b92989cf46..f671c2b7963 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -29,8 +29,7 @@ use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArr use middle::def_id::DefId; use rustc::infer::normalize_associated_type; use rustc::ty::subst::{self, Substs}; -use rustc_front; -use rustc_front::hir; +use rustc::hir; use abi::Abi; use common::{NodeIdAndSpan, CrateContext, FunctionContext, Block}; @@ -39,7 +38,7 @@ use rustc::infer; use rustc::ty::{self, Ty}; use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo}; use util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use libc::c_uint; use std::cell::{Cell, RefCell}; @@ -239,7 +238,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return FunctionDebugContext::FunctionWithoutDebugInfo; } - let empty_generics = rustc_front::util::empty_generics(); + let empty_generics = hir::util::empty_generics(); let fnitem = cx.tcx().map.get(fn_ast_id); diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 445f85c52fc..1feb47a3a7d 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -15,7 +15,7 @@ use super::utils::{DIB, debug_context}; use llvm; use llvm::debuginfo::DIScope; use rustc::middle::def_id::DefId; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use common::CrateContext; use std::ffi::CString; diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index a6aa8df92db..f5bb1677f29 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -18,7 +18,7 @@ use rustc::infer; use rustc::ty::subst; use rustc::ty::{self, Ty}; -use rustc_front::hir; +use rustc::hir; // Compute the name of the type as it should be stored in debuginfo. Does not do // any caching, i.e. calling the function twice with the same type will also do diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index 5e193b96278..7c2557fb090 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -80,8 +80,7 @@ use util::common::indenter; use machine::{llsize_of, llsize_of_alloc}; use type_::Type; -use rustc_front; -use rustc_front::hir; +use rustc::hir; use syntax::{ast, codemap}; use syntax::parse::token::InternedString; @@ -1181,7 +1180,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // if not overloaded, would be RvalueDatumExpr let lhs = unpack_datum!(bcx, trans(bcx, &lhs)); let mut rhs = unpack_datum!(bcx, trans(bcx, &rhs_expr)); - if !rustc_front::util::is_by_value_binop(op.node) { + if !hir::util::is_by_value_binop(op.node) { rhs = unpack_datum!(bcx, auto_ref(bcx, rhs, rhs_expr)); } @@ -1205,7 +1204,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, span_bug!( expr.span, "augmented assignment `{}=` should always be a rvalue_stmt", - rustc_front::util::binop_to_string(op.node)) + hir::util::binop_to_string(op.node)) } _ => { span_bug!( diff --git a/src/librustc_trans/inline.rs b/src/librustc_trans/inline.rs index 4d18e3bd495..36dfbec115e 100644 --- a/src/librustc_trans/inline.rs +++ b/src/librustc_trans/inline.rs @@ -17,7 +17,7 @@ use callee::Callee; use common::*; use rustc::dep_graph::DepNode; -use rustc_front::hir; +use rustc::hir; fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option { debug!("instantiate_inline({:?})", fn_id); diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs index 28d5d9ac176..355de31bf59 100644 --- a/src/librustc_trans/intrinsic.rs +++ b/src/librustc_trans/intrinsic.rs @@ -40,7 +40,7 @@ use rustc::ty::{self, Ty, TypeFoldable}; use Disr; use rustc::ty::subst::Substs; use rustc::dep_graph::DepNode; -use rustc_front::hir; +use rustc::hir; use syntax::ast; use syntax::ptr::P; use syntax::parse::token; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 8c6a68cfcf1..19a172e7f10 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -46,7 +46,6 @@ extern crate libc; #[macro_use] extern crate rustc; extern crate rustc_back; extern crate rustc_data_structures; -extern crate rustc_front; pub extern crate rustc_llvm as llvm; extern crate rustc_mir; extern crate rustc_platform_intrinsics as intrinsics; @@ -67,7 +66,7 @@ pub use disr::Disr; pub mod back { pub use rustc_back::rpath; - pub use rustc_back::svh; + pub use rustc::hir::svh; pub mod archive; pub mod linker; diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 3f7a6c5f180..8e5d220b4f4 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -134,7 +134,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { _ => { // FIXME Shouldn't need to manually trigger closure instantiations. if let mir::AggregateKind::Closure(def_id, substs) = *kind { - use rustc_front::hir; + use rustc::hir; use syntax::ast::DUMMY_NODE_ID; use syntax::codemap::DUMMY_SP; use syntax::ptr::P; diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 554e1948fe9..de66951d091 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -23,10 +23,10 @@ use base; use common::*; use declare; use Disr; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::util::ppaux; -use rustc_front::hir; +use rustc::hir; use syntax::attr; use syntax::errors; diff --git a/src/librustc_trans/symbol_names_test.rs b/src/librustc_trans/symbol_names_test.rs index a75b6f736ee..2e3355968df 100644 --- a/src/librustc_trans/symbol_names_test.rs +++ b/src/librustc_trans/symbol_names_test.rs @@ -15,8 +15,8 @@ //! paths etc in all kinds of annoying scenarios. use back::symbol_names; -use rustc_front::hir; -use rustc_front::intravisit::{self, Visitor}; +use rustc::hir; +use rustc::hir::intravisit::{self, Visitor}; use syntax::ast; use syntax::attr::AttrMetaMethods; diff --git a/src/librustc_trans/tvec.rs b/src/librustc_trans/tvec.rs index b9af02ac529..f5b9bef5313 100644 --- a/src/librustc_trans/tvec.rs +++ b/src/librustc_trans/tvec.rs @@ -29,7 +29,7 @@ use type_of; use value::Value; use rustc::ty::{self, Ty}; -use rustc_front::hir; +use rustc::hir; use rustc_const_eval::eval_repeat_count; use syntax::ast; diff --git a/src/librustc_typeck/Cargo.toml b/src/librustc_typeck/Cargo.toml index 6f46686feb5..e9dabf16eae 100644 --- a/src/librustc_typeck/Cargo.toml +++ b/src/librustc_typeck/Cargo.toml @@ -17,5 +17,4 @@ rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_eval = { path = "../librustc_const_eval" } rustc_const_math = { path = "../librustc_const_math" } -rustc_front = { path = "../librustc_front" } rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d925ff9fa3c..a52b8cad108 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -74,8 +74,8 @@ use syntax::errors::DiagnosticBuilder; use syntax::feature_gate::{GateIssue, emit_feature_err}; use syntax::parse::token; -use rustc_front::print::pprust; -use rustc_front::hir; +use rustc::hir::print as pprust; +use rustc::hir; use rustc_back::slice; pub trait AstConv<'tcx> { diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 55c3a5add37..5c93c170590 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -30,9 +30,9 @@ use syntax::ast; use syntax::codemap::{Span, Spanned}; use syntax::ptr::P; -use rustc_front::hir::{self, PatKind}; -use rustc_front::print::pprust; -use rustc_front::util as hir_util; +use rustc::hir::{self, PatKind}; +use rustc::hir::print as pprust; +use rustc::hir::util as hir_util; pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat, diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index bedf4753313..460230c60c6 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -34,7 +34,7 @@ use syntax::codemap::Span; use syntax::parse::token; use syntax::ptr::P; -use rustc_front::hir; +use rustc::hir; /// Check that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index d743a036040..00a73a062fe 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -48,7 +48,7 @@ use middle::def_id::DefId; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::cast::{CastKind, CastTy}; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; use syntax::ast; diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 9333b10d27e..7bca570411c 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -17,7 +17,7 @@ use rustc::ty::subst; use rustc::ty::{self, ToPolyTraitRef, Ty}; use std::cmp; use syntax::abi::Abi; -use rustc_front::hir; +use rustc::hir; pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, expr: &hir::Expr, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index cafd0519c28..f1c6868efd2 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -76,7 +76,7 @@ use util::common::indent; use std::cell::RefCell; use std::collections::VecDeque; -use rustc_front::hir; +use rustc::hir; struct Coerce<'a, 'tcx: 'a> { fcx: &'a FnCtxt<'a, 'tcx>, diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index bc2ef9aafee..5b163eb7de4 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -14,7 +14,7 @@ use rustc::ty::Ty; use rustc::infer::{InferOk, TypeOrigin}; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; // Requires that the two types unify, and prints an error message if // they don't. diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index 3c43e0d5217..eae0cfb0f22 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -26,7 +26,7 @@ use syntax::attr::AttrMetaMethods; use syntax::codemap::Span; use syntax::parse::token; -use rustc_front::hir; +use rustc::hir; fn equate_intrinsic_type<'a, 'tcx>(tcx: &TyCtxt<'tcx>, it: &hir::ForeignItem, n_tps: usize, diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index f90a5696539..cc12b2e0515 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -21,7 +21,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::infer; use rustc::infer::{InferCtxt, TypeOrigin}; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; struct ConfirmContext<'a, 'tcx:'a> { fcx: &'a FnCtxt<'a, 'tcx>, diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 43a18d2c102..72ca73aac94 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -23,7 +23,7 @@ use rustc::infer; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; +use rustc::hir; pub use self::MethodError::*; pub use self::CandidateSource::*; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 2e15ac0e130..c907a6dc640 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -24,7 +24,7 @@ use rustc::ty::{self, NoPreference, Ty, TyCtxt, ToPolyTraitRef, TraitRef, TypeFo use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin}; use syntax::ast; use syntax::codemap::{Span, DUMMY_SP}; -use rustc_front::hir; +use rustc::hir; use std::collections::HashSet; use std::mem; use std::rc::Rc; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 32b5a63817e..620863a7a2e 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -15,7 +15,7 @@ use CrateCtxt; use astconv::AstConv; use check::{self, FnCtxt, UnresolvedTypeAction, autoderef}; -use front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; use middle::cstore::{self, CrateStore}; use middle::def::Def; @@ -30,9 +30,9 @@ use util::nodemap::{FnvHashSet}; use syntax::ast; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; -use rustc_front::print::pprust; -use rustc_front::hir; -use rustc_front::hir::Expr_; +use rustc::hir::print as pprust; +use rustc::hir; +use rustc::hir::Expr_; use std::cell; use std::cmp::Ordering; @@ -436,7 +436,7 @@ impl Ord for TraitInfo { /// Retrieve all traits in this crate and any dependent crates. pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { if ccx.all_traits.borrow().is_none() { - use rustc_front::intravisit; + use rustc::hir::intravisit; let mut traits = vec![]; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e485fbe1621..20b9a75e0e5 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -124,10 +124,10 @@ use syntax::parse::token::{self, InternedString, special_idents}; use syntax::ptr::P; use syntax::util::lev_distance::find_best_match_for_name; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir; -use rustc_front::hir::{Visibility, PatKind}; -use rustc_front::print::pprust; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir; +use rustc::hir::{Visibility, PatKind}; +use rustc::hir::print as pprust; use rustc_back::slice; use rustc_const_eval::eval_repeat_count; @@ -3987,7 +3987,7 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let mut any_err = false; for s in &blk.stmts { check_stmt(fcx, s); - let s_id = ::rustc_front::util::stmt_id(s); + let s_id = hir::util::stmt_id(s); let s_ty = fcx.node_ty(s_id); if any_diverges && !warned && match s.node { hir::StmtDecl(ref decl, _) => { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 494135ee3ff..1af015cdebf 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -22,8 +22,8 @@ use middle::def_id::DefId; use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue}; use syntax::ast; use syntax::parse::token; -use rustc_front::hir; -use rustc_front::util as hir_util; +use rustc::hir; +use rustc::hir::util as hir_util; /// Check a `a = b` pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 15bf6671de5..ed9372acba9 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -100,9 +100,9 @@ use rustc::ty::wf::ImpliedBound; use std::mem; use syntax::ast; use syntax::codemap::Span; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir::{self, PatKind}; -use rustc_front::util as hir_util; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::{self, PatKind}; +use rustc::hir::util as hir_util; use self::SubjectNode::Subject; diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 7d51d5ec7f7..40481cda762 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -51,8 +51,8 @@ use rustc::infer::{InferCtxt, UpvarRegion}; use std::collections::HashSet; use syntax::ast; use syntax::codemap::Span; -use rustc_front::hir; -use rustc_front::intravisit::{self, Visitor}; +use rustc::hir; +use rustc::hir::intravisit::{self, Visitor}; /////////////////////////////////////////////////////////////////////////// // PUBLIC ENTRY POINTS diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 68c9816b48c..0ed0b64b970 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -25,8 +25,8 @@ use syntax::ast; use syntax::codemap::{Span}; use syntax::errors::DiagnosticBuilder; use syntax::parse::token::{special_idents}; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::hir; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir; pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { ccx: &'ccx CrateCtxt<'ccx, 'tcx>, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 7ede85454e9..6ac6f1d6e17 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -28,10 +28,10 @@ use std::cell::Cell; use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; -use rustc_front::print::pprust::pat_to_string; -use rustc_front::intravisit::{self, Visitor}; -use rustc_front::util as hir_util; -use rustc_front::hir; +use rustc::hir::print::pat_to_string; +use rustc::hir::intravisit::{self, Visitor}; +use rustc::hir::util as hir_util; +use rustc::hir; /////////////////////////////////////////////////////////////////////////// // Entry point functions diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index f9a4cfadc0b..1f7fc453279 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -39,10 +39,10 @@ use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; use util::nodemap::{DefIdMap, FnvHashMap}; use rustc::dep_graph::DepNode; -use rustc::front::map as hir_map; -use rustc_front::intravisit; -use rustc_front::hir::{Item, ItemImpl}; -use rustc_front::hir; +use rustc::hir::map as hir_map; +use rustc::hir::intravisit; +use rustc::hir::{Item, ItemImpl}; +use rustc::hir; mod orphan; mod overlap; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index eba3e56c722..0821d5582bd 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -18,8 +18,8 @@ use rustc::ty::{self, TyCtxt}; use syntax::ast; use syntax::codemap::Span; use rustc::dep_graph::DepNode; -use rustc_front::intravisit; -use rustc_front::hir; +use rustc::hir::intravisit; +use rustc::hir; pub fn check(tcx: &TyCtxt) { let mut orphan = OrphanChecker { tcx: tcx }; diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index d7d4560a4ea..d99c5d52f4a 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -19,8 +19,8 @@ use rustc::infer; use rustc::ty::{self, TyCtxt}; use syntax::ast; use rustc::dep_graph::DepNode; -use rustc_front::hir; -use rustc_front::intravisit; +use rustc::hir; +use rustc::hir::intravisit; use util::nodemap::DefIdMap; use lint; diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 6d77200daa3..b042e23e0ac 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -12,8 +12,8 @@ //! crate or pertains to a type defined in this crate. use rustc::ty::TyCtxt; -use rustc_front::intravisit; -use rustc_front::hir; +use rustc::hir::intravisit; +use rustc::hir; pub fn check(tcx: &TyCtxt) { let mut orphan = UnsafetyChecker { tcx: tcx }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 59546f619c0..53126d3494a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -77,7 +77,7 @@ use rustc::ty::fold::{TypeFolder}; use rustc::ty::util::IntTypeExt; use rscope::*; use rustc::dep_graph::DepNode; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use util::common::{ErrorReported, MemoizationMap}; use util::nodemap::{FnvHashMap, FnvHashSet}; use write_ty_to_tcx; @@ -94,9 +94,9 @@ use syntax::attr; use syntax::codemap::Span; use syntax::parse::token::special_idents; use syntax::ptr::P; -use rustc_front::hir::{self, PatKind}; -use rustc_front::intravisit; -use rustc_front::print::pprust; +use rustc::hir::{self, PatKind}; +use rustc::hir::intravisit; +use rustc::hir::print as pprust; /////////////////////////////////////////////////////////////////////////// // Main entry point diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index fa23445fe63..af32026d47e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -90,20 +90,19 @@ extern crate arena; extern crate fmt_macros; #[macro_use] extern crate rustc; extern crate rustc_platform_intrinsics as intrinsics; -extern crate rustc_front; extern crate rustc_back; extern crate rustc_const_math; extern crate rustc_const_eval; pub use rustc::dep_graph; -pub use rustc::front; +pub use rustc::hir; pub use rustc::lint; pub use rustc::middle; pub use rustc::session; pub use rustc::util; use dep_graph::DepNode; -use front::map as hir_map; +use hir::map as hir_map; use middle::def::Def; use rustc::infer::{self, TypeOrigin}; use rustc::ty::subst::Substs; @@ -111,7 +110,6 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::traits::ProjectionMode; use session::{config, CompileResult}; use util::common::time; -use rustc_front::hir; use syntax::codemap::Span; use syntax::ast; diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index 50c99e33b44..fa3ee80c6da 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -20,10 +20,10 @@ use rustc::ty::subst; use rustc::ty::subst::ParamSpace; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::maps::ItemVariances; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use syntax::ast; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; +use rustc::hir; +use rustc::hir::intravisit::Visitor; use super::terms::*; use super::terms::VarianceTerm::*; diff --git a/src/librustc_typeck/variance/terms.rs b/src/librustc_typeck/variance/terms.rs index c6f82ba42e6..413dc83e638 100644 --- a/src/librustc_typeck/variance/terms.rs +++ b/src/librustc_typeck/variance/terms.rs @@ -27,8 +27,8 @@ use rustc::ty::maps::ItemVariances; use std::fmt; use std::rc::Rc; use syntax::ast; -use rustc_front::hir; -use rustc_front::intravisit::Visitor; +use rustc::hir; +use rustc::hir::intravisit::Visitor; use util::nodemap::NodeMap; use self::VarianceTerm::*; diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 228eb099a04..9d76dd81e5f 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -15,7 +15,6 @@ rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_eval = { path = "../librustc_const_eval" } rustc_driver = { path = "../librustc_driver" } -rustc_front = { path = "../librustc_front" } rustc_lint = { path = "../librustc_lint" } rustc_metadata = { path = "../librustc_metadata" } rustc_resolve = { path = "../librustc_resolve" } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3e4ba47ce4c..2f080dae370 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -14,7 +14,7 @@ use std::collections::HashSet; use syntax::ast; use syntax::attr::AttrMetaMethods; -use rustc_front::hir; +use rustc::hir; use rustc::middle::cstore::{self, CrateStore}; use rustc::middle::def::Def; @@ -484,7 +484,7 @@ fn build_module(cx: &DocContext, tcx: &TyCtxt, fn build_const(cx: &DocContext, tcx: &TyCtxt, did: DefId) -> clean::Constant { - use rustc_front::print::pprust; + use rustc::hir::print as pprust; let (expr, ty) = lookup_const_by_id(tcx, did, None).unwrap_or_else(|| { panic!("expected lookup_const_by_id to succeed for {:?}", did); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7437d608771..715d0e759c3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -41,7 +41,7 @@ use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace}; use rustc::ty; use rustc::middle::stability; -use rustc_front::hir; +use rustc::hir; use std::collections::{HashMap, HashSet}; use std::path::PathBuf; @@ -563,7 +563,7 @@ pub enum TyParamBound { impl TyParamBound { fn maybe_sized(cx: &DocContext) -> TyParamBound { - use rustc_front::hir::TraitBoundModifier as TBM; + use rustc::hir::TraitBoundModifier as TBM; let mut sized_bound = ty::BoundSized.clean(cx); if let TyParamBound::TraitBound(_, ref mut tbm) = sized_bound { *tbm = TBM::Maybe @@ -572,7 +572,7 @@ impl TyParamBound { } fn is_sized_bound(&self, cx: &DocContext) -> bool { - use rustc_front::hir::TraitBoundModifier as TBM; + use rustc::hir::TraitBoundModifier as TBM; if let Some(tcx) = cx.tcx_opt() { if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self { if trait_.def_id() == tcx.lang_items.sized_trait() { @@ -1609,7 +1609,7 @@ impl PrimitiveType { impl Clean for hir::Ty { fn clean(&self, cx: &DocContext) -> Type { - use rustc_front::hir::*; + use rustc::hir::*; match self.node { TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), TyRptr(ref l, ref m) => @@ -1826,7 +1826,7 @@ pub struct VariantStruct { pub fields_stripped: bool, } -impl Clean for ::rustc_front::hir::VariantData { +impl Clean for ::rustc::hir::VariantData { fn clean(&self, cx: &DocContext) -> VariantStruct { VariantStruct { struct_type: doctree::struct_type_from_def(self), @@ -2554,7 +2554,7 @@ fn lit_to_string(lit: &ast::Lit) -> String { } fn name_from_pat(p: &hir::Pat) -> String { - use rustc_front::hir::*; + use rustc::hir::*; debug!("Trying to get a name from pattern: {:?}", p); match p.node { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 15a10a84e43..4686e60be87 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -16,11 +16,11 @@ use rustc::session::{self, config}; use rustc::middle::def_id::DefId; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::lint; use rustc_trans::back::link; use rustc_resolve as resolve; -use rustc_front::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_metadata::cstore::CStore; use syntax::{ast, codemap, errors}; diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index fc0422b3a3f..2db4b779eed 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -20,7 +20,7 @@ use syntax::ast; use syntax::ast::{Name, NodeId}; use syntax::attr; use syntax::ptr::P; -use rustc_front::hir; +use rustc::hir; pub struct Module { pub name: Option, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index e9a883d6d7a..9f0b636227f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -21,7 +21,7 @@ use std::iter::repeat; use rustc::middle::cstore::LOCAL_CRATE; use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId}; use syntax::abi::Abi; -use rustc_front::hir; +use rustc::hir; use clean; use html::item_type::ItemType; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 1427dfcbaf1..f97d4fee053 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -60,7 +60,7 @@ use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc::session::config::get_unstable_features_setting; -use rustc_front::hir; +use rustc::hir; use clean::{self, SelfTy, Attributes, GetDefId}; use doctree; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index a35fe20b6b6..9439c258318 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -41,7 +41,6 @@ extern crate rustc_driver; extern crate rustc_resolve; extern crate rustc_lint; extern crate rustc_back; -extern crate rustc_front; extern crate rustc_metadata; extern crate serialize; #[macro_use] extern crate syntax; diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index f93ecb46228..31f00caee43 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -14,7 +14,7 @@ use rustc::util::nodemap::DefIdSet; use std::cmp; use std::string::String; use std::usize; -use rustc_front::hir; +use rustc::hir; use clean::{self, Attributes, GetDefId}; use clean::Item; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5bd3b9c4f59..3810fb87acf 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -24,11 +24,11 @@ use std::sync::{Arc, Mutex}; use testing; use rustc_lint; use rustc::dep_graph::DepGraph; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::session::{self, config}; use rustc::session::config::{get_unstable_features_setting, OutputType}; use rustc::session::search_paths::{SearchPaths, PathKind}; -use rustc_front::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_back::dynamic_lib::DynamicLibrary; use rustc_back::tempdir::TempDir; use rustc_driver::{driver, Compilation}; @@ -141,7 +141,7 @@ pub fn run(input: &str, } // Look for #![doc(test(no_crate_inject))], used by crates in the std facade -fn scrape_test_config(krate: &::rustc_front::hir::Crate) -> TestOptions { +fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions { use syntax::attr::AttrMetaMethods; use syntax::print::pprust; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index e4ef0c1a4d6..45c7969ef7c 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -20,10 +20,10 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::Span; -use rustc::front::map as hir_map; +use rustc::hir::map as hir_map; use rustc::middle::stability; -use rustc_front::hir; +use rustc::hir; use core; use clean::{Clean, Attributes}; diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index 3f0d5086a17..4b5c2850dab 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -75,7 +75,6 @@ dependencies = [ "rustc_bitflags 0.0.0", "rustc_const_eval 0.0.0", "rustc_data_structures 0.0.0", - "rustc_front 0.0.0", "serialize 0.0.0", "syntax 0.0.0", ] @@ -85,7 +84,6 @@ name = "rustc_back" version = "0.0.0" dependencies = [ "log 0.0.0", - "rustc_front 0.0.0", "serialize 0.0.0", "syntax 0.0.0", ] @@ -101,7 +99,6 @@ dependencies = [ "graphviz 0.0.0", "log 0.0.0", "rustc 0.0.0", - "rustc_front 0.0.0", "rustc_mir 0.0.0", "syntax 0.0.0", ] @@ -134,7 +131,6 @@ dependencies = [ "rustc 0.0.0", "rustc_back 0.0.0", "rustc_borrowck 0.0.0", - "rustc_front 0.0.0", "rustc_lint 0.0.0", "rustc_llvm 0.0.0", "rustc_metadata 0.0.0", @@ -151,16 +147,6 @@ dependencies = [ "syntax_ext 0.0.0", ] -[[package]] -name = "rustc_front" -version = "0.0.0" -dependencies = [ - "log 0.0.0", - "rustc_bitflags 0.0.0", - "serialize 0.0.0", - "syntax 0.0.0", -] - [[package]] name = "rustc_lint" version = "0.0.0" @@ -168,7 +154,6 @@ dependencies = [ "log 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", - "rustc_front 0.0.0", "syntax 0.0.0", ] @@ -192,7 +177,6 @@ dependencies = [ "rustc_back 0.0.0", "rustc_bitflags 0.0.0", "rustc_const_eval 0.0.0", - "rustc_front 0.0.0", "rustc_llvm 0.0.0", "serialize 0.0.0", "syntax 0.0.0", @@ -208,7 +192,6 @@ dependencies = [ "rustc_back 0.0.0", "rustc_const_eval 0.0.0", "rustc_data_structures 0.0.0", - "rustc_front 0.0.0", "syntax 0.0.0", ] @@ -218,7 +201,6 @@ version = "0.0.0" dependencies = [ "log 0.0.0", "rustc 0.0.0", - "rustc_front 0.0.0", "syntax 0.0.0", ] @@ -234,7 +216,6 @@ dependencies = [ "rustc 0.0.0", "rustc_back 0.0.0", "rustc_bitflags 0.0.0", - "rustc_front 0.0.0", "rustc_metadata 0.0.0", "rustc_mir 0.0.0", "syntax 0.0.0", @@ -246,7 +227,6 @@ version = "0.0.0" dependencies = [ "log 0.0.0", "rustc 0.0.0", - "rustc_front 0.0.0", "syntax 0.0.0", ] @@ -258,7 +238,6 @@ dependencies = [ "log 0.0.0", "rustc 0.0.0", "rustc_bitflags 0.0.0", - "rustc_front 0.0.0", "syntax 0.0.0", ] @@ -284,7 +263,6 @@ dependencies = [ "rustc_back 0.0.0", "rustc_const_eval 0.0.0", "rustc_data_structures 0.0.0", - "rustc_front 0.0.0", "rustc_llvm 0.0.0", "rustc_mir 0.0.0", "rustc_platform_intrinsics 0.0.0", @@ -302,7 +280,6 @@ dependencies = [ "rustc 0.0.0", "rustc_back 0.0.0", "rustc_const_eval 0.0.0", - "rustc_front 0.0.0", "rustc_platform_intrinsics 0.0.0", "syntax 0.0.0", ] @@ -318,7 +295,6 @@ dependencies = [ "rustc 0.0.0", "rustc_back 0.0.0", "rustc_driver 0.0.0", - "rustc_front 0.0.0", "rustc_lint 0.0.0", "rustc_metadata 0.0.0", "rustc_resolve 0.0.0", diff --git a/src/test/auxiliary/dummy_mir_pass.rs b/src/test/auxiliary/dummy_mir_pass.rs index fc1ef4d41a8..b5234af937b 100644 --- a/src/test/auxiliary/dummy_mir_pass.rs +++ b/src/test/auxiliary/dummy_mir_pass.rs @@ -14,7 +14,6 @@ #![feature(box_syntax)] #[macro_use] extern crate rustc; -extern crate rustc_front; extern crate rustc_plugin; extern crate rustc_const_math; extern crate syntax; diff --git a/src/test/auxiliary/lint_for_crate.rs b/src/test/auxiliary/lint_for_crate.rs index 1933188ccbf..a424517da12 100644 --- a/src/test/auxiliary/lint_for_crate.rs +++ b/src/test/auxiliary/lint_for_crate.rs @@ -14,13 +14,12 @@ #![feature(box_syntax)] #[macro_use] extern crate rustc; -extern crate rustc_front; extern crate rustc_plugin; extern crate syntax; use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; use rustc_plugin::Registry; -use rustc_front::hir; +use rustc::hir; use syntax::attr; declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]"); diff --git a/src/test/auxiliary/lint_group_plugin_test.rs b/src/test/auxiliary/lint_group_plugin_test.rs index 98ed86bb390..1e9a77724a8 100644 --- a/src/test/auxiliary/lint_group_plugin_test.rs +++ b/src/test/auxiliary/lint_group_plugin_test.rs @@ -13,14 +13,12 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -extern crate rustc_front; - // Load rustc as a plugin to get macros #[macro_use] extern crate rustc; extern crate rustc_plugin; -use rustc_front::hir; +use rustc::hir; use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; use rustc_plugin::Registry; diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 81ad276ca68..91b4f5f30ad 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -14,7 +14,6 @@ extern crate libc; extern crate rustc; extern crate rustc_driver; -extern crate rustc_front; extern crate rustc_lint; extern crate rustc_llvm as llvm; extern crate rustc_metadata; @@ -28,13 +27,13 @@ use std::rc::Rc; use std::thread::Builder; use rustc::dep_graph::DepGraph; -use rustc::front::map as ast_map; +use rustc::hir::map as ast_map; use rustc::middle::cstore::{CrateStore, LinkagePreference}; use rustc::ty; use rustc::session::config::{self, basic_options, build_configuration, Input, Options}; use rustc::session::build_session; use rustc_driver::{driver, abort_on_err}; -use rustc_front::lowering::{lower_crate, LoweringContext}; +use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_resolve::MakeGlobMap; use rustc_metadata::cstore::CStore; use libc::c_void; -- cgit 1.4.1-3-g733a5 From ef4c7241f82c08848938b8b2dafed01535559ec0 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 29 Mar 2016 09:32:58 +0300 Subject: rustc: dismantle hir::util, mostly moving functions to methods. --- src/librustc/cfg/construct.rs | 2 +- src/librustc/hir/intravisit.rs | 183 ++++++++++++ src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/mod.rs | 165 ++++++++++- src/librustc/hir/print.rs | 8 +- src/librustc/hir/util.rs | 362 ----------------------- src/librustc/lint/context.rs | 6 +- src/librustc/middle/cstore.rs | 3 +- src/librustc/middle/expr_use_visitor.rs | 6 +- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/pat_util.rs | 11 +- src/librustc/middle/region.rs | 3 +- src/librustc_borrowck/borrowck/mod.rs | 3 +- src/librustc_const_eval/check_match.rs | 11 +- src/librustc_lint/types.rs | 3 +- src/librustc_mir/hair/cx/expr.rs | 5 +- src/librustc_resolve/lib.rs | 3 +- src/librustc_trans/base.rs | 2 +- src/librustc_trans/controlflow.rs | 5 +- src/librustc_trans/debuginfo/create_scope_map.rs | 2 +- src/librustc_trans/debuginfo/mod.rs | 2 +- src/librustc_trans/expr.rs | 4 +- src/librustc_typeck/check/_match.rs | 3 +- src/librustc_typeck/check/mod.rs | 2 +- src/librustc_typeck/check/op.rs | 9 +- src/librustc_typeck/check/regionck.rs | 5 +- src/librustc_typeck/check/writeback.rs | 5 +- 27 files changed, 393 insertions(+), 426 deletions(-) delete mode 100644 src/librustc/hir/util.rs (limited to 'src') diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 4fc0a092613..13c3e3895b5 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -257,7 +257,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { self.match_(expr.id, &discr, &arms, pred) } - hir::ExprBinary(op, ref l, ref r) if hir::util::lazy_binop(op.node) => { + hir::ExprBinary(op, ref l, ref r) if op.node.is_lazy() => { // // [pred] // | diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index be1cc528d88..90fba0c8985 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -27,6 +27,7 @@ use syntax::abi::Abi; use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; +use syntax::ast_util; use syntax::attr::ThinAttributesExt; use syntax::codemap::Span; use hir::*; @@ -835,3 +836,185 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { visitor.visit_expr(&arm.body); walk_list!(visitor, visit_attribute, &arm.attrs); } + +pub struct IdVisitor<'a, O: 'a> { + operation: &'a mut O, + + // In general, the id visitor visits the contents of an item, but + // not including nested trait/impl items, nor other nested items. + // The base visitor itself always skips nested items, but not + // trait/impl items. This means in particular that if you start by + // visiting a trait or an impl, you should not visit the + // trait/impl items respectively. This is handled by setting + // `skip_members` to true when `visit_item` is on the stack. This + // way, if the user begins by calling `visit_trait_item`, we will + // visit the trait item, but if they begin with `visit_item`, we + // won't visit the (nested) trait items. + skip_members: bool, +} + +impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { + pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { + IdVisitor { operation: operation, skip_members: false } + } + + fn visit_generics_helper(&mut self, generics: &Generics) { + for type_parameter in generics.ty_params.iter() { + self.operation.visit_id(type_parameter.id) + } + for lifetime in &generics.lifetimes { + self.operation.visit_id(lifetime.lifetime.id) + } + } +} + +impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { + fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { + self.operation.visit_id(node_id); + walk_mod(self, module) + } + + fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { + self.operation.visit_id(foreign_item.id); + walk_foreign_item(self, foreign_item) + } + + fn visit_item(&mut self, item: &Item) { + assert!(!self.skip_members); + self.skip_members = true; + + self.operation.visit_id(item.id); + match item.node { + ItemUse(ref view_path) => { + match view_path.node { + ViewPathSimple(_, _) | + ViewPathGlob(_) => {} + ViewPathList(_, ref paths) => { + for path in paths { + self.operation.visit_id(path.node.id()) + } + } + } + } + _ => {} + } + walk_item(self, item); + + self.skip_members = false; + } + + fn visit_local(&mut self, local: &Local) { + self.operation.visit_id(local.id); + walk_local(self, local) + } + + fn visit_block(&mut self, block: &Block) { + self.operation.visit_id(block.id); + walk_block(self, block) + } + + fn visit_stmt(&mut self, statement: &Stmt) { + self.operation.visit_id(statement.node.id()); + walk_stmt(self, statement) + } + + fn visit_pat(&mut self, pattern: &Pat) { + self.operation.visit_id(pattern.id); + walk_pat(self, pattern) + } + + fn visit_expr(&mut self, expression: &Expr) { + self.operation.visit_id(expression.id); + walk_expr(self, expression) + } + + fn visit_ty(&mut self, typ: &Ty) { + self.operation.visit_id(typ.id); + walk_ty(self, typ) + } + + fn visit_generics(&mut self, generics: &Generics) { + self.visit_generics_helper(generics); + walk_generics(self, generics) + } + + fn visit_fn(&mut self, + function_kind: FnKind<'v>, + function_declaration: &'v FnDecl, + block: &'v Block, + span: Span, + node_id: NodeId) { + self.operation.visit_id(node_id); + + match function_kind { + FnKind::ItemFn(_, generics, _, _, _, _, _) => { + self.visit_generics_helper(generics) + } + FnKind::Method(_, sig, _, _) => { + self.visit_generics_helper(&sig.generics) + } + FnKind::Closure(_) => {} + } + + for argument in &function_declaration.inputs { + self.operation.visit_id(argument.id) + } + + walk_fn(self, function_kind, function_declaration, block, span); + } + + fn visit_struct_field(&mut self, struct_field: &StructField) { + self.operation.visit_id(struct_field.id); + walk_struct_field(self, struct_field) + } + + fn visit_variant_data(&mut self, + struct_def: &VariantData, + _: Name, + _: &Generics, + _: NodeId, + _: Span) { + self.operation.visit_id(struct_def.id()); + walk_struct_def(self, struct_def); + } + + fn visit_trait_item(&mut self, ti: &TraitItem) { + if !self.skip_members { + self.operation.visit_id(ti.id); + walk_trait_item(self, ti); + } + } + + fn visit_impl_item(&mut self, ii: &ImplItem) { + if !self.skip_members { + self.operation.visit_id(ii.id); + walk_impl_item(self, ii); + } + } + + fn visit_lifetime(&mut self, lifetime: &Lifetime) { + self.operation.visit_id(lifetime.id); + } + + fn visit_lifetime_def(&mut self, def: &LifetimeDef) { + self.visit_lifetime(&def.lifetime); + } + + fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { + self.operation.visit_id(trait_ref.ref_id); + walk_trait_ref(self, trait_ref); + } +} + +/// Computes the id range for a single fn body, ignoring nested items. +pub fn compute_id_range_for_fn_body(fk: FnKind, + decl: &FnDecl, + body: &Block, + sp: Span, + id: NodeId) + -> ast_util::IdRange { + let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; + let mut id_visitor = IdVisitor::new(&mut visitor); + id_visitor.visit_fn(fk, decl, body, sp, id); + id_visitor.operation.result +} diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 70368222172..62c80c9c8bb 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -304,7 +304,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_stmt(&mut self, stmt: &'ast Stmt) { - let id = util::stmt_id(stmt); + let id = stmt.node.id(); self.insert(id, NodeStmt(stmt)); let parent_node = self.parent_node; self.parent_node = id; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index eaf59af2cc3..cb3cdd0b825 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -59,7 +59,7 @@ macro_rules! hir_vec { ($($x:expr),*) => ( $crate::hir::HirVec::from(vec![$($x),*]) ); - ($($x:expr,)*) => (vec![$($x),*]) + ($($x:expr,)*) => (hir_vec![$($x),*]) } pub mod check_attr; @@ -69,7 +69,6 @@ pub mod lowering; pub mod map; pub mod print; pub mod svh; -pub mod util; /// Identifier in HIR #[derive(Clone, Copy, Eq)] @@ -176,6 +175,21 @@ impl fmt::Display for Path { } } +impl Path { + /// Convert a span and an identifier to the corresponding + /// 1-segment path. + pub fn from_ident(s: Span, ident: Ident) -> Path { + Path { + span: s, + global: false, + segments: hir_vec![PathSegment { + identifier: ident, + parameters: PathParameters::none() + }], + } + } +} + /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] @@ -349,12 +363,25 @@ pub struct Generics { } impl Generics { + pub fn empty() -> Generics { + Generics { + lifetimes: HirVec::new(), + ty_params: HirVec::new(), + where_clause: WhereClause { + id: DUMMY_NODE_ID, + predicates: HirVec::new(), + }, + } + } + pub fn is_lt_parameterized(&self) -> bool { !self.lifetimes.is_empty() } + pub fn is_type_parameterized(&self) -> bool { !self.ty_params.is_empty() } + pub fn is_parameterized(&self) -> bool { self.is_lt_parameterized() || self.is_type_parameterized() } @@ -490,6 +517,50 @@ impl fmt::Debug for Pat { } } +impl Pat { + // FIXME(#19596) this is a workaround, but there should be a better way + fn walk_(&self, it: &mut G) -> bool + where G: FnMut(&Pat) -> bool + { + if !it(self) { + return false; + } + + match self.node { + PatKind::Ident(_, _, Some(ref p)) => p.walk_(it), + PatKind::Struct(_, ref fields, _) => { + fields.iter().all(|field| field.node.pat.walk_(it)) + } + PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { + s.iter().all(|p| p.walk_(it)) + } + PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { + s.walk_(it) + } + PatKind::Vec(ref before, ref slice, ref after) => { + before.iter().all(|p| p.walk_(it)) && + slice.iter().all(|p| p.walk_(it)) && + after.iter().all(|p| p.walk_(it)) + } + PatKind::Wild | + PatKind::Lit(_) | + PatKind::Range(_, _) | + PatKind::Ident(_, _, _) | + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::QPath(_, _) => { + true + } + } + } + + pub fn walk(&self, mut it: F) -> bool + where F: FnMut(&Pat) -> bool + { + self.walk_(&mut it) + } +} + /// A single field in a struct pattern /// /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` @@ -604,6 +675,68 @@ pub enum BinOp_ { BiGt, } +impl BinOp_ { + pub fn as_str(self) -> &'static str { + match self { + BiAdd => "+", + BiSub => "-", + BiMul => "*", + BiDiv => "/", + BiRem => "%", + BiAnd => "&&", + BiOr => "||", + BiBitXor => "^", + BiBitAnd => "&", + BiBitOr => "|", + BiShl => "<<", + BiShr => ">>", + BiEq => "==", + BiLt => "<", + BiLe => "<=", + BiNe => "!=", + BiGe => ">=", + BiGt => ">", + } + } + + pub fn is_lazy(self) -> bool { + match self { + BiAnd | BiOr => true, + _ => false, + } + } + + pub fn is_shift(self) -> bool { + match self { + BiShl | BiShr => true, + _ => false, + } + } + + pub fn is_comparison(self) -> bool { + match self { + BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true, + BiAnd | + BiOr | + BiAdd | + BiSub | + BiMul | + BiDiv | + BiRem | + BiBitXor | + BiBitAnd | + BiBitOr | + BiShl | + BiShr => false, + } + } + + /// Returns `true` if the binary operator takes its arguments by value + pub fn is_by_value(self) -> bool { + !self.is_comparison() + } +} + pub type BinOp = Spanned; #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)] @@ -616,6 +749,24 @@ pub enum UnOp { UnNeg, } +impl UnOp { + pub fn as_str(self) -> &'static str { + match self { + UnDeref => "*", + UnNot => "!", + UnNeg => "-", + } + } + + /// Returns `true` if the unary operator takes its argument by value + pub fn is_by_value(self) -> bool { + match self { + UnNeg | UnNot => true, + _ => false, + } + } +} + /// A statement pub type Stmt = Spanned; @@ -625,7 +776,7 @@ impl fmt::Debug for Stmt_ { let spanned = codemap::dummy_spanned(self.clone()); write!(f, "stmt({}: {})", - util::stmt_id(&spanned), + spanned.node.id(), print::stmt_to_string(&spanned)) } } @@ -650,6 +801,14 @@ impl Stmt_ { StmtSemi(ref e, _) => e.attrs.as_attr_slice(), } } + + pub fn id(&self) -> NodeId { + match *self { + StmtDecl(_, id) => id, + StmtExpr(_, id) => id, + StmtSemi(_, id) => id, + } + } } // FIXME (pending discussion of #1697, #2178...): local should really be diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 568986f39c5..cd2dfd44639 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -950,7 +950,7 @@ impl<'a> State<'a> { pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> { self.head("")?; - let generics = hir::util::empty_generics(); + let generics = hir::Generics::empty(); self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; match v.node.disr_expr { Some(ref d) => { @@ -1285,12 +1285,12 @@ impl<'a> State<'a> { -> io::Result<()> { self.print_expr(lhs)?; space(&mut self.s)?; - self.word_space(hir::util::binop_to_string(op.node))?; + self.word_space(op.node.as_str())?; self.print_expr(rhs) } fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) -> io::Result<()> { - word(&mut self.s, hir::util::unop_to_string(op))?; + word(&mut self.s, op.as_str())?; self.print_expr_maybe_paren(expr) } @@ -1434,7 +1434,7 @@ impl<'a> State<'a> { hir::ExprAssignOp(op, ref lhs, ref rhs) => { self.print_expr(&lhs)?; space(&mut self.s)?; - word(&mut self.s, hir::util::binop_to_string(op.node))?; + word(&mut self.s, op.node.as_str())?; self.word_space("=")?; self.print_expr(&rhs)?; } diff --git a/src/librustc/hir/util.rs b/src/librustc/hir/util.rs deleted file mode 100644 index 7745c320e76..00000000000 --- a/src/librustc/hir/util.rs +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use hir; -use hir::*; -use hir::intravisit::{Visitor, FnKind}; -use syntax::ast_util; -use syntax::ast::{Name, NodeId, DUMMY_NODE_ID}; -use syntax::codemap::Span; -use syntax::ptr::P; - -pub fn walk_pat(pat: &Pat, mut it: F) -> bool - where F: FnMut(&Pat) -> bool -{ - // FIXME(#19596) this is a workaround, but there should be a better way - fn walk_pat_(pat: &Pat, it: &mut G) -> bool - where G: FnMut(&Pat) -> bool - { - if !it(pat) { - return false; - } - - match pat.node { - PatKind::Ident(_, _, Some(ref p)) => walk_pat_(&p, it), - PatKind::Struct(_, ref fields, _) => { - fields.iter().all(|field| walk_pat_(&field.node.pat, it)) - } - PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { - s.iter().all(|p| walk_pat_(&p, it)) - } - PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { - walk_pat_(&s, it) - } - PatKind::Vec(ref before, ref slice, ref after) => { - before.iter().all(|p| walk_pat_(&p, it)) && - slice.iter().all(|p| walk_pat_(&p, it)) && - after.iter().all(|p| walk_pat_(&p, it)) - } - PatKind::Wild | - PatKind::Lit(_) | - PatKind::Range(_, _) | - PatKind::Ident(_, _, _) | - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::QPath(_, _) => { - true - } - } - } - - walk_pat_(pat, &mut it) -} - -pub fn binop_to_string(op: BinOp_) -> &'static str { - match op { - BiAdd => "+", - BiSub => "-", - BiMul => "*", - BiDiv => "/", - BiRem => "%", - BiAnd => "&&", - BiOr => "||", - BiBitXor => "^", - BiBitAnd => "&", - BiBitOr => "|", - BiShl => "<<", - BiShr => ">>", - BiEq => "==", - BiLt => "<", - BiLe => "<=", - BiNe => "!=", - BiGe => ">=", - BiGt => ">", - } -} - -pub fn stmt_id(s: &Stmt) -> NodeId { - match s.node { - StmtDecl(_, id) => id, - StmtExpr(_, id) => id, - StmtSemi(_, id) => id, - } -} - -pub fn lazy_binop(b: BinOp_) -> bool { - match b { - BiAnd => true, - BiOr => true, - _ => false, - } -} - -pub fn is_shift_binop(b: BinOp_) -> bool { - match b { - BiShl => true, - BiShr => true, - _ => false, - } -} - -pub fn is_comparison_binop(b: BinOp_) -> bool { - match b { - BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true, - BiAnd | - BiOr | - BiAdd | - BiSub | - BiMul | - BiDiv | - BiRem | - BiBitXor | - BiBitAnd | - BiBitOr | - BiShl | - BiShr => false, - } -} - -/// Returns `true` if the binary operator takes its arguments by value -pub fn is_by_value_binop(b: BinOp_) -> bool { - !is_comparison_binop(b) -} - -/// Returns `true` if the unary operator takes its argument by value -pub fn is_by_value_unop(u: UnOp) -> bool { - match u { - UnNeg | UnNot => true, - _ => false, - } -} - -pub fn unop_to_string(op: UnOp) -> &'static str { - match op { - UnDeref => "*", - UnNot => "!", - UnNeg => "-", - } -} - -pub struct IdVisitor<'a, O: 'a> { - operation: &'a mut O, - - // In general, the id visitor visits the contents of an item, but - // not including nested trait/impl items, nor other nested items. - // The base visitor itself always skips nested items, but not - // trait/impl items. This means in particular that if you start by - // visiting a trait or an impl, you should not visit the - // trait/impl items respectively. This is handled by setting - // `skip_members` to true when `visit_item` is on the stack. This - // way, if the user begins by calling `visit_trait_item`, we will - // visit the trait item, but if they begin with `visit_item`, we - // won't visit the (nested) trait items. - skip_members: bool, -} - -impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { - pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { - IdVisitor { operation: operation, skip_members: false } - } - - fn visit_generics_helper(&mut self, generics: &Generics) { - for type_parameter in generics.ty_params.iter() { - self.operation.visit_id(type_parameter.id) - } - for lifetime in &generics.lifetimes { - self.operation.visit_id(lifetime.lifetime.id) - } - } -} - -impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { - fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { - self.operation.visit_id(node_id); - intravisit::walk_mod(self, module) - } - - fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.operation.visit_id(foreign_item.id); - intravisit::walk_foreign_item(self, foreign_item) - } - - fn visit_item(&mut self, item: &Item) { - assert!(!self.skip_members); - self.skip_members = true; - - self.operation.visit_id(item.id); - match item.node { - ItemUse(ref view_path) => { - match view_path.node { - ViewPathSimple(_, _) | - ViewPathGlob(_) => {} - ViewPathList(_, ref paths) => { - for path in paths { - self.operation.visit_id(path.node.id()) - } - } - } - } - _ => {} - } - intravisit::walk_item(self, item); - - self.skip_members = false; - } - - fn visit_local(&mut self, local: &Local) { - self.operation.visit_id(local.id); - intravisit::walk_local(self, local) - } - - fn visit_block(&mut self, block: &Block) { - self.operation.visit_id(block.id); - intravisit::walk_block(self, block) - } - - fn visit_stmt(&mut self, statement: &Stmt) { - self.operation.visit_id(stmt_id(statement)); - intravisit::walk_stmt(self, statement) - } - - fn visit_pat(&mut self, pattern: &Pat) { - self.operation.visit_id(pattern.id); - intravisit::walk_pat(self, pattern) - } - - fn visit_expr(&mut self, expression: &Expr) { - self.operation.visit_id(expression.id); - intravisit::walk_expr(self, expression) - } - - fn visit_ty(&mut self, typ: &Ty) { - self.operation.visit_id(typ.id); - intravisit::walk_ty(self, typ) - } - - fn visit_generics(&mut self, generics: &Generics) { - self.visit_generics_helper(generics); - intravisit::walk_generics(self, generics) - } - - fn visit_fn(&mut self, - function_kind: FnKind<'v>, - function_declaration: &'v FnDecl, - block: &'v Block, - span: Span, - node_id: NodeId) { - self.operation.visit_id(node_id); - - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { - self.visit_generics_helper(generics) - } - FnKind::Method(_, sig, _, _) => { - self.visit_generics_helper(&sig.generics) - } - FnKind::Closure(_) => {} - } - - for argument in &function_declaration.inputs { - self.operation.visit_id(argument.id) - } - - intravisit::walk_fn(self, function_kind, function_declaration, block, span); - } - - fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.id); - intravisit::walk_struct_field(self, struct_field) - } - - fn visit_variant_data(&mut self, - struct_def: &VariantData, - _: Name, - _: &hir::Generics, - _: NodeId, - _: Span) { - self.operation.visit_id(struct_def.id()); - intravisit::walk_struct_def(self, struct_def); - } - - fn visit_trait_item(&mut self, ti: &hir::TraitItem) { - if !self.skip_members { - self.operation.visit_id(ti.id); - intravisit::walk_trait_item(self, ti); - } - } - - fn visit_impl_item(&mut self, ii: &hir::ImplItem) { - if !self.skip_members { - self.operation.visit_id(ii.id); - intravisit::walk_impl_item(self, ii); - } - } - - fn visit_lifetime(&mut self, lifetime: &Lifetime) { - self.operation.visit_id(lifetime.id); - } - - fn visit_lifetime_def(&mut self, def: &LifetimeDef) { - self.visit_lifetime(&def.lifetime); - } - - fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { - self.operation.visit_id(trait_ref.ref_id); - intravisit::walk_trait_ref(self, trait_ref); - } -} - -/// Computes the id range for a single fn body, ignoring nested items. -pub fn compute_id_range_for_fn_body(fk: FnKind, - decl: &FnDecl, - body: &Block, - sp: Span, - id: NodeId) - -> ast_util::IdRange { - let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; - let mut id_visitor = IdVisitor::new(&mut visitor); - id_visitor.visit_fn(fk, decl, body, sp, id); - id_visitor.operation.result -} - -pub fn is_path(e: P) -> bool { - match e.node { - ExprPath(..) => true, - _ => false, - } -} - -pub fn empty_generics() -> Generics { - Generics { - lifetimes: HirVec::new(), - ty_params: HirVec::new(), - where_clause: WhereClause { - id: DUMMY_NODE_ID, - predicates: HirVec::new(), - }, - } -} - -// convert a span and an identifier to the corresponding -// 1-segment path -pub fn ident_to_path(s: Span, ident: Ident) -> Path { - hir::Path { - span: s, - global: false, - segments: hir_vec![hir::PathSegment { - identifier: ident, - parameters: hir::AngleBracketedParameters(hir::AngleBracketedParameterData { - lifetimes: HirVec::new(), - types: HirVec::new(), - bindings: HirVec::new(), - }), - }], - } -} diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 83244352769..18c82201924 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -47,8 +47,8 @@ use syntax::parse::token::InternedString; use syntax::ast; use syntax::attr::ThinAttributesExt; use hir; -use hir::util; use hir::intravisit as hir_visit; +use hir::intravisit::IdVisitor; use syntax::visit as ast_visit; /// Information about the registered lints. @@ -685,9 +685,9 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> { } fn visit_ids(&mut self, f: F) - where F: FnOnce(&mut util::IdVisitor) + where F: FnOnce(&mut IdVisitor) { - let mut v = util::IdVisitor::new(self); + let mut v = IdVisitor::new(self); f(&mut v); } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 59a3ab44645..3ac2c384134 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -45,8 +45,7 @@ use syntax::ptr::P; use syntax::parse::token::InternedString; use rustc_back::target::Target; use hir; -use hir::intravisit::Visitor; -use hir::util::IdVisitor; +use hir::intravisit::{IdVisitor, Visitor}; pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 47ec7ab5ff0..1b967377304 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -479,7 +479,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } hir::ExprUnary(op, ref lhs) => { - let pass_args = if hir::util::is_by_value_unop(op) { + let pass_args = if op.is_by_value() { PassArgs::ByValue } else { PassArgs::ByRef @@ -491,7 +491,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { } hir::ExprBinary(op, ref lhs, ref rhs) => { - let pass_args = if hir::util::is_by_value_binop(op.node) { + let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { PassArgs::ByRef @@ -524,7 +524,7 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { hir::ExprAssignOp(op, ref lhs, ref rhs) => { // NB All our assignment operations take the RHS by value - assert!(hir::util::is_by_value_binop(op.node)); + assert!(op.node.is_by_value()); if !self.walk_overloaded_operator(expr, lhs, vec![rhs], PassArgs::ByValue) { self.mutate_expr(expr, &lhs, MutateMode::WriteAndRead); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 8d429ff2384..72d3c9414a4 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -484,7 +484,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); } - hir::ExprBinary(op, _, _) if hir::util::lazy_binop(op.node) => { + hir::ExprBinary(op, _, _) if op.node.is_lazy() => { ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); intravisit::walk_expr(ir, expr); } @@ -1142,7 +1142,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.propagate_through_exprs(&exprs[..], succ) } - hir::ExprBinary(op, ref l, ref r) if hir::util::lazy_binop(op.node) => { + hir::ExprBinary(op, ref l, ref r) if op.node.is_lazy() => { let r_succ = self.propagate_through_expr(&r, succ); let ln = self.live_node(expr.id, expr.span); diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs index 3cd69603b5b..3c60d544228 100644 --- a/src/librustc/middle/pat_util.rs +++ b/src/librustc/middle/pat_util.rs @@ -15,7 +15,6 @@ use util::nodemap::FnvHashMap; use syntax::ast; use hir::{self, PatKind}; -use hir::util::walk_pat; use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; use std::cell::RefCell; @@ -115,7 +114,7 @@ pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { pub fn pat_bindings(dm: &RefCell, pat: &hir::Pat, mut it: I) where I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), { - walk_pat(pat, |p| { + pat.walk(|p| { match p.node { PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { it(binding_mode, p.id, p.span, &respan(pth.span, pth.node.name)); @@ -128,7 +127,7 @@ pub fn pat_bindings(dm: &RefCell, pat: &hir::Pat, mut it: I) where pub fn pat_bindings_ident(dm: &RefCell, pat: &hir::Pat, mut it: I) where I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), { - walk_pat(pat, |p| { + pat.walk(|p| { match p.node { PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { it(binding_mode, p.id, p.span, &respan(pth.span, pth.node)); @@ -143,7 +142,7 @@ pub fn pat_bindings_ident(dm: &RefCell, pat: &hir::Pat, mut it: I) wh /// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool { let mut contains_bindings = false; - walk_pat(pat, |p| { + pat.walk(|p| { if pat_is_binding(dm, p) { contains_bindings = true; false // there's at least one binding, can short circuit now. @@ -188,7 +187,7 @@ pub fn arm_contains_ref_binding(dm: &RefCell, arm: &hir::Arm) -> Option< /// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`, pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { let mut contains_bindings = false; - walk_pat(pat, |p| { + pat.walk(|p| { if pat_is_binding_or_wild(dm, p) { contains_bindings = true; false // there's at least one binding/wildcard, can short circuit now. @@ -224,7 +223,7 @@ pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path { /// Return variants that are necessary to exist for the pattern to match. pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { let mut variants = vec![]; - walk_pat(pat, |p| { + pat.walk(|p| { match p.node { PatKind::TupleStruct(..) | PatKind::Path(..) | diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 99ebf5ccb84..f8c0b63bf11 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -33,7 +33,6 @@ use syntax::ast::{self, NodeId}; use hir; use hir::intravisit::{self, Visitor, FnKind}; use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local}; -use hir::util::stmt_id; #[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable, RustcDecodable, Copy)] @@ -765,7 +764,7 @@ fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &hir::Pat) { } fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &hir::Stmt) { - let stmt_id = stmt_id(stmt); + let stmt_id = stmt.node.id(); debug!("resolve_stmt(stmt.id={:?})", stmt_id); // Every statement will clean up the temporaries created during diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index fec327f4aa0..789d7dd9fef 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -48,7 +48,6 @@ use rustc::hir; use rustc::hir::{FnDecl, Block}; use rustc::hir::intravisit; use rustc::hir::intravisit::{Visitor, FnKind}; -use rustc::hir::util as hir_util; use rustc::mir::mir_map::MirMap; @@ -210,7 +209,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, { // Check the body of fn items. let tcx = this.tcx; - let id_range = hir_util::compute_id_range_for_fn_body(fk, decl, body, sp, id); + let id_range = intravisit::compute_id_range_for_fn_body(fk, decl, body, sp, id); let (all_loans, move_data) = gather_loans::gather_loans_in_fn(this, id, decl, body); diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 70781184f74..d290652576d 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -34,8 +34,7 @@ use std::iter::{FromIterator, IntoIterator, repeat}; use rustc::hir; use rustc::hir::{Pat, PatKind}; -use rustc::hir::intravisit::{self, Visitor, FnKind}; -use rustc::hir::util as front_util; +use rustc::hir::intravisit::{self, IdVisitor, Visitor, FnKind}; use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; @@ -241,7 +240,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) { } fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) { - front_util::walk_pat(pat, |p| { + pat.walk(|p| { match p.node { PatKind::Ident(hir::BindByValue(hir::MutImmutable), ident, None) => { let pat_ty = cx.tcx.pat_ty(p); @@ -274,7 +273,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) // Check that we do not match against a static NaN (#6804) fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) { - front_util::walk_pat(pat, |p| { + pat.walk(|p| { if let PatKind::Lit(ref expr) = p.node { match eval_const_expr_partial(cx.tcx, &expr, ExprTypeChecked, None) { Ok(ConstVal::Float(f)) if f.is_nan() => { @@ -518,7 +517,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { renaming_map: renaming_map, }; - let mut id_visitor = front_util::IdVisitor::new(&mut renaming_recorder); + let mut id_visitor = IdVisitor::new(&mut renaming_recorder); id_visitor.visit_expr(const_expr); } @@ -1100,7 +1099,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt, }; for pat in pats { - front_util::walk_pat(&pat, |p| { + pat.walk(|p| { if pat_is_binding(&def_map.borrow(), &p) { match p.node { PatKind::Ident(hir::BindByValue(_), _, ref sub) => { diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index b094bca8410..574c7af4cfc 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -30,7 +30,6 @@ use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{self, Span}; use rustc::hir; -use rustc::hir::util::is_shift_binop; register_long_diagnostics! { E0519: r##" @@ -130,7 +129,7 @@ impl LateLintPass for TypeLimits { "comparison is useless due to type limits"); } - if is_shift_binop(binop.node) { + if binop.node.is_shift() { let opt_ty_bits = match cx.tcx.node_id_to_type(l.id).sty { ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)), ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)), diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 475ae459fef..790833f99ca 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -23,7 +23,6 @@ use rustc::middle::pat_util; use rustc::ty::{self, VariantDef, Ty}; use rustc::mir::repr::*; use rustc::hir; -use rustc::hir::util as hir_util; use syntax::ptr::P; impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { @@ -150,7 +149,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { hir::ExprAssignOp(op, ref lhs, ref rhs) => { if cx.tcx.is_method_call(self.id) { - let pass_args = if hir_util::is_by_value_binop(op.node) { + let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { PassArgs::ByRef @@ -172,7 +171,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr { hir::ExprBinary(op, ref lhs, ref rhs) => { if cx.tcx.is_method_call(self.id) { - let pass_args = if hir_util::is_by_value_binop(op.node) { + let pass_args = if op.node.is_by_value() { PassArgs::ByValue } else { PassArgs::ByRef diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index bbf8796436e..c0b8aad1c09 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -84,7 +84,6 @@ use rustc::hir::{PathSegment, PathParameters}; use rustc::hir::HirVec; use rustc::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt}; use rustc::hir::{TyRptr, TyStr, TyUint, TyPath, TyPtr}; -use rustc::hir::util::walk_pat; use std::collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; @@ -2244,7 +2243,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // pattern that binds them bindings_list: &mut HashMap) { let pat_id = pattern.id; - walk_pat(pattern, |pattern| { + pattern.walk(|pattern| { match pattern.node { PatKind::Ident(binding_mode, ref path1, ref at_rhs) => { // The meaning of PatKind::Ident with no type parameters diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index d2fc20fd837..6714f6440ee 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -712,7 +712,7 @@ fn cast_shift_rhs(op: hir::BinOp_, G: FnOnce(ValueRef, Type) -> ValueRef { // Shifts may have any size int on the rhs - if hir::util::is_shift_binop(op) { + if op.is_shift() { let mut rhs_llty = val_ty(rhs); let mut lhs_llty = val_ty(lhs); if rhs_llty.kind() == Vector { diff --git a/src/librustc_trans/controlflow.rs b/src/librustc_trans/controlflow.rs index 60ae91a8c5f..f3cb4d5001a 100644 --- a/src/librustc_trans/controlflow.rs +++ b/src/librustc_trans/controlflow.rs @@ -26,7 +26,6 @@ use expr; use machine; use rustc::hir; -use rustc::hir::util as ast_util; use syntax::ast; use syntax::parse::token::InternedString; @@ -49,7 +48,7 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>, let mut bcx = cx; - let id = ast_util::stmt_id(s); + let id = s.node.id(); let cleanup_debug_loc = debuginfo::get_cleanup_debug_loc_for_ast_node(bcx.ccx(), id, s.span, false); fcx.push_ast_cleanup_scope(cleanup_debug_loc); @@ -70,7 +69,7 @@ pub fn trans_stmt<'blk, 'tcx>(cx: Block<'blk, 'tcx>, } } - bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, ast_util::stmt_id(s)); + bcx = fcx.pop_and_trans_ast_cleanup_scope(bcx, s.node.id()); return bcx; } diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index 477dc0b4b52..b98b9881350 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -116,7 +116,7 @@ fn walk_block(cx: &CrateContext, // The interesting things here are statements and the concluding expression. for statement in &block.stmts { - scope_map.insert(hir::util::stmt_id(statement), + scope_map.insert(statement.node.id(), scope_stack.last().unwrap().scope_metadata); match statement.node { diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index f671c2b7963..7e9c8228f29 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -238,7 +238,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, return FunctionDebugContext::FunctionWithoutDebugInfo; } - let empty_generics = hir::util::empty_generics(); + let empty_generics = hir::Generics::empty(); let fnitem = cx.tcx().map.get(fn_ast_id); diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index 7c2557fb090..fce8656fb93 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -1180,7 +1180,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // if not overloaded, would be RvalueDatumExpr let lhs = unpack_datum!(bcx, trans(bcx, &lhs)); let mut rhs = unpack_datum!(bcx, trans(bcx, &rhs_expr)); - if !hir::util::is_by_value_binop(op.node) { + if !op.node.is_by_value() { rhs = unpack_datum!(bcx, auto_ref(bcx, rhs, rhs_expr)); } @@ -1204,7 +1204,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, span_bug!( expr.span, "augmented assignment `{}=` should always be a rvalue_stmt", - hir::util::binop_to_string(op.node)) + op.node.as_str()) } _ => { span_bug!( diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 5c93c170590..eaf8479585f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -32,7 +32,6 @@ use syntax::ptr::P; use rustc::hir::{self, PatKind}; use rustc::hir::print as pprust; -use rustc::hir::util as hir_util; pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat, @@ -197,7 +196,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, } } PatKind::Ident(_, ref path, _) => { - let path = hir_util::ident_to_path(path.span, path.node); + let path = hir::Path::from_ident(path.span, path.node); check_pat_enum(pcx, pat, &path, Some(&[]), expected, false); } PatKind::TupleStruct(ref path, ref subpats) => { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 20b9a75e0e5..c3a42826dbc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3987,7 +3987,7 @@ fn check_block_with_expected<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, let mut any_err = false; for s in &blk.stmts { check_stmt(fcx, s); - let s_id = hir::util::stmt_id(s); + let s_id = s.node.id(); let s_ty = fcx.node_ty(s_id); if any_diverges && !warned && match s.node { hir::StmtDecl(ref decl, _) => { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index 1af015cdebf..f7f40e6077f 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -23,7 +23,6 @@ use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue}; use syntax::ast; use syntax::parse::token; use rustc::hir; -use rustc::hir::util as hir_util; /// Check a `a = b` pub fn check_binop_assign<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>, @@ -184,12 +183,12 @@ fn check_overloaded_binop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, if let IsAssign::Yes = is_assign { span_err!(fcx.tcx().sess, lhs_expr.span, E0368, "binary assignment operation `{}=` cannot be applied to type `{}`", - hir_util::binop_to_string(op.node), + op.node.as_str(), lhs_ty); } else { let mut err = struct_span_err!(fcx.tcx().sess, lhs_expr.span, E0369, "binary operation `{}` cannot be applied to type `{}`", - hir_util::binop_to_string(op.node), + op.node.as_str(), lhs_ty); let missing_trait = match op.node { hir::BiAdd => Some("std::ops::Add"), @@ -235,7 +234,7 @@ pub fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, op: hir::UnOp) -> Ty<'tcx> { - assert!(hir_util::is_by_value_unop(op)); + assert!(op.is_by_value()); match lookup_op_method(fcx, ex, operand_ty, vec![], token::intern(mname), trait_did, operand_expr) { @@ -272,7 +271,7 @@ fn name_and_trait_def_id(fcx: &FnCtxt, hir::BiOr => { span_bug!(op.span, "impossible assignment operation: {}=", - hir_util::binop_to_string(op.node)) + op.node.as_str()) } } } else { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index ed9372acba9..02114c170c4 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -102,7 +102,6 @@ use syntax::ast; use syntax::codemap::Span; use rustc::hir::intravisit::{self, Visitor}; use rustc::hir::{self, PatKind}; -use rustc::hir::util as hir_util; use self::SubjectNode::Subject; @@ -689,7 +688,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { }, hir::ExprBinary(op, ref lhs, ref rhs) if has_method_map => { - let implicitly_ref_args = !hir_util::is_by_value_binop(op.node); + let implicitly_ref_args = !op.node.is_by_value(); // As `expr_method_call`, but the call is via an // overloaded op. Note that we (sadly) currently use an @@ -716,7 +715,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &hir::Expr) { } hir::ExprUnary(op, ref lhs) if has_method_map => { - let implicitly_ref_args = !hir_util::is_by_value_unop(op); + let implicitly_ref_args = !op.is_by_value(); // As above. constrain_call(rcx, expr, Some(&lhs), diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 6ac6f1d6e17..50f2f27b3d2 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -30,7 +30,6 @@ use syntax::ast; use syntax::codemap::{DUMMY_SP, Span}; use rustc::hir::print::pat_to_string; use rustc::hir::intravisit::{self, Visitor}; -use rustc::hir::util as hir_util; use rustc::hir; /////////////////////////////////////////////////////////////////////////// @@ -112,7 +111,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // system. match e.node { hir::ExprBinary(..) => { - if !hir_util::is_by_value_binop(op.node) { + if !op.node.is_by_value() { self.fcx.inh.tables.borrow_mut().adjustments.remove(&lhs.id); } }, @@ -142,7 +141,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> { return; } - self.visit_node_id(ResolvingExpr(s.span), hir_util::stmt_id(s)); + self.visit_node_id(ResolvingExpr(s.span), s.node.id()); intravisit::walk_stmt(self, s); } -- cgit 1.4.1-3-g733a5 From 7bebe80bc28ff818c7990061275fa0ad6c8b3686 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 29 Mar 2016 12:12:01 +0300 Subject: syntax: dismantle ast_util. --- src/librustc/hir/fold.rs | 8 - src/librustc/hir/intravisit.rs | 60 ++++- src/librustc/lint/context.rs | 39 +-- src/librustc/middle/cstore.rs | 3 +- src/librustc/middle/dataflow.rs | 3 +- src/librustc_borrowck/borrowck/move_data.rs | 4 +- src/librustc_const_eval/check_match.rs | 5 +- src/librustc_metadata/astencode.rs | 17 +- src/librustc_save_analysis/lib.rs | 3 +- src/libsyntax/ast.rs | 17 ++ src/libsyntax/ast_util.rs | 398 ---------------------------- src/libsyntax/fold.rs | 8 - src/libsyntax/lib.rs | 1 - src/libsyntax/parse/parser.rs | 20 +- src/libsyntax/test.rs | 16 +- src/libsyntax_ext/deriving/generic/mod.rs | 4 +- 16 files changed, 117 insertions(+), 489 deletions(-) delete mode 100644 src/libsyntax/ast_util.rs (limited to 'src') diff --git a/src/librustc/hir/fold.rs b/src/librustc/hir/fold.rs index e65f2fc37de..a6ff7164885 100644 --- a/src/librustc/hir/fold.rs +++ b/src/librustc/hir/fold.rs @@ -908,14 +908,6 @@ pub fn noop_fold_item(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); - // FIXME: we should update the impl_pretty_name, but it uses pretty printing. - // let ident = match node { - // // The node may have changed, recompute the "pretty" impl name. - // ItemImpl(_, _, _, ref maybe_trait, ref ty, _) => { - // impl_pretty_name(maybe_trait, Some(&**ty)) - // } - // _ => ident - // }; Item { id: id, diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 90fba0c8985..d34d66918ca 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -27,11 +27,13 @@ use syntax::abi::Abi; use syntax::ast::{NodeId, CRATE_NODE_ID, Name, Attribute}; -use syntax::ast_util; use syntax::attr::ThinAttributesExt; use syntax::codemap::Span; use hir::*; +use std::cmp; +use std::u32; + #[derive(Copy, Clone, PartialEq, Eq)] pub enum FnKind<'a> { /// fn foo() or extern "Abi" fn foo() @@ -837,6 +839,54 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm) { walk_list!(visitor, visit_attribute, &arm.attrs); } +#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] +pub struct IdRange { + pub min: NodeId, + pub max: NodeId, +} + +impl IdRange { + pub fn max() -> IdRange { + IdRange { + min: u32::MAX, + max: u32::MIN, + } + } + + pub fn empty(&self) -> bool { + self.min >= self.max + } + + pub fn add(&mut self, id: NodeId) { + self.min = cmp::min(self.min, id); + self.max = cmp::max(self.max, id + 1); + } +} + +pub trait IdVisitingOperation { + fn visit_id(&mut self, node_id: NodeId); +} + +pub struct IdRangeComputingVisitor { + pub result: IdRange, +} + +impl IdRangeComputingVisitor { + pub fn new() -> IdRangeComputingVisitor { + IdRangeComputingVisitor { result: IdRange::max() } + } + + pub fn result(&self) -> IdRange { + self.result + } +} + +impl IdVisitingOperation for IdRangeComputingVisitor { + fn visit_id(&mut self, id: NodeId) { + self.result.add(id); + } +} + pub struct IdVisitor<'a, O: 'a> { operation: &'a mut O, @@ -853,7 +903,7 @@ pub struct IdVisitor<'a, O: 'a> { skip_members: bool, } -impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { +impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { pub fn new(operation: &'a mut O) -> IdVisitor<'a, O> { IdVisitor { operation: operation, skip_members: false } } @@ -868,7 +918,7 @@ impl<'a, O: ast_util::IdVisitingOperation> IdVisitor<'a, O> { } } -impl<'a, 'v, O: ast_util::IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { +impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { fn visit_mod(&mut self, module: &Mod, _: Span, node_id: NodeId) { self.operation.visit_id(node_id); walk_mod(self, module) @@ -1012,8 +1062,8 @@ pub fn compute_id_range_for_fn_body(fk: FnKind, body: &Block, sp: Span, id: NodeId) - -> ast_util::IdRange { - let mut visitor = ast_util::IdRangeComputingVisitor { result: ast_util::IdRange::max() }; + -> IdRange { + let mut visitor = IdRangeComputingVisitor { result: IdRange::max() }; let mut id_visitor = IdVisitor::new(&mut visitor); id_visitor.visit_fn(fk, decl, body, sp, id); id_visitor.operation.result diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 18c82201924..fd45f58327f 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -39,7 +39,6 @@ use std::cell::RefCell; use std::cmp; use std::default::Default as StdDefault; use std::mem; -use syntax::ast_util::{self, IdVisitingOperation}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; @@ -48,7 +47,7 @@ use syntax::ast; use syntax::attr::ThinAttributesExt; use hir; use hir::intravisit as hir_visit; -use hir::intravisit::IdVisitor; +use hir::intravisit::{IdVisitor, IdVisitingOperation}; use syntax::visit as ast_visit; /// Information about the registered lints. @@ -654,16 +653,6 @@ impl<'a> EarlyContext<'a> { level_stack: vec![], } } - - fn visit_ids(&mut self, f: F) - where F: FnOnce(&mut ast_util::IdVisitor) - { - let mut v = ast_util::IdVisitor { - operation: self, - visited_outermost: false, - }; - f(&mut v); - } } impl<'a, 'tcx> LateContext<'a, 'tcx> { @@ -928,7 +917,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> { fn visit_item(&mut self, it: &ast::Item) { self.with_lint_attrs(&it.attrs, |cx| { run_lints!(cx, check_item, early_passes, it); - cx.visit_ids(|v| v.visit_item(it)); ast_visit::walk_item(cx, it); run_lints!(cx, check_item_post, early_passes, it); }) @@ -1042,7 +1030,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> { fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) { self.with_lint_attrs(&trait_item.attrs, |cx| { run_lints!(cx, check_trait_item, early_passes, trait_item); - cx.visit_ids(|v| v.visit_trait_item(trait_item)); ast_visit::walk_trait_item(cx, trait_item); run_lints!(cx, check_trait_item_post, early_passes, trait_item); }); @@ -1051,7 +1038,6 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> { fn visit_impl_item(&mut self, impl_item: &ast::ImplItem) { self.with_lint_attrs(&impl_item.attrs, |cx| { run_lints!(cx, check_impl_item, early_passes, impl_item); - cx.visit_ids(|v| v.visit_impl_item(impl_item)); ast_visit::walk_impl_item(cx, impl_item); run_lints!(cx, check_impl_item_post, early_passes, impl_item); }); @@ -1099,18 +1085,6 @@ impl<'a, 'tcx> IdVisitingOperation for LateContext<'a, 'tcx> { } } } -impl<'a> IdVisitingOperation for EarlyContext<'a> { - fn visit_id(&mut self, id: ast::NodeId) { - match self.sess.lints.borrow_mut().remove(&id) { - None => {} - Some(lints) => { - for (lint_id, span, msg) in lints { - self.span_lint(lint_id.lint, span, &msg[..]) - } - } - } - } -} // This lint pass is defined here because it touches parts of the `LateContext` // that we don't want to expose. It records the lint level at certain AST @@ -1292,11 +1266,12 @@ pub fn check_ast_crate(sess: &Session, krate: &ast::Crate) { // Visit the whole crate. cx.with_lint_attrs(&krate.attrs, |cx| { - cx.visit_id(ast::CRATE_NODE_ID); - cx.visit_ids(|v| { - v.visited_outermost = true; - ast_visit::walk_crate(v, krate); - }); + // Lints may be assigned to the whole crate. + if let Some(lints) = cx.sess.lints.borrow_mut().remove(&ast::CRATE_NODE_ID) { + for (lint_id, span, msg) in lints { + cx.span_lint(lint_id.lint, span, &msg[..]) + } + } // since the root module isn't visited as an item (because it isn't an // item), warn for it here. diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 3ac2c384134..a7f415ef2a0 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -38,14 +38,13 @@ use std::cell::RefCell; use std::rc::Rc; use std::path::PathBuf; use syntax::ast; -use syntax::ast_util::{IdVisitingOperation}; use syntax::attr; use syntax::codemap::Span; use syntax::ptr::P; use syntax::parse::token::InternedString; use rustc_back::target::Target; use hir; -use hir::intravisit::{IdVisitor, Visitor}; +use hir::intravisit::{IdVisitor, IdVisitingOperation, Visitor}; pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index 99b512141a4..1aaaa4bcd77 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -21,12 +21,11 @@ use std::io; use std::mem; use std::usize; use syntax::ast; -use syntax::ast_util::IdRange; use syntax::print::pp; use syntax::print::pprust::PrintState; use util::nodemap::NodeMap; use hir; -use hir::intravisit; +use hir::intravisit::{self, IdRange}; use hir::print as pprust; diff --git a/src/librustc_borrowck/borrowck/move_data.rs b/src/librustc_borrowck/borrowck/move_data.rs index 292cfcfeac1..80e408e9a6e 100644 --- a/src/librustc_borrowck/borrowck/move_data.rs +++ b/src/librustc_borrowck/borrowck/move_data.rs @@ -28,9 +28,9 @@ use std::cell::RefCell; use std::rc::Rc; use std::usize; use syntax::ast; -use syntax::ast_util; use syntax::codemap::Span; use rustc::hir; +use rustc::hir::intravisit::IdRange; #[path="fragments.rs"] pub mod fragments; @@ -602,7 +602,7 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> { pub fn new(move_data: MoveData<'tcx>, tcx: &'a TyCtxt<'tcx>, cfg: &cfg::CFG, - id_range: ast_util::IdRange, + id_range: IdRange, decl: &hir::FnDecl, body: &hir::Block) -> FlowedMoveData<'a, 'tcx> { diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index d290652576d..797580319b2 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -34,11 +34,10 @@ use std::iter::{FromIterator, IntoIterator, repeat}; use rustc::hir; use rustc::hir::{Pat, PatKind}; -use rustc::hir::intravisit::{self, IdVisitor, Visitor, FnKind}; +use rustc::hir::intravisit::{self, IdVisitor, IdVisitingOperation, Visitor, FnKind}; use rustc_back::slice; use syntax::ast::{self, DUMMY_NODE_ID, NodeId}; -use syntax::ast_util; use syntax::codemap::{Span, Spanned, DUMMY_SP}; use rustc::hir::fold::{Folder, noop_fold_pat}; use rustc::hir::print::pat_to_string; @@ -460,7 +459,7 @@ struct RenamingRecorder<'map> { renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId> } -impl<'map> ast_util::IdVisitingOperation for RenamingRecorder<'map> { +impl<'map> IdVisitingOperation 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); diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 98e73f2902b..61f35a12df7 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,6 +18,7 @@ use rustc::session::Session; use rustc::hir; use rustc::hir::fold; use rustc::hir::fold::Folder; +use rustc::hir::intravisit::{IdRange, IdRangeComputingVisitor, IdVisitingOperation}; use common as c; use cstore; @@ -36,7 +37,7 @@ use middle::region; use rustc::ty::subst; use rustc::ty::{self, Ty, TyCtxt}; -use syntax::{ast, ast_util, codemap}; +use syntax::{ast, codemap}; use syntax::ast::NodeIdAssigner; use syntax::ptr::P; @@ -61,8 +62,8 @@ use serialize::EncoderHelpers; struct DecodeContext<'a, 'b, 'tcx: 'a> { tcx: &'a TyCtxt<'tcx>, cdata: &'b cstore::crate_metadata, - from_id_range: ast_util::IdRange, - to_id_range: ast_util::IdRange, + from_id_range: IdRange, + to_id_range: IdRange, // Cache the last used filemap for translating spans as an optimization. last_filemap_index: Cell, } @@ -178,13 +179,13 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, // Enumerating the IDs which appear in an AST fn reserve_id_range(sess: &Session, - from_id_range: ast_util::IdRange) -> ast_util::IdRange { + from_id_range: IdRange) -> IdRange { // Handle the case of an empty range: if from_id_range.empty() { return from_id_range; } let cnt = from_id_range.max - from_id_range.min; let to_id_min = sess.reserve_node_ids(cnt); let to_id_max = to_id_min + cnt; - ast_util::IdRange { min: to_id_min, max: to_id_max } + IdRange { min: to_id_min, max: to_id_max } } impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> { @@ -705,7 +706,7 @@ struct SideTableEncodingIdVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w: &'a mut Encoder<'b>, } -impl<'a, 'b, 'c, 'tcx> ast_util::IdVisitingOperation for +impl<'a, 'b, 'c, 'tcx> IdVisitingOperation for SideTableEncodingIdVisitor<'a, 'b, 'c, 'tcx> { fn visit_id(&mut self, id: ast::NodeId) { encode_side_tables_for_id(self.ecx, self.rbml_w, id) @@ -1261,8 +1262,8 @@ fn copy_item_types(dcx: &DecodeContext, ii: &InlinedItem, orig_did: DefId) { } } -fn inlined_item_id_range(v: &InlinedItem) -> ast_util::IdRange { - let mut visitor = ast_util::IdRangeComputingVisitor::new(); +fn inlined_item_id_range(v: &InlinedItem) -> IdRange { + let mut visitor = IdRangeComputingVisitor::new(); v.visit_ids(&mut visitor); visitor.result() } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index e65bf5be256..a4f9720bbe2 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -39,7 +39,6 @@ use std::fs::{self, File}; use std::path::{Path, PathBuf}; use syntax::ast::{self, NodeId, PatKind}; -use syntax::ast_util; use syntax::codemap::*; use syntax::parse::token::{self, keywords}; use syntax::visit::{self, Visitor}; @@ -670,7 +669,7 @@ impl<'v> Visitor<'v> for PathCollector { ast::BindingMode::ByValue(mt) => mt, }; // collect path for either visit_local or visit_arm - let path = ast_util::ident_to_path(path1.span, path1.node); + let path = ast::Path::from_ident(path1.span, path1.node); self.collected_paths.push((p.id, path, immut, recorder::VarRef)); } _ => {} diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a441f2990cd..370dd0dad72 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -205,6 +205,23 @@ impl fmt::Display for Path { } } +impl Path { + // convert a span and an identifier to the corresponding + // 1-segment path + pub fn from_ident(s: Span, identifier: Ident) -> Path { + Path { + span: s, + global: false, + segments: vec!( + PathSegment { + identifier: identifier, + parameters: PathParameters::none() + } + ), + } + } +} + /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs deleted file mode 100644 index 852b153044f..00000000000 --- a/src/libsyntax/ast_util.rs +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright 2012-2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast::*; -use ast; -use codemap; -use codemap::Span; -use parse::token; -use print::pprust; -use ptr::P; -use visit::{FnKind, Visitor}; -use visit; - -use std::cmp; -use std::u32; - -pub fn path_name_i(idents: &[Ident]) -> String { - // FIXME: Bad copies (#2543 -- same for everything else that says "bad") - idents.iter().map(|i| i.to_string()).collect::>().join("::") -} - -pub fn is_path(e: P) -> bool { - match e.node { ExprKind::Path(..) => true, _ => false } -} - - -// convert a span and an identifier to the corresponding -// 1-segment path -pub fn ident_to_path(s: Span, identifier: Ident) -> Path { - ast::Path { - span: s, - global: false, - segments: vec!( - ast::PathSegment { - identifier: identifier, - parameters: ast::PathParameters::AngleBracketed(ast::AngleBracketedParameterData { - lifetimes: Vec::new(), - types: P::empty(), - bindings: P::empty(), - }) - } - ), - } -} - -// If path is a single segment ident path, return that ident. Otherwise, return -// None. -pub fn path_to_ident(path: &Path) -> Option { - if path.segments.len() != 1 { - return None; - } - - let segment = &path.segments[0]; - if !segment.parameters.is_empty() { - return None; - } - - Some(segment.identifier) -} - -pub fn ident_to_pat(id: NodeId, s: Span, i: Ident) -> P { - let spanned = codemap::Spanned{ span: s, node: i }; - P(Pat { - id: id, - node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), spanned, None), - span: s - }) -} - -/// Generate a "pretty" name for an `impl` from its type and trait. -/// This is designed so that symbols of `impl`'d methods give some -/// hint of where they came from, (previously they would all just be -/// listed as `__extensions__::method_name::hash`, with no indication -/// of the type). -pub fn impl_pretty_name(trait_ref: &Option, ty: Option<&Ty>) -> Ident { - let mut pretty = match ty { - Some(t) => pprust::ty_to_string(t), - None => String::from("..") - }; - - match *trait_ref { - Some(ref trait_ref) => { - pretty.push('.'); - pretty.push_str(&pprust::path_to_string(&trait_ref.path)); - } - None => {} - } - token::gensym_ident(&pretty[..]) -} - -pub fn struct_field_visibility(field: ast::StructField) -> Visibility { - match field.node.kind { - ast::NamedField(_, v) | ast::UnnamedField(v) => v - } -} - -// ______________________________________________________________________ -// Enumerating the IDs which appear in an AST - -#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct IdRange { - pub min: NodeId, - pub max: NodeId, -} - -impl IdRange { - pub fn max() -> IdRange { - IdRange { - min: u32::MAX, - max: u32::MIN, - } - } - - pub fn empty(&self) -> bool { - self.min >= self.max - } - - pub fn add(&mut self, id: NodeId) { - self.min = cmp::min(self.min, id); - self.max = cmp::max(self.max, id + 1); - } -} - -pub trait IdVisitingOperation { - fn visit_id(&mut self, node_id: NodeId); -} - -/// A visitor that applies its operation to all of the node IDs -/// in a visitable thing. - -pub struct IdVisitor<'a, O:'a> { - pub operation: &'a mut O, - pub visited_outermost: bool, -} - -impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> { - fn visit_generics_helper(&mut self, generics: &Generics) { - for type_parameter in generics.ty_params.iter() { - self.operation.visit_id(type_parameter.id) - } - for lifetime in &generics.lifetimes { - self.operation.visit_id(lifetime.lifetime.id) - } - } -} - -impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { - fn visit_mod(&mut self, - module: &Mod, - _: Span, - node_id: NodeId) { - self.operation.visit_id(node_id); - visit::walk_mod(self, module) - } - - fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { - self.operation.visit_id(foreign_item.id); - visit::walk_foreign_item(self, foreign_item) - } - - fn visit_item(&mut self, item: &Item) { - if self.visited_outermost { - return - } else { - self.visited_outermost = true - } - - self.operation.visit_id(item.id); - match item.node { - ItemKind::Use(ref view_path) => { - match view_path.node { - ViewPathSimple(_, _) | - ViewPathGlob(_) => {} - ViewPathList(_, ref paths) => { - for path in paths { - self.operation.visit_id(path.node.id()) - } - } - } - } - _ => {} - } - - visit::walk_item(self, item); - - self.visited_outermost = false - } - - fn visit_local(&mut self, local: &Local) { - self.operation.visit_id(local.id); - visit::walk_local(self, local) - } - - fn visit_block(&mut self, block: &Block) { - self.operation.visit_id(block.id); - visit::walk_block(self, block) - } - - fn visit_stmt(&mut self, statement: &Stmt) { - self.operation - .visit_id(statement.node.id().expect("attempted to visit unexpanded stmt")); - visit::walk_stmt(self, statement) - } - - fn visit_pat(&mut self, pattern: &Pat) { - self.operation.visit_id(pattern.id); - visit::walk_pat(self, pattern) - } - - fn visit_expr(&mut self, expression: &Expr) { - self.operation.visit_id(expression.id); - visit::walk_expr(self, expression) - } - - fn visit_ty(&mut self, typ: &Ty) { - self.operation.visit_id(typ.id); - visit::walk_ty(self, typ) - } - - fn visit_generics(&mut self, generics: &Generics) { - self.visit_generics_helper(generics); - visit::walk_generics(self, generics) - } - - fn visit_fn(&mut self, - function_kind: visit::FnKind<'v>, - function_declaration: &'v FnDecl, - block: &'v Block, - span: Span, - node_id: NodeId) { - match function_kind { - FnKind::Method(..) if self.visited_outermost => return, - FnKind::Method(..) => self.visited_outermost = true, - _ => {} - } - - self.operation.visit_id(node_id); - - match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _) => { - self.visit_generics_helper(generics) - } - FnKind::Method(_, ref sig, _) => { - self.visit_generics_helper(&sig.generics) - } - FnKind::Closure => {} - } - - for argument in &function_declaration.inputs { - self.operation.visit_id(argument.id) - } - - visit::walk_fn(self, - function_kind, - function_declaration, - block, - span); - - if let FnKind::Method(..) = function_kind { - self.visited_outermost = false; - } - } - - fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.node.id); - visit::walk_struct_field(self, struct_field) - } - - fn visit_variant_data(&mut self, - struct_def: &VariantData, - _: ast::Ident, - _: &ast::Generics, - _: NodeId, - _: Span) { - self.operation.visit_id(struct_def.id()); - visit::walk_struct_def(self, struct_def); - } - - fn visit_trait_item(&mut self, ti: &ast::TraitItem) { - self.operation.visit_id(ti.id); - visit::walk_trait_item(self, ti); - } - - fn visit_impl_item(&mut self, ii: &ast::ImplItem) { - self.operation.visit_id(ii.id); - visit::walk_impl_item(self, ii); - } - - fn visit_lifetime(&mut self, lifetime: &Lifetime) { - self.operation.visit_id(lifetime.id); - } - - fn visit_lifetime_def(&mut self, def: &LifetimeDef) { - self.visit_lifetime(&def.lifetime); - } - - fn visit_trait_ref(&mut self, trait_ref: &TraitRef) { - self.operation.visit_id(trait_ref.ref_id); - visit::walk_trait_ref(self, trait_ref); - } -} - -pub struct IdRangeComputingVisitor { - pub result: IdRange, -} - -impl IdRangeComputingVisitor { - pub fn new() -> IdRangeComputingVisitor { - IdRangeComputingVisitor { result: IdRange::max() } - } - - pub fn result(&self) -> IdRange { - self.result - } -} - -impl IdVisitingOperation for IdRangeComputingVisitor { - fn visit_id(&mut self, id: NodeId) { - self.result.add(id); - } -} - -/// Computes the id range for a single fn body, ignoring nested items. -pub fn compute_id_range_for_fn_body(fk: FnKind, - decl: &FnDecl, - body: &Block, - sp: Span, - id: NodeId) - -> IdRange -{ - let mut visitor = IdRangeComputingVisitor::new(); - let mut id_visitor = IdVisitor { - operation: &mut visitor, - visited_outermost: false, - }; - id_visitor.visit_fn(fk, decl, body, sp, id); - id_visitor.operation.result -} - -/// Returns true if the given pattern consists solely of an identifier -/// and false otherwise. -pub fn pat_is_ident(pat: P) -> bool { - match pat.node { - PatKind::Ident(..) => true, - _ => false, - } -} - -// are two paths equal when compared unhygienically? -// since I'm using this to replace ==, it seems appropriate -// to compare the span, global, etc. fields as well. -pub fn path_name_eq(a : &ast::Path, b : &ast::Path) -> bool { - (a.span.source_equal(&b.span)) - && (a.global == b.global) - && (segments_name_eq(&a.segments[..], &b.segments[..])) -} - -// are two arrays of segments equal when compared unhygienically? -pub fn segments_name_eq(a : &[ast::PathSegment], b : &[ast::PathSegment]) -> bool { - a.len() == b.len() && - a.iter().zip(b).all(|(s, t)| { - s.identifier.name == t.identifier.name && - // FIXME #7743: ident -> name problems in lifetime comparison? - // can types contain idents? - s.parameters == t.parameters - }) -} - -#[cfg(test)] -mod tests { - use ast::*; - use super::*; - - fn ident_to_segment(id: Ident) -> PathSegment { - PathSegment {identifier: id, - parameters: PathParameters::none()} - } - - #[test] fn idents_name_eq_test() { - assert!(segments_name_eq( - &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))] - .iter().cloned().map(ident_to_segment).collect::>(), - &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(78),SyntaxContext(182))] - .iter().cloned().map(ident_to_segment).collect::>())); - assert!(!segments_name_eq( - &[Ident::new(Name(3),SyntaxContext(4)), Ident::new(Name(78),SyntaxContext(82))] - .iter().cloned().map(ident_to_segment).collect::>(), - &[Ident::new(Name(3),SyntaxContext(104)), Ident::new(Name(77),SyntaxContext(182))] - .iter().cloned().map(ident_to_segment).collect::>())); - } -} diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 46bcb8067a3..55eec165517 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -21,7 +21,6 @@ use ast::*; use ast; use attr::{ThinAttributes, ThinAttributesExt}; -use ast_util; use codemap::{respan, Span, Spanned}; use parse::token; use ptr::P; @@ -1073,13 +1072,6 @@ pub fn noop_fold_item_simple(Item {id, ident, attrs, node, vis, span} folder: &mut T) -> Item { let id = folder.new_id(id); let node = folder.fold_item_kind(node); - let ident = match node { - // The node may have changed, recompute the "pretty" impl name. - ItemKind::Impl(_, _, _, ref maybe_trait, ref ty, _) => { - ast_util::impl_pretty_name(maybe_trait, Some(&ty)) - } - _ => ident - }; Item { id: id, diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7f8472f8b28..ab14e21e251 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -91,7 +91,6 @@ pub mod syntax { pub mod abi; pub mod ast; -pub mod ast_util; pub mod attr; pub mod codemap; pub mod config; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 89a504e1ebd..36f01463205 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -44,7 +44,6 @@ use ast::{Visibility, WhereClause}; use attr::{ThinAttributes, ThinAttributesExt, AttributesExt}; use ast::{BinOpKind, UnOp}; use ast; -use ast_util::{self, ident_to_path}; use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; use errors::{self, DiagnosticBuilder}; use ext::tt::macro_parser; @@ -1577,9 +1576,14 @@ impl<'a> Parser<'a> { pat } else { debug!("parse_arg_general ident_to_pat"); - ast_util::ident_to_pat(ast::DUMMY_NODE_ID, - self.last_span, - special_idents::invalid) + let sp = self.last_span; + let spanned = Spanned { span: sp, node: special_idents::invalid }; + P(Pat { + id: ast::DUMMY_NODE_ID, + node: PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), + spanned, None), + span: sp + }) }; let t = self.parse_ty_sum()?; @@ -2223,7 +2227,7 @@ impl<'a> Parser<'a> { ctxt: _ }, token::Plain) => { self.bump(); - let path = ast_util::ident_to_path(mk_sp(lo, hi), id); + let path = ast::Path::from_ident(mk_sp(lo, hi), id); ex = ExprKind::Path(None, path); hi = self.last_span.hi; } @@ -3679,7 +3683,7 @@ impl<'a> Parser<'a> { // Parse macro invocation let ident = self.parse_ident()?; let ident_span = self.last_span; - let path = ident_to_path(ident_span, ident); + let path = ast::Path::from_ident(ident_span, ident); self.bump(); let delim = self.expect_open_delim()?; let tts = self.parse_seq_to_end( @@ -5116,7 +5120,7 @@ impl<'a> Parser<'a> { self.expect(&token::OpenDelim(token::Brace))?; self.expect(&token::CloseDelim(token::Brace))?; - Ok((ast_util::impl_pretty_name(&opt_trait, None), + Ok((special_idents::invalid, ItemKind::DefaultImpl(unsafety, opt_trait.unwrap()), None)) } else { if opt_trait.is_some() { @@ -5132,7 +5136,7 @@ impl<'a> Parser<'a> { impl_items.push(self.parse_impl_item()?); } - Ok((ast_util::impl_pretty_name(&opt_trait, Some(&ty)), + Ok((special_idents::invalid, ItemKind::Impl(unsafety, polarity, generics, opt_trait, ty, impl_items), Some(attrs))) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 81b702e794d..703b1611540 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -18,7 +18,6 @@ use std::iter; use std::slice; use std::mem; use std::vec; -use ast_util::*; use attr::AttrMetaMethods; use attr; use codemap::{DUMMY_SP, Span, ExpnInfo, NameAndSpan, MacroAttribute}; @@ -35,7 +34,7 @@ use fold; use parse::token::{intern, InternedString}; use parse::{token, ParseSess}; use print::pprust; -use {ast, ast_util}; +use ast; use ptr::P; use util::small_vector::SmallVector; @@ -120,8 +119,7 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { if ident.name != token::special_idents::invalid.name { self.cx.path.push(ident); } - debug!("current path: {}", - ast_util::path_name_i(&self.cx.path)); + debug!("current path: {}", path_name_i(&self.cx.path)); let i = if is_test_fn(&self.cx, &i) || is_bench_fn(&self.cx, &i) { match i.node { @@ -349,7 +347,6 @@ enum HasTestSignature { NotEvenAFunction, } - fn is_test_fn(cx: &TestCtxt, i: &ast::Item) -> bool { let has_test_attr = attr::contains_name(&i.attrs, "test"); @@ -576,6 +573,11 @@ fn path_node(ids: Vec ) -> ast::Path { } } +fn path_name_i(idents: &[ast::Ident]) -> String { + // FIXME: Bad copies (#2543 -- same for everything else that says "bad") + idents.iter().map(|i| i.to_string()).collect::>().join("::") +} + fn mk_tests(cx: &TestCtxt) -> P { // The vector of test_descs for this crate let test_descs = mk_test_descs(cx); @@ -645,10 +647,10 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P { // creates $name: $expr let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr); - debug!("encoding {}", ast_util::path_name_i(&path[..])); + debug!("encoding {}", path_name_i(&path[..])); // path to the #[test] function: "foo::bar::baz" - let path_string = ast_util::path_name_i(&path[..]); + let path_string = path_name_i(&path[..]); let name_expr = ecx.expr_str(span, token::intern_and_get_ident(&path_string[..])); // self::test::StaticTestName($name_expr) diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 7d452b14dae..37c77ec5b2f 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -194,7 +194,6 @@ use std::vec; use syntax::abi::Abi; use syntax::ast::{self, EnumDef, Expr, Ident, Generics, VariantData, BinOpKind, PatKind}; -use syntax::ast_util; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::ext::base::{ExtCtxt, Annotatable}; @@ -620,7 +619,6 @@ impl<'a> TraitDef<'a> { // Just mark it now since we know that it'll end up used downstream attr::mark_used(&attr); let opt_trait_ref = Some(trait_ref); - let ident = ast_util::impl_pretty_name(&opt_trait_ref, Some(&self_type)); let unused_qual = cx.attribute( self.span, cx.meta_list(self.span, @@ -638,7 +636,7 @@ impl<'a> TraitDef<'a> { cx.item( self.span, - ident, + special_idents::invalid, a, ast::ItemKind::Impl(unsafety, ast::ImplPolarity::Positive, -- cgit 1.4.1-3-g733a5 From ffca6c3e155cb6033b1f749d0ba1be32dfc4d22a Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 29 Mar 2016 12:54:26 +0300 Subject: rustc: move middle::{def,def_id,pat_util} to hir. --- src/librustc/cfg/construct.rs | 4 +- src/librustc/dep_graph/mod.rs | 2 +- src/librustc/hir/def.rs | 176 +++++++++++++++ src/librustc/hir/def_id.rs | 88 ++++++++ src/librustc/hir/map/collector.rs | 2 +- src/librustc/hir/map/definitions.rs | 2 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 3 + src/librustc/hir/pat_util.rs | 246 +++++++++++++++++++++ src/librustc/infer/error_reporting.rs | 4 +- src/librustc/infer/mod.rs | 2 +- src/librustc/infer/type_variable.rs | 2 +- src/librustc/lib.rs | 3 - src/librustc/middle/astconv_util.rs | 2 +- src/librustc/middle/const_val.rs | 2 +- src/librustc/middle/cstore.rs | 6 +- src/librustc/middle/dead.rs | 8 +- src/librustc/middle/def.rs | 176 --------------- src/librustc/middle/def_id.rs | 88 -------- src/librustc/middle/effect.rs | 2 +- src/librustc/middle/entry.rs | 2 +- src/librustc/middle/expr_use_visitor.rs | 6 +- src/librustc/middle/intrinsicck.rs | 4 +- src/librustc/middle/lang_items.rs | 2 +- src/librustc/middle/liveness.rs | 4 +- src/librustc/middle/mem_categorization.rs | 4 +- src/librustc/middle/pat_util.rs | 246 --------------------- src/librustc/middle/reachable.rs | 4 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/middle/stability.rs | 4 +- src/librustc/mir/repr.rs | 2 +- src/librustc/mir/visit.rs | 2 +- src/librustc/traits/coherence.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/object_safety.rs | 2 +- src/librustc/traits/project.rs | 2 +- src/librustc/traits/select.rs | 2 +- src/librustc/traits/specialize/mod.rs | 2 +- .../traits/specialize/specialization_graph.rs | 2 +- src/librustc/traits/util.rs | 2 +- src/librustc/ty/contents.rs | 2 +- src/librustc/ty/context.rs | 4 +- src/librustc/ty/error.rs | 2 +- src/librustc/ty/fast_reject.rs | 2 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 4 +- src/librustc/ty/relate.rs | 2 +- src/librustc/ty/sty.rs | 2 +- src/librustc/ty/subst.rs | 2 +- src/librustc/ty/trait_def.rs | 2 +- src/librustc/ty/util.rs | 4 +- src/librustc/ty/wf.rs | 2 +- src/librustc/util/nodemap.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_borrowck/borrowck/fragments.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_const_eval/check_match.rs | 6 +- src/librustc_const_eval/eval.rs | 6 +- src/librustc_lint/bad_style.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_lint/types.rs | 2 +- src/librustc_lint/unused.rs | 2 +- src/librustc_metadata/astencode.rs | 4 +- src/librustc_metadata/csearch.rs | 4 +- src/librustc_metadata/cstore.rs | 2 +- src/librustc_metadata/decoder.rs | 4 +- src/librustc_metadata/encoder.rs | 4 +- src/librustc_metadata/index.rs | 2 +- src/librustc_metadata/tls_context.rs | 2 +- src/librustc_metadata/tydecode.rs | 2 +- src/librustc_metadata/tyencode.rs | 2 +- src/librustc_mir/hair/cx/expr.rs | 4 +- src/librustc_mir/hair/cx/mod.rs | 2 +- src/librustc_mir/hair/cx/pattern.rs | 4 +- src/librustc_mir/hair/mod.rs | 2 +- src/librustc_passes/consts.rs | 4 +- src/librustc_passes/static_recursion.rs | 2 +- src/librustc_privacy/lib.rs | 4 +- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_resolve/lib.rs | 8 +- src/librustc_resolve/resolve_imports.rs | 2 +- src/librustc_save_analysis/csv_dumper.rs | 2 +- src/librustc_save_analysis/data.rs | 2 +- src/librustc_save_analysis/dump_visitor.rs | 4 +- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_trans/_match.rs | 6 +- src/librustc_trans/assert_dep_graph.rs | 2 +- src/librustc_trans/back/symbol_names.rs | 2 +- src/librustc_trans/base.rs | 4 +- src/librustc_trans/callee.rs | 2 +- src/librustc_trans/closure.rs | 2 +- src/librustc_trans/collector.rs | 2 +- src/librustc_trans/common.rs | 4 +- src/librustc_trans/consts.rs | 4 +- src/librustc_trans/context.rs | 4 +- src/librustc_trans/controlflow.rs | 2 +- src/librustc_trans/debuginfo/create_scope_map.rs | 2 +- src/librustc_trans/debuginfo/metadata.rs | 4 +- src/librustc_trans/debuginfo/mod.rs | 2 +- src/librustc_trans/debuginfo/namespace.rs | 2 +- src/librustc_trans/debuginfo/type_names.rs | 2 +- src/librustc_trans/debuginfo/utils.rs | 2 +- src/librustc_trans/expr.rs | 2 +- src/librustc_trans/inline.rs | 2 +- src/librustc_trans/meth.rs | 2 +- src/librustc_trans/monomorphize.rs | 2 +- src/librustc_trans/type_of.rs | 2 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/_match.rs | 6 +- src/librustc_typeck/check/callee.rs | 4 +- src/librustc_typeck/check/cast.rs | 2 +- src/librustc_typeck/check/dropck.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 4 +- src/librustc_typeck/check/method/probe.rs | 4 +- src/librustc_typeck/check/method/suggest.rs | 4 +- src/librustc_typeck/check/mod.rs | 6 +- src/librustc_typeck/check/op.rs | 2 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/check/wfcheck.rs | 2 +- src/librustc_typeck/check/writeback.rs | 4 +- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 2 +- src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/collect.rs | 4 +- src/librustc_typeck/lib.rs | 2 +- src/librustc_typeck/variance/constraints.rs | 2 +- src/librustdoc/clean/inline.rs | 4 +- src/librustdoc/clean/mod.rs | 4 +- src/librustdoc/clean/simplify.rs | 2 +- src/librustdoc/core.rs | 2 +- src/librustdoc/html/format.rs | 2 +- src/librustdoc/html/render.rs | 2 +- src/librustdoc/passes.rs | 2 +- 136 files changed, 697 insertions(+), 697 deletions(-) create mode 100644 src/librustc/hir/def.rs create mode 100644 src/librustc/hir/def_id.rs create mode 100644 src/librustc/hir/pat_util.rs delete mode 100644 src/librustc/middle/def.rs delete mode 100644 src/librustc/middle/def_id.rs delete mode 100644 src/librustc/middle/pat_util.rs (limited to 'src') diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index 13c3e3895b5..70497491355 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -10,8 +10,8 @@ use rustc_data_structures::graph; use cfg::*; -use middle::def::Def; -use middle::pat_util; +use hir::def::Def; +use hir::pat_util; use ty::{self, TyCtxt}; use syntax::ast; use syntax::ptr::P; diff --git a/src/librustc/dep_graph/mod.rs b/src/librustc/dep_graph/mod.rs index 70e7f675fce..55ec56a4bbe 100644 --- a/src/librustc/dep_graph/mod.rs +++ b/src/librustc/dep_graph/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. use self::thread::{DepGraphThreadData, DepMessage}; -use middle::def_id::DefId; +use hir::def_id::DefId; use syntax::ast::NodeId; use ty::TyCtxt; use hir; diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs new file mode 100644 index 00000000000..c270a4413bf --- /dev/null +++ b/src/librustc/hir/def.rs @@ -0,0 +1,176 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use hir::def_id::DefId; +use ty::subst::ParamSpace; +use util::nodemap::NodeMap; +use syntax::ast; +use hir; + +#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] +pub enum Def { + Fn(DefId), + SelfTy(Option, // trait id + Option<(ast::NodeId, ast::NodeId)>), // (impl id, self type id) + Mod(DefId), + ForeignMod(DefId), + Static(DefId, bool /* is_mutbl */), + Const(DefId), + AssociatedConst(DefId), + Local(DefId, // def id of variable + ast::NodeId), // node id of variable + Variant(DefId /* enum */, DefId /* variant */), + Enum(DefId), + TyAlias(DefId), + AssociatedTy(DefId /* trait */, DefId), + Trait(DefId), + PrimTy(hir::PrimTy), + TyParam(ParamSpace, u32, DefId, ast::Name), + Upvar(DefId, // def id of closed over local + ast::NodeId, // node id of closed over local + usize, // index in the freevars list of the closure + ast::NodeId), // expr node that creates the closure + + // If Def::Struct lives in type namespace it denotes a struct item and its DefId refers + // to NodeId of the struct itself. + // If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions) + // it denotes a constructor and its DefId refers to NodeId of the struct's constructor. + Struct(DefId), + Label(ast::NodeId), + Method(DefId), + Err, +} + +/// The result of resolving a path. +/// Before type checking completes, `depth` represents the number of +/// trailing segments which are yet unresolved. Afterwards, if there +/// were no errors, all paths should be fully resolved, with `depth` +/// set to `0` and `base_def` representing the final resolution. +/// +/// module::Type::AssocX::AssocY::MethodOrAssocType +/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +/// base_def depth = 3 +/// +/// ::AssocX::AssocY::MethodOrAssocType +/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~ +/// base_def depth = 2 +#[derive(Copy, Clone, Debug)] +pub struct PathResolution { + pub base_def: Def, + pub depth: usize +} + +impl PathResolution { + /// Get the definition, if fully resolved, otherwise panic. + pub fn full_def(&self) -> Def { + if self.depth != 0 { + bug!("path not fully resolved: {:?}", self); + } + self.base_def + } + + /// Get the DefId, if fully resolved, otherwise panic. + pub fn def_id(&self) -> DefId { + self.full_def().def_id() + } + + pub fn new(base_def: Def, + depth: usize) + -> PathResolution { + PathResolution { + base_def: base_def, + depth: depth, + } + } +} + +// Definition mapping +pub type DefMap = NodeMap; +// This is the replacement export map. It maps a module to all of the exports +// within. +pub type ExportMap = NodeMap>; + +#[derive(Copy, Clone)] +pub struct Export { + pub name: ast::Name, // The name of the target. + pub def_id: DefId, // The definition of the target. +} + +impl Def { + pub fn var_id(&self) -> ast::NodeId { + match *self { + Def::Local(_, id) | + Def::Upvar(_, id, _, _) => { + id + } + + Def::Fn(..) | Def::Mod(..) | Def::ForeignMod(..) | Def::Static(..) | + Def::Variant(..) | Def::Enum(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | + Def::TyParam(..) | Def::Struct(..) | Def::Trait(..) | + Def::Method(..) | Def::Const(..) | Def::AssociatedConst(..) | + Def::PrimTy(..) | Def::Label(..) | Def::SelfTy(..) | Def::Err => { + bug!("attempted .var_id() on invalid {:?}", self) + } + } + } + + pub fn def_id(&self) -> DefId { + match *self { + Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) | + Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) | + Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) | + Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | + Def::Local(id, _) | Def::Upvar(id, _, _, _) => { + id + } + + Def::Label(..) | + Def::PrimTy(..) | + Def::SelfTy(..) | + Def::Err => { + bug!("attempted .def_id() on invalid def: {:?}", self) + } + } + } + + pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> { + match *self { + Def::Variant(enum_id, var_id) => { + Some((enum_id, var_id)) + } + _ => None + } + } + + pub fn kind_name(&self) -> &'static str { + match *self { + Def::Fn(..) => "function", + Def::Mod(..) => "module", + Def::ForeignMod(..) => "foreign module", + Def::Static(..) => "static", + Def::Variant(..) => "variant", + Def::Enum(..) => "enum", + Def::TyAlias(..) => "type", + Def::AssociatedTy(..) => "associated type", + Def::Struct(..) => "struct", + Def::Trait(..) => "trait", + Def::Method(..) => "method", + Def::Const(..) => "const", + Def::AssociatedConst(..) => "associated const", + Def::TyParam(..) => "type parameter", + Def::PrimTy(..) => "builtin type", + Def::Local(..) => "local variable", + Def::Upvar(..) => "closure capture", + Def::Label(..) => "label", + Def::SelfTy(..) => "self type", + Def::Err => "unresolved item", + } + } +} diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs new file mode 100644 index 00000000000..a3b83ec5be4 --- /dev/null +++ b/src/librustc/hir/def_id.rs @@ -0,0 +1,88 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use middle::cstore::LOCAL_CRATE; +use ty; +use syntax::ast::CrateNum; +use std::fmt; +use std::u32; + +/// A DefIndex is an index into the hir-map for a crate, identifying a +/// particular definition. It should really be considered an interned +/// shorthand for a particular DefPath. +#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, + RustcDecodable, Hash, Copy)] +pub struct DefIndex(u32); + +impl DefIndex { + pub fn new(x: usize) -> DefIndex { + assert!(x < (u32::MAX as usize)); + DefIndex(x as u32) + } + + pub fn from_u32(x: u32) -> DefIndex { + DefIndex(x) + } + + pub fn as_usize(&self) -> usize { + self.0 as usize + } + + pub fn as_u32(&self) -> u32 { + self.0 + } +} + +/// The crate root is always assigned index 0 by the AST Map code, +/// thanks to `NodeCollector::new`. +pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0); + +/// A DefId identifies a particular *definition*, by combining a crate +/// index and a def index. +#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, + RustcDecodable, Hash, Copy)] +pub struct DefId { + pub krate: CrateNum, + pub index: DefIndex, +} + +impl fmt::Debug for DefId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "DefId {{ krate: {:?}, node: {:?}", + self.krate, self.index)?; + + // Unfortunately, there seems to be no way to attempt to print + // a path for a def-id, so I'll just make a best effort for now + // and otherwise fallback to just printing the crate/node pair + if self.is_local() { // (1) + // (1) side-step fact that not all external things have paths at + // the moment, such as type parameters + ty::tls::with_opt(|opt_tcx| { + if let Some(tcx) = opt_tcx { + write!(f, " => {}", tcx.item_path_str(*self))?; + } + Ok(()) + })?; + } + + write!(f, " }}") + } +} + + +impl DefId { + pub fn local(index: DefIndex) -> DefId { + DefId { krate: LOCAL_CRATE, index: index } + } + + pub fn is_local(&self) -> bool { + self.krate == LOCAL_CRATE + } +} diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 62c80c9c8bb..b1a084ac799 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -13,7 +13,7 @@ use super::MapEntry::*; use hir::*; use hir::intravisit::Visitor; -use middle::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; use syntax::codemap::Span; diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 82574b85229..d045313cb1e 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -9,7 +9,7 @@ // except according to those terms. use middle::cstore::LOCAL_CRATE; -use middle::def_id::{DefId, DefIndex}; +use hir::def_id::{DefId, DefIndex}; use rustc_data_structures::fnv::FnvHashMap; use syntax::ast; use syntax::parse::token::InternedString; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 4325be9b9a4..4096606b001 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -19,7 +19,7 @@ use dep_graph::{DepGraph, DepNode}; use middle::cstore::InlinedItem; use middle::cstore::InlinedItem as II; -use middle::def_id::{CRATE_DEF_INDEX, DefId}; +use hir::def_id::{CRATE_DEF_INDEX, DefId}; use syntax::abi::Abi; use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index cb3cdd0b825..10fe86246de 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -63,10 +63,13 @@ 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; +pub mod pat_util; pub mod print; pub mod svh; diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs new file mode 100644 index 00000000000..5eb4d53ea6a --- /dev/null +++ b/src/librustc/hir/pat_util.rs @@ -0,0 +1,246 @@ +// Copyright 2012 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use hir::def::*; +use hir::def_id::DefId; +use ty::TyCtxt; +use util::nodemap::FnvHashMap; + +use syntax::ast; +use hir::{self, PatKind}; +use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; + +use std::cell::RefCell; + +pub type PatIdMap = FnvHashMap; + +// This is used because same-named variables in alternative patterns need to +// use the NodeId of their namesake in the first pattern. +pub fn pat_id_map(dm: &RefCell, pat: &hir::Pat) -> PatIdMap { + let mut map = FnvHashMap(); + pat_bindings(dm, pat, |_bm, p_id, _s, path1| { + map.insert(path1.node, p_id); + }); + map +} + +pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true, + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::Ident(_, _, None) | + PatKind::Struct(..) => { + match dm.get(&pat.id).map(|d| d.full_def()) { + Some(Def::Variant(..)) => true, + _ => false + } + } + PatKind::Vec(_, _, _) => true, + _ => false + } +} + +pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::Ident(_, _, None) | + PatKind::Struct(..) => { + match dm.get(&pat.id).map(|d| d.full_def()) { + Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true, + _ => false + } + } + _ => false + } +} + +pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => { + match dm.get(&pat.id).map(|d| d.full_def()) { + Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, + _ => false + } + } + _ => false + } +} + +// Same as above, except that partially-resolved defs cause `false` to be +// returned instead of a panic. +pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => { + match dm.get(&pat.id) + .and_then(|d| if d.depth == 0 { Some(d.base_def) } + else { None } ) { + Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, + _ => false + } + } + _ => false + } +} + +pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::Ident(..) => { + !pat_is_variant_or_struct(dm, pat) && + !pat_is_const(dm, pat) + } + _ => false + } +} + +pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { + match pat.node { + PatKind::Ident(..) => pat_is_binding(dm, pat), + PatKind::Wild => true, + _ => false + } +} + +/// Call `it` on every "binding" in a pattern, e.g., on `a` in +/// `match foo() { Some(a) => (), None => () }` +pub fn pat_bindings(dm: &RefCell, pat: &hir::Pat, mut it: I) where + I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), +{ + pat.walk(|p| { + match p.node { + PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { + it(binding_mode, p.id, p.span, &respan(pth.span, pth.node.name)); + } + _ => {} + } + true + }); +} +pub fn pat_bindings_ident(dm: &RefCell, pat: &hir::Pat, mut it: I) where + I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), +{ + pat.walk(|p| { + match p.node { + PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { + it(binding_mode, p.id, p.span, &respan(pth.span, pth.node)); + } + _ => {} + } + true + }); +} + +/// Checks if the pattern contains any patterns that bind something to +/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. +pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool { + let mut contains_bindings = false; + pat.walk(|p| { + if pat_is_binding(dm, p) { + contains_bindings = true; + false // there's at least one binding, can short circuit now. + } else { + true + } + }); + contains_bindings +} + +/// Checks if the pattern contains any `ref` or `ref mut` bindings, +/// and if yes whether its containing mutable ones or just immutables ones. +pub fn pat_contains_ref_binding(dm: &RefCell, pat: &hir::Pat) -> Option { + let mut result = None; + pat_bindings(dm, pat, |mode, _, _, _| { + match mode { + hir::BindingMode::BindByRef(m) => { + // Pick Mutable as maximum + match result { + None | Some(hir::MutImmutable) => result = Some(m), + _ => (), + } + } + hir::BindingMode::BindByValue(_) => { } + } + }); + result +} + +/// Checks if the patterns for this arm contain any `ref` or `ref mut` +/// bindings, and if yes whether its containing mutable ones or just immutables ones. +pub fn arm_contains_ref_binding(dm: &RefCell, arm: &hir::Arm) -> Option { + arm.pats.iter() + .filter_map(|pat| pat_contains_ref_binding(dm, pat)) + .max_by_key(|m| match *m { + hir::MutMutable => 1, + hir::MutImmutable => 0, + }) +} + +/// Checks if the pattern contains any patterns that bind something to +/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`, +pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { + let mut contains_bindings = false; + pat.walk(|p| { + if pat_is_binding_or_wild(dm, p) { + contains_bindings = true; + false // there's at least one binding/wildcard, can short circuit now. + } else { + true + } + }); + contains_bindings +} + +pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option { + match pat.node { + PatKind::Ident(hir::BindByValue(_), ref path1, None) => { + Some(path1.node.name) + } + _ => { + None + } + } +} + +pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path { + tcx.with_path(id, |path| hir::Path { + global: false, + segments: path.last().map(|elem| hir::PathSegment { + identifier: hir::Ident::from_name(elem.name()), + parameters: hir::PathParameters::none(), + }).into_iter().collect(), + span: DUMMY_SP, + }) +} + +/// Return variants that are necessary to exist for the pattern to match. +pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { + let mut variants = vec![]; + pat.walk(|p| { + match p.node { + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::Ident(_, _, None) | + PatKind::Struct(..) => { + match dm.get(&p.id) { + Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => { + variants.push(id); + } + _ => () + } + } + _ => () + } + true + }); + variants.sort(); + variants.dedup(); + variants +} diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index c0c63ac5042..5a0d9ec1332 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -78,8 +78,8 @@ use hir; use hir::print as pprust; use middle::cstore::CrateStore; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use infer::{self, TypeOrigin}; use middle::region; use ty::subst; diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 427ff88b8f2..4c1216aa862 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -18,7 +18,7 @@ pub use ty::IntVarValue; pub use self::freshen::TypeFreshener; pub use self::region_inference::{GenericKind, VerifyBound}; -use middle::def_id::DefId; +use hir::def_id::DefId; use hir; use middle::free_region::FreeRegionMap; use middle::mem_categorization as mc; diff --git a/src/librustc/infer/type_variable.rs b/src/librustc/infer/type_variable.rs index 3cc076f1f00..c2a8d04ac00 100644 --- a/src/librustc/infer/type_variable.rs +++ b/src/librustc/infer/type_variable.rs @@ -11,7 +11,7 @@ pub use self::RelationDir::*; use self::TypeVariableValue::*; use self::UndoEntry::*; -use middle::def_id::{DefId}; +use hir::def_id::{DefId}; use ty::{self, Ty}; use syntax::codemap::Span; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 291eab30dec..deb20627772 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -86,8 +86,6 @@ pub mod middle { pub mod cstore; pub mod dataflow; pub mod dead; - pub mod def; - pub mod def_id; pub mod dependency_format; pub mod effect; pub mod entry; @@ -96,7 +94,6 @@ pub mod middle { pub mod lang_items; pub mod liveness; pub mod mem_categorization; - pub mod pat_util; pub mod privacy; pub mod reachable; pub mod region; diff --git a/src/librustc/middle/astconv_util.rs b/src/librustc/middle/astconv_util.rs index 871440a7e54..2a27732b953 100644 --- a/src/librustc/middle/astconv_util.rs +++ b/src/librustc/middle/astconv_util.rs @@ -14,7 +14,7 @@ * Almost certainly this could (and should) be refactored out of existence. */ -use middle::def::Def; +use hir::def::Def; use ty::{Ty, TyCtxt}; use syntax::codemap::Span; diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs index a939389c460..3621cb267d9 100644 --- a/src/librustc/middle/const_val.rs +++ b/src/librustc/middle/const_val.rs @@ -11,7 +11,7 @@ use syntax::parse::token::InternedString; use syntax::ast; use std::rc::Rc; -use middle::def_id::DefId; +use hir::def_id::DefId; use std::hash; use std::mem::transmute; use rustc_const_math::*; diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index a7f415ef2a0..027792b7439 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -24,10 +24,10 @@ use hir::svh::Svh; use hir::map as hir_map; -use middle::def::{self, Def}; +use hir::def::{self, Def}; use middle::lang_items; use ty::{self, Ty, TyCtxt, VariantKind}; -use middle::def_id::{DefId, DefIndex}; +use hir::def_id::{DefId, DefIndex}; use mir::repr::Mir; use mir::mir_map::MirMap; use session::Session; @@ -504,7 +504,7 @@ pub mod tls { use std::mem; use ty::{self, Ty, TyCtxt}; use ty::subst::Substs; - use middle::def_id::DefId; + use hir::def_id::DefId; pub trait EncodingContext<'tcx> { fn tcx<'a>(&'a self) -> &'a TyCtxt<'tcx>; diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index b7b6279270c..dcdc02c9df6 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -14,13 +14,13 @@ use dep_graph::DepNode; use hir::map as ast_map; -use hir::{self, PatKind}; +use hir::{self, pat_util, PatKind}; use hir::intravisit::{self, Visitor}; -use middle::{pat_util, privacy}; +use middle::privacy; use ty::{self, TyCtxt}; -use middle::def::Def; -use middle::def_id::{DefId}; +use hir::def::Def; +use hir::def_id::{DefId}; use lint; use std::collections::HashSet; diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs deleted file mode 100644 index ee6e747a855..00000000000 --- a/src/librustc/middle/def.rs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2014 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use middle::def_id::DefId; -use ty::subst::ParamSpace; -use util::nodemap::NodeMap; -use syntax::ast; -use hir; - -#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum Def { - Fn(DefId), - SelfTy(Option, // trait id - Option<(ast::NodeId, ast::NodeId)>), // (impl id, self type id) - Mod(DefId), - ForeignMod(DefId), - Static(DefId, bool /* is_mutbl */), - Const(DefId), - AssociatedConst(DefId), - Local(DefId, // def id of variable - ast::NodeId), // node id of variable - Variant(DefId /* enum */, DefId /* variant */), - Enum(DefId), - TyAlias(DefId), - AssociatedTy(DefId /* trait */, DefId), - Trait(DefId), - PrimTy(hir::PrimTy), - TyParam(ParamSpace, u32, DefId, ast::Name), - Upvar(DefId, // def id of closed over local - ast::NodeId, // node id of closed over local - usize, // index in the freevars list of the closure - ast::NodeId), // expr node that creates the closure - - // If Def::Struct lives in type namespace it denotes a struct item and its DefId refers - // to NodeId of the struct itself. - // If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions) - // it denotes a constructor and its DefId refers to NodeId of the struct's constructor. - Struct(DefId), - Label(ast::NodeId), - Method(DefId), - Err, -} - -/// The result of resolving a path. -/// Before type checking completes, `depth` represents the number of -/// trailing segments which are yet unresolved. Afterwards, if there -/// were no errors, all paths should be fully resolved, with `depth` -/// set to `0` and `base_def` representing the final resolution. -/// -/// module::Type::AssocX::AssocY::MethodOrAssocType -/// ^~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -/// base_def depth = 3 -/// -/// ::AssocX::AssocY::MethodOrAssocType -/// ^~~~~~~~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~ -/// base_def depth = 2 -#[derive(Copy, Clone, Debug)] -pub struct PathResolution { - pub base_def: Def, - pub depth: usize -} - -impl PathResolution { - /// Get the definition, if fully resolved, otherwise panic. - pub fn full_def(&self) -> Def { - if self.depth != 0 { - bug!("path not fully resolved: {:?}", self); - } - self.base_def - } - - /// Get the DefId, if fully resolved, otherwise panic. - pub fn def_id(&self) -> DefId { - self.full_def().def_id() - } - - pub fn new(base_def: Def, - depth: usize) - -> PathResolution { - PathResolution { - base_def: base_def, - depth: depth, - } - } -} - -// Definition mapping -pub type DefMap = NodeMap; -// This is the replacement export map. It maps a module to all of the exports -// within. -pub type ExportMap = NodeMap>; - -#[derive(Copy, Clone)] -pub struct Export { - pub name: ast::Name, // The name of the target. - pub def_id: DefId, // The definition of the target. -} - -impl Def { - pub fn var_id(&self) -> ast::NodeId { - match *self { - Def::Local(_, id) | - Def::Upvar(_, id, _, _) => { - id - } - - Def::Fn(..) | Def::Mod(..) | Def::ForeignMod(..) | Def::Static(..) | - Def::Variant(..) | Def::Enum(..) | Def::TyAlias(..) | Def::AssociatedTy(..) | - Def::TyParam(..) | Def::Struct(..) | Def::Trait(..) | - Def::Method(..) | Def::Const(..) | Def::AssociatedConst(..) | - Def::PrimTy(..) | Def::Label(..) | Def::SelfTy(..) | Def::Err => { - bug!("attempted .var_id() on invalid {:?}", self) - } - } - } - - pub fn def_id(&self) -> DefId { - match *self { - Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) | - Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) | - Def::TyParam(_, _, id, _) | Def::Struct(id) | Def::Trait(id) | - Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | - Def::Local(id, _) | Def::Upvar(id, _, _, _) => { - id - } - - Def::Label(..) | - Def::PrimTy(..) | - Def::SelfTy(..) | - Def::Err => { - bug!("attempted .def_id() on invalid def: {:?}", self) - } - } - } - - pub fn variant_def_ids(&self) -> Option<(DefId, DefId)> { - match *self { - Def::Variant(enum_id, var_id) => { - Some((enum_id, var_id)) - } - _ => None - } - } - - pub fn kind_name(&self) -> &'static str { - match *self { - Def::Fn(..) => "function", - Def::Mod(..) => "module", - Def::ForeignMod(..) => "foreign module", - Def::Static(..) => "static", - Def::Variant(..) => "variant", - Def::Enum(..) => "enum", - Def::TyAlias(..) => "type", - Def::AssociatedTy(..) => "associated type", - Def::Struct(..) => "struct", - Def::Trait(..) => "trait", - Def::Method(..) => "method", - Def::Const(..) => "const", - Def::AssociatedConst(..) => "associated const", - Def::TyParam(..) => "type parameter", - Def::PrimTy(..) => "builtin type", - Def::Local(..) => "local variable", - Def::Upvar(..) => "closure capture", - Def::Label(..) => "label", - Def::SelfTy(..) => "self type", - Def::Err => "unresolved item", - } - } -} diff --git a/src/librustc/middle/def_id.rs b/src/librustc/middle/def_id.rs deleted file mode 100644 index a3b83ec5be4..00000000000 --- a/src/librustc/middle/def_id.rs +++ /dev/null @@ -1,88 +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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use middle::cstore::LOCAL_CRATE; -use ty; -use syntax::ast::CrateNum; -use std::fmt; -use std::u32; - -/// A DefIndex is an index into the hir-map for a crate, identifying a -/// particular definition. It should really be considered an interned -/// shorthand for a particular DefPath. -#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, - RustcDecodable, Hash, Copy)] -pub struct DefIndex(u32); - -impl DefIndex { - pub fn new(x: usize) -> DefIndex { - assert!(x < (u32::MAX as usize)); - DefIndex(x as u32) - } - - pub fn from_u32(x: u32) -> DefIndex { - DefIndex(x) - } - - pub fn as_usize(&self) -> usize { - self.0 as usize - } - - pub fn as_u32(&self) -> u32 { - self.0 - } -} - -/// The crate root is always assigned index 0 by the AST Map code, -/// thanks to `NodeCollector::new`. -pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0); - -/// A DefId identifies a particular *definition*, by combining a crate -/// index and a def index. -#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable, - RustcDecodable, Hash, Copy)] -pub struct DefId { - pub krate: CrateNum, - pub index: DefIndex, -} - -impl fmt::Debug for DefId { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "DefId {{ krate: {:?}, node: {:?}", - self.krate, self.index)?; - - // Unfortunately, there seems to be no way to attempt to print - // a path for a def-id, so I'll just make a best effort for now - // and otherwise fallback to just printing the crate/node pair - if self.is_local() { // (1) - // (1) side-step fact that not all external things have paths at - // the moment, such as type parameters - ty::tls::with_opt(|opt_tcx| { - if let Some(tcx) = opt_tcx { - write!(f, " => {}", tcx.item_path_str(*self))?; - } - Ok(()) - })?; - } - - write!(f, " }}") - } -} - - -impl DefId { - pub fn local(index: DefIndex) -> DefId { - DefId { krate: LOCAL_CRATE, index: index } - } - - pub fn is_local(&self) -> bool { - self.krate == LOCAL_CRATE - } -} diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index e4c93dfdb93..ac7a1b8aa0d 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -13,7 +13,7 @@ use self::RootUnsafeContext::*; use dep_graph::DepNode; -use middle::def::Def; +use hir::def::Def; use ty::{self, Ty, TyCtxt}; use ty::MethodCall; diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 4a64980fcdd..602889375e9 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -11,7 +11,7 @@ use dep_graph::DepNode; use hir::map as ast_map; -use middle::def_id::{CRATE_DEF_INDEX}; +use hir::def_id::{CRATE_DEF_INDEX}; use session::{config, Session}; use syntax::ast::NodeId; use syntax::attr; diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 1b967377304..c4d6f100671 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -19,9 +19,9 @@ pub use self::MatchMode::*; use self::TrackMatchMode::*; use self::OverloadedCallType::*; -use middle::pat_util; -use middle::def::Def; -use middle::def_id::{DefId}; +use hir::pat_util; +use hir::def::Def; +use hir::def_id::{DefId}; use infer; use middle::mem_categorization as mc; use ty::{self, TyCtxt, adjustment}; diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 354a6c5e13b..767c5adc81e 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -9,8 +9,8 @@ // except according to those terms. use dep_graph::DepNode; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use ty::subst::{Subst, Substs, EnumeratedItems}; use ty::{TransmuteRestriction, TyCtxt}; use ty::{self, Ty, TypeFoldable}; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 7aad106c4ed..86531ced8df 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -25,7 +25,7 @@ use dep_graph::DepNode; use hir::map as hir_map; use session::Session; use middle::cstore::CrateStore; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty; use middle::weak_lang_items; use util::nodemap::FnvHashMap; diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 72d3c9414a4..35991ae56c8 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -110,8 +110,8 @@ use self::LiveNodeKind::*; use self::VarKind::*; use dep_graph::DepNode; -use middle::def::*; -use middle::pat_util; +use hir::def::*; +use hir::pat_util; use ty::{self, TyCtxt, ParameterEnvironment}; use traits::{self, ProjectionMode}; use infer; diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 7260bdde3ee..2f77552c389 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -71,11 +71,11 @@ pub use self::deref_kind::*; use self::Aliasability::*; -use middle::def_id::DefId; +use hir::def_id::DefId; use hir::map as ast_map; use infer; use middle::const_qualif::ConstQualif; -use middle::def::Def; +use hir::def::Def; use ty::adjustment; use ty::{self, Ty, TyCtxt}; diff --git a/src/librustc/middle/pat_util.rs b/src/librustc/middle/pat_util.rs deleted file mode 100644 index 3c60d544228..00000000000 --- a/src/librustc/middle/pat_util.rs +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use middle::def::*; -use middle::def_id::DefId; -use ty::TyCtxt; -use util::nodemap::FnvHashMap; - -use syntax::ast; -use hir::{self, PatKind}; -use syntax::codemap::{respan, Span, Spanned, DUMMY_SP}; - -use std::cell::RefCell; - -pub type PatIdMap = FnvHashMap; - -// This is used because same-named variables in alternative patterns need to -// use the NodeId of their namesake in the first pattern. -pub fn pat_id_map(dm: &RefCell, pat: &hir::Pat) -> PatIdMap { - let mut map = FnvHashMap(); - pat_bindings(dm, pat, |_bm, p_id, _s, path1| { - map.insert(path1.node, p_id); - }); - map -} - -pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Lit(_) | PatKind::Range(_, _) | PatKind::QPath(..) => true, - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::Ident(_, _, None) | - PatKind::Struct(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(..)) => true, - _ => false - } - } - PatKind::Vec(_, _, _) => true, - _ => false - } -} - -pub fn pat_is_variant_or_struct(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::Ident(_, _, None) | - PatKind::Struct(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Variant(..)) | Some(Def::Struct(..)) | Some(Def::TyAlias(..)) => true, - _ => false - } - } - _ => false - } -} - -pub fn pat_is_const(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => { - match dm.get(&pat.id).map(|d| d.full_def()) { - Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, - _ => false - } - } - _ => false - } -} - -// Same as above, except that partially-resolved defs cause `false` to be -// returned instead of a panic. -pub fn pat_is_resolved_const(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Ident(_, _, None) | PatKind::Path(..) | PatKind::QPath(..) => { - match dm.get(&pat.id) - .and_then(|d| if d.depth == 0 { Some(d.base_def) } - else { None } ) { - Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => true, - _ => false - } - } - _ => false - } -} - -pub fn pat_is_binding(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Ident(..) => { - !pat_is_variant_or_struct(dm, pat) && - !pat_is_const(dm, pat) - } - _ => false - } -} - -pub fn pat_is_binding_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { - match pat.node { - PatKind::Ident(..) => pat_is_binding(dm, pat), - PatKind::Wild => true, - _ => false - } -} - -/// Call `it` on every "binding" in a pattern, e.g., on `a` in -/// `match foo() { Some(a) => (), None => () }` -pub fn pat_bindings(dm: &RefCell, pat: &hir::Pat, mut it: I) where - I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), -{ - pat.walk(|p| { - match p.node { - PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { - it(binding_mode, p.id, p.span, &respan(pth.span, pth.node.name)); - } - _ => {} - } - true - }); -} -pub fn pat_bindings_ident(dm: &RefCell, pat: &hir::Pat, mut it: I) where - I: FnMut(hir::BindingMode, ast::NodeId, Span, &Spanned), -{ - pat.walk(|p| { - match p.node { - PatKind::Ident(binding_mode, ref pth, _) if pat_is_binding(&dm.borrow(), p) => { - it(binding_mode, p.id, p.span, &respan(pth.span, pth.node)); - } - _ => {} - } - true - }); -} - -/// Checks if the pattern contains any patterns that bind something to -/// an ident, e.g. `foo`, or `Foo(foo)` or `foo @ Bar(..)`. -pub fn pat_contains_bindings(dm: &DefMap, pat: &hir::Pat) -> bool { - let mut contains_bindings = false; - pat.walk(|p| { - if pat_is_binding(dm, p) { - contains_bindings = true; - false // there's at least one binding, can short circuit now. - } else { - true - } - }); - contains_bindings -} - -/// Checks if the pattern contains any `ref` or `ref mut` bindings, -/// and if yes whether its containing mutable ones or just immutables ones. -pub fn pat_contains_ref_binding(dm: &RefCell, pat: &hir::Pat) -> Option { - let mut result = None; - pat_bindings(dm, pat, |mode, _, _, _| { - match mode { - hir::BindingMode::BindByRef(m) => { - // Pick Mutable as maximum - match result { - None | Some(hir::MutImmutable) => result = Some(m), - _ => (), - } - } - hir::BindingMode::BindByValue(_) => { } - } - }); - result -} - -/// Checks if the patterns for this arm contain any `ref` or `ref mut` -/// bindings, and if yes whether its containing mutable ones or just immutables ones. -pub fn arm_contains_ref_binding(dm: &RefCell, arm: &hir::Arm) -> Option { - arm.pats.iter() - .filter_map(|pat| pat_contains_ref_binding(dm, pat)) - .max_by_key(|m| match *m { - hir::MutMutable => 1, - hir::MutImmutable => 0, - }) -} - -/// Checks if the pattern contains any patterns that bind something to -/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`, -pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &hir::Pat) -> bool { - let mut contains_bindings = false; - pat.walk(|p| { - if pat_is_binding_or_wild(dm, p) { - contains_bindings = true; - false // there's at least one binding/wildcard, can short circuit now. - } else { - true - } - }); - contains_bindings -} - -pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option { - match pat.node { - PatKind::Ident(hir::BindByValue(_), ref path1, None) => { - Some(path1.node.name) - } - _ => { - None - } - } -} - -pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path { - tcx.with_path(id, |path| hir::Path { - global: false, - segments: path.last().map(|elem| hir::PathSegment { - identifier: hir::Ident::from_name(elem.name()), - parameters: hir::PathParameters::none(), - }).into_iter().collect(), - span: DUMMY_SP, - }) -} - -/// Return variants that are necessary to exist for the pattern to match. -pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { - let mut variants = vec![]; - pat.walk(|p| { - match p.node { - PatKind::TupleStruct(..) | - PatKind::Path(..) | - PatKind::Ident(_, _, None) | - PatKind::Struct(..) => { - match dm.get(&p.id) { - Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => { - variants.push(id); - } - _ => () - } - } - _ => () - } - true - }); - variants.sort(); - variants.dedup(); - variants -} diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 8c44594c1f7..63bccc2d02e 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -17,8 +17,8 @@ use dep_graph::DepNode; use hir::map as ast_map; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use ty::{self, TyCtxt}; use middle::privacy; use session::config; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 1275753a340..585b65b9f5e 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -21,7 +21,7 @@ use self::ScopeChain::*; use dep_graph::DepNode; use hir::map::Map; use session::Session; -use middle::def::{Def, DefMap}; +use hir::def::{Def, DefMap}; use middle::region; use ty::subst; use ty; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index ffb4a791363..6c7c7f160f4 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -18,8 +18,8 @@ use hir::map as hir_map; use session::Session; use lint; use middle::cstore::{CrateStore, LOCAL_CRATE}; -use middle::def::Def; -use middle::def_id::{CRATE_DEF_INDEX, DefId}; +use hir::def::Def; +use hir::def_id::{CRATE_DEF_INDEX, DefId}; use ty::{self, TyCtxt}; use middle::privacy::AccessLevels; use syntax::parse::token::InternedString; diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 1b24b4f6210..28437fa1336 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -11,7 +11,7 @@ use graphviz::IntoCow; use middle::const_val::ConstVal; use rustc_const_math::{ConstUsize, ConstInt}; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::Substs; use ty::{self, AdtDef, ClosureSubsts, FnOutput, Region, Ty}; use util::ppaux; diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 403c749fe4b..ae803f50231 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -9,7 +9,7 @@ // except according to those terms. use middle::const_val::ConstVal; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::Substs; use ty::{ClosureSubsts, FnOutput, Region, Ty}; use mir::repr::*; diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index a0ac5148526..6710d2a653c 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -13,7 +13,7 @@ use super::{SelectionContext, Obligation, ObligationCause}; use middle::cstore::LOCAL_CRATE; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::TypeSpace; use ty::{self, Ty, TyCtxt}; use infer::{self, InferCtxt, TypeOrigin}; diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index f15b9ee44ce..9357dda2583 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -24,7 +24,7 @@ use super::{ }; use fmt_macros::{Parser, Piece, Position}; -use middle::def_id::DefId; +use hir::def_id::DefId; use infer::InferCtxt; use ty::{self, ToPredicate, ToPolyTraitRef, TraitRef, Ty, TyCtxt, TypeFoldable}; use ty::fast_reject; diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 867bd054fa9..a160465e2e8 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -15,7 +15,7 @@ pub use self::FulfillmentErrorCode::*; pub use self::Vtable::*; pub use self::ObligationCauseCode::*; -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::free_region::FreeRegionMap; use ty::subst; use ty::{self, Ty, TypeFoldable}; diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 7cd2ac5938d..9af2cfbd04d 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -20,7 +20,7 @@ use super::supertraits; use super::elaborate_predicates; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::{self, SelfSpace, TypeSpace}; use traits; use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable}; diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index d4d61ec0244..a0d6f5f912b 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -23,7 +23,7 @@ use super::VtableClosureData; use super::VtableImplData; use super::util; -use middle::def_id::DefId; +use hir::def_id::DefId; use infer::{self, InferOk, TypeOrigin}; use ty::subst::Subst; use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt}; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 97c9caadd52..8d7df6e44ae 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -36,7 +36,7 @@ use super::{VtableImplData, VtableObjectData, VtableBuiltinData, use super::object_safety; use super::util; -use middle::def_id::DefId; +use hir::def_id::DefId; use infer; use infer::{InferCtxt, InferOk, TypeFreshener, TypeOrigin}; use ty::subst::{Subst, Substs, TypeSpace}; diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 88f4129d886..63647515a97 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -21,7 +21,7 @@ use super::{SelectionContext, FulfillmentContext}; use super::util::{fresh_type_vars_for_impl, impl_trait_ref_and_oblig}; use middle::cstore::CrateStore; -use middle::def_id::DefId; +use hir::def_id::DefId; use infer::{self, InferCtxt, TypeOrigin}; use middle::region; use ty::subst::{Subst, Substs}; diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index d3146697ee6..51b0b6b8b38 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -14,7 +14,7 @@ use std::rc::Rc; use super::{Overlap, specializes}; use middle::cstore::CrateStore; -use middle::def_id::DefId; +use hir::def_id::DefId; use infer; use traits::{self, ProjectionMode}; use ty::{self, TyCtxt, ImplOrTraitItem, TraitDef, TypeFoldable}; diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index befca878bc0..7668b8bf202 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::DefId; +use hir::def_id::DefId; use infer::InferCtxt; use ty::subst::{Subst, Substs}; use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef}; diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index ba237184a9f..f5dedb13248 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::{DefId}; +use hir::def_id::{DefId}; use ty::{self, Ty, TyCtxt}; use util::common::MemoizationMap; use util::nodemap::FnvHashMap; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index fa5a7f3ca69..14ffeadbb3a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -16,8 +16,8 @@ use session::Session; use lint; use middle; use middle::cstore::{CrateStore, LOCAL_CRATE}; -use middle::def::DefMap; -use middle::def_id::DefId; +use hir::def::DefMap; +use hir::def_id::DefId; use middle::free_region::FreeRegionMap; use middle::region::RegionMaps; use middle::resolve_lifetime; diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index e6b7b49ea57..73bafc5e850 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst; use infer::type_variable; use ty::{self, BoundRegion, Region, Ty, TyCtxt}; diff --git a/src/librustc/ty/fast_reject.rs b/src/librustc/ty/fast_reject.rs index 0865e059f59..29647253ad2 100644 --- a/src/librustc/ty/fast_reject.rs +++ b/src/librustc/ty/fast_reject.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use syntax::ast; diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 0648450d833..4d88b697416 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -10,7 +10,7 @@ use hir::map::DefPathData; use middle::cstore::LOCAL_CRATE; -use middle::def_id::{DefId, CRATE_DEF_INDEX}; +use hir::def_id::{DefId, CRATE_DEF_INDEX}; use ty::{self, Ty, TyCtxt}; use syntax::ast; diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 77b6b03e48f..65a96e79ff4 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -9,7 +9,7 @@ // except according to those terms. use dep_graph::{DepNode, DepTrackingMapConfig}; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty; use std::marker::PhantomData; use std::rc::Rc; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 69a6a6aa920..2f0b520d842 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -23,8 +23,8 @@ use hir::map as ast_map; use hir::map::LinkedPath; use middle; use middle::cstore::{self, CrateStore, LOCAL_CRATE}; -use middle::def::{self, Def, ExportMap}; -use middle::def_id::DefId; +use hir::def::{self, Def, ExportMap}; +use hir::def_id::DefId; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::region::{CodeExtent}; use traits; diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index b1bff9b43cc..f14e680e9e0 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -13,7 +13,7 @@ //! can be other things. Examples of type relations are subtyping, //! type equality, etc. -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::{ParamSpace, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 101c8501bd3..c0fb60d4dd3 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -11,7 +11,7 @@ //! This module contains TypeVariants and its major components use middle::cstore; -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::region; use ty::subst::{self, Substs}; use traits; diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 93157f28482..dd547da59e9 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -13,7 +13,7 @@ pub use self::ParamSpace::*; use middle::cstore; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::{self, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder}; diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 0eb70f93bed..94f4e31efc6 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -9,7 +9,7 @@ // except according to those terms. use dep_graph::DepNode; -use middle::def_id::DefId; +use hir::def_id::DefId; use traits::{self, specialization_graph}; use ty; use ty::fast_reject; diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 710cd2e301c..354744b2787 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -11,10 +11,10 @@ //! misc. type-system utilities too small to deserve their own file use hir::svh::Svh; -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst; use infer; -use middle::pat_util; +use hir::pat_util; use traits::{self, ProjectionMode}; use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFlags, TypeFoldable}; use ty::{Disr, ParameterEnvironment}; diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index e6c4e90babb..9ea634bb41c 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::DefId; +use hir::def_id::DefId; use infer::InferCtxt; use ty::outlives::{self, Component}; use ty::subst::Substs; diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs index 4a45797602d..69bcc9cbfff 100644 --- a/src/librustc/util/nodemap.rs +++ b/src/librustc/util/nodemap.rs @@ -12,7 +12,7 @@ #![allow(non_snake_case)] -use middle::def_id::DefId; +use hir::def_id::DefId; use syntax::ast; pub use rustc_data_structures::fnv::FnvHashMap; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index c386a670ba2..a84a42fc2b5 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -9,7 +9,7 @@ // except according to those terms. -use middle::def_id::DefId; +use hir::def_id::DefId; use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use ty::{TyBool, TyChar, TyStruct, TyEnum}; diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index d1b30bb2746..0b1c4efa9ac 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -20,7 +20,7 @@ use borrowck::LoanPathKind::{LpVar, LpUpvar, LpDowncast, LpExtend}; use borrowck::LoanPathElem::{LpDeref, LpInterior}; use borrowck::move_data::InvalidMovePathIndex; use borrowck::move_data::{MoveData, MovePathIndex}; -use rustc::middle::def_id::{DefId}; +use rustc::hir::def_id::{DefId}; use rustc::ty::{self, TyCtxt}; use rustc::middle::mem_categorization as mc; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index 789d7dd9fef..d7c928b8d6e 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -28,7 +28,7 @@ use rustc::middle::dataflow::DataFlowContext; use rustc::middle::dataflow::BitwiseOperator; use rustc::middle::dataflow::DataFlowOperator; use rustc::middle::dataflow::KillFrom; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::middle::expr_use_visitor as euv; use rustc::middle::free_region::FreeRegionMap; use rustc::middle::mem_categorization as mc; diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 797580319b2..1e662d456d1 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -17,14 +17,14 @@ use rustc::middle::const_val::ConstVal; use ::{eval_const_expr, eval_const_expr_partial, compare_const_vals}; use ::{const_expr_to_pat, lookup_const_by_id}; use ::EvalHint::ExprTypeChecked; -use rustc::middle::def::*; -use rustc::middle::def_id::{DefId}; +use rustc::hir::def::*; +use rustc::hir::def_id::{DefId}; use rustc::middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor}; use rustc::middle::expr_use_visitor::{LoanCause, MutateMode}; use rustc::middle::expr_use_visitor as euv; use rustc::infer; use rustc::middle::mem_categorization::{cmt}; -use rustc::middle::pat_util::*; +use rustc::hir::pat_util::*; use rustc::traits::ProjectionMode; use rustc::ty::*; use rustc::ty; diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index dba31ddef95..45a90bf0068 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -19,9 +19,9 @@ use rustc::hir::map as ast_map; use rustc::hir::map::blocks::FnLikeNode; use rustc::middle::cstore::{self, CrateStore, InlinedItem}; use rustc::{infer, traits}; -use rustc::middle::def::Def; -use rustc::middle::def_id::DefId; -use rustc::middle::pat_util::def_to_path; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; +use rustc::hir::pat_util::def_to_path; use rustc::ty::{self, Ty, TyCtxt, subst}; use rustc::ty::util::IntTypeExt; use rustc::traits::ProjectionMode; diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index ed9c66a1882..d10691d12ed 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def::Def; +use rustc::hir::def::Def; use rustc::ty; use lint::{LateContext, LintContext, LintArray}; use lint::{LintPass, LateLintPass}; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6f11ebafa86..fe10ca87b75 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -28,9 +28,9 @@ //! Use the former for unit-like structs and the latter for structs with //! a `pub fn new()`. -use middle::def::Def; +use rustc::hir::def::Def; use middle::cstore::CrateStore; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use middle::stability; use rustc::{cfg, infer}; use rustc::ty::subst::Substs; diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 574c7af4cfc..891731cb296 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -10,7 +10,7 @@ #![allow(non_snake_case)] -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index f531628601b..d1595f243c9 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::pat_util; +use rustc::hir::pat_util; use rustc::ty; use rustc::ty::adjustment; use util::nodemap::FnvHashMap; diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 61f35a12df7..df60e35d0f3 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -31,8 +31,8 @@ use middle::cstore::{InlinedItem, InlinedItemRef}; use rustc::ty::adjustment; use rustc::ty::cast; use middle::const_qualif::ConstQualif; -use middle::def::{self, Def}; -use middle::def_id::DefId; +use rustc::hir::def::{self, Def}; +use rustc::hir::def_id::DefId; use middle::region; use rustc::ty::subst; use rustc::ty::{self, Ty, TyCtxt}; diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index c9e661dec51..bb691cebccd 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -15,10 +15,10 @@ use loader; use middle::cstore::{CrateStore, CrateSource, ChildItem, ExternCrate, FoundAst, DefLike}; use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; -use middle::def; +use rustc::hir::def; use middle::lang_items; use rustc::ty::{self, Ty, TyCtxt, VariantKind}; -use middle::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; +use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::hir::map as hir_map; use rustc::mir::repr::Mir; diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 3a6cd4d832b..d5a9adafe7d 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -20,10 +20,10 @@ use decoder; use index; use loader; +use rustc::hir::def_id::DefId; use rustc::hir::svh::Svh; use rustc::middle::cstore::{ExternCrate}; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap}; -use rustc::middle::def_id::DefId; use std::cell::{RefCell, Ref, Cell}; use std::rc::Rc; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 5aafd015f9a..e6f538255ac 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -29,8 +29,8 @@ use rustc::hir; use middle::cstore::{LOCAL_CRATE, FoundAst, InlinedItem, LinkagePreference}; use middle::cstore::{DefLike, DlDef, DlField, DlImpl, tls}; -use middle::def::Def; -use middle::def_id::{DefId, DefIndex}; +use rustc::hir::def::Def; +use rustc::hir::def_id::{DefId, DefIndex}; use middle::lang_items; use rustc::ty::subst; use rustc::ty::{ImplContainer, TraitContainer}; diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index dc21ebcbcfc..83ffd8afbeb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -21,8 +21,8 @@ use tyencode; use index::{self, IndexData}; use middle::cstore::{LOCAL_CRATE, CrateStore, InlinedItemRef, LinkMeta, tls}; -use middle::def; -use middle::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; use middle::stability; use rustc::ty::subst; diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index 60bbdaddd75..9c066f9f5f1 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def_id::{DefId, DefIndex}; +use rustc::hir::def_id::{DefId, DefIndex}; use rbml; use std::io::{Cursor, Write}; use std::slice; diff --git a/src/librustc_metadata/tls_context.rs b/src/librustc_metadata/tls_context.rs index 6ecd7a7f50a..782c7cba26e 100644 --- a/src/librustc_metadata/tls_context.rs +++ b/src/librustc_metadata/tls_context.rs @@ -14,7 +14,7 @@ use rbml::opaque::Encoder as OpaqueEncoder; use rbml::opaque::Decoder as OpaqueDecoder; use rustc::middle::cstore::tls; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use rustc::ty::{self, TyCtxt}; diff --git a/src/librustc_metadata/tydecode.rs b/src/librustc_metadata/tydecode.rs index cd63b58372b..3004246d1d7 100644 --- a/src/librustc_metadata/tydecode.rs +++ b/src/librustc_metadata/tydecode.rs @@ -18,7 +18,7 @@ use rustc::hir; -use middle::def_id::{DefId, DefIndex}; +use rustc::hir::def_id::{DefId, DefIndex}; use middle::region; use rustc::ty::subst; use rustc::ty::subst::VecPerParamSpace; diff --git a/src/librustc_metadata/tyencode.rs b/src/librustc_metadata/tyencode.rs index b5079256487..f49c2e22c6a 100644 --- a/src/librustc_metadata/tyencode.rs +++ b/src/librustc_metadata/tyencode.rs @@ -17,7 +17,7 @@ use std::cell::RefCell; use std::io::Cursor; use std::io::prelude::*; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use middle::region; use rustc::ty::subst; use rustc::ty::subst::VecPerParamSpace; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 790833f99ca..7f748ef9b1e 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -15,11 +15,11 @@ use hair::cx::Cx; use hair::cx::block; use hair::cx::to_ref::ToRef; use rustc::hir::map; -use rustc::middle::def::Def; +use rustc::hir::def::Def; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; use rustc::middle::region::CodeExtent; -use rustc::middle::pat_util; +use rustc::hir::pat_util; use rustc::ty::{self, VariantDef, Ty}; use rustc::mir::repr::*; use rustc::hir; diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index f0c6887802d..c3a5fbd967c 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -20,7 +20,7 @@ use rustc::mir::repr::*; use rustc::middle::const_val::ConstVal; use rustc_const_eval as const_eval; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt}; diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index 673d12c3316..990ba9e786c 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -12,8 +12,8 @@ use hair::*; use hair::cx::Cx; use rustc_data_structures::fnv::FnvHashMap; use rustc_const_eval as const_eval; -use rustc::middle::def::Def; -use rustc::middle::pat_util::{pat_is_resolved_const, pat_is_binding}; +use rustc::hir::def::Def; +use rustc::hir::pat_util::{pat_is_resolved_const, pat_is_binding}; use rustc::ty::{self, Ty}; use rustc::mir::repr::*; use rustc::hir::{self, PatKind}; diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 0ea8dece47c..51f2cc2687a 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -17,7 +17,7 @@ use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, Mutability, UnOp, TypedConstVal}; use rustc::middle::const_val::ConstVal; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::middle::region::CodeExtent; use rustc::ty::subst::Substs; use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty}; diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs index 38784191a78..4659bb389dc 100644 --- a/src/librustc_passes/consts.rs +++ b/src/librustc_passes/consts.rs @@ -30,8 +30,8 @@ use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, compare_lit_exprs}; use rustc_const_eval::{eval_const_expr_partial, lookup_const_by_id}; use rustc_const_eval::ErrKind::{IndexOpFeatureGated, UnimplementedConstVal}; use rustc_const_eval::EvalHint::ExprTypeChecked; -use rustc::middle::def::Def; -use rustc::middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::middle::expr_use_visitor as euv; use rustc::infer; use rustc::middle::mem_categorization as mc; diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index 2766d13d7b8..245960a04f0 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -14,7 +14,7 @@ use rustc::dep_graph::DepNode; use rustc::hir::map as ast_map; use rustc::session::{Session, CompileResult}; -use rustc::middle::def::{Def, DefMap}; +use rustc::hir::def::{Def, DefMap}; use rustc::util::nodemap::NodeMap; use syntax::{ast}; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 908a7869c42..8840bd42717 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -35,8 +35,8 @@ use rustc::hir::intravisit::{self, Visitor}; use rustc::dep_graph::DepNode; use rustc::lint; use rustc::middle::cstore::CrateStore; -use rustc::middle::def::{self, Def}; -use rustc::middle::def_id::DefId; +use rustc::hir::def::{self, Def}; +use rustc::hir::def_id::DefId; use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::ty::{self, TyCtxt}; use rustc::util::nodemap::NodeSet; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 470fd88025e..a422b09f96b 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -24,8 +24,8 @@ use {resolve_error, resolve_struct_error, ResolutionError}; use rustc::middle::cstore::{CrateStore, ChildItem, DlDef}; use rustc::lint; -use rustc::middle::def::*; -use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def::*; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::ty::VariantKind; use syntax::ast::Name; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c0b8aad1c09..502b45c9453 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -52,9 +52,9 @@ use rustc::hir::map as hir_map; use rustc::session::Session; use rustc::lint; use rustc::middle::cstore::CrateStore; -use rustc::middle::def::*; -use rustc::middle::def_id::DefId; -use rustc::middle::pat_util::pat_bindings; +use rustc::hir::def::*; +use rustc::hir::def_id::DefId; +use rustc::hir::pat_util::pat_bindings; use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::ty::{Freevar, FreevarMap, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, FnvHashMap}; @@ -2570,7 +2570,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } /// Skips `path_depth` trailing segments, which is also reflected in the - /// returned value. See `middle::def::PathResolution` for more info. + /// returned value. See `hir::def::PathResolution` for more info. fn resolve_path(&mut self, id: NodeId, path: &Path, path_depth: usize, namespace: Namespace) -> Option { let span = path.span; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 2aa8925fb54..738a99fbe92 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -22,7 +22,7 @@ use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc::lint; -use rustc::middle::def::*; +use rustc::hir::def::*; use syntax::ast::{NodeId, Name}; use syntax::attr::AttrMetaMethods; diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs index 3021d4e9820..0e02830db7a 100644 --- a/src/librustc_save_analysis/csv_dumper.rs +++ b/src/librustc_save_analysis/csv_dumper.rs @@ -10,7 +10,7 @@ use std::io::Write; -use rustc::middle::def_id::{DefId, DefIndex}; +use rustc::hir::def_id::{DefId, DefIndex}; use syntax::codemap::Span; use super::data::*; diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index 649c8387eb3..7f2f2618c3c 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -15,7 +15,7 @@ use std::hash::Hasher; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty; use syntax::ast::{CrateNum, NodeId}; use syntax::codemap::Span; diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 310747c8991..c724091a2ec 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -27,8 +27,8 @@ //! is used for recording the output in a format-agnostic way (see CsvDumper //! for an example). -use rustc::middle::def::Def; -use rustc::middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::session::Session; use rustc::ty::{self, TyCtxt}; diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index a4f9720bbe2..98c0be1c93c 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -29,8 +29,8 @@ use rustc::hir::{self, lowering}; use rustc::hir::map::NodeItem; -use rustc::middle::def::Def; -use rustc::middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::session::config::CrateType::CrateTypeExecutable; use rustc::ty::{self, TyCtxt}; diff --git a/src/librustc_trans/_match.rs b/src/librustc_trans/_match.rs index 3bbead9847b..d8b8f9f0806 100644 --- a/src/librustc_trans/_match.rs +++ b/src/librustc_trans/_match.rs @@ -191,14 +191,14 @@ use self::FailureHandler::*; use llvm::{ValueRef, BasicBlockRef}; use rustc_const_eval::check_match::{self, StaticInliner}; use rustc_const_eval::{compare_lit_exprs, eval_const_expr}; -use middle::def::{Def, DefMap}; -use middle::def_id::DefId; +use rustc::hir::def::{Def, DefMap}; +use rustc::hir::def_id::DefId; use middle::expr_use_visitor as euv; use rustc::infer; use middle::lang_items::StrEqFnLangItem; use middle::mem_categorization as mc; use middle::mem_categorization::Categorization; -use middle::pat_util::*; +use rustc::hir::pat_util::*; use rustc::ty::subst::Substs; use adt; use base::*; diff --git a/src/librustc_trans/assert_dep_graph.rs b/src/librustc_trans/assert_dep_graph.rs index ecbb5049443..932f66f17cc 100644 --- a/src/librustc_trans/assert_dep_graph.rs +++ b/src/librustc_trans/assert_dep_graph.rs @@ -39,7 +39,7 @@ use graphviz as dot; use rustc::dep_graph::{DepGraphQuery, DepNode}; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty::TyCtxt; use rustc_data_structures::fnv::{FnvHashMap, FnvHashSet}; use rustc_data_structures::graph::{Direction, INCOMING, OUTGOING, NodeIndex}; diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 949a10297c1..8127d1c0e29 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -102,7 +102,7 @@ use monomorphize::Instance; use util::sha2::{Digest, Sha256}; use rustc::middle::cstore; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty::{self, TypeFoldable}; use rustc::ty::item_path::{ItemPathBuffer, RootMode}; use rustc::hir::map::definitions::{DefPath, DefPathData}; diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 6714f6440ee..4f1585eeaca 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -36,11 +36,11 @@ use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param}; use llvm; use rustc::cfg; use middle::cstore::CrateStore; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; -use middle::pat_util::simple_name; +use rustc::hir::pat_util::simple_name; use rustc::ty::subst::{self, Substs}; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 2da9acf3250..392c40a6015 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -21,7 +21,7 @@ use arena::TypedArena; use back::symbol_names; use llvm::{self, ValueRef, get_params}; use middle::cstore::LOCAL_CRATE; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::ty::subst; use rustc::ty::subst::{Substs}; diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs index 579848919ec..6bd5fd355a7 100644 --- a/src/librustc_trans/closure.rs +++ b/src/librustc_trans/closure.rs @@ -11,7 +11,7 @@ use arena::TypedArena; use back::symbol_names; use llvm::{ValueRef, get_param, get_params}; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::traits::ProjectionMode; use abi::{Abi, FnType}; diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 4f197dbee13..c72a1a6bef3 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -192,7 +192,7 @@ use rustc::hir; use rustc::hir::intravisit as hir_visit; use rustc::hir::map as hir_map; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::middle::lang_items::{ExchangeFreeFnLangItem, ExchangeMallocFnLangItem}; use rustc::traits; use rustc::ty::subst::{self, Substs, Subst}; diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs index 1f48eb91603..5ce7caf5deb 100644 --- a/src/librustc_trans/common.rs +++ b/src/librustc_trans/common.rs @@ -17,8 +17,8 @@ use llvm; use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef, TypeKind}; use llvm::{True, False, Bool, OperandBundleDef}; use rustc::cfg; -use middle::def::Def; -use middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::infer; use middle::lang_items::LangItem; use rustc::ty::subst::Substs; diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 7945639f86b..89f3b295c8d 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -15,8 +15,8 @@ use llvm::{InternalLinkage, ValueRef, Bool, True}; use middle::const_qualif::ConstQualif; use rustc_const_eval::{ConstEvalErr, lookup_const_fn_by_id, lookup_const_by_id, ErrKind}; use rustc_const_eval::eval_repeat_count; -use middle::def::Def; -use middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use {abi, adt, closure, debuginfo, expr, machine}; use base::{self, exported_name, imported_name, push_ctxt}; diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index 3574883c5f5..9bbc72eba36 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -12,8 +12,8 @@ use llvm; use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef}; use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig}; use middle::cstore::LinkMeta; -use middle::def::ExportMap; -use middle::def_id::DefId; +use rustc::hir::def::ExportMap; +use rustc::hir::def_id::DefId; use rustc::traits; use rustc::mir::mir_map::MirMap; use rustc::mir::repr as mir; diff --git a/src/librustc_trans/controlflow.rs b/src/librustc_trans/controlflow.rs index f3cb4d5001a..58971dec8a9 100644 --- a/src/librustc_trans/controlflow.rs +++ b/src/librustc_trans/controlflow.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::ValueRef; -use middle::def::Def; +use rustc::hir::def::Def; use middle::lang_items::{PanicFnLangItem, PanicBoundsCheckFnLangItem}; use rustc::ty::subst::Substs; use base::*; diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index b98b9881350..b1cfeb8125b 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -14,7 +14,7 @@ use super::utils::DIB; use llvm; use llvm::debuginfo::{DIScope, DISubprogram}; use common::CrateContext; -use middle::pat_util; +use rustc::hir::pat_util; use rustc::util::nodemap::NodeMap; use libc::c_uint; diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index acfafc6e329..822155f8c36 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -23,9 +23,9 @@ use super::{declare_local, VariableKind, VariableAccess}; use llvm::{self, ValueRef}; use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType}; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; -use middle::pat_util; +use rustc::hir::pat_util; use rustc::ty::subst; use rustc::hir::map as hir_map; use rustc::hir::{self, PatKind}; diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 7e9c8228f29..bb999c31ffb 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -26,7 +26,7 @@ use llvm; use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIDescriptor, FlagPrototyped}; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer::normalize_associated_type; use rustc::ty::subst::{self, Substs}; use rustc::hir; diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 1feb47a3a7d..c1487f56956 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -14,7 +14,7 @@ use super::utils::{DIB, debug_context}; use llvm; use llvm::debuginfo::DIScope; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::hir::map as hir_map; use common::CrateContext; diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index f5bb1677f29..0169734ad3b 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -13,7 +13,7 @@ use super::namespace::crate_root_namespace; use common::CrateContext; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::ty::subst; use rustc::ty::{self, Ty}; diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index 61dc3dc3f8f..bef7af3aec6 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -13,7 +13,7 @@ use super::{FunctionDebugContext, CrateDebugContext}; use super::namespace::namespace_for_item; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use llvm; use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; diff --git a/src/librustc_trans/expr.rs b/src/librustc_trans/expr.rs index fce8656fb93..beca81da05f 100644 --- a/src/librustc_trans/expr.rs +++ b/src/librustc_trans/expr.rs @@ -53,7 +53,7 @@ use self::lazy_binop_ty::*; use llvm::{self, ValueRef, TypeKind}; use middle::const_qualif::ConstQualif; -use middle::def::Def; +use rustc::hir::def::Def; use rustc::ty::subst::Substs; use {_match, abi, adt, asm, base, closure, consts, controlflow}; use base::*; diff --git a/src/librustc_trans/inline.rs b/src/librustc_trans/inline.rs index 36dfbec115e..1eff09d67f9 100644 --- a/src/librustc_trans/inline.rs +++ b/src/librustc_trans/inline.rs @@ -10,7 +10,7 @@ use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage}; use middle::cstore::{CrateStore, FoundAst, InlinedItem}; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty::subst::Substs; use base::{push_ctxt, trans_item, trans_fn}; use callee::Callee; diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 82b61e15f2b..478094c2b87 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -13,7 +13,7 @@ use std::rc::Rc; use arena::TypedArena; use back::symbol_names; use llvm::{ValueRef, get_params}; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::ty::subst::{FnSpace, Subst, Substs}; use rustc::ty::subst; diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index de66951d091..ef0da37f0b2 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -11,7 +11,7 @@ use back::symbol_names; use llvm::ValueRef; use llvm; -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer::normalize_associated_type; use rustc::ty::subst; use rustc::ty::subst::{Subst, Substs}; diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs index 8b1aaafab58..500eda2624c 100644 --- a/src/librustc_trans/type_of.rs +++ b/src/librustc_trans/type_of.rs @@ -10,7 +10,7 @@ #![allow(non_camel_case_types)] -use middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::infer; use rustc::ty::subst; use abi::FnType; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a52b8cad108..21122e7095d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -52,8 +52,8 @@ use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_project use middle::const_val::ConstVal; use rustc_const_eval::eval_const_expr_partial; use rustc_const_eval::EvalHint::UncheckedExprHint; -use middle::def::{self, Def}; -use middle::def_id::DefId; +use hir::def::{self, Def}; +use hir::def_id::DefId; use middle::resolve_lifetime as rl; use rustc::ty::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace}; use rustc::traits; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index eaf8479585f..8dbd6496b6f 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -8,10 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use middle::def::{self, Def}; +use hir::def::{self, Def}; use rustc::infer::{self, InferOk, TypeOrigin}; -use middle::pat_util::{PatIdMap, pat_id_map, pat_is_binding}; -use middle::pat_util::pat_is_resolved_const; +use hir::pat_util::{PatIdMap, pat_id_map, pat_is_binding}; +use hir::pat_util::pat_is_resolved_const; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference}; use check::{check_expr, check_expr_has_type, check_expr_with_expectation}; diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 460230c60c6..21800d91d94 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -26,8 +26,8 @@ use super::write_call; use CrateCtxt; use middle::cstore::LOCAL_CRATE; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use rustc::infer; use rustc::ty::{self, LvaluePreference, Ty}; use syntax::codemap::Span; diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 00a73a062fe..91cdb8d966d 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -44,7 +44,7 @@ use super::FnCtxt; use super::structurally_resolved_type; use lint; -use middle::def_id::DefId; +use hir::def_id::DefId; use rustc::ty::{self, Ty, TypeFoldable}; use rustc::ty::cast::{CastKind, CastTy}; use syntax::codemap::Span; diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 1f1bba509e0..368b826b1bb 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -10,7 +10,7 @@ use check::regionck::{self, Rcx}; -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::free_region::FreeRegionMap; use rustc::infer; use middle::region; diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index cc12b2e0515..b98f1884f01 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -12,7 +12,7 @@ use super::probe; use check::{self, FnCtxt, callee, demand}; use check::UnresolvedTypeAction; -use middle::def_id::DefId; +use hir::def_id::DefId; use rustc::ty::subst::{self}; use rustc::traits; use rustc::ty::{self, NoPreference, PreferMutLvalue, Ty, TyCtxt}; diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 72ca73aac94..3f069a68316 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -12,8 +12,8 @@ use astconv::AstConv; use check::FnCtxt; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use rustc::ty::subst; use rustc::traits; use rustc::ty::{self, TyCtxt, ToPredicate, ToPolyTraitRef, TraitRef, TypeFoldable}; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index c907a6dc640..7d98eac30c5 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -15,8 +15,8 @@ use super::suggest; use check; use check::{FnCtxt, UnresolvedTypeAction}; -use middle::def_id::DefId; -use middle::def::Def; +use hir::def_id::DefId; +use hir::def::Def; use rustc::ty::subst; use rustc::ty::subst::Subst; use rustc::traits; diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 620863a7a2e..c5195cf8787 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -18,8 +18,8 @@ use check::{self, FnCtxt, UnresolvedTypeAction, autoderef}; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; use middle::cstore::{self, CrateStore}; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use middle::lang_items::FnOnceTraitLangItem; use rustc::ty::subst::Substs; use rustc::ty::LvaluePreference; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c3a42826dbc..e7159e65eeb 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -86,10 +86,10 @@ use dep_graph::DepNode; use fmt_macros::{Parser, Piece, Position}; use middle::astconv_util::prohibit_type_params; use middle::cstore::LOCAL_CRATE; -use middle::def::{self, Def}; -use middle::def_id::DefId; +use hir::def::{self, Def}; +use hir::def_id::DefId; use rustc::infer::{self, InferOk, TypeOrigin, TypeTrace, type_variable}; -use middle::pat_util::{self, pat_id_map}; +use hir::pat_util::{self, pat_id_map}; use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace}; use rustc::traits::{self, report_fulfillment_errors, ProjectionMode}; use rustc::ty::{GenericPredicates, TypeScheme}; diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index f7f40e6077f..debf9258757 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -18,7 +18,7 @@ use super::{ method, FnCtxt, }; -use middle::def_id::DefId; +use hir::def_id::DefId; use rustc::ty::{Ty, TypeFoldable, PreferMutLvalue}; use syntax::ast; use syntax::parse::token; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 02114c170c4..2a4de6e091b 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -93,7 +93,7 @@ use rustc::ty::subst::Substs; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, MethodCall, TypeFoldable}; use rustc::infer::{self, GenericKind, InferCtxt, InferOk, SubregionOrigin, TypeOrigin, VerifyBound}; -use middle::pat_util; +use hir::pat_util; use rustc::ty::adjustment; use rustc::ty::wf::ImpliedBound; diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 0ed0b64b970..1b21e6ce9eb 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -12,7 +12,7 @@ use astconv::AstConv; use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck}; use constrained_type_params::{identify_constrained_type_params, Parameter}; use CrateCtxt; -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::region::{CodeExtent}; use rustc::ty::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; use rustc::traits; diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 50f2f27b3d2..68327ccd39a 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -15,8 +15,8 @@ use self::ResolveReason::*; use astconv::AstConv; use check::FnCtxt; -use middle::def_id::DefId; -use middle::pat_util; +use hir::def_id::DefId; +use hir::pat_util; use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee}; use rustc::ty::adjustment; use rustc::ty::fold::{TypeFolder,TypeFoldable}; diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 1f7fc453279..9c8c9ba5056 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -15,7 +15,7 @@ // done by the orphan and overlap modules. Then we build up various // mappings. That mapping code resides here. -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::lang_items::UnsizeTraitLangItem; use rustc::ty::subst::{self, Subst}; use rustc::ty::{self, TyCtxt, TypeFoldable}; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 0821d5582bd..f3d63957018 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -12,7 +12,7 @@ //! crate or pertains to a type defined in this crate. use middle::cstore::LOCAL_CRATE; -use middle::def_id::DefId; +use hir::def_id::DefId; use rustc::traits; use rustc::ty::{self, TyCtxt}; use syntax::ast; diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index d99c5d52f4a..a05167dbe43 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -13,7 +13,7 @@ //! constructor provide a method with the same name. use middle::cstore::CrateStore; -use middle::def_id::DefId; +use hir::def_id::DefId; use rustc::traits::{self, ProjectionMode}; use rustc::infer; use rustc::ty::{self, TyCtxt}; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 53126d3494a..9d76b4c5284 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -60,8 +60,8 @@ There are some shortcomings in this design: use astconv::{self, AstConv, ty_of_arg, ast_ty_to_ty, ast_region_to_region}; use lint; -use middle::def::Def; -use middle::def_id::DefId; +use hir::def::Def; +use hir::def_id::DefId; use constrained_type_params as ctp; use coherence; use middle::lang_items::SizedTraitLangItem; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index af32026d47e..ab2276c324b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -103,7 +103,7 @@ pub use rustc::util; use dep_graph::DepNode; use hir::map as hir_map; -use middle::def::Def; +use hir::def::Def; use rustc::infer::{self, TypeOrigin}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index fa3ee80c6da..3b03a713a5b 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -14,7 +14,7 @@ //! We walk the set of items and, for each member, generate new constraints. use dep_graph::DepTrackingMapConfig; -use middle::def_id::DefId; +use hir::def_id::DefId; use middle::resolve_lifetime as rl; use rustc::ty::subst; use rustc::ty::subst::ParamSpace; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 2f080dae370..70997a1a6ee 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -17,8 +17,8 @@ use syntax::attr::AttrMetaMethods; use rustc::hir; use rustc::middle::cstore::{self, CrateStore}; -use rustc::middle::def::Def; -use rustc::middle::def_id::DefId; +use rustc::hir::def::Def; +use rustc::hir::def_id::DefId; use rustc::ty::{self, TyCtxt}; use rustc::ty::subst; use rustc::middle::stability; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 715d0e759c3..4895022cfac 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -35,8 +35,8 @@ use syntax::ptr::P; use rustc_trans::back::link; use rustc::middle::cstore::{self, CrateStore}; -use rustc::middle::def::Def; -use rustc::middle::def_id::{DefId, DefIndex}; +use rustc::hir::def::Def; +use rustc::hir::def_id::{DefId, DefIndex}; use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace}; use rustc::ty; use rustc::middle::stability; diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index e6a4d882c04..4ba412cdc85 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -29,7 +29,7 @@ use std::mem; use std::collections::HashMap; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::ty::subst; use clean::PathParameters as PP; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 4686e60be87..6b7aa103e1d 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -13,7 +13,7 @@ use rustc_lint; use rustc_driver::{driver, target_features, abort_on_err}; use rustc::dep_graph::DepGraph; use rustc::session::{self, config}; -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; use rustc::hir::map as hir_map; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 9f0b636227f..a43711a3273 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -19,7 +19,7 @@ use std::fmt; use std::iter::repeat; use rustc::middle::cstore::LOCAL_CRATE; -use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use syntax::abi::Abi; use rustc::hir; diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index f97d4fee053..d63e704e06b 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -56,7 +56,7 @@ use serialize::json::{ToJson, Json, as_json}; use syntax::{abi, ast}; use syntax::feature_gate::UnstableFeatures; use rustc::middle::cstore::LOCAL_CRATE; -use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::middle::privacy::AccessLevels; use rustc::middle::stability; use rustc::session::config::get_unstable_features_setting; diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 31f00caee43..ff2a9f13e8a 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::middle::def_id::DefId; +use rustc::hir::def_id::DefId; use rustc::middle::privacy::AccessLevels; use rustc::util::nodemap::DefIdSet; use std::cmp; -- cgit 1.4.1-3-g733a5 From 20f0f3c1f131b54dcc6fdc7eeb1d04ea89f5f6fd Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Tue, 29 Mar 2016 13:14:01 +0300 Subject: rustc: move some maps from ty to hir. --- src/librustc/hir/mod.rs | 25 +++++++++++++++++++++++++ src/librustc/ty/context.rs | 2 +- src/librustc/ty/mod.rs | 28 +++------------------------- src/librustc_metadata/astencode.rs | 14 +++++++------- src/librustc_mir/hair/cx/expr.rs | 2 +- src/librustc_resolve/lib.rs | 8 ++++---- src/librustc_typeck/lib.rs | 4 ++-- 7 files changed, 43 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 10fe86246de..edb9b783527 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -33,6 +33,10 @@ pub use self::ViewPath_::*; pub use self::Visibility::*; pub use self::PathParameters::*; +use hir::def::Def; +use hir::def_id::DefId; +use util::nodemap::{NodeMap, FnvHashSet}; + use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId}; use syntax::abi::Abi; use syntax::ast::{Name, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect}; @@ -1625,3 +1629,24 @@ impl ForeignItem_ { } } } + +/// A free variable referred to in a function. +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] +pub struct Freevar { + /// The variable being accessed free. + pub def: Def, + + // First span where it is accessed (there can be multiple). + pub span: Span +} + +pub type FreevarMap = NodeMap>; + +pub type CaptureModeMap = NodeMap; + +// Trait method resolution +pub type TraitMap = NodeMap>; + +// Map from the NodeId of a glob import to a list of items which are actually +// imported. +pub type GlobMap = NodeMap>; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 14ffeadbb3a..bdba700f49a 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -27,7 +27,7 @@ use traits; use ty::{self, TraitRef, Ty, TypeAndMut}; use ty::{TyS, TypeVariants}; use ty::{AdtDef, ClosureSubsts, ExistentialBounds, Region}; -use ty::{FreevarMap}; +use hir::FreevarMap; use ty::{BareFnTy, InferTy, ParamTy, ProjectionTy, TraitTy}; use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid}; use ty::TypeVariants::*; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2f0b520d842..4ff859f5a94 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -33,7 +33,7 @@ use ty::fold::TypeFolder; use ty::subst::{Subst, Substs, VecPerParamSpace}; use ty::walk::TypeWalker; use util::common::MemoizationMap; -use util::nodemap::{NodeMap, NodeSet}; +use util::nodemap::NodeSet; use util::nodemap::FnvHashMap; use serialize::{Encodable, Encoder, Decodable, Decoder}; @@ -44,7 +44,6 @@ use std::iter; use std::rc::Rc; use std::slice; use std::vec::IntoIter; -use std::collections::{HashMap, HashSet}; use syntax::ast::{self, CrateNum, Name, NodeId}; use syntax::attr::{self, AttrMetaMethods}; use syntax::codemap::{DUMMY_SP, Span}; @@ -115,7 +114,7 @@ pub struct CrateAnalysis<'a> { pub access_levels: middle::privacy::AccessLevels, pub reachable: NodeSet, pub name: &'a str, - pub glob_map: Option, + pub glob_map: Option, } #[derive(Copy, Clone)] @@ -2724,30 +2723,9 @@ pub enum ExplicitSelfCategory { ByBox, } -/// A free variable referred to in a function. -#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] -pub struct Freevar { - /// The variable being accessed free. - pub def: Def, - - // First span where it is accessed (there can be multiple). - pub span: Span -} - -pub type FreevarMap = NodeMap>; - -pub type CaptureModeMap = NodeMap; - -// Trait method resolution -pub type TraitMap = NodeMap>; - -// Map from the NodeId of a glob import to a list of items which are actually -// imported. -pub type GlobMap = HashMap>; - impl<'tcx> TyCtxt<'tcx> { pub fn with_freevars(&self, fid: NodeId, f: F) -> T where - F: FnOnce(&[Freevar]) -> T, + F: FnOnce(&[hir::Freevar]) -> T, { match self.freevars.borrow().get(&fid) { None => f(&[]), diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index df60e35d0f3..3becc93f8a4 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -410,20 +410,20 @@ impl tr for Def { // ______________________________________________________________________ // Encoding and decoding of freevar information -fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &ty::Freevar) { +fn encode_freevar_entry(rbml_w: &mut Encoder, fv: &hir::Freevar) { (*fv).encode(rbml_w).unwrap(); } trait rbml_decoder_helper { fn read_freevar_entry(&mut self, dcx: &DecodeContext) - -> ty::Freevar; + -> hir::Freevar; fn read_capture_mode(&mut self) -> hir::CaptureClause; } impl<'a> rbml_decoder_helper for reader::Decoder<'a> { fn read_freevar_entry(&mut self, dcx: &DecodeContext) - -> ty::Freevar { - let fv: ty::Freevar = Decodable::decode(self).unwrap(); + -> hir::Freevar { + let fv: hir::Freevar = Decodable::decode(self).unwrap(); fv.tr(dcx) } @@ -433,9 +433,9 @@ impl<'a> rbml_decoder_helper for reader::Decoder<'a> { } } -impl tr for ty::Freevar { - fn tr(&self, dcx: &DecodeContext) -> ty::Freevar { - ty::Freevar { +impl tr for hir::Freevar { + fn tr(&self, dcx: &DecodeContext) -> hir::Freevar { + hir::Freevar { def: self.def.tr(dcx), span: self.span.tr(dcx), } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 7f748ef9b1e..12dcb32da3f 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -958,7 +958,7 @@ fn overloaded_lvalue<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, fn capture_freevar<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, closure_expr: &'tcx hir::Expr, - freevar: &ty::Freevar, + freevar: &hir::Freevar, freevar_ty: Ty<'tcx>) -> ExprRef<'tcx> { let id_var = freevar.def.var_id(); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 502b45c9453..299a8c0299d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -56,8 +56,8 @@ use rustc::hir::def::*; use rustc::hir::def_id::DefId; use rustc::hir::pat_util::pat_bindings; use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; -use rustc::ty::{Freevar, FreevarMap, TraitMap, GlobMap}; -use rustc::util::nodemap::{NodeMap, FnvHashMap}; +use rustc::hir::{Freevar, FreevarMap, TraitMap, GlobMap}; +use rustc::util::nodemap::{NodeMap, FnvHashMap, FnvHashSet}; use syntax::ast::{self, FloatTy}; use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy}; @@ -1186,7 +1186,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { emit_errors: true, make_glob_map: make_glob_map == MakeGlobMap::Yes, - glob_map: HashMap::new(), + glob_map: NodeMap(), callback: None, resolved: false, @@ -1253,7 +1253,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return; } - let mut new_set = HashSet::new(); + let mut new_set = FnvHashSet(); new_set.insert(name); self.glob_map.insert(import_id, new_set); } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index ab2276c324b..7f27d10ce1e 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -136,7 +136,7 @@ pub struct TypeAndSubsts<'tcx> { pub struct CrateCtxt<'a, 'tcx: 'a> { // A mapping from method call sites to traits that have that method. - pub trait_map: ty::TraitMap, + pub trait_map: hir::TraitMap, /// A vector of every trait accessible in the whole crate /// (i.e. including those from subcrates). This is used only for /// error reporting, and so is lazily initialised and generally @@ -329,7 +329,7 @@ fn check_for_entry_fn(ccx: &CrateCtxt) { } } -pub fn check_crate(tcx: &TyCtxt, trait_map: ty::TraitMap) -> CompileResult { +pub fn check_crate(tcx: &TyCtxt, trait_map: hir::TraitMap) -> CompileResult { let time_passes = tcx.sess.time_passes(); let ccx = CrateCtxt { trait_map: trait_map, -- cgit 1.4.1-3-g733a5 From 7f3744f07f0d32f9673af1563d70b22985b1c2cf Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 2 Apr 2016 16:47:53 +0300 Subject: Get rid of ast::StructFieldKind --- src/librustc_front/lowering.rs | 5 ++- src/librustc_save_analysis/lib.rs | 33 +++++++++---------- src/libsyntax/ast.rs | 35 ++------------------ src/libsyntax/ast_util.rs | 6 ---- src/libsyntax/ext/build.rs | 3 +- src/libsyntax/fold.rs | 12 +++---- src/libsyntax/parse/parser.rs | 8 ++--- src/libsyntax/print/pprust.rs | 32 +++++++----------- src/libsyntax/visit.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 55 +++++++------------------------ 10 files changed, 55 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index 66b9e217bd3..4ca30a041a5 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -622,9 +622,8 @@ pub fn lower_struct_field(lctx: &LoweringContext, hir::StructField { span: f.span, id: f.node.id, - name: f.node.ident().map(|ident| ident.name) - .unwrap_or(token::intern(&index.to_string())), - vis: lower_visibility(lctx, f.node.kind.visibility()), + name: f.node.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), + vis: lower_visibility(lctx, f.node.vis), ty: lower_ty(lctx, &f.node.ty), attrs: lower_attrs(lctx, &f.node.attrs), } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 36b94731e45..550628741c2 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -246,23 +246,22 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option { - match field.node.kind { - ast::NamedField(ident, _) => { - let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident); - let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string(); - let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); - filter!(self.span_utils, sub_span, field.span, None); - Some(VariableData { - id: field.node.id, - name: ident.to_string(), - qualname: qualname, - span: sub_span.unwrap(), - scope: scope, - value: "".to_owned(), - type_value: typ, - }) - } - _ => None, + if let Some(ident) = field.node.ident { + let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident); + let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string(); + let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); + filter!(self.span_utils, sub_span, field.span, None); + Some(VariableData { + id: field.node.id, + name: ident.to_string(), + qualname: qualname, + span: sub_span.unwrap(), + scope: scope, + value: "".to_owned(), + type_value: typ, + }) + } else { + None } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a441f2990cd..fb6ae8b88be 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,7 +10,6 @@ // The Rust abstract syntax tree. -pub use self::StructFieldKind::*; pub use self::TyParamBound::*; pub use self::UnsafeSource::*; pub use self::ViewPath_::*; @@ -1878,45 +1877,15 @@ pub enum Visibility { #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub struct StructField_ { - pub kind: StructFieldKind, + pub ident: Option, + pub vis: Visibility, pub id: NodeId, pub ty: P, pub attrs: Vec, } -impl StructField_ { - pub fn ident(&self) -> Option { - match self.kind { - NamedField(ref ident, _) => Some(ident.clone()), - UnnamedField(_) => None - } - } -} - pub type StructField = Spanned; -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub enum StructFieldKind { - NamedField(Ident, Visibility), - /// Element of a tuple-like struct - UnnamedField(Visibility), -} - -impl StructFieldKind { - pub fn is_unnamed(&self) -> bool { - match *self { - UnnamedField(..) => true, - NamedField(..) => false, - } - } - - pub fn visibility(&self) -> &Visibility { - match *self { - NamedField(_, ref vis) | UnnamedField(ref vis) => vis - } - } -} - /// Fields and Ids of enum variants and structs /// /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 852b153044f..671ba3b0996 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -95,12 +95,6 @@ pub fn impl_pretty_name(trait_ref: &Option, ty: Option<&Ty>) -> Ident token::gensym_ident(&pretty[..]) } -pub fn struct_field_visibility(field: ast::StructField) -> Visibility { - match field.node.kind { - ast::NamedField(_, v) | ast::UnnamedField(v) => v - } -} - // ______________________________________________________________________ // Enumerating the IDs which appear in an AST diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0eb42f17f68..a62832b928d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1009,7 +1009,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let fields: Vec<_> = tys.into_iter().map(|ty| { Spanned { span: ty.span, node: ast::StructField_ { ty: ty, - kind: ast::UnnamedField(ast::Visibility::Inherited), + ident: None, + vis: ast::Visibility::Inherited, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, }} diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 46bcb8067a3..eb35d3fd9d3 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -847,15 +847,15 @@ pub fn noop_fold_poly_trait_ref(p: PolyTraitRef, fld: &mut T) -> Poly } pub fn noop_fold_struct_field(f: StructField, fld: &mut T) -> StructField { - let StructField {node: StructField_ {id, kind, ty, attrs}, span} = f; Spanned { node: StructField_ { - id: fld.new_id(id), - kind: kind, - ty: fld.fold_ty(ty), - attrs: fold_attrs(attrs, fld), + id: fld.new_id(f.node.id), + ident: f.node.ident.map(|ident| fld.fold_ident(ident)), + vis: f.node.vis, + ty: fld.fold_ty(f.node.ty), + attrs: fold_attrs(f.node.attrs, fld), }, - span: fld.new_span(span) + span: fld.new_span(f.span) } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 89a504e1ebd..00d60630eac 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -29,7 +29,6 @@ use ast::Local; use ast::MacStmtStyle; use ast::Mac_; use ast::{MutTy, Mutability}; -use ast::NamedField; use ast::{Pat, PatKind}; use ast::{PolyTraitRef, QSelf}; use ast::{Stmt, StmtKind}; @@ -38,7 +37,6 @@ use ast::StrStyle; use ast::SelfKind; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds}; -use ast::UnnamedField; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; use attr::{ThinAttributes, ThinAttributesExt, AttributesExt}; @@ -3848,7 +3846,8 @@ impl<'a> Parser<'a> { self.expect(&token::Colon)?; let ty = self.parse_ty_sum()?; Ok(spanned(lo, self.last_span.hi, ast::StructField_ { - kind: NamedField(name, pr), + ident: Some(name), + vis: pr, id: ast::DUMMY_NODE_ID, ty: ty, attrs: attrs, @@ -5247,7 +5246,8 @@ impl<'a> Parser<'a> { let attrs = p.parse_outer_attributes()?; let lo = p.span.lo; let struct_field_ = ast::StructField_ { - kind: UnnamedField(p.parse_visibility()?), + vis: p.parse_visibility()?, + ident: None, id: ast::DUMMY_NODE_ID, ty: p.parse_ty_sum()?, attrs: attrs, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index a8f28ed3d9e..c7a755aeeac 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1407,14 +1407,9 @@ impl<'a> State<'a> { self.commasep( Inconsistent, struct_def.fields(), |s, field| { - match field.node.kind { - ast::NamedField(..) => panic!("unexpected named field"), - ast::UnnamedField(ref vis) => { - s.print_visibility(vis)?; - s.maybe_print_comment(field.span.lo)?; - s.print_type(&field.node.ty) - } - } + s.print_visibility(field.node.vis)?; + s.maybe_print_comment(field.span.lo)?; + s.print_type(&field.node.ty) } )?; self.pclose()?; @@ -1432,19 +1427,14 @@ impl<'a> State<'a> { self.hardbreak_if_not_bol()?; for field in struct_def.fields() { - match field.node.kind { - ast::UnnamedField(..) => panic!("unexpected unnamed field"), - ast::NamedField(ident, ref visibility) => { - self.hardbreak_if_not_bol()?; - self.maybe_print_comment(field.span.lo)?; - self.print_outer_attributes(&field.node.attrs)?; - self.print_visibility(visibility)?; - self.print_ident(ident)?; - self.word_nbsp(":")?; - self.print_type(&field.node.ty)?; - word(&mut self.s, ",")?; - } - } + self.hardbreak_if_not_bol()?; + self.maybe_print_comment(field.span.lo)?; + self.print_outer_attributes(&field.node.attrs)?; + self.print_visibility(field.node.vis)?; + self.print_ident(field.node.ident.unwrap())?; + self.word_nbsp(":")?; + self.print_type(&field.node.ty)?; + word(&mut self.s, ",")?; } self.bclose(span) diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1251f9bfe13..d97e2db6265 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -619,7 +619,7 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { - walk_opt_ident(visitor, struct_field.span, struct_field.node.ident()); + walk_opt_ident(visitor, struct_field.span, struct_field.node.ident); visitor.visit_ty(&struct_field.node.ty); walk_list!(visitor, visit_attribute, &struct_field.node.attrs); } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 7d452b14dae..12a7270d521 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -186,7 +186,6 @@ pub use self::StaticFields::*; pub use self::SubstructureFields::*; -use self::StructType::*; use std::cell::RefCell; use std::collections::HashSet; @@ -1409,11 +1408,6 @@ impl<'a> MethodDef<'a> { } } -#[derive(PartialEq)] // dogfooding! -enum StructType { - Unknown, Record, Tuple -} - // general helper methods. impl<'a> TraitDef<'a> { fn set_expn_info(&self, @@ -1441,9 +1435,9 @@ impl<'a> TraitDef<'a> { let mut just_spans = Vec::new(); for field in struct_def.fields(){ let sp = self.set_expn_info(cx, field.span); - match field.node.kind { - ast::NamedField(ident, _) => named_idents.push((ident, sp)), - ast::UnnamedField(..) => just_spans.push(sp), + match field.node.ident { + Some(ident) => named_idents.push((ident, sp)), + _ => just_spans.push(sp), } } @@ -1479,53 +1473,26 @@ impl<'a> TraitDef<'a> { -> (P, Vec<(Span, Option, P, &'a [ast::Attribute])>) { - if struct_def.fields().is_empty() { - if struct_def.is_struct() { - return (cx.pat_struct(self.span, struct_path, vec![]), vec![]); - } else { - return (cx.pat_enum(self.span, struct_path, vec![]), vec![]); - } - } - let mut paths = Vec::new(); - let mut ident_expr = Vec::new(); - let mut struct_type = Unknown; - + let mut ident_exprs = Vec::new(); for (i, struct_field) in struct_def.fields().iter().enumerate() { let sp = self.set_expn_info(cx, struct_field.span); - let opt_id = match struct_field.node.kind { - ast::NamedField(ident, _) if (struct_type == Unknown || - struct_type == Record) => { - struct_type = Record; - Some(ident) - } - ast::UnnamedField(..) if (struct_type == Unknown || - struct_type == Tuple) => { - struct_type = Tuple; - None - } - _ => { - cx.span_bug(sp, "a struct with named and unnamed fields in `derive`"); - } - }; let ident = cx.ident_of(&format!("{}_{}", prefix, i)); paths.push(codemap::Spanned{span: sp, node: ident}); let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident))); let val = cx.expr(sp, ast::ExprKind::Paren(val)); - ident_expr.push((sp, opt_id, val, &struct_field.node.attrs[..])); + ident_exprs.push((sp, struct_field.node.ident, val, &struct_field.node.attrs[..])); } let subpats = self.create_subpatterns(cx, paths, mutbl); - - // struct_type is definitely not Unknown, since struct_def.fields - // must be nonempty to reach here let pattern = if struct_def.is_struct() { - let field_pats = subpats.into_iter().zip(&ident_expr) - .map(|(pat, &(_, id, _, _))| { - // id is guaranteed to be Some + let field_pats = subpats.into_iter().zip(&ident_exprs).map(|(pat, &(sp, ident, _, _))| { + if ident.is_none() { + cx.span_bug(sp, "a braced struct with unnamed fields in `derive`"); + } codemap::Spanned { span: pat.span, - node: ast::FieldPat { ident: id.unwrap(), pat: pat, is_shorthand: false }, + node: ast::FieldPat { ident: ident.unwrap(), pat: pat, is_shorthand: false }, } }).collect(); cx.pat_struct(self.span, struct_path, field_pats) @@ -1533,7 +1500,7 @@ impl<'a> TraitDef<'a> { cx.pat_enum(self.span, struct_path, subpats) }; - (pattern, ident_expr) + (pattern, ident_exprs) } fn create_enum_variant_pattern(&self, -- cgit 1.4.1-3-g733a5 From 8fe4290f1cf87bf7b0a0661e6bbe84f3319e614d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Wed, 6 Apr 2016 11:19:10 +0300 Subject: Move span into `StructField` --- src/librustc/lint/context.rs | 2 +- src/librustc_front/lowering.rs | 10 +++++----- src/librustc_save_analysis/dump_visitor.rs | 4 ++-- src/librustc_save_analysis/lib.rs | 6 +++--- src/libsyntax/ast.rs | 5 ++--- src/libsyntax/ast_util.rs | 2 +- src/libsyntax/config.rs | 6 +++--- src/libsyntax/ext/build.rs | 5 +++-- src/libsyntax/fold.rs | 16 +++++++--------- src/libsyntax/parse/parser.rs | 17 ++++++++++------- src/libsyntax/print/pprust.rs | 12 ++++++------ src/libsyntax/visit.rs | 6 +++--- src/libsyntax_ext/deriving/generic/mod.rs | 8 ++++---- 13 files changed, 50 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e78ff513ac4..46ac3846706 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -978,7 +978,7 @@ impl<'a, 'v> ast_visit::Visitor<'v> for EarlyContext<'a> { } fn visit_struct_field(&mut self, s: &ast::StructField) { - self.with_lint_attrs(&s.node.attrs, |cx| { + self.with_lint_attrs(&s.attrs, |cx| { run_lints!(cx, check_struct_field, early_passes, s); ast_visit::walk_struct_field(cx, s); }) diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs index 4ca30a041a5..738a04dea58 100644 --- a/src/librustc_front/lowering.rs +++ b/src/librustc_front/lowering.rs @@ -621,11 +621,11 @@ pub fn lower_struct_field(lctx: &LoweringContext, -> hir::StructField { hir::StructField { span: f.span, - id: f.node.id, - name: f.node.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), - vis: lower_visibility(lctx, f.node.vis), - ty: lower_ty(lctx, &f.node.ty), - attrs: lower_attrs(lctx, &f.node.attrs), + id: f.id, + name: f.ident.map(|ident| ident.name).unwrap_or(token::intern(&index.to_string())), + vis: lower_visibility(lctx, &f.vis), + ty: lower_ty(lctx, &f.ty), + attrs: lower_attrs(lctx, &f.attrs), } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 35ca2a9b014..e9cfd24d410 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -563,7 +563,7 @@ where D: Dump // fields for field in def.fields() { self.process_struct_field_def(field, item.id); - self.visit_ty(&field.node.ty); + self.visit_ty(&field.ty); } self.process_generic_params(ty_params, item.span, &qualname, item.id); @@ -624,7 +624,7 @@ where D: Dump for field in variant.node.data.fields() { self.process_struct_field_def(field, variant.node.data.id()); - self.visit_ty(&field.node.ty); + self.visit_ty(&field.ty); } } self.process_generic_params(ty_params, item.span, &enum_data.qualname, enum_data.id); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 550628741c2..95339c79371 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -246,13 +246,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option { - if let Some(ident) = field.node.ident { + if let Some(ident) = field.ident { let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident); - let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string(); + let typ = self.tcx.node_types().get(&field.id).unwrap().to_string(); let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); filter!(self.span_utils, sub_span, field.span, None); Some(VariableData { - id: field.node.id, + id: field.id, name: ident.to_string(), qualname: qualname, span: sub_span.unwrap(), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fb6ae8b88be..dbe7b078498 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1876,7 +1876,8 @@ pub enum Visibility { } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] -pub struct StructField_ { +pub struct StructField { + pub span: Span, pub ident: Option, pub vis: Visibility, pub id: NodeId, @@ -1884,8 +1885,6 @@ pub struct StructField_ { pub attrs: Vec, } -pub type StructField = Spanned; - /// Fields and Ids of enum variants and structs /// /// For enum variants: `NodeId` represents both an Id of the variant itself (relevant for all diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 671ba3b0996..ffba9e824d4 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -263,7 +263,7 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> { } fn visit_struct_field(&mut self, struct_field: &StructField) { - self.operation.visit_id(struct_field.node.id); + self.operation.visit_id(struct_field.id); visit::walk_struct_field(self, struct_field) } diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 9acb1805cdd..4554a280e5f 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -180,12 +180,12 @@ fn fold_struct(cx: &mut Context, vdata: ast::VariantData) -> ast::VariantD match vdata { ast::VariantData::Struct(fields, id) => { ast::VariantData::Struct(fields.into_iter().filter(|m| { - (cx.in_cfg)(&m.node.attrs) + (cx.in_cfg)(&m.attrs) }).collect(), id) } ast::VariantData::Tuple(fields, id) => { ast::VariantData::Tuple(fields.into_iter().filter(|m| { - (cx.in_cfg)(&m.node.attrs) + (cx.in_cfg)(&m.attrs) }).collect(), id) } ast::VariantData::Unit(id) => ast::VariantData::Unit(id) @@ -434,7 +434,7 @@ impl<'v, 'a, 'b> visit::Visitor<'v> for StmtExprAttrFeatureVisitor<'a, 'b> { } fn visit_struct_field(&mut self, s: &'v ast::StructField) { - if node_survives_cfg(&s.node.attrs, self.config) { + if node_survives_cfg(&s.attrs, self.config) { visit::walk_struct_field(self, s); } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index a62832b928d..a4e5b68277d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1007,13 +1007,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn variant(&self, span: Span, name: Ident, tys: Vec> ) -> ast::Variant { let fields: Vec<_> = tys.into_iter().map(|ty| { - Spanned { span: ty.span, node: ast::StructField_ { + ast::StructField { + span: ty.span, ty: ty, ident: None, vis: ast::Visibility::Inherited, attrs: Vec::new(), id: ast::DUMMY_NODE_ID, - }} + } }).collect(); let vdata = if fields.is_empty() { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index eb35d3fd9d3..46191b95f81 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -847,15 +847,13 @@ pub fn noop_fold_poly_trait_ref(p: PolyTraitRef, fld: &mut T) -> Poly } pub fn noop_fold_struct_field(f: StructField, fld: &mut T) -> StructField { - Spanned { - node: StructField_ { - id: fld.new_id(f.node.id), - ident: f.node.ident.map(|ident| fld.fold_ident(ident)), - vis: f.node.vis, - ty: fld.fold_ty(f.node.ty), - attrs: fold_attrs(f.node.attrs, fld), - }, - span: fld.new_span(f.span) + StructField { + span: fld.new_span(f.span), + id: fld.new_id(f.id), + ident: f.ident.map(|ident| fld.fold_ident(ident)), + vis: f.vis, + ty: fld.fold_ty(f.ty), + attrs: fold_attrs(f.attrs, fld), } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 00d60630eac..28e4682f66b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3845,13 +3845,14 @@ impl<'a> Parser<'a> { let name = self.parse_ident()?; self.expect(&token::Colon)?; let ty = self.parse_ty_sum()?; - Ok(spanned(lo, self.last_span.hi, ast::StructField_ { + Ok(StructField { + span: mk_sp(lo, self.last_span.hi), ident: Some(name), vis: pr, id: ast::DUMMY_NODE_ID, ty: ty, attrs: attrs, - })) + }) } /// Emit an expected item after attributes error. @@ -5245,14 +5246,16 @@ impl<'a> Parser<'a> { |p| { let attrs = p.parse_outer_attributes()?; let lo = p.span.lo; - let struct_field_ = ast::StructField_ { - vis: p.parse_visibility()?, + let vis = p.parse_visibility()?; + let ty = p.parse_ty_sum()?; + Ok(StructField { + span: mk_sp(lo, p.span.hi), + vis: vis, ident: None, id: ast::DUMMY_NODE_ID, - ty: p.parse_ty_sum()?, + ty: ty, attrs: attrs, - }; - Ok(spanned(lo, p.span.hi, struct_field_)) + }) })?; Ok(fields) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c7a755aeeac..e2b1d2f5e7a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1407,9 +1407,9 @@ impl<'a> State<'a> { self.commasep( Inconsistent, struct_def.fields(), |s, field| { - s.print_visibility(field.node.vis)?; + s.print_visibility(&field.vis)?; s.maybe_print_comment(field.span.lo)?; - s.print_type(&field.node.ty) + s.print_type(&field.ty) } )?; self.pclose()?; @@ -1429,11 +1429,11 @@ impl<'a> State<'a> { for field in struct_def.fields() { self.hardbreak_if_not_bol()?; self.maybe_print_comment(field.span.lo)?; - self.print_outer_attributes(&field.node.attrs)?; - self.print_visibility(field.node.vis)?; - self.print_ident(field.node.ident.unwrap())?; + self.print_outer_attributes(&field.attrs)?; + self.print_visibility(&field.vis)?; + self.print_ident(field.ident.unwrap())?; self.word_nbsp(":")?; - self.print_type(&field.node.ty)?; + self.print_type(&field.ty)?; word(&mut self.s, ",")?; } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d97e2db6265..839bbf4805d 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -619,9 +619,9 @@ pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V, struct_field: &'v StructField) { - walk_opt_ident(visitor, struct_field.span, struct_field.node.ident); - visitor.visit_ty(&struct_field.node.ty); - walk_list!(visitor, visit_attribute, &struct_field.node.attrs); + walk_opt_ident(visitor, struct_field.span, struct_field.ident); + visitor.visit_ty(&struct_field.ty); + walk_list!(visitor, visit_attribute, &struct_field.attrs); } pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) { diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 12a7270d521..a389165f715 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -653,7 +653,7 @@ impl<'a> TraitDef<'a> { type_ident: Ident, generics: &Generics) -> P { let field_tys: Vec> = struct_def.fields().iter() - .map(|field| field.node.ty.clone()) + .map(|field| field.ty.clone()) .collect(); let methods = self.methods.iter().map(|method_def| { @@ -701,7 +701,7 @@ impl<'a> TraitDef<'a> { for variant in &enum_def.variants { field_tys.extend(variant.node.data.fields().iter() - .map(|field| field.node.ty.clone())); + .map(|field| field.ty.clone())); } let methods = self.methods.iter().map(|method_def| { @@ -1435,7 +1435,7 @@ impl<'a> TraitDef<'a> { let mut just_spans = Vec::new(); for field in struct_def.fields(){ let sp = self.set_expn_info(cx, field.span); - match field.node.ident { + match field.ident { Some(ident) => named_idents.push((ident, sp)), _ => just_spans.push(sp), } @@ -1481,7 +1481,7 @@ impl<'a> TraitDef<'a> { paths.push(codemap::Spanned{span: sp, node: ident}); let val = cx.expr_deref(sp, cx.expr_path(cx.path_ident(sp,ident))); let val = cx.expr(sp, ast::ExprKind::Paren(val)); - ident_exprs.push((sp, struct_field.node.ident, val, &struct_field.node.attrs[..])); + ident_exprs.push((sp, struct_field.ident, val, &struct_field.attrs[..])); } let subpats = self.create_subpatterns(cx, paths, mutbl); -- cgit 1.4.1-3-g733a5 From e8a8dfb056fb3654bacd6aaa6acbc4536358df23 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Wed, 6 Apr 2016 13:51:55 +0300 Subject: rustc: retire hir::map's paths. --- src/librustc/hir/map/collector.rs | 3 +- src/librustc/hir/map/mod.rs | 239 +++++---------------- src/librustc/hir/pat_util.rs | 10 +- src/librustc/infer/error_reporting.rs | 10 +- src/librustc/middle/cstore.rs | 5 - src/librustc/ty/item_path.rs | 5 + src/librustc/ty/mod.rs | 33 +-- src/librustc_driver/pretty.rs | 19 +- src/librustc_lint/builtin.rs | 5 +- src/librustc_metadata/astencode.rs | 17 +- src/librustc_metadata/common.rs | 9 +- src/librustc_metadata/csearch.rs | 16 -- src/librustc_metadata/decoder.rs | 26 --- src/librustc_metadata/encoder.rs | 101 +-------- src/librustc_mir/graphviz.rs | 2 +- src/librustc_mir/pretty.rs | 2 +- src/librustc_save_analysis/dump_visitor.rs | 8 +- src/librustc_save_analysis/lib.rs | 12 +- src/librustc_trans/base.rs | 11 +- src/librustc_trans/debuginfo/namespace.rs | 140 ++++++------ src/librustc_trans/debuginfo/type_names.rs | 34 +-- src/librustdoc/clean/inline.rs | 8 +- .../pretty-print-path-suffix/foo_method.pp | 2 +- 23 files changed, 192 insertions(+), 525 deletions(-) (limited to 'src') diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index b1a084ac799..94fa393ae3d 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -14,6 +14,7 @@ use super::MapEntry::*; use hir::*; use hir::intravisit::Visitor; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use middle::cstore::InlinedItem; use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; use syntax::codemap::Span; @@ -46,7 +47,7 @@ impl<'ast> NodeCollector<'ast> { } pub fn extend(krate: &'ast Crate, - parent: &'ast InlinedParent, + parent: &'ast InlinedItem, parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 4096606b001..e1b7afda58b 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -9,7 +9,6 @@ // except according to those terms. pub use self::Node::*; -pub use self::PathElem::*; use self::MapEntry::*; use self::collector::NodeCollector; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, @@ -25,7 +24,6 @@ use syntax::abi::Abi; use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; use syntax::attr::ThinAttributesExt; use syntax::codemap::{Span, Spanned}; -use syntax::parse::token; use hir::*; use hir::fold::Folder; @@ -33,85 +31,13 @@ use hir::print as pprust; use arena::TypedArena; use std::cell::RefCell; -use std::fmt; use std::io; -use std::iter; use std::mem; -use std::slice; pub mod blocks; mod collector; pub mod definitions; -#[derive(Clone, Copy, PartialEq, Debug)] -pub enum PathElem { - PathMod(Name), - PathName(Name) -} - -impl PathElem { - pub fn name(&self) -> Name { - match *self { - PathMod(name) | PathName(name) => name - } - } -} - -impl fmt::Display for PathElem { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.name()) - } -} - -#[derive(Clone)] -pub struct LinkedPathNode<'a> { - node: PathElem, - next: LinkedPath<'a>, -} - -#[derive(Copy, Clone)] -pub struct LinkedPath<'a>(Option<&'a LinkedPathNode<'a>>); - -impl<'a> LinkedPath<'a> { - pub fn empty() -> LinkedPath<'a> { - LinkedPath(None) - } - - pub fn from(node: &'a LinkedPathNode) -> LinkedPath<'a> { - LinkedPath(Some(node)) - } -} - -impl<'a> Iterator for LinkedPath<'a> { - type Item = PathElem; - - fn next(&mut self) -> Option { - match self.0 { - Some(node) => { - *self = node.next; - Some(node.node) - } - None => None - } - } -} - -/// The type of the iterator used by with_path. -pub type PathElems<'a, 'b> = iter::Chain>, LinkedPath<'b>>; - -pub fn path_to_string>(path: PI) -> String { - let itr = token::get_ident_interner(); - - path.fold(String::new(), |mut s, e| { - let e = itr.get(e.name()); - if !s.is_empty() { - s.push_str("::"); - } - s.push_str(&e[..]); - s - }) -} - #[derive(Copy, Clone, Debug)] pub enum Node<'ast> { NodeItem(&'ast Item), @@ -156,7 +82,7 @@ pub enum MapEntry<'ast> { /// Roots for node trees. RootCrate, - RootInlinedParent(&'ast InlinedParent) + RootInlinedParent(&'ast InlinedItem) } impl<'ast> Clone for MapEntry<'ast> { @@ -165,12 +91,6 @@ impl<'ast> Clone for MapEntry<'ast> { } } -#[derive(Debug)] -pub struct InlinedParent { - path: Vec, - ii: InlinedItem -} - impl<'ast> MapEntry<'ast> { fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> { match node { @@ -233,7 +153,7 @@ impl<'ast> MapEntry<'ast> { pub struct Forest { krate: Crate, pub dep_graph: DepGraph, - inlined_items: TypedArena + inlined_items: TypedArena } impl Forest { @@ -351,8 +271,10 @@ impl<'ast> Map<'ast> { self.definitions.borrow().def_key(def_id.index) } - pub fn def_path_from_id(&self, id: NodeId) -> DefPath { - self.def_path(self.local_def_id(id)) + pub fn def_path_from_id(&self, id: NodeId) -> Option { + self.opt_local_def_id(id).map(|def_id| { + self.def_path(def_id) + }) } pub fn def_path(&self, def_id: DefId) -> DefPath { @@ -551,8 +473,8 @@ impl<'ast> Map<'ast> { pub fn get_parent_did(&self, id: NodeId) -> DefId { let parent = self.get_parent(id); match self.find_entry(parent) { - Some(RootInlinedParent(&InlinedParent {ii: II::TraitItem(did, _), ..})) => did, - Some(RootInlinedParent(&InlinedParent {ii: II::ImplItem(did, _), ..})) => did, + Some(RootInlinedParent(&II::TraitItem(did, _))) | + Some(RootInlinedParent(&II::ImplItem(did, _))) => did, _ => self.local_def_id(parent) } } @@ -634,80 +556,21 @@ impl<'ast> Map<'ast> { } } - /// returns the name associated with the given NodeId's AST - pub fn get_path_elem(&self, id: NodeId) -> PathElem { - let node = self.get(id); - match node { - NodeItem(item) => { - match item.node { - ItemMod(_) | ItemForeignMod(_) => { - PathMod(item.name) - } - _ => PathName(item.name) - } - } - NodeForeignItem(i) => PathName(i.name), - NodeImplItem(ii) => PathName(ii.name), - NodeTraitItem(ti) => PathName(ti.name), - NodeVariant(v) => PathName(v.node.name), - NodeLifetime(lt) => PathName(lt.name), - NodeTyParam(tp) => PathName(tp.name), + /// Returns the name associated with the given NodeId's AST. + pub fn name(&self, id: NodeId) -> Name { + match self.get(id) { + NodeItem(i) => i.name, + NodeForeignItem(i) => i.name, + NodeImplItem(ii) => ii.name, + NodeTraitItem(ti) => ti.name, + NodeVariant(v) => v.node.name, + NodeLifetime(lt) => lt.name, + NodeTyParam(tp) => tp.name, NodeLocal(&Pat { node: PatKind::Ident(_,l,_), .. }) => { - PathName(l.node.name) + l.node.name }, - _ => bug!("no path elem for {:?}", node) - } - } - - pub fn with_path(&self, id: NodeId, f: F) -> T where - F: FnOnce(PathElems) -> T, - { - self.with_path_next(id, LinkedPath::empty(), f) - } - - pub fn path_to_string(&self, id: NodeId) -> String { - self.with_path(id, |path| path_to_string(path)) - } - - fn path_to_str_with_name(&self, id: NodeId, name: Name) -> String { - self.with_path(id, |path| { - path_to_string(path.chain(Some(PathName(name)))) - }) - } - - fn with_path_next(&self, id: NodeId, next: LinkedPath, f: F) -> T where - F: FnOnce(PathElems) -> T, - { - // This function reveals the name of the item and hence is a - // kind of read. This is inefficient, since it walks ancestors - // and we are walking them anyhow, but whatever. - self.read(id); - - let parent = self.get_parent(id); - let parent = match self.find_entry(id) { - Some(EntryForeignItem(..)) => { - // Anonymous extern items go in the parent scope. - self.get_parent(parent) - } - // But tuple struct ctors don't have names, so use the path of its - // parent, the struct item. Similarly with closure expressions. - Some(EntryStructCtor(..)) | Some(EntryExpr(..)) => { - return self.with_path_next(parent, next, f); - } - _ => parent - }; - if parent == id { - match self.find_entry(id) { - Some(RootInlinedParent(data)) => { - f(data.path.iter().cloned().chain(next)) - } - _ => f([].iter().cloned().chain(next)) - } - } else { - self.with_path_next(parent, LinkedPath::from(&LinkedPathNode { - node: self.get_path_elem(id), - next: next - }), f) + NodeStructCtor(_) => self.name(self.get_parent(id)), + _ => bug!("no name for {}", self.node_to_string(id)) } } @@ -958,7 +821,6 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { /// Used for items loaded from external crate that are being inlined into this /// crate. pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, - parent_path: Vec, parent_def_path: DefPath, parent_def_id: DefId, ii: InlinedItem, @@ -978,27 +840,24 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, II::Foreign(i) => II::Foreign(i.map(|i| fld.fold_foreign_item(i))) }; - let ii_parent = map.forest.inlined_items.alloc(InlinedParent { - path: parent_path, - ii: ii - }); + let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let mut collector = NodeCollector::extend( map.krate(), - ii_parent, + ii, ii_parent_id, parent_def_path, parent_def_id, mem::replace(&mut *map.map.borrow_mut(), vec![]), mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); - ii_parent.ii.visit(&mut collector); + ii.visit(&mut collector); *map.map.borrow_mut() = collector.map; *map.definitions.borrow_mut() = collector.definitions; - &ii_parent.ii + ii } pub trait NodePrinter { @@ -1032,9 +891,24 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { let id_str = format!(" (id={})", id); let id_str = if include_id { &id_str[..] } else { "" }; + let path_str = || { + // This functionality is used for debugging, try to use TyCtxt to get + // the user-friendly path, otherwise fall back to stringifying DefPath. + ::ty::tls::with_opt(|tcx| { + if let Some(tcx) = tcx { + tcx.node_path_str(id) + } else if let Some(path) = map.def_path_from_id(id) { + path.data.into_iter().map(|elem| { + elem.data.to_string() + }).collect::>().join("::") + } else { + String::from("") + } + }) + }; + match map.find(id) { Some(NodeItem(item)) => { - let path_str = map.path_to_str_with_name(id, item.name); let item_str = match item.node { ItemExternCrate(..) => "extern crate", ItemUse(..) => "use", @@ -1050,30 +924,21 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { ItemImpl(..) => "impl", ItemDefaultImpl(..) => "default impl", }; - format!("{} {}{}", item_str, path_str, id_str) + format!("{} {}{}", item_str, path_str(), id_str) } - Some(NodeForeignItem(item)) => { - let path_str = map.path_to_str_with_name(id, item.name); - format!("foreign item {}{}", path_str, id_str) + Some(NodeForeignItem(_)) => { + format!("foreign item {}{}", path_str(), id_str) } Some(NodeImplItem(ii)) => { match ii.node { ImplItemKind::Const(..) => { - format!("assoc const {} in {}{}", - ii.name, - map.path_to_string(id), - id_str) + format!("assoc const {} in {}{}", ii.name, path_str(), id_str) } ImplItemKind::Method(..) => { - format!("method {} in {}{}", - ii.name, - map.path_to_string(id), id_str) + format!("method {} in {}{}", ii.name, path_str(), id_str) } ImplItemKind::Type(_) => { - format!("assoc type {} in {}{}", - ii.name, - map.path_to_string(id), - id_str) + format!("assoc type {} in {}{}", ii.name, path_str(), id_str) } } } @@ -1084,16 +949,12 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { TypeTraitItem(..) => "assoc type", }; - format!("{} {} in {}{}", - kind, - ti.name, - map.path_to_string(id), - id_str) + format!("{} {} in {}{}", kind, ti.name, path_str(), id_str) } Some(NodeVariant(ref variant)) => { format!("variant {} in {}{}", variant.node.name, - map.path_to_string(id), id_str) + path_str(), id_str) } Some(NodeExpr(ref expr)) => { format!("expr {}{}", pprust::expr_to_string(&expr), id_str) @@ -1111,7 +972,7 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String { format!("block {}{}", pprust::block_to_string(&block), id_str) } Some(NodeStructCtor(_)) => { - format!("struct_ctor {}{}", map.path_to_string(id), id_str) + format!("struct_ctor {}{}", path_str(), id_str) } Some(NodeLifetime(ref l)) => { format!("lifetime {}{}", diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index 5eb4d53ea6a..6cc5a29062f 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -210,14 +210,8 @@ pub fn simple_name<'a>(pat: &'a hir::Pat) -> Option { } pub fn def_to_path(tcx: &TyCtxt, id: DefId) -> hir::Path { - tcx.with_path(id, |path| hir::Path { - global: false, - segments: path.last().map(|elem| hir::PathSegment { - identifier: hir::Ident::from_name(elem.name()), - parameters: hir::PathParameters::none(), - }).into_iter().collect(), - span: DUMMY_SP, - }) + let name = tcx.item_name(id); + hir::Path::from_ident(DUMMY_SP, hir::Ident::from_name(name)) } /// Return variants that are necessary to exist for the pattern to match. diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs index 5a0d9ec1332..a7553f4eb1f 100644 --- a/src/librustc/infer/error_reporting.rs +++ b/src/librustc/infer/error_reporting.rs @@ -587,13 +587,9 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { // Only external crates, if either is from a local // module we could have false positives if !(did1.is_local() || did2.is_local()) && did1.krate != did2.krate { - let exp_path = self.tcx.with_path(did1, - |p| p.map(|x| x.to_string()) - .collect::>()); - let found_path = self.tcx.with_path(did2, - |p| p.map(|x| x.to_string()) - .collect::>()); - // We compare strings because PathMod and PathName can be different + let exp_path = self.tcx.item_path_str(did1); + let found_path = self.tcx.item_path_str(did2); + // We compare strings because DefPath can be different // for imported and non-imported crates if exp_path == found_path { let crate_name = self.tcx.sess.cstore.crate_name(did1.krate); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 027792b7439..1f6328187a5 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -166,9 +166,7 @@ pub trait CrateStore<'tcx> : Any { fn repr_attrs(&self, def: DefId) -> Vec; fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::TypeScheme<'tcx>; - fn relative_item_path(&self, def: DefId) -> Vec; fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap>; - fn extern_item_path(&self, def: DefId) -> Vec; fn item_name(&self, def: DefId) -> ast::Name; fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::GenericPredicates<'tcx>; @@ -345,12 +343,9 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn repr_attrs(&self, def: DefId) -> Vec { bug!("repr_attrs") } fn item_type(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::TypeScheme<'tcx> { bug!("item_type") } - fn relative_item_path(&self, def: DefId) - -> Vec { bug!("relative_item_path") } fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap> { bug!("visible_parent_map") } - fn extern_item_path(&self, def: DefId) -> Vec { bug!("extern_item_path") } fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") } fn item_predicates(&self, tcx: &TyCtxt<'tcx>, def: DefId) -> ty::GenericPredicates<'tcx> { bug!("item_predicates") } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index 4d88b697416..5c1e19aee7b 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -24,6 +24,11 @@ impl<'tcx> TyCtxt<'tcx> { buffer.into_string() } + /// Returns a string identifying this local node-id. + pub fn node_path_str(&self, id: ast::NodeId) -> String { + self.item_path_str(self.map.local_def_id(id)) + } + /// Returns a string identifying this def-id. This string is /// suitable for user output. It always begins with a crate identifier. pub fn absolute_item_path_str(&self, def_id: DefId) -> String { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4ff859f5a94..444fea0918f 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -20,7 +20,6 @@ pub use self::fold::TypeFoldable; use dep_graph::{self, DepNode}; use hir::map as ast_map; -use hir::map::LinkedPath; use middle; use middle::cstore::{self, CrateStore, LOCAL_CRATE}; use hir::def::{self, Def, ExportMap}; @@ -2231,39 +2230,9 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn with_path(&self, id: DefId, f: F) -> T where - F: FnOnce(ast_map::PathElems) -> T, - { - if let Some(id) = self.map.as_local_node_id(id) { - self.map.with_path(id, f) - } else { - let mut path: Vec<_>; - if let Some(extern_crate) = self.sess.cstore.extern_crate(id.krate) { - if !extern_crate.direct { - // this comes from some crate that we don't have a direct - // path to; we'll settle for just prepending the name of - // the crate. - path = self.sess.cstore.extern_item_path(id) - } else { - // start with the path to the extern crate, then - // add the relative path to the actual item - fn collector(elems: ast_map::PathElems) -> Vec { - elems.collect() - } - path = self.with_path(extern_crate.def_id, collector); - path.extend(self.sess.cstore.relative_item_path(id)); - } - } else { - // if this was injected, just make a path with name of crate - path = self.sess.cstore.extern_item_path(id); - } - f(path.iter().cloned().chain(LinkedPath::empty())) - } - } - pub fn item_name(&self, id: DefId) -> ast::Name { if let Some(id) = self.map.as_local_node_id(id) { - self.map.get_path_elem(id).name() + self.map.name(id) } else { self.sess.cstore.item_name(id) } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index cda5595c102..cde5ba19859 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -256,6 +256,15 @@ trait HirPrinterSupport<'ast>: pprust_hir::PpAnn { /// (Rust does not yet support upcasting from a trait object to /// an object for one of its super-traits.) fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn; + + /// Computes an user-readable representation of a path, if possible. + fn node_path(&self, id: ast::NodeId) -> Option { + self.ast_map().and_then(|map| map.def_path_from_id(id)).map(|path| { + path.data.into_iter().map(|elem| { + elem.data.to_string() + }).collect::>().join("::") + }) + } } struct NoAnn<'ast> { @@ -452,6 +461,10 @@ impl<'b, 'tcx> HirPrinterSupport<'tcx> for TypedAnnotation<'b, 'tcx> { fn pp_ann<'a>(&'a self) -> &'a pprust_hir::PpAnn { self } + + fn node_path(&self, id: ast::NodeId) -> Option { + Some(self.tcx.node_path_str(id)) + } } impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { @@ -794,7 +807,7 @@ pub fn pretty_print_input(sess: Session, |annotation, (out,uii), _| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); - let ast_map = annotation.ast_map().expect("--pretty missing ast_map"); + let ast_map = annotation.ast_map().expect("--unpretty missing HIR map"); let mut pp_state = pprust_hir::State::new_from_input(sess.codemap(), sess.diagnostic(), @@ -808,7 +821,9 @@ pub fn pretty_print_input(sess: Session, let node = ast_map.get(node_id); pp_state.print_node(&node)?; pp::space(&mut pp_state.s)?; - pp_state.synth_comment(ast_map.path_to_string(node_id))?; + let path = annotation.node_path(node_id) + .expect("--unpretty missing node paths"); + pp_state.synth_comment(path)?; pp::hardbreak(&mut pp_state.s)?; } pp::eof(&mut pp_state.s) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index fe10ca87b75..5e3a47701eb 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1087,10 +1087,7 @@ impl LateLintPass for MutableTransmutes { ty::TyFnDef(_, _, ref bfty) if bfty.abi == RustIntrinsic => (), _ => return false } - cx.tcx.with_path(def_id, |path| match path.last() { - Some(ref last) => last.name().as_str() == "transmute", - _ => false - }) + cx.tcx.item_name(def_id).as_str() == "transmute" } } } diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 3becc93f8a4..6fd9f27f0fb 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -85,7 +85,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, InlinedItemRef::ImplItem(_, ii) => ii.id, }; debug!("> Encoding inlined item: {} ({:?})", - ecx.tcx.map.path_to_string(id), + ecx.tcx.node_path_str(id), rbml_w.writer.seek(SeekFrom::Current(0))); // Folding could be avoided with a smarter encoder. @@ -99,7 +99,7 @@ pub fn encode_inlined_item(ecx: &e::EncodeContext, rbml_w.end_tag(); debug!("< Encoded inlined fn: {} ({:?})", - ecx.tcx.map.path_to_string(id), + ecx.tcx.node_path_str(id), rbml_w.writer.seek(SeekFrom::Current(0))); } @@ -124,20 +124,12 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> { /// ast-map. pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, tcx: &TyCtxt<'tcx>, - parent_path: Vec, parent_def_path: ast_map::DefPath, parent_did: DefId, ast_doc: rbml::Doc, orig_did: DefId) -> &'tcx InlinedItem { - let mut path_as_str = None; - debug!("> Decoding inlined fn: {:?}::?", - { - // Do an Option dance to use the path after it is moved below. - let s = ast_map::path_to_string(parent_path.iter().cloned()); - path_as_str = Some(s); - path_as_str.as_ref().map(|x| &x[..]) - }); + debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did)); let mut ast_dsr = reader::Decoder::new(ast_doc); let from_id_range = Decodable::decode(&mut ast_dsr).unwrap(); let to_id_range = reserve_id_range(&tcx.sess, from_id_range); @@ -149,7 +141,6 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, last_filemap_index: Cell::new(0) }; let ii = ast_map::map_decoded_item(&dcx.tcx.map, - parent_path, parent_def_path, parent_did, decode_ast(ast_doc), @@ -162,7 +153,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, }; debug!("Fn named: {}", name); debug!("< Decoded inlined fn: {}::{}", - path_as_str.unwrap(), + tcx.item_path_str(parent_did), name); region::resolve_inlined_item(&tcx.sess, &tcx.region_maps, ii); decode_side_tables(dcx, ast_doc); diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index 22a5289f02b..ea4e2575420 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -86,13 +86,10 @@ pub const tag_item_trait_ref: usize = 0x3b; // discriminator value for variants pub const tag_disr_val: usize = 0x3c; -// used to encode ast_map::PathElem -pub const tag_path: usize = 0x3d; -pub const tag_path_len: usize = 0x3e; -pub const tag_path_elem_mod: usize = 0x3f; -pub const tag_path_elem_name: usize = 0x40; -pub const tag_item_field: usize = 0x41; +// GAP 0x3d, 0x3e, 0x3f, 0x40 +pub const tag_item_field: usize = 0x41; +// GAP 0x42 pub const tag_item_variances: usize = 0x43; /* trait items contain tag_item_trait_item elements, diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index bb691cebccd..0b90ad5b4e2 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -128,22 +128,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_method_arg_names(&cdata, did.index) } - fn relative_item_path(&self, def: DefId) -> Vec { - let cdata = self.get_crate_data(def.krate); - decoder::get_item_path(&cdata, def.index) - } - - fn extern_item_path(&self, def: DefId) -> Vec { - let cdata = self.get_crate_data(def.krate); - let path = decoder::get_item_path(&cdata, def.index); - - let mut r = Vec::with_capacity(path.len() + 1); - let crate_name = hir_map::PathMod(token::intern(&cdata.name)); - r.push(crate_name); - r.extend_from_slice(&path); - r - } - fn item_name(&self, def: DefId) -> ast::Name { let cdata = self.get_crate_data(def.krate); decoder::get_item_name(&self.intr, &cdata, def.index) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index e6f538255ac..6b53edbbff1 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -255,22 +255,6 @@ fn item_trait_ref<'tcx>(doc: rbml::Doc, tcx: &TyCtxt<'tcx>, cdata: Cmd) doc_trait_ref(tp, tcx, cdata) } -fn item_path(item_doc: rbml::Doc) -> Vec { - let path_doc = reader::get_doc(item_doc, tag_path); - reader::docs(path_doc).filter_map(|(tag, elt_doc)| { - if tag == tag_path_elem_mod { - let s = elt_doc.as_str_slice(); - Some(hir_map::PathMod(token::intern(s))) - } else if tag == tag_path_elem_name { - let s = elt_doc.as_str_slice(); - Some(hir_map::PathName(token::intern(s))) - } else { - // ignore tag_path_len element - None - } - }).collect() -} - fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name { let name = reader::get_doc(item, tag_paths_data_name); let string = name.as_str_slice(); @@ -786,10 +770,6 @@ pub fn each_top_level_item_of_crate(intr: Rc, callback) } -pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec { - item_path(cdata.lookup_item(id)) -} - pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name { item_name(intr, cdata.lookup_item(id)) } @@ -803,14 +783,11 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex) krate: cdata.cnum, index: def_key(cdata, id).parent.unwrap() }; - let mut parent_path = item_path(item_doc); - parent_path.pop(); let mut parent_def_path = def_path(cdata, id); parent_def_path.data.pop(); if let Some(ast_doc) = reader::maybe_get_doc(item_doc, tag_ast as usize) { let ii = decode_inlined_item(cdata, tcx, - parent_path, parent_def_path, parent_def_id, ast_doc, @@ -823,15 +800,12 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex) krate: cdata.cnum, index: def_key(cdata, parent_def_id.index).parent.unwrap() }; - let mut grandparent_path = parent_path; - grandparent_path.pop(); let mut grandparent_def_path = parent_def_path; grandparent_def_path.data.pop(); let parent_doc = cdata.lookup_item(parent_did.index); if let Some(ast_doc) = reader::maybe_get_doc(parent_doc, tag_ast as usize) { let ii = decode_inlined_item(cdata, tcx, - grandparent_path, grandparent_def_path, grandparent_def_id, ast_doc, diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 83ffd8afbeb..d45650159e3 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -31,8 +31,6 @@ use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::util::IntTypeExt; use rustc::hir::svh::Svh; -use rustc::hir::map::{LinkedPath, PathElem, PathElems}; -use rustc::hir::map as ast_map; use rustc::mir::mir_map::MirMap; use rustc::session::config; use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet}; @@ -300,26 +298,11 @@ fn encode_enum_variant_info<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } encode_bounds_and_type_for_item(rbml_w, ecx, index, variant_node_id); - ecx.tcx.map.with_path(variant_node_id, |path| encode_path(rbml_w, path)); rbml_w.end_tag(); disr_val = disr_val.wrap_incr(); } } -fn encode_path>(rbml_w: &mut Encoder, path: PI) { - let path = path.collect::>(); - rbml_w.start_tag(tag_path); - rbml_w.wr_tagged_u32(tag_path_len, path.len() as u32); - for pe in &path { - let tag = match *pe { - ast_map::PathMod(_) => tag_path_elem_mod, - ast_map::PathName(_) => tag_path_elem_name - }; - rbml_w.wr_tagged_str(tag, &pe.name().as_str()); - } - rbml_w.end_tag(); -} - /// Iterates through "auxiliary node IDs", which are node IDs that describe /// top-level items that are sub-items of the given item. Specifically: /// @@ -371,7 +354,6 @@ fn encode_info_for_mod(ecx: &EncodeContext, md: &hir::Mod, attrs: &[ast::Attribute], id: NodeId, - path: PathElems, name: Name, vis: hir::Visibility) { rbml_w.start_tag(tag_items_data_item); @@ -393,7 +375,6 @@ fn encode_info_for_mod(ecx: &EncodeContext, }); } - encode_path(rbml_w, path.clone()); encode_visibility(rbml_w, vis); let stab = stability::lookup_stability(ecx.tcx, ecx.tcx.map.local_def_id(id)); @@ -521,7 +502,6 @@ fn encode_info_for_struct_ctor<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, }); encode_bounds_and_type_for_item(rbml_w, ecx, index, ctor_id); encode_name(rbml_w, name); - ecx.tcx.map.with_path(ctor_id, |path| encode_path(rbml_w, path)); encode_parent_item(rbml_w, ecx.tcx.map.local_def_id(struct_id)); if ecx.item_symbols.borrow().contains_key(&ctor_id) { @@ -637,7 +617,6 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, index: &mut CrateIndex<'tcx>, associated_const: &ty::AssociatedConst, - impl_path: PathElems, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { debug!("encode_info_for_associated_const({:?},{:?})", @@ -663,9 +642,6 @@ fn encode_info_for_associated_const<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); - let elem = ast_map::PathName(associated_const.name); - encode_path(rbml_w, impl_path.chain(Some(elem))); - if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); encode_defaultness(rbml_w, ii.defaultness); @@ -683,7 +659,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, index: &mut CrateIndex<'tcx>, m: &ty::Method<'tcx>, - impl_path: PathElems, is_default_impl: bool, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { @@ -705,8 +680,6 @@ fn encode_info_for_method<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let m_node_id = ecx.local_id(m.def_id); encode_bounds_and_type_for_item(rbml_w, ecx, index, m_node_id); - let elem = ast_map::PathName(m.name); - encode_path(rbml_w, impl_path.chain(Some(elem))); if let Some(impl_item) = impl_item_opt { if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { encode_attributes(rbml_w, &impl_item.attrs); @@ -738,7 +711,6 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, index: &mut CrateIndex<'tcx>, associated_type: &ty::AssociatedType<'tcx>, - impl_path: PathElems, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { debug!("encode_info_for_associated_type({:?},{:?})", @@ -760,9 +732,6 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); - let elem = ast_map::PathName(associated_type.name); - encode_path(rbml_w, impl_path.chain(Some(elem))); - if let Some(ii) = impl_item_opt { encode_attributes(rbml_w, &ii.attrs); encode_defaultness(rbml_w, ii.defaultness); @@ -886,14 +855,13 @@ fn encode_xrefs<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, item: &hir::Item, - index: &mut CrateIndex<'tcx>, - path: PathElems, - vis: hir::Visibility) { + index: &mut CrateIndex<'tcx>) { let tcx = ecx.tcx; debug!("encoding info for item at {}", tcx.sess.codemap().span_to_string(item.span)); + let vis = item.vis; let def_id = ecx.tcx.map.local_def_id(item.id); let stab = stability::lookup_stability(tcx, ecx.tcx.map.local_def_id(item.id)); let depr = stability::lookup_deprecation(tcx, ecx.tcx.map.local_def_id(item.id)); @@ -911,7 +879,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_symbol(ecx, rbml_w, item.id); encode_name(rbml_w, item.name); - encode_path(rbml_w, path); encode_visibility(rbml_w, vis); encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); @@ -925,7 +892,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_family(rbml_w, 'C'); encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); - encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); encode_mir(ecx, rbml_w, item.id); @@ -942,7 +908,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, let tps_len = generics.ty_params.len(); encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); - encode_path(rbml_w, path); encode_attributes(rbml_w, &item.attrs); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); if needs_inline || constness == hir::Constness::Const { @@ -966,7 +931,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, m, &item.attrs, item.id, - path, item.name, item.vis); } @@ -976,7 +940,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_def_id_and_key(ecx, rbml_w, def_id); encode_family(rbml_w, 'n'); encode_name(rbml_w, item.name); - encode_path(rbml_w, path); // Encode all the items in this module. for foreign_item in &fm.items { @@ -995,7 +958,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_family(rbml_w, 'y'); encode_bounds_and_type_for_item(rbml_w, ecx, index, item.id); encode_name(rbml_w, item.name); - encode_path(rbml_w, path); encode_visibility(rbml_w, vis); encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); @@ -1017,7 +979,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, } encode_inlined_item(ecx, rbml_w, InlinedItemRef::Item(item)); encode_mir(ecx, rbml_w, item.id); - encode_path(rbml_w, path); // Encode inherent implementations for this enumeration. encode_inherent_implementations(ecx, rbml_w, def_id); @@ -1053,7 +1014,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_item_variances(rbml_w, ecx, item.id); encode_name(rbml_w, item.name); encode_attributes(rbml_w, &item.attrs); - encode_path(rbml_w, path.clone()); encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); encode_visibility(rbml_w, vis); @@ -1156,7 +1116,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, }); encode_parent_impl(rbml_w, parent); } - encode_path(rbml_w, path.clone()); encode_stability(rbml_w, stab); encode_deprecation(rbml_w, depr); rbml_w.end_tag(); @@ -1179,7 +1138,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w, index, &associated_const, - path.clone(), item.id, ast_item) } @@ -1188,7 +1146,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w, index, &method_type, - path.clone(), false, item.id, ast_item) @@ -1198,7 +1155,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w, index, &associated_type, - path.clone(), item.id, ast_item) } @@ -1250,7 +1206,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w.wr_tagged_u64(tag_mod_child, def_to_u64(method_def_id.def_id())); } - encode_path(rbml_w, path.clone()); // Encode inherent implementations for this trait. encode_inherent_implementations(ecx, rbml_w, def_id); @@ -1281,10 +1236,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_def_id_and_key(ecx, rbml_w, associated_const.def_id); encode_visibility(rbml_w, associated_const.vis); - let elem = ast_map::PathName(associated_const.name); - encode_path(rbml_w, - path.clone().chain(Some(elem))); - encode_family(rbml_w, 'C'); encode_bounds_and_type_for_item(rbml_w, ecx, index, @@ -1297,10 +1248,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_method_ty_fields(ecx, rbml_w, index, &method_ty); - let elem = ast_map::PathName(method_ty.name); - encode_path(rbml_w, - path.clone().chain(Some(elem))); - match method_ty.explicit_self { ty::ExplicitSelfCategory::Static => { encode_family(rbml_w, @@ -1320,11 +1267,6 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, ty::TypeTraitItem(associated_type) => { encode_name(rbml_w, associated_type.name); encode_def_id_and_key(ecx, rbml_w, associated_type.def_id); - - let elem = ast_map::PathName(associated_type.name); - encode_path(rbml_w, - path.clone().chain(Some(elem))); - encode_item_sort(rbml_w, 't'); encode_family(rbml_w, 'y'); @@ -1386,10 +1328,10 @@ fn encode_info_for_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, rbml_w: &mut Encoder, nitem: &hir::ForeignItem, - index: &mut CrateIndex<'tcx>, - path: PathElems, - abi: Abi) { + index: &mut CrateIndex<'tcx>) { + debug!("writing foreign item {}", ecx.tcx.node_path_str(nitem.id)); let def_id = ecx.tcx.map.local_def_id(nitem.id); + let abi = ecx.tcx.map.get_foreign_abi(nitem.id); index.record(def_id, rbml_w); rbml_w.start_tag(tag_items_data_item); @@ -1429,7 +1371,6 @@ fn encode_info_for_foreign_item<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, encode_name(rbml_w, nitem.name); } } - encode_path(rbml_w, path); rbml_w.end_tag(); } @@ -1454,8 +1395,6 @@ fn my_visit_expr(expr: &hir::Expr, ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap(); rbml_w.end_tag(); - ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path)); - assert!(ecx.mir_map.map.contains_key(&expr.id)); encode_mir(ecx, rbml_w, expr.id); @@ -1465,31 +1404,6 @@ fn my_visit_expr(expr: &hir::Expr, } } -fn my_visit_item<'a, 'tcx>(i: &hir::Item, - rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - index: &mut CrateIndex<'tcx>) { - ecx.tcx.map.with_path(i.id, |path| { - encode_info_for_item(ecx, rbml_w, i, index, path, i.vis); - }); -} - -fn my_visit_foreign_item<'a, 'tcx>(ni: &hir::ForeignItem, - rbml_w: &mut Encoder, - ecx: &EncodeContext<'a, 'tcx>, - index: &mut CrateIndex<'tcx>) { - debug!("writing foreign item {}::{}", - ecx.tcx.map.path_to_string(ni.id), - ni.name); - - let abi = ecx.tcx.map.get_foreign_abi(ni.id); - ecx.tcx.map.with_path(ni.id, |path| { - encode_info_for_foreign_item(ecx, rbml_w, - ni, index, - path, abi); - }); -} - struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { rbml_w_for_visit_item: &'a mut Encoder<'b>, ecx: &'a EncodeContext<'c,'tcx>, @@ -1503,11 +1417,11 @@ impl<'a, 'b, 'c, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'c, 'tcx> { } fn visit_item(&mut self, i: &'tcx hir::Item) { intravisit::walk_item(self, i); - my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index); + encode_info_for_item(self.ecx, self.rbml_w_for_visit_item, i, self.index); } fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) { intravisit::walk_foreign_item(self, ni); - my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index); + encode_info_for_foreign_item(self.ecx, self.rbml_w_for_visit_item, ni, self.index); } } @@ -1528,7 +1442,6 @@ fn encode_info_for_items<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, &krate.module, &[], CRATE_NODE_ID, - [].iter().cloned().chain(LinkedPath::empty()), syntax::parse::token::intern(&ecx.link_meta.crate_name), hir::Public); diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs index 959b1fdef52..069bd7826bc 100644 --- a/src/librustc_mir/graphviz.rs +++ b/src/librustc_mir/graphviz.rs @@ -118,7 +118,7 @@ fn write_edges(source: BasicBlock, mir: &Mir, w: &mut W) -> io::Result /// all the variables and temporaries. fn write_graph_label(tcx: &ty::TyCtxt, nid: NodeId, mir: &Mir, w: &mut W) -> io::Result<()> { - write!(w, " label= io::Result<()> { - write!(w, "fn {}(", tcx.map.path_to_string(nid))?; + write!(w, "fn {}(", tcx.node_path_str(nid))?; // fn argument types. for (i, arg) in mir.arg_decls.iter().enumerate() { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index c724091a2ec..da0e8ba78cf 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -519,7 +519,7 @@ where D: Dump span: Span, typ: &ast::Ty, expr: &ast::Expr) { - let qualname = format!("::{}", self.tcx.map.path_to_string(id)); + let qualname = format!("::{}", self.tcx.node_path_str(id)); let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); @@ -544,7 +544,7 @@ where D: Dump item: &ast::Item, def: &ast::VariantData, ty_params: &ast::Generics) { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let val = self.span.snippet(item.span); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Struct); @@ -677,7 +677,7 @@ where D: Dump generics: &ast::Generics, trait_refs: &ast::TyParamBounds, methods: &[ast::TraitItem]) { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let val = self.span.snippet(item.span); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait); if !self.span.filter_generated(sub_span, item.span) { @@ -1108,7 +1108,7 @@ impl<'l, 'tcx, 'v, D: Dump + 'l> Visitor<'v> for DumpVisitor<'l, 'tcx, D> { self.nest(item.id, |v| visit::walk_mod(v, m)); } Ty(ref ty, ref ty_params) => { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let value = ty_to_string(&ty); let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type); if !self.span.filter_generated(sub_span, item.span) { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 98c0be1c93c..da4c8770b7e 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -116,7 +116,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn get_item_data(&self, item: &ast::Item) -> Option { match item.node { ast::ItemKind::Fn(..) => { - let name = self.tcx.map.path_to_string(item.id); + let name = self.tcx.node_path_str(item.id); let qualname = format!("::{}", name); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn); filter!(self.span_utils, sub_span, item.span, None); @@ -130,7 +130,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Static(ref typ, mt, ref expr) => { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); // If the variable is immutable, save the initialising expression. let (value, keyword) = match mt { @@ -153,7 +153,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Const(ref typ, ref expr) => { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Const); filter!(self.span_utils, sub_span, item.span, None); Some(Data::VariableData(VariableData { @@ -167,7 +167,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Mod(ref m) => { - let qualname = format!("::{}", self.tcx.map.path_to_string(item.id)); + let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let cm = self.tcx.sess.codemap(); let filename = cm.span_to_filename(m.inner); @@ -184,7 +184,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { })) } ast::ItemKind::Enum(..) => { - let enum_name = format!("::{}", self.tcx.map.path_to_string(item.id)); + let enum_name = format!("::{}", self.tcx.node_path_str(item.id)); let val = self.span_utils.snippet(item.span); let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Enum); filter!(self.span_utils, sub_span, item.span, None); @@ -246,7 +246,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { scope: NodeId) -> Option { match field.node.kind { ast::NamedField(ident, _) => { - let qualname = format!("::{}::{}", self.tcx.map.path_to_string(scope), ident); + let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); let typ = self.tcx.node_types().get(&field.node.id).unwrap().to_string(); let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon); filter!(self.span_utils, sub_span, field.span, None); diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 4f1585eeaca..c8ed4e629e4 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -1351,7 +1351,7 @@ fn build_cfg(tcx: &TyCtxt, id: ast::NodeId) -> (ast::NodeId, Option) { None if id == ast::DUMMY_NODE_ID => return (ast::DUMMY_NODE_ID, None), _ => bug!("unexpected variant in has_nested_returns: {}", - tcx.map.path_to_string(id)), + tcx.node_path_str(id)), }; (blk.id, Some(cfg::CFG::new(tcx, blk))) @@ -1412,9 +1412,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> { let local_id = def_id.and_then(|id| ccx.tcx().map.as_local_node_id(id)); debug!("FunctionContext::new(path={}, def_id={:?}, param_substs={:?})", - inlined_id.map_or(String::new(), |id| { - ccx.tcx().map.path_to_string(id).to_string() - }), + inlined_id.map_or(String::new(), |id| ccx.tcx().node_path_str(id)), def_id, param_substs); @@ -1906,7 +1904,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, llfndecl: ValueRef, param_substs: &'tcx Substs<'tcx>, id: ast::NodeId) { - let _s = StatRecorder::new(ccx, ccx.tcx().map.path_to_string(id).to_string()); + let _s = StatRecorder::new(ccx, ccx.tcx().node_path_str(id)); debug!("trans_fn(param_substs={:?})", param_substs); let _icx = push_ctxt("trans_fn"); let fn_ty = ccx.tcx().node_id_to_type(id); @@ -2446,8 +2444,7 @@ pub fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => { if attr::contains_name(attrs, "no_mangle") { // Don't mangle - let path = ccx.tcx().map.def_path_from_id(id); - path.data.last().unwrap().data.to_string() + ccx.tcx().map.name(id).as_str().to_string() } else { match weak_lang_items::link_name(attrs) { Some(name) => name.to_string(), diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index c1487f56956..5272a4fbbb7 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -19,6 +19,7 @@ use rustc::hir::map as hir_map; use common::CrateContext; use std::ffi::CString; +use std::iter::once; use std::ptr; use std::rc::{Rc, Weak}; use syntax::ast; @@ -51,85 +52,76 @@ impl NamespaceTreeNode { } } -pub fn crate_root_namespace<'a>(cx: &'a CrateContext) -> &'a str { - &cx.link_meta().crate_name -} - pub fn namespace_for_item(cx: &CrateContext, def_id: DefId) -> Rc { - cx.tcx().with_path(def_id, |path| { - // prepend crate name if not already present - let krate = if def_id.is_local() { - let crate_namespace_name = token::intern(crate_root_namespace(cx)); - Some(hir_map::PathMod(crate_namespace_name)) - } else { - None + // prepend crate name. + // This shouldn't need a roundtrip through InternedString. + let krate = token::intern(&cx.tcx().crate_name(def_id.krate)); + let krate = hir_map::DefPathData::TypeNs(krate); + let path = cx.tcx().def_path(def_id).data; + let mut path = once(krate).chain(path.into_iter().map(|e| e.data)).peekable(); + + let mut current_key = Vec::new(); + let mut parent_node: Option> = None; + + // Create/Lookup namespace for each element of the path. + loop { + // Emulate a for loop so we can use peek below. + let path_element = match path.next() { + Some(e) => e, + None => break }; - let mut path = krate.into_iter().chain(path).peekable(); - - let mut current_key = Vec::new(); - let mut parent_node: Option> = None; - - // Create/Lookup namespace for each element of the path. - loop { - // Emulate a for loop so we can use peek below. - let path_element = match path.next() { - Some(e) => e, - None => break - }; - // Ignore the name of the item (the last path element). - if path.peek().is_none() { - break; - } - - let name = path_element.name(); - current_key.push(name); - - let existing_node = debug_context(cx).namespace_map.borrow() - .get(¤t_key).cloned(); - let current_node = match existing_node { - Some(existing_node) => existing_node, - None => { - // create and insert - let parent_scope = match parent_node { - Some(ref node) => node.scope, - None => ptr::null_mut() - }; - let namespace_name = name.as_str(); - let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); - let scope = unsafe { - llvm::LLVMDIBuilderCreateNameSpace( - DIB(cx), - parent_scope, - namespace_name.as_ptr(), - // cannot reconstruct file ... - ptr::null_mut(), - // ... or line information, but that's not so important. - 0) - }; - - let node = Rc::new(NamespaceTreeNode { - name: name, - scope: scope, - parent: parent_node.map(|parent| Rc::downgrade(&parent)), - }); - - debug_context(cx).namespace_map.borrow_mut() - .insert(current_key.clone(), node.clone()); - - node - } - }; - - parent_node = Some(current_node); + // Ignore the name of the item (the last path element). + if path.peek().is_none() { + break; } - match parent_node { - Some(node) => node, + // This shouldn't need a roundtrip through InternedString. + let namespace_name = path_element.as_interned_str(); + let name = token::intern(&namespace_name); + current_key.push(name); + + let existing_node = debug_context(cx).namespace_map.borrow() + .get(¤t_key).cloned(); + let current_node = match existing_node { + Some(existing_node) => existing_node, None => { - bug!("debuginfo::namespace_for_item(): \ - path too short for {:?}", - def_id); + // create and insert + let parent_scope = match parent_node { + Some(ref node) => node.scope, + None => ptr::null_mut() + }; + let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); + let scope = unsafe { + llvm::LLVMDIBuilderCreateNameSpace( + DIB(cx), + parent_scope, + namespace_name.as_ptr(), + // cannot reconstruct file ... + ptr::null_mut(), + // ... or line information, but that's not so important. + 0) + }; + + let node = Rc::new(NamespaceTreeNode { + name: name, + scope: scope, + parent: parent_node.map(|parent| Rc::downgrade(&parent)), + }); + + debug_context(cx).namespace_map.borrow_mut() + .insert(current_key.clone(), node.clone()); + + node } + }; + + parent_node = Some(current_node); + } + + match parent_node { + Some(node) => node, + None => { + bug!("debuginfo::namespace_for_item: path too short for {:?}", def_id); } - }) + } } diff --git a/src/librustc_trans/debuginfo/type_names.rs b/src/librustc_trans/debuginfo/type_names.rs index 0169734ad3b..6fdd6a2c1d1 100644 --- a/src/librustc_trans/debuginfo/type_names.rs +++ b/src/librustc_trans/debuginfo/type_names.rs @@ -10,8 +10,6 @@ // Type Names for Debug Info. -use super::namespace::crate_root_namespace; - use common::CrateContext; use rustc::hir::def_id::DefId; use rustc::infer; @@ -163,31 +161,15 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, def_id: DefId, qualified: bool, output: &mut String) { - cx.tcx().with_path(def_id, |path| { - if qualified { - if def_id.is_local() { - output.push_str(crate_root_namespace(cx)); - output.push_str("::"); - } - - let mut path_element_count = 0; - for path_element in path { - output.push_str(&path_element.name().as_str()); - output.push_str("::"); - path_element_count += 1; - } - - if path_element_count == 0 { - bug!("debuginfo: Encountered empty item path!"); - } - - output.pop(); - output.pop(); - } else { - let name = path.last().expect("debuginfo: Empty item path?").name(); - output.push_str(&name.as_str()); + if qualified { + output.push_str(&cx.tcx().crate_name(def_id.krate)); + for path_element in cx.tcx().def_path(def_id).data { + output.push_str("::"); + output.push_str(&path_element.data.as_interned_str()); } - }); + } else { + output.push_str(&cx.tcx().item_name(def_id).as_str()); + } } // Pushes the type parameters in the given `Substs` to the output string. diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 70997a1a6ee..8c65eb8dbd3 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -11,6 +11,7 @@ //! Support for inlining external documentation into the current AST. use std::collections::HashSet; +use std::iter::once; use syntax::ast; use syntax::attr::AttrMetaMethods; @@ -140,8 +141,11 @@ pub fn load_attrs(cx: &DocContext, tcx: &TyCtxt, /// source links back to the original item. pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) { if let Some(tcx) = cx.tcx_opt() { - let fqn = tcx.sess.cstore.extern_item_path(did); - let fqn = fqn.into_iter().map(|i| i.to_string()).collect(); + let crate_name = tcx.sess.cstore.crate_name(did.krate).to_string(); + let relative = tcx.def_path(did).data.into_iter().map(|elem| { + elem.data.to_string() + }); + let fqn = once(crate_name).chain(relative).collect(); cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind)); } } diff --git a/src/test/run-make/pretty-print-path-suffix/foo_method.pp b/src/test/run-make/pretty-print-path-suffix/foo_method.pp index 4879fbfe6d3..696e0544fdc 100644 --- a/src/test/run-make/pretty-print-path-suffix/foo_method.pp +++ b/src/test/run-make/pretty-print-path-suffix/foo_method.pp @@ -13,4 +13,4 @@ fn foo_method(&self) -> &'static str { return "i am very similar to foo."; } -/* nest::S::foo_method */ +/* nest::{{impl}}::foo_method */ -- cgit 1.4.1-3-g733a5