rustc: remove hir::fold.
This commit is contained in:
parent
ed593bed88
commit
02c4155d2c
6 changed files with 143 additions and 1261 deletions
File diff suppressed because it is too large
Load diff
|
@ -67,7 +67,6 @@ macro_rules! hir_vec {
|
|||
pub mod check_attr;
|
||||
pub mod def;
|
||||
pub mod def_id;
|
||||
pub mod fold;
|
||||
pub mod intravisit;
|
||||
pub mod lowering;
|
||||
pub mod map;
|
||||
|
|
|
@ -40,11 +40,10 @@ use rustc_back::slice;
|
|||
use syntax::ast::{self, DUMMY_NODE_ID, NodeId};
|
||||
use syntax::codemap::Spanned;
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use rustc::hir::fold::{Folder, noop_fold_pat};
|
||||
use rustc::hir::print::pat_to_string;
|
||||
use syntax::ptr::P;
|
||||
use syntax::util::move_map::MoveMap;
|
||||
use rustc::util::common::ErrorReported;
|
||||
use rustc::util::nodemap::FnvHashMap;
|
||||
|
||||
pub const DUMMY_WILD_PAT: &'static Pat = &Pat {
|
||||
id: DUMMY_NODE_ID,
|
||||
|
@ -182,7 +181,7 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
|
|||
}
|
||||
}
|
||||
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx, None);
|
||||
let mut static_inliner = StaticInliner::new(cx.tcx);
|
||||
let inlined_arms = arms.iter().map(|arm| {
|
||||
(arm.pats.iter().map(|pat| {
|
||||
static_inliner.fold_pat((*pat).clone())
|
||||
|
@ -467,53 +466,30 @@ fn const_val_to_expr(value: &ConstVal) -> P<hir::Expr> {
|
|||
})
|
||||
}
|
||||
|
||||
pub struct StaticInliner<'a, 'tcx: 'a> {
|
||||
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pub failed: bool,
|
||||
pub renaming_map: Option<&'a mut FnvHashMap<(NodeId, Span), NodeId>>,
|
||||
struct StaticInliner<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
failed: bool
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> StaticInliner<'a, 'tcx> {
|
||||
pub fn new<'b>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
||||
renaming_map: Option<&'b mut FnvHashMap<(NodeId, Span), NodeId>>)
|
||||
-> StaticInliner<'b, 'tcx> {
|
||||
pub fn new<'b>(tcx: TyCtxt<'b, 'tcx, 'tcx>) -> StaticInliner<'b, 'tcx> {
|
||||
StaticInliner {
|
||||
tcx: tcx,
|
||||
failed: false,
|
||||
renaming_map: renaming_map
|
||||
failed: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct RenamingRecorder<'map> {
|
||||
substituted_node_id: NodeId,
|
||||
origin_span: Span,
|
||||
renaming_map: &'map mut FnvHashMap<(NodeId, Span), NodeId>
|
||||
}
|
||||
|
||||
impl<'v, 'map> Visitor<'v> for RenamingRecorder<'map> {
|
||||
fn visit_id(&mut self, node_id: NodeId) {
|
||||
let key = (node_id, self.origin_span);
|
||||
self.renaming_map.insert(key, self.substituted_node_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
||||
impl<'a, 'tcx> StaticInliner<'a, 'tcx> {
|
||||
fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
|
||||
return match pat.node {
|
||||
match pat.node {
|
||||
PatKind::Path(..) => {
|
||||
match self.tcx.expect_def(pat.id) {
|
||||
Def::AssociatedConst(did) | Def::Const(did) => {
|
||||
let substs = Some(self.tcx.node_id_item_substs(pat.id).substs);
|
||||
if let Some((const_expr, _)) = lookup_const_by_id(self.tcx, did, substs) {
|
||||
match const_expr_to_pat(self.tcx, const_expr, pat.id, pat.span) {
|
||||
Ok(new_pat) => {
|
||||
if let Some(ref mut map) = self.renaming_map {
|
||||
// Record any renamings we do here
|
||||
record_renamings(const_expr, &pat, map);
|
||||
}
|
||||
new_pat
|
||||
}
|
||||
Ok(new_pat) => return new_pat,
|
||||
Err(def_id) => {
|
||||
self.failed = true;
|
||||
self.tcx.sess.span_err(
|
||||
|
@ -521,33 +497,62 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> {
|
|||
&format!("constants of the type `{}` \
|
||||
cannot be used in patterns",
|
||||
self.tcx.item_path_str(def_id)));
|
||||
pat
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.failed = true;
|
||||
span_err!(self.tcx.sess, pat.span, E0158,
|
||||
"statics cannot be referenced in patterns");
|
||||
pat
|
||||
}
|
||||
}
|
||||
_ => noop_fold_pat(pat, self)
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => noop_fold_pat(pat, self)
|
||||
};
|
||||
|
||||
fn record_renamings(const_expr: &hir::Expr,
|
||||
substituted_pat: &hir::Pat,
|
||||
renaming_map: &mut FnvHashMap<(NodeId, Span), NodeId>) {
|
||||
let mut renaming_recorder = RenamingRecorder {
|
||||
substituted_node_id: substituted_pat.id,
|
||||
origin_span: substituted_pat.span,
|
||||
renaming_map: renaming_map,
|
||||
};
|
||||
|
||||
renaming_recorder.visit_expr(const_expr);
|
||||
_ => {}
|
||||
}
|
||||
|
||||
pat.map(|Pat { id, node, span }| {
|
||||
let node = match node {
|
||||
PatKind::Binding(binding_mode, pth1, sub) => {
|
||||
PatKind::Binding(binding_mode, pth1, sub.map(|x| self.fold_pat(x)))
|
||||
}
|
||||
PatKind::TupleStruct(pth, pats, ddpos) => {
|
||||
PatKind::TupleStruct(pth, pats.move_map(|x| self.fold_pat(x)), ddpos)
|
||||
}
|
||||
PatKind::Struct(pth, fields, etc) => {
|
||||
let fs = fields.move_map(|f| {
|
||||
Spanned {
|
||||
span: f.span,
|
||||
node: hir::FieldPat {
|
||||
name: f.node.name,
|
||||
pat: self.fold_pat(f.node.pat),
|
||||
is_shorthand: f.node.is_shorthand,
|
||||
},
|
||||
}
|
||||
});
|
||||
PatKind::Struct(pth, fs, etc)
|
||||
}
|
||||
PatKind::Tuple(elts, ddpos) => {
|
||||
PatKind::Tuple(elts.move_map(|x| self.fold_pat(x)), ddpos)
|
||||
}
|
||||
PatKind::Box(inner) => PatKind::Box(self.fold_pat(inner)),
|
||||
PatKind::Ref(inner, mutbl) => PatKind::Ref(self.fold_pat(inner), mutbl),
|
||||
PatKind::Vec(before, slice, after) => {
|
||||
PatKind::Vec(before.move_map(|x| self.fold_pat(x)),
|
||||
slice.map(|x| self.fold_pat(x)),
|
||||
after.move_map(|x| self.fold_pat(x)))
|
||||
}
|
||||
PatKind::Wild |
|
||||
PatKind::Lit(_) |
|
||||
PatKind::Range(..) |
|
||||
PatKind::Path(..) => node
|
||||
};
|
||||
Pat {
|
||||
id: id,
|
||||
node: node,
|
||||
span: span
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1047,7 +1052,7 @@ pub fn specialize<'a, 'b, 'tcx>(
|
|||
fn check_local(cx: &mut MatchCheckCtxt, loc: &hir::Local) {
|
||||
intravisit::walk_local(cx, loc);
|
||||
|
||||
let pat = StaticInliner::new(cx.tcx, None).fold_pat(loc.pat.clone());
|
||||
let pat = StaticInliner::new(cx.tcx).fold_pat(loc.pat.clone());
|
||||
check_irrefutable(cx, &pat, false);
|
||||
|
||||
// Check legality of move bindings and `@` patterns.
|
||||
|
|
|
@ -38,7 +38,6 @@ use rustc::middle::privacy::AccessLevels;
|
|||
use rustc::middle::resolve_lifetime::DefRegion::*;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX};
|
||||
use rustc::hir::fold::Folder;
|
||||
use rustc::hir::print as pprust;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, AdtKind};
|
||||
|
@ -774,7 +773,20 @@ impl Lifetime {
|
|||
}
|
||||
|
||||
impl Clean<Lifetime> for hir::Lifetime {
|
||||
fn clean(&self, _: &DocContext) -> Lifetime {
|
||||
fn clean(&self, cx: &DocContext) -> Lifetime {
|
||||
if let Some(tcx) = cx.tcx_opt() {
|
||||
let def = tcx.named_region_map.defs.get(&self.id).cloned();
|
||||
match def {
|
||||
Some(DefEarlyBoundRegion(_, node_id)) |
|
||||
Some(DefLateBoundRegion(_, node_id)) |
|
||||
Some(DefFreeRegion(_, node_id)) => {
|
||||
if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() {
|
||||
return lt;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Lifetime(self.name.to_string())
|
||||
}
|
||||
}
|
||||
|
@ -1629,42 +1641,6 @@ impl From<ast::FloatTy> for PrimitiveType {
|
|||
}
|
||||
}
|
||||
|
||||
// Poor man's type parameter substitution at HIR level.
|
||||
// Used to replace private type aliases in public signatures with their aliased types.
|
||||
struct SubstAlias<'a, 'tcx: 'a> {
|
||||
tcx: &'a ty::TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// Table type parameter definition -> substituted type
|
||||
ty_substs: FnvHashMap<Def, hir::Ty>,
|
||||
// Table node id of lifetime parameter definition -> substituted lifetime
|
||||
lt_substs: FnvHashMap<ast::NodeId, hir::Lifetime>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx: 'a, 'b: 'tcx> Folder for SubstAlias<'a, 'tcx> {
|
||||
fn fold_ty(&mut self, ty: P<hir::Ty>) -> P<hir::Ty> {
|
||||
if let hir::TyPath(..) = ty.node {
|
||||
let def = self.tcx.expect_def(ty.id);
|
||||
if let Some(new_ty) = self.ty_substs.get(&def).cloned() {
|
||||
return P(new_ty);
|
||||
}
|
||||
}
|
||||
hir::fold::noop_fold_ty(ty, self)
|
||||
}
|
||||
fn fold_lifetime(&mut self, lt: hir::Lifetime) -> hir::Lifetime {
|
||||
let def = self.tcx.named_region_map.defs.get(<.id).cloned();
|
||||
match def {
|
||||
Some(DefEarlyBoundRegion(_, node_id)) |
|
||||
Some(DefLateBoundRegion(_, node_id)) |
|
||||
Some(DefFreeRegion(_, node_id)) => {
|
||||
if let Some(lt) = self.lt_substs.get(&node_id).cloned() {
|
||||
return lt;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
hir::fold::noop_fold_lifetime(lt, self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Type> for hir::Ty {
|
||||
fn clean(&self, cx: &DocContext) -> Type {
|
||||
use rustc::hir::*;
|
||||
|
@ -1696,43 +1672,47 @@ impl Clean<Type> for hir::Ty {
|
|||
},
|
||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyPath(None, ref path) => {
|
||||
if let Some(tcx) = cx.tcx_opt() {
|
||||
// Substitute private type aliases
|
||||
let def = tcx.expect_def(self.id);
|
||||
let tcx_and_def = cx.tcx_opt().map(|tcx| (tcx, tcx.expect_def(self.id)));
|
||||
if let Some((_, def)) = tcx_and_def {
|
||||
if let Some(new_ty) = cx.ty_substs.borrow().get(&def).cloned() {
|
||||
return new_ty;
|
||||
}
|
||||
}
|
||||
|
||||
let tcx_and_alias = tcx_and_def.and_then(|(tcx, def)| {
|
||||
if let Def::TyAlias(def_id) = def {
|
||||
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
|
||||
// Substitute private type aliases
|
||||
tcx.map.as_local_node_id(def_id).and_then(|node_id| {
|
||||
if !cx.access_levels.borrow().is_exported(def_id) {
|
||||
let item = tcx.map.expect_item(node_id);
|
||||
if let hir::ItemTy(ref ty, ref generics) = item.node {
|
||||
let provided_params = &path.segments.last().unwrap().parameters;
|
||||
let mut ty_substs = FnvHashMap();
|
||||
let mut lt_substs = FnvHashMap();
|
||||
for (i, ty_param) in generics.ty_params.iter().enumerate() {
|
||||
let ty_param_def = tcx.expect_def(ty_param.id);
|
||||
if let Some(ty) = provided_params.types().get(i).cloned()
|
||||
.cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.unwrap());
|
||||
} else if let Some(default) = ty_param.default.clone() {
|
||||
ty_substs.insert(ty_param_def, default.unwrap());
|
||||
}
|
||||
}
|
||||
for (i, lt_param) in generics.lifetimes.iter().enumerate() {
|
||||
if let Some(lt) = provided_params.lifetimes().get(i)
|
||||
.cloned()
|
||||
.cloned() {
|
||||
lt_substs.insert(lt_param.lifetime.id, lt);
|
||||
}
|
||||
}
|
||||
let mut subst_alias = SubstAlias {
|
||||
tcx: &tcx,
|
||||
ty_substs: ty_substs,
|
||||
lt_substs: lt_substs
|
||||
};
|
||||
return subst_alias.fold_ty(ty.clone()).clean(cx);
|
||||
}
|
||||
Some((tcx, &tcx.map.expect_item(node_id).node))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
if let Some((tcx, &hir::ItemTy(ref ty, ref generics))) = tcx_and_alias {
|
||||
let provided_params = &path.segments.last().unwrap().parameters;
|
||||
let mut ty_substs = FnvHashMap();
|
||||
let mut lt_substs = FnvHashMap();
|
||||
for (i, ty_param) in generics.ty_params.iter().enumerate() {
|
||||
let ty_param_def = tcx.expect_def(ty_param.id);
|
||||
if let Some(ty) = provided_params.types().get(i).cloned()
|
||||
.cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.unwrap().clean(cx));
|
||||
} else if let Some(default) = ty_param.default.clone() {
|
||||
ty_substs.insert(ty_param_def, default.unwrap().clean(cx));
|
||||
}
|
||||
}
|
||||
for (i, lt_param) in generics.lifetimes.iter().enumerate() {
|
||||
if let Some(lt) = provided_params.lifetimes().get(i).cloned()
|
||||
.cloned() {
|
||||
lt_substs.insert(lt_param.lifetime.id, lt.clean(cx));
|
||||
}
|
||||
}
|
||||
return cx.enter_alias(ty_substs, lt_substs, || ty.clean(cx));
|
||||
}
|
||||
resolve_type(cx, path.clean(cx), self.id)
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use rustc_driver::{driver, target_features, abort_on_err};
|
|||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::session::{self, config};
|
||||
use rustc::hir::def_id::{CrateNum, DefId};
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::hir::map as hir_map;
|
||||
|
@ -23,12 +24,13 @@ use rustc_trans::back::link;
|
|||
use rustc_resolve as resolve;
|
||||
use rustc_metadata::cstore::CStore;
|
||||
|
||||
use syntax::codemap;
|
||||
use syntax::{ast, codemap};
|
||||
use syntax::feature_gate::UnstableFeatures;
|
||||
use errors;
|
||||
use errors::emitter::ColorConfig;
|
||||
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
|
||||
use visit_ast::RustdocVisitor;
|
||||
|
@ -63,6 +65,14 @@ pub struct DocContext<'a, 'tcx: 'a> {
|
|||
pub renderinfo: RefCell<RenderInfo>,
|
||||
/// Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
|
||||
pub external_traits: RefCell<FnvHashMap<DefId, clean::Trait>>,
|
||||
|
||||
// The current set of type and lifetime substitutions,
|
||||
// for expanding type aliases at the HIR level:
|
||||
|
||||
/// Table type parameter definition -> substituted type
|
||||
pub ty_substs: RefCell<FnvHashMap<Def, clean::Type>>,
|
||||
/// Table node id of lifetime parameter definition -> substituted lifetime
|
||||
pub lt_substs: RefCell<FnvHashMap<ast::NodeId, clean::Lifetime>>,
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> DocContext<'b, 'tcx> {
|
||||
|
@ -84,6 +94,22 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> {
|
|||
let tcx_opt = self.tcx_opt();
|
||||
tcx_opt.expect("tcx not present")
|
||||
}
|
||||
|
||||
/// Call the closure with the given parameters set as
|
||||
/// the substitutions for a type alias' RHS.
|
||||
pub fn enter_alias<F, R>(&self,
|
||||
ty_substs: FnvHashMap<Def, clean::Type>,
|
||||
lt_substs: FnvHashMap<ast::NodeId, clean::Lifetime>,
|
||||
f: F) -> R
|
||||
where F: FnOnce() -> R {
|
||||
let (old_tys, old_lts) =
|
||||
(mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs),
|
||||
mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs));
|
||||
let r = f();
|
||||
*self.ty_substs.borrow_mut() = old_tys;
|
||||
*self.lt_substs.borrow_mut() = old_lts;
|
||||
r
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DocAccessLevels {
|
||||
|
@ -179,12 +205,14 @@ pub fn run_core(search_paths: SearchPaths,
|
|||
map: &tcx.map,
|
||||
maybe_typed: Typed(tcx),
|
||||
input: input,
|
||||
populated_crate_impls: RefCell::new(FnvHashSet()),
|
||||
populated_crate_impls: Default::default(),
|
||||
deref_trait_did: Cell::new(None),
|
||||
deref_mut_trait_did: Cell::new(None),
|
||||
access_levels: RefCell::new(access_levels),
|
||||
external_traits: RefCell::new(FnvHashMap()),
|
||||
renderinfo: RefCell::new(Default::default()),
|
||||
external_traits: Default::default(),
|
||||
renderinfo: Default::default(),
|
||||
ty_substs: Default::default(),
|
||||
lt_substs: Default::default(),
|
||||
};
|
||||
debug!("crate: {:?}", ctxt.map.krate());
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use std::cell::{RefCell, Cell};
|
||||
use std::cell::Cell;
|
||||
use std::env;
|
||||
use std::ffi::OsString;
|
||||
use std::io::prelude::*;
|
||||
|
@ -28,7 +28,6 @@ use rustc::session::{self, config};
|
|||
use rustc::session::config::{get_unstable_features_setting, OutputType,
|
||||
OutputTypes, Externs};
|
||||
use rustc::session::search_paths::{SearchPaths, PathKind};
|
||||
use rustc::util::nodemap::{FnvHashMap, FnvHashSet};
|
||||
use rustc_back::dynamic_lib::DynamicLibrary;
|
||||
use rustc_back::tempdir::TempDir;
|
||||
use rustc_driver::{driver, Compilation};
|
||||
|
@ -107,12 +106,14 @@ pub fn run(input: &str,
|
|||
map: &map,
|
||||
maybe_typed: core::NotTyped(&sess),
|
||||
input: input,
|
||||
external_traits: RefCell::new(FnvHashMap()),
|
||||
populated_crate_impls: RefCell::new(FnvHashSet()),
|
||||
external_traits: Default::default(),
|
||||
populated_crate_impls: Default::default(),
|
||||
deref_trait_did: Cell::new(None),
|
||||
deref_mut_trait_did: Cell::new(None),
|
||||
access_levels: Default::default(),
|
||||
renderinfo: Default::default(),
|
||||
ty_substs: Default::default(),
|
||||
lt_substs: Default::default(),
|
||||
};
|
||||
|
||||
let mut v = RustdocVisitor::new(&ctx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue