Remove FinderTrait and move its functions into DocContext
This commit is contained in:
parent
fc81adb3c2
commit
0bff861d32
@ -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>>,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
@ -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>,
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user