rustdoc: Move inlining to its own module
This commit is contained in:
parent
bd339ced36
commit
3100bc5b82
@ -41,7 +41,9 @@ pub fn recalibrate() {
|
||||
# }
|
||||
~~~
|
||||
|
||||
Documentation can also be controlled via the `doc` attribute on items.
|
||||
Documentation can also be controlled via the `doc` attribute on items. This is
|
||||
implicitly done by the compiler when using the above form of doc comments
|
||||
(converting the slash-based comments to `#[doc]` attributes).
|
||||
|
||||
~~~
|
||||
#[doc = "
|
||||
@ -50,6 +52,7 @@ Calculates the factorial of a number.
|
||||
Given the input integer `n`, this function will calculate `n!` and return it.
|
||||
"]
|
||||
pub fn factorial(n: int) -> int { if n < 2 {1} else {n * factorial(n)} }
|
||||
# fn main() {}
|
||||
~~~
|
||||
|
||||
The `doc` attribute can also be used to control how rustdoc emits documentation
|
||||
@ -60,6 +63,7 @@ in some cases.
|
||||
// `pub use` reaches across crates, but this behavior can also be disabled.
|
||||
#[doc(no_inline)]
|
||||
pub use std::option::Option;
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Doc comments are markdown, and are currently parsed with the
|
||||
|
@ -308,7 +308,7 @@ pub fn get_missing_lang_items(cstore: &cstore::CStore, cnum: ast::CrateNum)
|
||||
}
|
||||
|
||||
pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
|
||||
-> Vec<StrBuf>
|
||||
-> Vec<String>
|
||||
{
|
||||
let cdata = cstore.get_crate_data(did.krate);
|
||||
decoder::get_method_arg_names(&*cdata, did.node)
|
||||
|
@ -1310,7 +1310,7 @@ pub fn get_missing_lang_items(cdata: Cmd)
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<StrBuf> {
|
||||
pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
|
||||
let mut ret = Vec::new();
|
||||
let method_doc = lookup_item(id, cdata.data());
|
||||
match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
|
||||
|
278
src/librustdoc/clean/inline.rs
Normal file
278
src/librustdoc/clean/inline.rs
Normal file
@ -0,0 +1,278 @@
|
||||
// Copyright 2012-2013 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.
|
||||
|
||||
//! Support for inlining external documentation into the current AST.
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::ast_util;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
|
||||
use rustc::metadata::csearch;
|
||||
use rustc::metadata::decoder;
|
||||
use rustc::middle::ty;
|
||||
|
||||
use core;
|
||||
use doctree;
|
||||
use clean;
|
||||
|
||||
use super::Clean;
|
||||
|
||||
/// Attempt to inline the definition of a local node id 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 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(id: ast::NodeId) -> Option<Vec<clean::Item>> {
|
||||
let cx = ::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => return None,
|
||||
};
|
||||
let def = match tcx.def_map.borrow().find(&id) {
|
||||
Some(def) => *def,
|
||||
None => return None,
|
||||
};
|
||||
let did = ast_util::def_id_of_def(def);
|
||||
if ast_util::is_local(did) { return None }
|
||||
try_inline_def(&**cx, tcx, def)
|
||||
}
|
||||
|
||||
fn try_inline_def(cx: &core::DocContext,
|
||||
tcx: &ty::ctxt,
|
||||
def: ast::Def) -> Option<Vec<clean::Item>> {
|
||||
let mut ret = Vec::new();
|
||||
let did = ast_util::def_id_of_def(def);
|
||||
let inner = match def {
|
||||
ast::DefTrait(did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeTrait);
|
||||
clean::TraitItem(build_external_trait(tcx, did))
|
||||
}
|
||||
ast::DefFn(did, style) => {
|
||||
record_extern_fqn(cx, did, clean::TypeFunction);
|
||||
clean::FunctionItem(build_external_function(tcx, did, style))
|
||||
}
|
||||
ast::DefStruct(did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeStruct);
|
||||
ret.extend(build_impls(tcx, did).move_iter());
|
||||
clean::StructItem(build_struct(tcx, did))
|
||||
}
|
||||
ast::DefTy(did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeEnum);
|
||||
ret.extend(build_impls(tcx, did).move_iter());
|
||||
build_type(tcx, did)
|
||||
}
|
||||
// Assume that the enum type is reexported next to the variant, and
|
||||
// variants don't show up in documentation specially.
|
||||
ast::DefVariant(..) => return Some(Vec::new()),
|
||||
ast::DefMod(did) => {
|
||||
record_extern_fqn(cx, did, clean::TypeModule);
|
||||
clean::ModuleItem(build_module(cx, tcx, did))
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
ret.push(clean::Item {
|
||||
source: clean::Span::empty(),
|
||||
name: Some(fqn.last().unwrap().to_str().to_strbuf()),
|
||||
attrs: load_attrs(tcx, did),
|
||||
inner: inner,
|
||||
visibility: Some(ast::Public),
|
||||
def_id: did,
|
||||
});
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
pub fn load_attrs(tcx: &ty::ctxt, did: ast::DefId) -> Vec<clean::Attribute> {
|
||||
let mut attrs = Vec::new();
|
||||
csearch::get_item_attrs(&tcx.sess.cstore, did, |v| {
|
||||
attrs.extend(v.move_iter().map(|mut a| {
|
||||
// FIXME this isn't quite always true, it's just true about 99% of
|
||||
// the time when dealing with documentation. For example,
|
||||
// this would treat doc comments of the form `#[doc = "foo"]`
|
||||
// incorrectly.
|
||||
if a.name().get() == "doc" && a.value_str().is_some() {
|
||||
a.node.is_sugared_doc = true;
|
||||
}
|
||||
a.clean()
|
||||
}));
|
||||
});
|
||||
attrs
|
||||
}
|
||||
|
||||
/// Record an external fully qualified name in the external_paths cache.
|
||||
///
|
||||
/// These names are used later on by HTML rendering to generate things like
|
||||
/// source links back to the original item.
|
||||
pub fn record_extern_fqn(cx: &core::DocContext,
|
||||
did: ast::DefId,
|
||||
kind: clean::TypeKind) {
|
||||
match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => {
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
let fqn = fqn.move_iter().map(|i| i.to_str().to_strbuf()).collect();
|
||||
cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
|
||||
}
|
||||
core::NotTyped(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
|
||||
let def = ty::lookup_trait_def(tcx, did);
|
||||
let methods = ty::trait_methods(tcx, did);
|
||||
clean::Trait {
|
||||
generics: def.generics.clean(),
|
||||
methods: methods.iter().map(|i| i.clean()).collect(),
|
||||
parents: Vec::new(), // FIXME: this is likely wrong
|
||||
}
|
||||
}
|
||||
|
||||
fn build_external_function(tcx: &ty::ctxt,
|
||||
did: ast::DefId,
|
||||
style: ast::FnStyle) -> clean::Function {
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
clean::Function {
|
||||
decl: match ty::get(t.ty).sty {
|
||||
ty::ty_bare_fn(ref f) => (did, &f.sig).clean(),
|
||||
_ => fail!("bad function"),
|
||||
},
|
||||
generics: t.generics.clean(),
|
||||
fn_style: style,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
|
||||
use syntax::parse::token::special_idents::unnamed_field;
|
||||
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
let fields = ty::lookup_struct_fields(tcx, did);
|
||||
|
||||
clean::Struct {
|
||||
struct_type: match fields.as_slice() {
|
||||
[] => doctree::Unit,
|
||||
[ref f] if f.name == unnamed_field.name => doctree::Newtype,
|
||||
[ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
|
||||
_ => doctree::Plain,
|
||||
},
|
||||
generics: t.generics.clean(),
|
||||
fields: fields.iter().map(|f| f.clean()).collect(),
|
||||
fields_stripped: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
match ty::get(t.ty).sty {
|
||||
ty::ty_enum(edid, _) => {
|
||||
return clean::EnumItem(clean::Enum {
|
||||
generics: t.generics.clean(),
|
||||
variants_stripped: false,
|
||||
variants: ty::enum_variants(tcx, edid).clean(),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
clean::TypedefItem(clean::Typedef {
|
||||
type_: t.ty.clean(),
|
||||
generics: t.generics.clean(),
|
||||
})
|
||||
}
|
||||
|
||||
fn build_impls(tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> Vec<clean::Item> {
|
||||
ty::populate_implementations_for_type_if_necessary(tcx, did);
|
||||
let mut impls = Vec::new();
|
||||
|
||||
match tcx.inherent_impls.borrow().find(&did) {
|
||||
None => {}
|
||||
Some(i) => {
|
||||
impls.extend(i.borrow().iter().map(|&did| { build_impl(tcx, did) }));
|
||||
}
|
||||
}
|
||||
|
||||
impls
|
||||
}
|
||||
|
||||
fn build_impl(tcx: &ty::ctxt, did: ast::DefId) -> clean::Item {
|
||||
let associated_trait = csearch::get_impl_trait(tcx, did);
|
||||
let attrs = load_attrs(tcx, did);
|
||||
let ty = ty::lookup_item_type(tcx, did);
|
||||
let methods = csearch::get_impl_methods(&tcx.sess.cstore, did).iter().map(|did| {
|
||||
let mut item = match ty::method(tcx, *did).clean() {
|
||||
clean::Provided(item) => item,
|
||||
clean::Required(item) => item,
|
||||
};
|
||||
item.inner = match item.inner.clone() {
|
||||
clean::TyMethodItem(clean::TyMethod {
|
||||
fn_style, decl, self_, generics
|
||||
}) => {
|
||||
clean::MethodItem(clean::Method {
|
||||
fn_style: fn_style,
|
||||
decl: decl,
|
||||
self_: self_,
|
||||
generics: generics,
|
||||
})
|
||||
}
|
||||
_ => fail!("not a tymethod"),
|
||||
};
|
||||
item
|
||||
}).collect();
|
||||
clean::Item {
|
||||
inner: clean::ImplItem(clean::Impl {
|
||||
derived: clean::detect_derived(attrs.as_slice()),
|
||||
trait_: associated_trait.clean().map(|bound| {
|
||||
match bound {
|
||||
clean::TraitBound(ty) => ty,
|
||||
clean::RegionBound => unreachable!(),
|
||||
}
|
||||
}),
|
||||
for_: ty.ty.clean(),
|
||||
generics: ty.generics.clean(),
|
||||
methods: methods,
|
||||
}),
|
||||
source: clean::Span::empty(),
|
||||
name: None,
|
||||
attrs: attrs,
|
||||
visibility: Some(ast::Inherited),
|
||||
def_id: did,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> clean::Module {
|
||||
let mut items = Vec::new();
|
||||
|
||||
// FIXME: this doesn't handle reexports inside the module itself.
|
||||
// Should they be handled?
|
||||
csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, _| {
|
||||
match def {
|
||||
decoder::DlDef(def) => {
|
||||
match try_inline_def(cx, tcx, def) {
|
||||
Some(i) => items.extend(i.move_iter()),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
decoder::DlImpl(did) => items.push(build_impl(tcx, did)),
|
||||
decoder::DlField => fail!("unimplemented field"),
|
||||
}
|
||||
});
|
||||
|
||||
clean::Module {
|
||||
items: items,
|
||||
is_crate: false,
|
||||
}
|
||||
}
|
@ -37,6 +37,8 @@
|
||||
/// Increment this when the `Crate` and related structures change.
|
||||
pub static SCHEMA_VERSION: &'static str = "0.8.2";
|
||||
|
||||
mod inline;
|
||||
|
||||
pub trait Clean<T> {
|
||||
fn clean(&self) -> T;
|
||||
}
|
||||
@ -727,7 +729,7 @@ fn clean(&self) -> FnDecl {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => fail!(),
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let (did, sig) = *self;
|
||||
let mut names = if did.node != 0 {
|
||||
@ -738,9 +740,6 @@ fn clean(&self) -> FnDecl {
|
||||
if names.peek().map(|s| s.as_slice()) == Some("self") {
|
||||
let _ = names.next();
|
||||
}
|
||||
if did.node == 0 {
|
||||
let _ = names.len();
|
||||
}
|
||||
FnDecl {
|
||||
output: sig.output.clean(),
|
||||
cf: Return,
|
||||
@ -862,7 +861,7 @@ fn clean(&self) -> TraitMethod {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => tcx,
|
||||
core::NotTyped(_) => fail!(),
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let (self_, sig) = match self.explicit_self {
|
||||
ast::SelfStatic => (ast::SelfStatic.clean(), self.fty.sig.clone()),
|
||||
@ -890,7 +889,7 @@ fn clean(&self) -> TraitMethod {
|
||||
name: Some(self.ident.clean()),
|
||||
visibility: Some(ast::Inherited),
|
||||
def_id: self.def_id,
|
||||
attrs: load_attrs(tcx, self.def_id),
|
||||
attrs: inline::load_attrs(tcx, self.def_id),
|
||||
source: Span::empty(),
|
||||
inner: TyMethodItem(TyMethod {
|
||||
fn_style: self.fty.fn_style,
|
||||
@ -1035,7 +1034,7 @@ fn clean(&self) -> Type {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => fail!(),
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
let fqn: Vec<String> = fqn.move_iter().map(|i| {
|
||||
@ -1110,12 +1109,12 @@ fn clean(&self) -> Item {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => fail!(),
|
||||
core::NotTyped(_) => unreachable!(),
|
||||
};
|
||||
let ty = ty::lookup_item_type(tcx, self.id);
|
||||
Item {
|
||||
name: name.clean(),
|
||||
attrs: load_attrs(tcx, self.id),
|
||||
attrs: inline::load_attrs(tcx, self.id),
|
||||
source: Span::empty(),
|
||||
visibility: Some(self.vis),
|
||||
def_id: self.id,
|
||||
@ -1245,7 +1244,11 @@ fn clean(&self) -> Item {
|
||||
name: Some(name.clean()),
|
||||
attrs: Vec::new(),
|
||||
visibility: Some(ast::Public),
|
||||
def_id: self.id, // FIXME: this is not accurate
|
||||
// FIXME: this is not accurate, we need an id for
|
||||
// the specific field but we're using the id
|
||||
// for the whole variant. Nothing currently
|
||||
// uses this so we should be good for now.
|
||||
def_id: self.id,
|
||||
inner: StructFieldItem(
|
||||
TypedStructField(ty.clean())
|
||||
)
|
||||
@ -1256,7 +1259,7 @@ fn clean(&self) -> Item {
|
||||
};
|
||||
Item {
|
||||
name: Some(self.name.clean()),
|
||||
attrs: load_attrs(tcx, self.id),
|
||||
attrs: inline::load_attrs(tcx, self.id),
|
||||
source: Span::empty(),
|
||||
visibility: Some(ast::Public),
|
||||
def_id: self.id,
|
||||
@ -1377,8 +1380,8 @@ fn clean(&self) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<StrBuf> for ast::Name {
|
||||
fn clean(&self) -> StrBuf {
|
||||
impl Clean<String> for ast::Name {
|
||||
fn clean(&self) -> String {
|
||||
token::get_name(*self).get().to_strbuf()
|
||||
}
|
||||
}
|
||||
@ -1480,9 +1483,7 @@ pub struct Impl {
|
||||
}
|
||||
|
||||
fn detect_derived<M: AttrMetaMethods>(attrs: &[M]) -> bool {
|
||||
attrs.iter().any(|attr| {
|
||||
attr.name().get() == "automatically_derived"
|
||||
})
|
||||
attr::contains_name(attrs, "automatically_derived")
|
||||
}
|
||||
|
||||
impl Clean<Item> for doctree::Impl {
|
||||
@ -1511,9 +1512,12 @@ pub struct ViewItem {
|
||||
|
||||
impl Clean<Vec<Item>> for ast::ViewItem {
|
||||
fn clean(&self) -> Vec<Item> {
|
||||
// We consider inlining the documentation of `pub use` statments, but we
|
||||
// forcefully don't inline if this is not public or if the
|
||||
// #[doc(no_inline)] attribute is present.
|
||||
let denied = self.vis != ast::Public || self.attrs.iter().any(|a| {
|
||||
a.name().get() == "doc" && match a.meta_item_list() {
|
||||
Some(l) => attr::contains_name(l, "noinline"),
|
||||
Some(l) => attr::contains_name(l, "no_inline"),
|
||||
None => false,
|
||||
}
|
||||
});
|
||||
@ -1533,8 +1537,11 @@ fn clean(&self) -> Vec<Item> {
|
||||
match path.node {
|
||||
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
|
||||
ast::ViewPathList(ref a, ref list, ref b) => {
|
||||
// Attempt to inline all reexported items, but be sure
|
||||
// to keep any non-inlineable reexports so they can be
|
||||
// listed in the documentation.
|
||||
let remaining = list.iter().filter(|path| {
|
||||
match try_inline(path.node.id) {
|
||||
match inline::try_inline(path.node.id) {
|
||||
Some(items) => {
|
||||
ret.extend(items.move_iter()); false
|
||||
}
|
||||
@ -1550,7 +1557,7 @@ fn clean(&self) -> Vec<Item> {
|
||||
}
|
||||
}
|
||||
ast::ViewPathSimple(_, _, id) => {
|
||||
match try_inline(id) {
|
||||
match inline::try_inline(id) {
|
||||
Some(items) => ret.extend(items.move_iter()),
|
||||
None => ret.push(convert(&self.node)),
|
||||
}
|
||||
@ -1563,82 +1570,6 @@ fn clean(&self) -> Vec<Item> {
|
||||
}
|
||||
}
|
||||
|
||||
fn try_inline(id: ast::NodeId) -> Option<Vec<Item>> {
|
||||
let cx = super::ctxtkey.get().unwrap();
|
||||
let tcx = match cx.maybe_typed {
|
||||
core::Typed(ref tycx) => tycx,
|
||||
core::NotTyped(_) => return None,
|
||||
};
|
||||
let def = match tcx.def_map.borrow().find(&id) {
|
||||
Some(def) => *def,
|
||||
None => return None,
|
||||
};
|
||||
let did = ast_util::def_id_of_def(def);
|
||||
if ast_util::is_local(did) { return None }
|
||||
try_inline_def(&**cx, tcx, def)
|
||||
}
|
||||
|
||||
fn try_inline_def(cx: &core::DocContext,
|
||||
tcx: &ty::ctxt,
|
||||
def: ast::Def) -> Option<Vec<Item>> {
|
||||
let mut ret = Vec::new();
|
||||
let did = ast_util::def_id_of_def(def);
|
||||
let inner = match def {
|
||||
ast::DefTrait(did) => {
|
||||
record_extern_fqn(cx, did, TypeTrait);
|
||||
TraitItem(build_external_trait(tcx, did))
|
||||
}
|
||||
ast::DefFn(did, style) => {
|
||||
record_extern_fqn(cx, did, TypeFunction);
|
||||
FunctionItem(build_external_function(tcx, did, style))
|
||||
}
|
||||
ast::DefStruct(did) => {
|
||||
record_extern_fqn(cx, did, TypeStruct);
|
||||
ret.extend(build_impls(tcx, did).move_iter());
|
||||
StructItem(build_struct(tcx, did))
|
||||
}
|
||||
ast::DefTy(did) => {
|
||||
record_extern_fqn(cx, did, TypeEnum);
|
||||
ret.extend(build_impls(tcx, did).move_iter());
|
||||
build_type(tcx, did)
|
||||
}
|
||||
// Assume that the enum type is reexported next to the variant, and
|
||||
// variants don't show up in documentation specially.
|
||||
ast::DefVariant(..) => return Some(Vec::new()),
|
||||
ast::DefMod(did) => {
|
||||
record_extern_fqn(cx, did, TypeModule);
|
||||
ModuleItem(build_module(cx, tcx, did))
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
ret.push(Item {
|
||||
source: Span::empty(),
|
||||
name: Some(fqn.last().unwrap().to_str().to_strbuf()),
|
||||
attrs: load_attrs(tcx, did),
|
||||
inner: inner,
|
||||
visibility: Some(ast::Public),
|
||||
def_id: did,
|
||||
});
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
fn load_attrs(tcx: &ty::ctxt, did: ast::DefId) -> Vec<Attribute> {
|
||||
let mut attrs = Vec::new();
|
||||
csearch::get_item_attrs(&tcx.sess.cstore, did, |v| {
|
||||
attrs.extend(v.move_iter().map(|item| {
|
||||
let mut a = attr::mk_attr_outer(item);
|
||||
// FIXME this isn't quite always true, it's just true about 99% of
|
||||
// the time when dealing with documentation
|
||||
if a.name().get() == "doc" && a.value_str().is_some() {
|
||||
a.node.is_sugared_doc = true;
|
||||
}
|
||||
a.clean()
|
||||
}));
|
||||
});
|
||||
attrs
|
||||
}
|
||||
|
||||
#[deriving(Clone, Encodable, Decodable)]
|
||||
pub enum ViewItemInner {
|
||||
ExternCrate(String, Option<String>, ast::NodeId),
|
||||
@ -1850,10 +1781,10 @@ fn register_def(cx: &core::DocContext, def: ast::Def) -> ast::DefId {
|
||||
core::Typed(ref t) => t,
|
||||
core::NotTyped(_) => return did
|
||||
};
|
||||
record_extern_fqn(cx, did, kind);
|
||||
inline::record_extern_fqn(cx, did, kind);
|
||||
match kind {
|
||||
TypeTrait => {
|
||||
let t = build_external_trait(tcx, did);
|
||||
let t = inline::build_external_trait(tcx, did);
|
||||
cx.external_traits.borrow_mut().get_mut_ref().insert(did, t);
|
||||
}
|
||||
_ => {}
|
||||
@ -1861,190 +1792,6 @@ fn register_def(cx: &core::DocContext, def: ast::Def) -> ast::DefId {
|
||||
return did;
|
||||
}
|
||||
|
||||
fn record_extern_fqn(cx: &core::DocContext,
|
||||
did: ast::DefId,
|
||||
kind: TypeKind) {
|
||||
match cx.maybe_typed {
|
||||
core::Typed(ref tcx) => {
|
||||
let fqn = csearch::get_item_path(tcx, did);
|
||||
let fqn = fqn.move_iter().map(|i| i.to_str().to_strbuf()).collect();
|
||||
cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
|
||||
}
|
||||
core::NotTyped(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> Trait {
|
||||
let def = ty::lookup_trait_def(tcx, did);
|
||||
let methods = ty::trait_methods(tcx, did);
|
||||
Trait {
|
||||
generics: def.generics.clean(),
|
||||
methods: methods.iter().map(|i| i.clean()).collect(),
|
||||
parents: Vec::new(), // FIXME: this is likely wrong
|
||||
}
|
||||
}
|
||||
|
||||
fn build_external_function(tcx: &ty::ctxt,
|
||||
did: ast::DefId,
|
||||
style: ast::FnStyle) -> Function {
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
Function {
|
||||
decl: match ty::get(t.ty).sty {
|
||||
ty::ty_bare_fn(ref f) => (did, &f.sig).clean(),
|
||||
_ => fail!("bad function"),
|
||||
},
|
||||
generics: t.generics.clean(),
|
||||
fn_style: style,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> Struct {
|
||||
use syntax::parse::token::special_idents::unnamed_field;
|
||||
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
let fields = ty::lookup_struct_fields(tcx, did);
|
||||
|
||||
Struct {
|
||||
struct_type: match fields.as_slice() {
|
||||
[] => doctree::Unit,
|
||||
[ref f] if f.name == unnamed_field.name => doctree::Newtype,
|
||||
[ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
|
||||
_ => doctree::Plain,
|
||||
},
|
||||
generics: t.generics.clean(),
|
||||
fields: fields.iter().map(|f| f.clean()).collect(),
|
||||
fields_stripped: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> ItemEnum {
|
||||
let t = ty::lookup_item_type(tcx, did);
|
||||
match ty::get(t.ty).sty {
|
||||
ty::ty_enum(edid, _) => {
|
||||
return EnumItem(Enum {
|
||||
generics: t.generics.clean(),
|
||||
variants_stripped: false,
|
||||
variants: ty::enum_variants(tcx, edid).clean(),
|
||||
})
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
TypedefItem(Typedef {
|
||||
type_: t.ty.clean(),
|
||||
generics: t.generics.clean(),
|
||||
})
|
||||
}
|
||||
|
||||
fn build_impls(tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> Vec<Item> {
|
||||
ty::populate_implementations_for_type_if_necessary(tcx, did);
|
||||
let mut impls = Vec::new();
|
||||
|
||||
match tcx.inherent_impls.borrow().find(&did) {
|
||||
None => {}
|
||||
Some(i) => {
|
||||
impls.extend(i.borrow().iter().map(|&did| { build_impl(tcx, did) }));
|
||||
}
|
||||
}
|
||||
|
||||
// csearch::each_impl(&tcx.sess.cstore, did.krate, |imp| {
|
||||
// // if imp.krate
|
||||
// let t = ty::lookup_item_type(tcx, imp);
|
||||
// println!("{}", ::rustc::util::ppaux::ty_to_str(tcx, t.ty));
|
||||
// match ty::get(t.ty).sty {
|
||||
// ty::ty_struct(tdid, _) |
|
||||
// ty::ty_enum(tdid, _) if tdid == did => {
|
||||
// impls.push(build_impl(tcx, imp));
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// });
|
||||
// for (k, v) in tcx.trait_impls.borrow().iter() {
|
||||
// if k.krate != did.krate { continue }
|
||||
// for imp in v.borrow().iter() {
|
||||
// if imp.krate != did.krate { continue }
|
||||
// let t = ty::lookup_item_type(tcx, *imp);
|
||||
// println!("{}", ::rustc::util::ppaux::ty_to_str(tcx, t.ty));
|
||||
// match ty::get(t.ty).sty {
|
||||
// ty::ty_struct(tdid, _) |
|
||||
// ty::ty_enum(tdid, _) if tdid == did => {
|
||||
// impls.push(build_impl(tcx, *imp));
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impls
|
||||
}
|
||||
|
||||
fn build_impl(tcx: &ty::ctxt, did: ast::DefId) -> Item {
|
||||
let associated_trait = csearch::get_impl_trait(tcx, did);
|
||||
let attrs = load_attrs(tcx, did);
|
||||
let ty = ty::lookup_item_type(tcx, did);
|
||||
let methods = csearch::get_impl_methods(&tcx.sess.cstore, did).iter().map(|did| {
|
||||
let mut item = match ty::method(tcx, *did).clean() {
|
||||
Provided(item) => item,
|
||||
Required(item) => item,
|
||||
};
|
||||
item.inner = match item.inner.clone() {
|
||||
TyMethodItem(TyMethod { fn_style, decl, self_, generics }) => {
|
||||
MethodItem(Method {
|
||||
fn_style: fn_style,
|
||||
decl: decl,
|
||||
self_: self_,
|
||||
generics: generics,
|
||||
})
|
||||
}
|
||||
_ => fail!("not a tymethod"),
|
||||
};
|
||||
item
|
||||
}).collect();
|
||||
Item {
|
||||
inner: ImplItem(Impl {
|
||||
derived: detect_derived(attrs.as_slice()),
|
||||
trait_: associated_trait.clean().map(|bound| {
|
||||
match bound {
|
||||
TraitBound(ty) => ty,
|
||||
RegionBound => fail!(),
|
||||
}
|
||||
}),
|
||||
for_: ty.ty.clean(),
|
||||
generics: ty.generics.clean(),
|
||||
methods: methods,
|
||||
}),
|
||||
source: Span::empty(),
|
||||
name: None,
|
||||
attrs: attrs,
|
||||
visibility: Some(ast::Inherited),
|
||||
def_id: did,
|
||||
}
|
||||
}
|
||||
|
||||
fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
|
||||
did: ast::DefId) -> Module {
|
||||
let mut items = Vec::new();
|
||||
|
||||
csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, _| {
|
||||
match def {
|
||||
decoder::DlDef(def) => {
|
||||
match try_inline_def(cx, tcx, def) {
|
||||
Some(i) => items.extend(i.move_iter()),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
decoder::DlImpl(did) => items.push(build_impl(tcx, did)),
|
||||
decoder::DlField => fail!("unimplemented field"),
|
||||
}
|
||||
});
|
||||
|
||||
Module {
|
||||
items: items,
|
||||
is_crate: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
|
||||
ImportSource {
|
||||
path: path,
|
@ -143,7 +143,7 @@ pub struct Cache {
|
||||
|
||||
/// Similar to `paths`, but only holds external paths. This is only used for
|
||||
/// generating explicit hyperlinks to other crates.
|
||||
pub external_paths: HashMap<ast::DefId, Vec<StrBuf>>,
|
||||
pub external_paths: HashMap<ast::DefId, Vec<String>>,
|
||||
|
||||
/// This map contains information about all known traits of this crate.
|
||||
/// Implementations of a crate should inherit the documentation of the
|
||||
@ -253,7 +253,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
|
||||
let analysis = ::analysiskey.get();
|
||||
let public_items = analysis.as_ref().map(|a| a.public_items.clone());
|
||||
let public_items = public_items.unwrap_or(NodeSet::new());
|
||||
let paths: HashMap<ast::DefId, (Vec<StrBuf>, ItemType)> =
|
||||
let paths: HashMap<ast::DefId, (Vec<String>, ItemType)> =
|
||||
analysis.as_ref().map(|a| {
|
||||
let paths = a.external_paths.borrow_mut().take_unwrap();
|
||||
paths.move_iter().map(|(k, (v, t))| {
|
||||
@ -1041,7 +1041,19 @@ fn ismodule(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn link(&self) -> Option<String> {
|
||||
/// Generate a url appropriate for an `href` attribute back to the source of
|
||||
/// this item.
|
||||
///
|
||||
/// The url generated, when clicked, will redirect the browser back to the
|
||||
/// original source code.
|
||||
///
|
||||
/// If `None` is returned, then a source link couldn't be generated. This
|
||||
/// may happen, for example, with externally inlined items where the source
|
||||
/// of their crate documentation isn't known.
|
||||
fn href(&self) -> Option<String> {
|
||||
// If this item is part of the local crate, then we're guaranteed to
|
||||
// know the span, so we plow forward and generate a proper url. The url
|
||||
// has anchors for the line numbers that we're linking to.
|
||||
if ast_util::is_local(self.item.def_id) {
|
||||
let mut path = Vec::new();
|
||||
clean_srcpath(self.item.source.filename.as_bytes(), |component| {
|
||||
@ -1059,6 +1071,18 @@ fn link(&self) -> Option<String> {
|
||||
krate = self.cx.layout.krate,
|
||||
path = path.connect("/"),
|
||||
href = href))
|
||||
|
||||
// If this item is not part of the local crate, then things get a little
|
||||
// trickier. We don't actually know the span of the external item, but
|
||||
// we know that the documentation on the other end knows the span!
|
||||
//
|
||||
// In this case, we generate a link to the *documentation* for this type
|
||||
// in the original crate. There's an extra URL parameter which says that
|
||||
// we want to go somewhere else, and the JS on the destination page will
|
||||
// pick it up and instantly redirect the browser to the source code.
|
||||
//
|
||||
// If we don't know where the external documentation for this crate is
|
||||
// located, then we return `None`.
|
||||
} else {
|
||||
let cache = cache_key.get().unwrap();
|
||||
let path = cache.external_paths.get(&self.item.def_id);
|
||||
@ -1120,8 +1144,13 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
}
|
||||
|
||||
// Write `src` tag
|
||||
//
|
||||
// When this item is part of a `pub use` in a downstream crate, the
|
||||
// [src] link in the downstream documentation will actually come back to
|
||||
// this page, and this link will be auto-clicked. The `id` attribute is
|
||||
// used to find the link to auto-click.
|
||||
if self.cx.include_sources {
|
||||
match self.link() {
|
||||
match self.href() {
|
||||
Some(l) => {
|
||||
try!(write!(fmt,
|
||||
"<a class='source' id='src-{}' \
|
||||
@ -1288,7 +1317,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "<code> = </code>"));
|
||||
if s.contains("\n") {
|
||||
write!(f, "<a href='{}'>[definition]</a>",
|
||||
item.link())
|
||||
item.href())
|
||||
} else {
|
||||
write!(f, "<code>{}</code>", s.as_slice())
|
||||
}
|
||||
|
@ -676,13 +676,9 @@
|
||||
window.register_implementors(window.pending_implementors);
|
||||
}
|
||||
|
||||
|
||||
var query = window.location.search.substring(1);
|
||||
var vars = query.split('&');
|
||||
for (var i = 0; i < vars.length; i++) {
|
||||
var pair = vars[i].split('=');
|
||||
if (pair[0] == 'gotosrc') {
|
||||
window.location = $('#src-' + pair[1]).attr('href');
|
||||
}
|
||||
// See documentaiton in html/render.rs for what this is doing.
|
||||
var query = getQueryStringParams();
|
||||
if (query['gotosrc']) {
|
||||
window.location = $('#src-' + query['gotosrc']).attr('href');
|
||||
}
|
||||
}());
|
||||
|
@ -16,10 +16,10 @@
|
||||
//!
|
||||
//! ## Intrinsic types and operations
|
||||
//!
|
||||
//! The [`ptr`](../core/ptr/index.html) and [`mem`](../core/mem/index.html)
|
||||
//! The [`ptr`](ptr/index.html) and [`mem`](mem/index.html)
|
||||
//! modules deal with unsafe pointers and memory manipulation.
|
||||
//! [`kinds`](../core/kinds/index.html) defines the special built-in traits,
|
||||
//! and [`raw`](../core/raw/index.html) the runtime representation of Rust types.
|
||||
//! [`kinds`](kinds/index.html) defines the special built-in traits,
|
||||
//! and [`raw`](raw/index.html) the runtime representation of Rust types.
|
||||
//! These are some of the lowest-level building blocks in Rust.
|
||||
//!
|
||||
//! ## Math on primitive types and math traits
|
||||
@ -31,11 +31,11 @@
|
||||
//!
|
||||
//! ## Pervasive types
|
||||
//!
|
||||
//! The [`option`](option/index.html) and [`result`](../core/result/index.html)
|
||||
//! The [`option`](option/index.html) and [`result`](result/index.html)
|
||||
//! modules define optional and error-handling types, `Option` and `Result`.
|
||||
//! [`iter`](../core/iter/index.html) defines Rust's iterator protocol
|
||||
//! [`iter`](iter/index.html) defines Rust's iterator protocol
|
||||
//! along with a wide variety of iterators.
|
||||
//! [`Cell` and `RefCell`](../core/cell/index.html) are for creating types that
|
||||
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that
|
||||
//! manage their own mutability.
|
||||
//!
|
||||
//! ## Vectors, slices and strings
|
||||
|
@ -38,62 +38,62 @@
|
||||
//! `drop`, `spawn`, and `channel`.
|
||||
|
||||
// Reexported core operators
|
||||
#[doc(noinline)] pub use kinds::{Copy, Send, Sized, Share};
|
||||
#[doc(noinline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
|
||||
#[doc(noinline)] pub use ops::{BitAnd, BitOr, BitXor};
|
||||
#[doc(noinline)] pub use ops::{Drop, Deref, DerefMut};
|
||||
#[doc(noinline)] pub use ops::{Shl, Shr, Index};
|
||||
#[doc(noinline)] pub use option::{Option, Some, None};
|
||||
#[doc(noinline)] pub use result::{Result, Ok, Err};
|
||||
#[doc(no_inline)] pub use kinds::{Copy, Send, Sized, Share};
|
||||
#[doc(no_inline)] pub use ops::{Add, Sub, Mul, Div, Rem, Neg, Not};
|
||||
#[doc(no_inline)] pub use ops::{BitAnd, BitOr, BitXor};
|
||||
#[doc(no_inline)] pub use ops::{Drop, Deref, DerefMut};
|
||||
#[doc(no_inline)] pub use ops::{Shl, Shr, Index};
|
||||
#[doc(no_inline)] pub use option::{Option, Some, None};
|
||||
#[doc(no_inline)] pub use result::{Result, Ok, Err};
|
||||
|
||||
// Reexported functions
|
||||
#[doc(noinline)] pub use from_str::from_str;
|
||||
#[doc(noinline)] pub use iter::range;
|
||||
#[doc(noinline)] pub use mem::drop;
|
||||
#[doc(no_inline)] pub use from_str::from_str;
|
||||
#[doc(no_inline)] pub use iter::range;
|
||||
#[doc(no_inline)] pub use mem::drop;
|
||||
|
||||
// Reexported types and traits
|
||||
|
||||
#[doc(noinline)] pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
|
||||
#[doc(noinline)] pub use ascii::IntoBytes;
|
||||
#[doc(noinline)] pub use c_str::ToCStr;
|
||||
#[doc(noinline)] pub use char::Char;
|
||||
#[doc(noinline)] pub use clone::Clone;
|
||||
#[doc(noinline)] pub use cmp::{Eq, Ord, TotalEq, TotalOrd};
|
||||
#[doc(noinline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
|
||||
#[doc(noinline)] pub use container::{Container, Mutable, Map, MutableMap};
|
||||
#[doc(noinline)] pub use container::{Set, MutableSet};
|
||||
#[doc(noinline)] pub use iter::{FromIterator, Extendable, ExactSize};
|
||||
#[doc(noinline)] pub use iter::{Iterator, DoubleEndedIterator};
|
||||
#[doc(noinline)] pub use iter::{RandomAccessIterator, CloneableIterator};
|
||||
#[doc(noinline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator};
|
||||
#[doc(noinline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
|
||||
#[doc(noinline)] pub use num::{Signed, Unsigned, Primitive, Int, Float};
|
||||
#[doc(noinline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
|
||||
#[doc(noinline)] pub use option::Expect;
|
||||
#[doc(noinline)] pub use owned::Box;
|
||||
#[doc(noinline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
|
||||
#[doc(noinline)] pub use ptr::RawPtr;
|
||||
#[doc(noinline)] pub use io::{Buffer, Writer, Reader, Seek};
|
||||
#[doc(noinline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
|
||||
#[doc(noinline)] pub use str::{IntoMaybeOwned, StrAllocating};
|
||||
#[doc(noinline)] pub use to_str::{ToStr, IntoStr};
|
||||
#[doc(noinline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
|
||||
#[doc(noinline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
|
||||
#[doc(noinline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
|
||||
#[doc(noinline)] pub use slice::{CloneableVector, ImmutableCloneableVector};
|
||||
#[doc(noinline)] pub use slice::{MutableCloneableVector, MutableTotalOrdVector};
|
||||
#[doc(noinline)] pub use slice::{ImmutableVector, MutableVector};
|
||||
#[doc(noinline)] pub use slice::{ImmutableEqVector, ImmutableTotalOrdVector};
|
||||
#[doc(noinline)] pub use slice::{Vector, VectorVector, OwnedVector};
|
||||
#[doc(noinline)] pub use slice::MutableVectorAllocating;
|
||||
#[doc(noinline)] pub use string::String;
|
||||
#[doc(noinline)] pub use vec::Vec;
|
||||
#[doc(no_inline)] pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr};
|
||||
#[doc(no_inline)] pub use ascii::IntoBytes;
|
||||
#[doc(no_inline)] pub use c_str::ToCStr;
|
||||
#[doc(no_inline)] pub use char::Char;
|
||||
#[doc(no_inline)] pub use clone::Clone;
|
||||
#[doc(no_inline)] pub use cmp::{Eq, Ord, TotalEq, TotalOrd};
|
||||
#[doc(no_inline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
|
||||
#[doc(no_inline)] pub use container::{Container, Mutable, Map, MutableMap};
|
||||
#[doc(no_inline)] pub use container::{Set, MutableSet};
|
||||
#[doc(no_inline)] pub use iter::{FromIterator, Extendable, ExactSize};
|
||||
#[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator};
|
||||
#[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator};
|
||||
#[doc(no_inline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator};
|
||||
#[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
|
||||
#[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float};
|
||||
#[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
|
||||
#[doc(no_inline)] pub use option::Expect;
|
||||
#[doc(no_inline)] pub use owned::Box;
|
||||
#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};
|
||||
#[doc(no_inline)] pub use ptr::RawPtr;
|
||||
#[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek};
|
||||
#[doc(no_inline)] pub use str::{Str, StrVector, StrSlice, OwnedStr};
|
||||
#[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating};
|
||||
#[doc(no_inline)] pub use to_str::{ToStr, IntoStr};
|
||||
#[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4};
|
||||
#[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8};
|
||||
#[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12};
|
||||
#[doc(no_inline)] pub use slice::{CloneableVector, ImmutableCloneableVector};
|
||||
#[doc(no_inline)] pub use slice::{MutableCloneableVector, MutableTotalOrdVector};
|
||||
#[doc(no_inline)] pub use slice::{ImmutableVector, MutableVector};
|
||||
#[doc(no_inline)] pub use slice::{ImmutableEqVector, ImmutableTotalOrdVector};
|
||||
#[doc(no_inline)] pub use slice::{Vector, VectorVector, OwnedVector};
|
||||
#[doc(no_inline)] pub use slice::MutableVectorAllocating;
|
||||
#[doc(no_inline)] pub use string::String;
|
||||
#[doc(no_inline)] pub use vec::Vec;
|
||||
|
||||
// Reexported runtime types
|
||||
#[doc(noinline)] pub use comm::{sync_channel, channel};
|
||||
#[doc(noinline)] pub use comm::{SyncSender, Sender, Receiver};
|
||||
#[doc(noinline)] pub use task::spawn;
|
||||
#[doc(no_inline)] pub use comm::{sync_channel, channel};
|
||||
#[doc(no_inline)] pub use comm::{SyncSender, Sender, Receiver};
|
||||
#[doc(no_inline)] pub use task::spawn;
|
||||
|
||||
// Reexported statics
|
||||
#[cfg(not(test))]
|
||||
#[doc(noinline)] pub use gc::GC;
|
||||
#[doc(no_inline)] pub use gc::GC;
|
||||
|
Loading…
Reference in New Issue
Block a user