rustc: embed path resolutions into the HIR instead of keeping DefMap.
This commit is contained in:
parent
bc096549e8
commit
962633cdbb
55 changed files with 951 additions and 949 deletions
|
|
@ -29,24 +29,21 @@ use clean::{self, GetDefId};
|
|||
|
||||
use super::Clean;
|
||||
|
||||
/// Attempt to inline the definition of a local node id into this AST.
|
||||
/// Attempt to inline a definition into this AST.
|
||||
///
|
||||
/// This function will fetch the definition of the id specified, and if it is
|
||||
/// from another crate it will attempt to inline the documentation from the
|
||||
/// other crate into this crate.
|
||||
/// This function will fetch the definition specified, and if it is
|
||||
/// from another crate it will attempt to inline the documentation
|
||||
/// from the other crate into this crate.
|
||||
///
|
||||
/// This is primarily used for `pub use` statements which are, in general,
|
||||
/// implementation details. Inlining the documentation should help provide a
|
||||
/// better experience when reading the documentation in this use case.
|
||||
///
|
||||
/// The returned value is `None` if the `id` could not be inlined, and `Some`
|
||||
/// of a vector of items if it was successfully expanded.
|
||||
pub fn try_inline(cx: &DocContext, id: ast::NodeId, into: Option<ast::Name>)
|
||||
/// The returned value is `None` if the definition could not be inlined,
|
||||
/// and `Some` of a vector of items if it was successfully expanded.
|
||||
pub fn try_inline(cx: &DocContext, def: Def, into: Option<ast::Name>)
|
||||
-> Option<Vec<clean::Item>> {
|
||||
let def = match cx.tcx.expect_def_or_none(id) {
|
||||
Some(def) => def,
|
||||
None => return None,
|
||||
};
|
||||
if def == Def::Err { return None }
|
||||
let did = def.def_id();
|
||||
if did.is_local() { return None }
|
||||
try_inline_def(cx, def).map(|vec| {
|
||||
|
|
|
|||
|
|
@ -667,6 +667,7 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self
|
|||
bindings: Vec<TypeBinding>, substs: &Substs) -> Path {
|
||||
Path {
|
||||
global: false,
|
||||
def: Def::Err,
|
||||
segments: vec![PathSegment {
|
||||
name: name.to_string(),
|
||||
params: external_path_params(cx, trait_did, has_self, bindings, substs)
|
||||
|
|
@ -1728,13 +1729,12 @@ impl Clean<Type> for hir::Ty {
|
|||
},
|
||||
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
||||
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
||||
let def = cx.tcx.expect_def(self.id);
|
||||
if let Some(new_ty) = cx.ty_substs.borrow().get(&def).cloned() {
|
||||
if let Some(new_ty) = cx.ty_substs.borrow().get(&path.def).cloned() {
|
||||
return new_ty;
|
||||
}
|
||||
|
||||
let mut alias = None;
|
||||
if let Def::TyAlias(def_id) = def {
|
||||
if let Def::TyAlias(def_id) = path.def {
|
||||
// Substitute private type aliases
|
||||
if let Some(node_id) = cx.tcx.map.as_local_node_id(def_id) {
|
||||
if !cx.access_levels.borrow().is_exported(def_id) {
|
||||
|
|
@ -1748,7 +1748,7 @@ impl Clean<Type> for hir::Ty {
|
|||
let mut ty_substs = FxHashMap();
|
||||
let mut lt_substs = FxHashMap();
|
||||
for (i, ty_param) in generics.ty_params.iter().enumerate() {
|
||||
let ty_param_def = cx.tcx.expect_def(ty_param.id);
|
||||
let ty_param_def = Def::TyParam(cx.tcx.map.local_def_id(ty_param.id));
|
||||
if let Some(ty) = provided_params.types().get(i).cloned()
|
||||
.cloned() {
|
||||
ty_substs.insert(ty_param_def, ty.unwrap().clean(cx));
|
||||
|
|
@ -1772,6 +1772,7 @@ impl Clean<Type> for hir::Ty {
|
|||
let trait_path = hir::Path {
|
||||
span: p.span,
|
||||
global: p.global,
|
||||
def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()),
|
||||
segments: segments.into(),
|
||||
};
|
||||
Type::QPath {
|
||||
|
|
@ -1784,6 +1785,10 @@ impl Clean<Type> for hir::Ty {
|
|||
let trait_path = hir::Path {
|
||||
span: self.span,
|
||||
global: false,
|
||||
def: cx.tcx_opt().map_or(Def::Err, |tcx| {
|
||||
let def_id = tcx.tables().type_relative_path_defs[&self.id].def_id();
|
||||
Def::Trait(tcx.associated_item(def_id).container.id())
|
||||
}),
|
||||
segments: vec![].into(),
|
||||
};
|
||||
Type::QPath {
|
||||
|
|
@ -2194,6 +2199,7 @@ impl Clean<Span> for syntax_pos::Span {
|
|||
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
||||
pub struct Path {
|
||||
pub global: bool,
|
||||
pub def: Def,
|
||||
pub segments: Vec<PathSegment>,
|
||||
}
|
||||
|
||||
|
|
@ -2201,6 +2207,7 @@ impl Path {
|
|||
pub fn singleton(name: String) -> Path {
|
||||
Path {
|
||||
global: false,
|
||||
def: Def::Err,
|
||||
segments: vec![PathSegment {
|
||||
name: name,
|
||||
params: PathParameters::AngleBracketed {
|
||||
|
|
@ -2221,6 +2228,7 @@ impl Clean<Path> for hir::Path {
|
|||
fn clean(&self, cx: &DocContext) -> Path {
|
||||
Path {
|
||||
global: self.global,
|
||||
def: self.def,
|
||||
segments: self.segments.clean(cx),
|
||||
}
|
||||
}
|
||||
|
|
@ -2591,15 +2599,15 @@ impl Clean<Vec<Item>> for doctree::Import {
|
|||
});
|
||||
let path = self.path.clean(cx);
|
||||
let inner = if self.glob {
|
||||
Import::Glob(resolve_use_source(cx, path, self.id))
|
||||
Import::Glob(resolve_use_source(cx, path))
|
||||
} else {
|
||||
let name = self.name;
|
||||
if !denied {
|
||||
if let Some(items) = inline::try_inline(cx, self.id, Some(name)) {
|
||||
if let Some(items) = inline::try_inline(cx, path.def, Some(name)) {
|
||||
return items;
|
||||
}
|
||||
}
|
||||
Import::Simple(name.clean(cx), resolve_use_source(cx, path, self.id))
|
||||
Import::Simple(name.clean(cx), resolve_use_source(cx, path))
|
||||
};
|
||||
vec![Item {
|
||||
name: None,
|
||||
|
|
@ -2697,7 +2705,7 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
|||
|
||||
match p.node {
|
||||
PatKind::Wild => "_".to_string(),
|
||||
PatKind::Binding(_, ref p, _) => p.node.to_string(),
|
||||
PatKind::Binding(_, _, ref p, _) => p.node.to_string(),
|
||||
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
|
||||
PatKind::Struct(ref name, ref fields, etc) => {
|
||||
format!("{} {{ {}{} }}", qpath_to_string(name),
|
||||
|
|
@ -2727,15 +2735,13 @@ fn name_from_pat(p: &hir::Pat) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Given a Type, resolve it using the def_map
|
||||
/// Given a type Path, resolve it to a Type using the TyCtxt
|
||||
fn resolve_type(cx: &DocContext,
|
||||
path: Path,
|
||||
id: ast::NodeId) -> Type {
|
||||
debug!("resolve_type({:?},{:?})", path, id);
|
||||
let def = cx.tcx.expect_def(id);
|
||||
debug!("resolve_type: def={:?}", def);
|
||||
|
||||
let is_generic = match def {
|
||||
let is_generic = match path.def {
|
||||
Def::PrimTy(p) => match p {
|
||||
hir::TyStr => return Primitive(PrimitiveType::Str),
|
||||
hir::TyBool => return Primitive(PrimitiveType::Bool),
|
||||
|
|
@ -2750,7 +2756,7 @@ fn resolve_type(cx: &DocContext,
|
|||
Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true,
|
||||
_ => false,
|
||||
};
|
||||
let did = register_def(&*cx, def);
|
||||
let did = register_def(&*cx, path.def);
|
||||
ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
|
||||
}
|
||||
|
||||
|
|
@ -2782,17 +2788,17 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
|
|||
did
|
||||
}
|
||||
|
||||
fn resolve_use_source(cx: &DocContext, path: Path, id: ast::NodeId) -> ImportSource {
|
||||
fn resolve_use_source(cx: &DocContext, path: Path) -> ImportSource {
|
||||
ImportSource {
|
||||
did: if path.def == Def::Err {
|
||||
None
|
||||
} else {
|
||||
Some(register_def(cx, path.def))
|
||||
},
|
||||
path: path,
|
||||
did: resolve_def(cx, id),
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option<DefId> {
|
||||
cx.tcx.expect_def_or_none(id).map(|def| register_def(cx, def))
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub struct Macro {
|
||||
pub source: String,
|
||||
|
|
@ -2896,6 +2902,7 @@ fn lang_struct(cx: &DocContext, did: Option<DefId>,
|
|||
did: did,
|
||||
path: Path {
|
||||
global: false,
|
||||
def: Def::Err,
|
||||
segments: vec![PathSegment {
|
||||
name: name.to_string(),
|
||||
params: PathParameters::AngleBracketed {
|
||||
|
|
|
|||
|
|
@ -234,8 +234,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
/// and follows different rules.
|
||||
///
|
||||
/// Returns true if the target has been inlined.
|
||||
fn maybe_inline_local(&mut self, id: ast::NodeId, renamed: Option<ast::Name>,
|
||||
glob: bool, om: &mut Module, please_inline: bool) -> bool {
|
||||
fn maybe_inline_local(&mut self,
|
||||
id: ast::NodeId,
|
||||
def: Def,
|
||||
renamed: Option<ast::Name>,
|
||||
glob: bool,
|
||||
om: &mut Module,
|
||||
please_inline: bool) -> bool {
|
||||
|
||||
fn inherits_doc_hidden(cx: &core::DocContext, mut node: ast::NodeId) -> bool {
|
||||
while let Some(id) = cx.tcx.map.get_enclosing_scope(node) {
|
||||
|
|
@ -251,7 +256,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
let tcx = self.cx.tcx;
|
||||
let def = tcx.expect_def(id);
|
||||
if def == Def::Err {
|
||||
return false;
|
||||
}
|
||||
let def_did = def.def_id();
|
||||
|
||||
let use_attrs = tcx.map.attrs(id);
|
||||
|
|
@ -368,13 +375,18 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
}
|
||||
});
|
||||
let name = if is_glob { None } else { Some(name) };
|
||||
if self.maybe_inline_local(item.id, name, is_glob, om, please_inline) {
|
||||
if self.maybe_inline_local(item.id,
|
||||
path.def,
|
||||
name,
|
||||
is_glob,
|
||||
om,
|
||||
please_inline) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
om.imports.push(Import {
|
||||
name: item.name,
|
||||
name: name,
|
||||
id: item.id,
|
||||
vis: item.vis.clone(),
|
||||
attrs: item.attrs.clone(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue