Remove FinderTrait and move its functions into DocContext

This commit is contained in:
Guillaume Gomez 2018-08-03 22:13:05 +02:00
parent fc81adb3c2
commit 0bff861d32
5 changed files with 150 additions and 180 deletions

View File

@ -17,7 +17,6 @@ use rustc::middle::cstore::CrateStore;
use std::fmt::Debug;
use self::def_ctor::{get_def_from_def_id, get_def_from_node_id};
use self::finder_trait::Finder;
use super::*;
@ -168,14 +167,14 @@ impl<'a, 'tcx, 'rcx, 'cstore> AutoTraitFinder<'a, 'tcx, 'rcx, 'cstore> {
_ => unreachable!(),
};
let real_name = name.map(|name| Ident::from_str(&name));
let ty = self.get_real_ty(def_id, def_ctor, &real_name, &generics);
let ty = self.cx.get_real_ty(def_id, def_ctor, &real_name, &generics);
return Some(Item {
source: Span::empty(),
name: None,
attrs: Default::default(),
visibility: None,
def_id: self.next_def_id(def_id.krate),
def_id: self.cx.next_def_id(def_id.krate),
stability: None,
deprecation: None,
inner: ImplItem(Impl {
@ -862,12 +861,6 @@ impl<'a, 'tcx, 'rcx, 'cstore> AutoTraitFinder<'a, 'tcx, 'rcx, 'cstore> {
}
}
impl<'a, 'tcx: 'a, 'rcx: 'a> Finder<'a, 'tcx, 'rcx> for AutoTraitFinder<'a, 'tcx, 'rcx> {
fn get_cx(&self) -> &DocContext<'a, 'tcx, 'rcx> {
&self.cx
}
}
// Replaces all ReVars in a type with ty::Region's, using the provided map
struct RegionReplacer<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,

View File

@ -20,7 +20,6 @@ use core::DocAccessLevels;
use super::*;
use self::def_ctor::{get_def_from_def_id, get_def_from_node_id};
use self::finder_trait::Finder;
pub struct BlanketImplFinder<'a, 'tcx: 'a, 'rcx: 'a> {
pub cx: &'a core::DocContext<'a, 'tcx, 'rcx>,
@ -127,7 +126,7 @@ impl<'a, 'tcx, 'rcx> BlanketImplFinder <'a, 'tcx, 'rcx> {
.map(|meth| meth.ident.to_string())
.collect();
let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics);
let ty = self.cx.get_real_ty(def_id, def_ctor, &real_name, generics);
let predicates = infcx.tcx.predicates_of(impl_def_id);
impls.push(Item {
@ -135,7 +134,7 @@ impl<'a, 'tcx, 'rcx> BlanketImplFinder <'a, 'tcx, 'rcx> {
name: None,
attrs: Default::default(),
visibility: None,
def_id: self.next_def_id(impl_def_id.krate),
def_id: self.cx.next_def_id(impl_def_id.krate),
stability: None,
deprecation: None,
inner: ImplItem(Impl {
@ -161,9 +160,3 @@ impl<'a, 'tcx, 'rcx> BlanketImplFinder <'a, 'tcx, 'rcx> {
impls
}
}
impl<'a, 'tcx: 'a, 'rcx: 'a> Finder<'a, 'tcx, 'rcx> for BlanketImplFinder<'a, 'tcx, 'rcx> {
fn get_cx(&self) -> &DocContext<'a, 'tcx, 'rcx> {
&self.cx
}
}

View File

@ -1,154 +0,0 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use rustc::hir;
use syntax_pos::DUMMY_SP;
use super::*;
pub trait Finder<'a, 'tcx: 'a, 'rcx: 'a> {
fn get_cx(&self) -> &DocContext<'a, 'tcx, 'rcx>;
// This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
// refactoring either librustdoc or librustc. In particular, allowing new DefIds to be
// registered after the AST is constructed would require storing the defid mapping in a
// RefCell, decreasing the performance for normal compilation for very little gain.
//
// Instead, we construct 'fake' def ids, which start immediately after the last DefId in
// DefIndexAddressSpace::Low. In the Debug impl for clean::Item, we explicitly check for fake
// def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds
fn next_def_id(&self, crate_num: CrateNum) -> DefId {
let start_def_id = {
let next_id = if crate_num == LOCAL_CRATE {
self.get_cx()
.tcx
.hir
.definitions()
.def_path_table()
.next_id(DefIndexAddressSpace::Low)
} else {
self.get_cx()
.cstore
.def_path_table(crate_num)
.next_id(DefIndexAddressSpace::Low)
};
DefId {
krate: crate_num,
index: next_id,
}
};
let mut fake_ids = self.get_cx().fake_def_ids.borrow_mut();
let def_id = fake_ids.entry(crate_num).or_insert(start_def_id).clone();
fake_ids.insert(
crate_num,
DefId {
krate: crate_num,
index: DefIndex::from_array_index(
def_id.index.as_array_index() + 1,
def_id.index.address_space(),
),
},
);
MAX_DEF_ID.with(|m| {
m.borrow_mut()
.entry(def_id.krate.clone())
.or_insert(start_def_id);
});
self.get_cx().all_fake_def_ids.borrow_mut().insert(def_id);
def_id.clone()
}
fn get_real_ty<F>(&self,
def_id: DefId,
def_ctor: &F,
real_name: &Option<Ident>,
generics: &ty::Generics,
) -> hir::Ty
where F: Fn(DefId) -> Def {
let path = get_path_for_type(self.get_cx().tcx, def_id, def_ctor);
let mut segments = path.segments.into_vec();
let last = segments.pop().expect("segments were empty");
segments.push(hir::PathSegment::new(
real_name.unwrap_or(last.ident),
self.generics_to_path_params(generics.clone()),
false,
));
let new_path = hir::Path {
span: path.span,
def: path.def,
segments: HirVec::from_vec(segments),
};
hir::Ty {
id: ast::DUMMY_NODE_ID,
node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
let mut args = vec![];
for param in generics.params.iter() {
match param.kind {
ty::GenericParamDefKind::Lifetime => {
let name = if param.name == "" {
hir::ParamName::Plain(keywords::StaticLifetime.ident())
} else {
hir::ParamName::Plain(ast::Ident::from_interned_str(param.name))
};
args.push(hir::GenericArg::Lifetime(hir::Lifetime {
id: ast::DUMMY_NODE_ID,
span: DUMMY_SP,
name: hir::LifetimeName::Param(name),
}));
}
ty::GenericParamDefKind::Type {..} => {
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
}
}
}
hir::GenericArgs {
args: HirVec::from_vec(args),
bindings: HirVec::new(),
parenthesized: false,
}
}
fn ty_param_to_ty(&self, param: ty::GenericParamDef) -> hir::Ty {
debug!("ty_param_to_ty({:?}) {:?}", param, param.def_id);
hir::Ty {
id: ast::DUMMY_NODE_ID,
node: hir::TyKind::Path(hir::QPath::Resolved(
None,
P(hir::Path {
span: DUMMY_SP,
def: Def::TyParam(param.def_id),
segments: HirVec::from_vec(vec![
hir::PathSegment::from_ident(Ident::from_interned_str(param.name))
]),
}),
)),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
}

View File

@ -37,8 +37,7 @@ use rustc::middle::lang_items;
use rustc::mir::interpret::GlobalId;
use rustc::hir::{self, GenericArg, HirVec};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::def_id::DefIndexAddressSpace;
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc::hir::map::Node;
use rustc::ty::subst::Substs;
use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind};
@ -75,13 +74,13 @@ mod simplify;
mod auto_trait;
mod blanket_impl;
pub mod def_ctor;
mod finder_trait;
use self::cfg::Cfg;
use self::auto_trait::AutoTraitFinder;
use self::blanket_impl::BlanketImplFinder;
thread_local!(static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> = RefCell::new(FxHashMap()));
thread_local!(pub static MAX_DEF_ID: RefCell<FxHashMap<CrateNum, DefId>> =
RefCell::new(FxHashMap()));
const FN_OUTPUT_NAME: &'static str = "Output";
@ -4505,7 +4504,7 @@ pub fn path_to_def(tcx: &TyCtxt, path: &[&str]) -> Option<DefId> {
}
}
fn get_path_for_type<F>(tcx: TyCtxt, def_id: DefId, def_ctor: F) -> hir::Path
pub fn get_path_for_type<F>(tcx: TyCtxt, def_id: DefId, def_ctor: F) -> hir::Path
where F: Fn(DefId) -> Def {
struct AbsolutePathBuffer {
names: Vec<String>,

View File

@ -11,8 +11,10 @@
use rustc_lint;
use rustc_driver::{self, driver, target_features, abort_on_err};
use rustc::session::{self, config};
use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
use rustc::hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CrateNum, LOCAL_CRATE};
use rustc::hir::def::Def;
use rustc::hir::{self, HirVec};
use rustc::middle::cstore::CrateStore;
use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt, AllArenas};
use rustc::hir::map as hir_map;
@ -24,11 +26,14 @@ use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::CStore;
use rustc_target::spec::TargetTriple;
use syntax::ast::{Name, NodeId};
use syntax::ast::{self, Ident, Name, NodeId};
use syntax::codemap;
use syntax::edition::Edition;
use syntax::feature_gate::UnstableFeatures;
use syntax::json::JsonEmitter;
use syntax::ptr::P;
use syntax::symbol::keywords;
use syntax_pos::DUMMY_SP;
use errors;
use errors::emitter::{Emitter, EmitterWriter};
@ -40,7 +45,7 @@ use std::path::PathBuf;
use visit_ast::RustdocVisitor;
use clean;
use clean::Clean;
use clean::{get_path_for_type, Clean, MAX_DEF_ID};
use html::render::RenderInfo;
pub use rustc::session::config::{Input, CodegenOptions};
@ -106,6 +111,140 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocContext<'a, 'tcx, 'rcx, 'cstore> {
*self.lt_substs.borrow_mut() = old_lts;
r
}
// This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
// refactoring either librustdoc or librustc. In particular, allowing new DefIds to be
// registered after the AST is constructed would require storing the defid mapping in a
// RefCell, decreasing the performance for normal compilation for very little gain.
//
// Instead, we construct 'fake' def ids, which start immediately after the last DefId in
// DefIndexAddressSpace::Low. In the Debug impl for clean::Item, we explicitly check for fake
// def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds
pub fn next_def_id(&self, crate_num: CrateNum) -> DefId {
let start_def_id = {
let next_id = if crate_num == LOCAL_CRATE {
self.tcx
.hir
.definitions()
.def_path_table()
.next_id(DefIndexAddressSpace::Low)
} else {
self.cstore
.def_path_table(crate_num)
.next_id(DefIndexAddressSpace::Low)
};
DefId {
krate: crate_num,
index: next_id,
}
};
let mut fake_ids = self.fake_def_ids.borrow_mut();
let def_id = fake_ids.entry(crate_num).or_insert(start_def_id).clone();
fake_ids.insert(
crate_num,
DefId {
krate: crate_num,
index: DefIndex::from_array_index(
def_id.index.as_array_index() + 1,
def_id.index.address_space(),
),
},
);
MAX_DEF_ID.with(|m| {
m.borrow_mut()
.entry(def_id.krate.clone())
.or_insert(start_def_id);
});
self.all_fake_def_ids.borrow_mut().insert(def_id);
def_id.clone()
}
pub fn get_real_ty<F>(&self,
def_id: DefId,
def_ctor: &F,
real_name: &Option<Ident>,
generics: &ty::Generics,
) -> hir::Ty
where F: Fn(DefId) -> Def {
let path = get_path_for_type(self.tcx, def_id, def_ctor);
let mut segments = path.segments.into_vec();
let last = segments.pop().expect("segments were empty");
segments.push(hir::PathSegment::new(
real_name.unwrap_or(last.ident),
self.generics_to_path_params(generics.clone()),
false,
));
let new_path = hir::Path {
span: path.span,
def: path.def,
segments: HirVec::from_vec(segments),
};
hir::Ty {
id: ast::DUMMY_NODE_ID,
node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
pub fn generics_to_path_params(&self, generics: ty::Generics) -> hir::GenericArgs {
let mut args = vec![];
for param in generics.params.iter() {
match param.kind {
ty::GenericParamDefKind::Lifetime => {
let name = if param.name == "" {
hir::ParamName::Plain(keywords::StaticLifetime.ident())
} else {
hir::ParamName::Plain(ast::Ident::from_interned_str(param.name))
};
args.push(hir::GenericArg::Lifetime(hir::Lifetime {
id: ast::DUMMY_NODE_ID,
span: DUMMY_SP,
name: hir::LifetimeName::Param(name),
}));
}
ty::GenericParamDefKind::Type {..} => {
args.push(hir::GenericArg::Type(self.ty_param_to_ty(param.clone())));
}
}
}
hir::GenericArgs {
args: HirVec::from_vec(args),
bindings: HirVec::new(),
parenthesized: false,
}
}
pub fn ty_param_to_ty(&self, param: ty::GenericParamDef) -> hir::Ty {
debug!("ty_param_to_ty({:?}) {:?}", param, param.def_id);
hir::Ty {
id: ast::DUMMY_NODE_ID,
node: hir::TyKind::Path(hir::QPath::Resolved(
None,
P(hir::Path {
span: DUMMY_SP,
def: Def::TyParam(param.def_id),
segments: HirVec::from_vec(vec![
hir::PathSegment::from_ident(Ident::from_interned_str(param.name))
]),
}),
)),
span: DUMMY_SP,
hir_id: hir::DUMMY_HIR_ID,
}
}
}
pub trait DocAccessLevels {