Auto merge of #23337 - Manishearth:rollup, r=Manishearth

r? @Manishearth
This commit is contained in:
bors 2015-03-13 17:49:15 +00:00
commit 9eb69abad8
29 changed files with 417 additions and 47 deletions

View File

@ -44,10 +44,10 @@ $$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
touch -r $$@.start_time $$@ && rm $$@.start_time touch -r $$@.start_time $$@ && rm $$@.start_time
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1) ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \ LLVM_STDCPP_RUSTFLAGS_$(1) = -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-print-file-name=libstdc++.a) -print-file-name=libstdc++.a))"
else else
LLVM_STDCPP_LOCATION_$(1) = LLVM_STDCPP_RUSTFLAGS_$(1) =
endif endif

View File

@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
CFG_DISABLE_UNSTABLE_FEATURES=1 CFG_DISABLE_UNSTABLE_FEATURES=1
endif endif
ifeq ($(CFG_RELEASE_CHANNEL),beta) ifeq ($(CFG_RELEASE_CHANNEL),beta)
CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) CFG_RELEASE=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION) CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-beta$(CFG_PRERELEASE_VERSION)
CFG_DISABLE_UNSTABLE_FEATURES=1 CFG_DISABLE_UNSTABLE_FEATURES=1
endif endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly) ifeq ($(CFG_RELEASE_CHANNEL),nightly)

View File

@ -85,7 +85,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
$$(RUST_LIB_FLAGS_ST$(1)) \ $$(RUST_LIB_FLAGS_ST$(1)) \
-L "$$(RT_OUTPUT_DIR_$(2))" \ -L "$$(RT_OUTPUT_DIR_$(2))" \
-L "$$(LLVM_LIBDIR_$(2))" \ -L "$$(LLVM_LIBDIR_$(2))" \
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \ $$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
$$(RUSTFLAGS_$(4)) \ $$(RUSTFLAGS_$(4)) \
--out-dir $$(@D) \ --out-dir $$(@D) \
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \ -C extra-filename=-$$(CFG_FILENAME_EXTRA) \

View File

@ -85,9 +85,11 @@ Hello, world!
Bam! We build our project with `cargo build`, and run it with Bam! We build our project with `cargo build`, and run it with
`./target/debug/hello_world`. This hasn't bought us a whole lot over our simple use `./target/debug/hello_world`. This hasn't bought us a whole lot over our simple use
of `rustc`, but think about the future: when our project has more than one of `rustc`, but think about the future: when our project has more than one
file, we would need to call `rustc` more than once, and pass it a bunch of options to file, we would need to call `rustc` more than once and pass it a bunch of options to
tell it to build everything together. With Cargo, as our project grows, we can tell it to build everything together. With Cargo, as our project grows, we can
just `cargo build` and it'll work the right way. When you're project is finally ready for release, you can use `cargo build --release` to compile your crates with optimizations. just `cargo build`, and it'll work the right way. When your project is finally
ready for release, you can use `cargo build --release` to compile your crates with
optimizations.
You'll also notice that Cargo has created a new file: `Cargo.lock`. You'll also notice that Cargo has created a new file: `Cargo.lock`.

View File

@ -27,9 +27,18 @@ def rust_pretty_printer_lookup_function(val):
if type_code == gdb.TYPE_CODE_STRUCT: if type_code == gdb.TYPE_CODE_STRUCT:
struct_kind = classify_struct(val.type) struct_kind = classify_struct(val.type)
if struct_kind == STRUCT_KIND_SLICE:
return RustSlicePrinter(val)
if struct_kind == STRUCT_KIND_STR_SLICE: if struct_kind == STRUCT_KIND_STR_SLICE:
return RustStringSlicePrinter(val) return RustStringSlicePrinter(val)
if struct_kind == STRUCT_KIND_STD_VEC:
return RustStdVecPrinter(val)
if struct_kind == STRUCT_KIND_STD_STRING:
return RustStdStringPrinter(val)
if struct_kind == STRUCT_KIND_TUPLE: if struct_kind == STRUCT_KIND_TUPLE:
return RustTuplePrinter(val) return RustTuplePrinter(val)
@ -172,6 +181,28 @@ class RustTupleStructPrinter:
def display_hint(self): def display_hint(self):
return "array" return "array"
class RustSlicePrinter:
def __init__(self, val):
self.val = val
def display_hint(self):
return "array"
def to_string(self):
length = int(self.val["length"])
return self.val.type.tag + ("(len: %i)" % length)
def children(self):
cs = []
length = int(self.val["length"])
data_ptr = self.val["data_ptr"]
assert data_ptr.type.code == gdb.TYPE_CODE_PTR
pointee_type = data_ptr.type.target()
for index in range(0, length):
cs.append((str(index), (data_ptr + index).dereference()))
return cs
class RustStringSlicePrinter: class RustStringSlicePrinter:
def __init__(self, val): def __init__(self, val):
@ -181,6 +212,35 @@ class RustStringSlicePrinter:
slice_byte_len = self.val["length"] slice_byte_len = self.val["length"]
return '"%s"' % self.val["data_ptr"].string(encoding="utf-8", length=slice_byte_len) return '"%s"' % self.val["data_ptr"].string(encoding="utf-8", length=slice_byte_len)
class RustStdVecPrinter:
def __init__(self, val):
self.val = val
def display_hint(self):
return "array"
def to_string(self):
length = int(self.val["len"])
cap = int(self.val["cap"])
return self.val.type.tag + ("(len: %i, cap: %i)" % (length, cap))
def children(self):
cs = []
(length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val)
pointee_type = data_ptr.type.target()
for index in range(0, length):
cs.append((str(index), (data_ptr + index).dereference()))
return cs
class RustStdStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
(length, data_ptr) = extract_length_and_data_ptr_from_std_vec(self.val["vec"])
return '"%s"' % data_ptr.string(encoding="utf-8", length=length)
class RustCStyleEnumPrinter: class RustCStyleEnumPrinter:
def __init__(self, val): def __init__(self, val):
@ -204,19 +264,38 @@ STRUCT_KIND_TUPLE = 2
STRUCT_KIND_TUPLE_VARIANT = 3 STRUCT_KIND_TUPLE_VARIANT = 3
STRUCT_KIND_STRUCT_VARIANT = 4 STRUCT_KIND_STRUCT_VARIANT = 4
STRUCT_KIND_CSTYLE_VARIANT = 5 STRUCT_KIND_CSTYLE_VARIANT = 5
STRUCT_KIND_STR_SLICE = 6 STRUCT_KIND_SLICE = 6
STRUCT_KIND_STR_SLICE = 7
STRUCT_KIND_STD_VEC = 8
STRUCT_KIND_STD_STRING = 9
def classify_struct(type): def classify_struct(type):
# print("\nclassify_struct: tag=%s\n" % type.tag)
if type.tag == "&str": if type.tag == "&str":
return STRUCT_KIND_STR_SLICE return STRUCT_KIND_STR_SLICE
if type.tag.startswith("&[") and type.tag.endswith("]"):
return STRUCT_KIND_SLICE
fields = list(type.fields()) fields = list(type.fields())
field_count = len(fields) field_count = len(fields)
if field_count == 0: if field_count == 0:
return STRUCT_KIND_REGULAR_STRUCT return STRUCT_KIND_REGULAR_STRUCT
if (field_count == 3 and
fields[0].name == "ptr" and
fields[1].name == "len" and
fields[2].name == "cap" and
type.tag.startswith("Vec<")):
return STRUCT_KIND_STD_VEC
if (field_count == 1 and
fields[0].name == "vec" and
type.tag == "String"):
return STRUCT_KIND_STD_STRING
if fields[0].name == "RUST$ENUM$DISR": if fields[0].name == "RUST$ENUM$DISR":
if field_count == 1: if field_count == 1:
return STRUCT_KIND_CSTYLE_VARIANT return STRUCT_KIND_CSTYLE_VARIANT
@ -254,3 +333,11 @@ def get_field_at_index(val, index):
return field return field
i += 1 i += 1
return None return None
def extract_length_and_data_ptr_from_std_vec(vec_val):
length = int(vec_val["len"])
vec_ptr_val = vec_val["ptr"]
unique_ptr_val = vec_ptr_val[first_field(vec_ptr_val)]
data_ptr = unique_ptr_val[first_field(unique_ptr_val)]
assert data_ptr.type.code == gdb.TYPE_CODE_PTR
return (length, data_ptr)

View File

@ -198,6 +198,7 @@ mod imp {
extern {} extern {}
extern { extern {
#[allocator]
fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void; fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;

View File

@ -69,6 +69,7 @@
#![feature(no_std)] #![feature(no_std)]
#![no_std] #![no_std]
#![feature(allocator)]
#![feature(lang_items, unsafe_destructor)] #![feature(lang_items, unsafe_destructor)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(optin_builtin_traits)] #![feature(optin_builtin_traits)]

View File

@ -70,9 +70,7 @@ mod sip;
/// A hashable type. /// A hashable type.
/// ///
/// The `H` type parameter is an abstract hash state that is used by the `Hash` /// The `H` type parameter is an abstract hash state that is used by the `Hash`
/// to compute the hash. Specific implementations of this trait may specialize /// to compute the hash.
/// for particular instances of `H` in order to be able to optimize the hashing
/// behavior.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait Hash { pub trait Hash {
/// Feeds this value into the state given, updating the hasher as necessary. /// Feeds this value into the state given, updating the hasher as necessary.

View File

@ -33,31 +33,34 @@
//! let my_speed_ptr: *mut i32 = &mut my_speed; //! let my_speed_ptr: *mut i32 = &mut my_speed;
//! ``` //! ```
//! //!
//! To get a pointer to a boxed value, dereference the box:
//!
//! ```
//! let my_num: Box<i32> = Box::new(10);
//! let my_num_ptr: *const i32 = &*my_num;
//! let mut my_speed: Box<i32> = Box::new(88);
//! let my_speed_ptr: *mut i32 = &mut *my_speed;
//! ```
//!
//! This does not take ownership of the original allocation //! This does not take ownership of the original allocation
//! and requires no resource management later, //! and requires no resource management later,
//! but you must not use the pointer after its lifetime. //! but you must not use the pointer after its lifetime.
//! //!
//! ## 2. Transmute an owned box (`Box<T>`). //! ## 2. Consume a box (`Box<T>`).
//! //!
//! The `transmute` function takes, by value, whatever it's given //! The `into_raw` function consumes a box and returns
//! and returns it as whatever type is requested, as long as the //! the raw pointer. It doesn't destroy `T` or deallocate any memory.
//! types are the same size. Because `Box<T>` and `*mut T` have the same
//! representation they can be trivially,
//! though unsafely, transformed from one type to the other.
//! //!
//! ``` //! ```
//! use std::mem; //! use std::boxed;
//! //!
//! unsafe { //! unsafe {
//! let my_num: Box<i32> = Box::new(10);
//! let my_num: *const i32 = mem::transmute(my_num);
//! let my_speed: Box<i32> = Box::new(88); //! let my_speed: Box<i32> = Box::new(88);
//! let my_speed: *mut i32 = mem::transmute(my_speed); //! let my_speed: *mut i32 = boxed::into_raw(my_speed);
//! //!
//! // By taking ownership of the original `Box<T>` though //! // By taking ownership of the original `Box<T>` though
//! // we are obligated to transmute it back later to be destroyed. //! // we are obligated to put it together later to be destroyed.
//! drop(mem::transmute::<_, Box<i32>>(my_speed)); //! drop(Box::from_raw(my_speed));
//! drop(mem::transmute::<_, Box<i32>>(my_num));
//! } //! }
//! ``` //! ```
//! //!

View File

@ -411,3 +411,8 @@ pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) ->
let cdata = cstore.get_crate_data(trait_def_id.krate); let cdata = cstore.get_crate_data(trait_def_id.krate);
decoder::is_defaulted_trait(&*cdata, trait_def_id.node) decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
} }
pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool {
let cdata = cstore.get_crate_data(impl_did.krate);
decoder::is_default_impl(&*cdata, impl_did.node)
}

View File

@ -1537,13 +1537,18 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool {
} }
} }
pub fn is_defaulted_trait<'tcx>(cdata: Cmd, trait_id: ast::NodeId) -> bool { pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool {
let trait_doc = lookup_item(trait_id, cdata.data()); let trait_doc = lookup_item(trait_id, cdata.data());
assert!(item_family(trait_doc) == Family::Trait); assert!(item_family(trait_doc) == Family::Trait);
let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait); let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
reader::doc_as_u8(defaulted_doc) != 0 reader::doc_as_u8(defaulted_doc) != 0
} }
pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool {
let impl_doc = lookup_item(impl_id, cdata.data());
item_family(impl_doc) == Family::DefaultImpl
}
pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> { pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
let crate_doc = rbml::Doc::new(metadata); let crate_doc = rbml::Doc::new(metadata);
let cm_doc = reader::get_doc(crate_doc, tag_codemap); let cm_doc = reader::get_doc(crate_doc, tag_codemap);

View File

@ -47,6 +47,7 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
struct_has_extern_repr: bool, struct_has_extern_repr: bool,
ignore_non_const_paths: bool, ignore_non_const_paths: bool,
inherited_pub_visibility: bool, inherited_pub_visibility: bool,
ignore_variant_stack: Vec<ast::NodeId>,
} }
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@ -59,6 +60,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
struct_has_extern_repr: false, struct_has_extern_repr: false,
ignore_non_const_paths: false, ignore_non_const_paths: false,
inherited_pub_visibility: false, inherited_pub_visibility: false,
ignore_variant_stack: vec![],
} }
} }
@ -79,8 +81,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
def::DefPrimTy(_) => (), def::DefPrimTy(_) => (),
def::DefVariant(enum_id, variant_id, _) => { def::DefVariant(enum_id, variant_id, _) => {
self.check_def_id(enum_id); self.check_def_id(enum_id);
if !self.ignore_variant_stack.contains(&variant_id.node) {
self.check_def_id(variant_id); self.check_def_id(variant_id);
} }
}
_ => { _ => {
self.check_def_id(def.def_id()); self.check_def_id(def.def_id());
} }
@ -278,6 +282,23 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
visit::walk_expr(self, expr); visit::walk_expr(self, expr);
} }
fn visit_arm(&mut self, arm: &ast::Arm) {
if arm.pats.len() == 1 {
let pat = &*arm.pats[0];
let variants = pat_util::necessary_variants(&self.tcx.def_map, pat);
// Inside the body, ignore constructions of variants
// necessary for the pattern to match. Those construction sites
// can't be reached unless the variant is constructed elsewhere.
let len = self.ignore_variant_stack.len();
self.ignore_variant_stack.push_all(&*variants);
visit::walk_arm(self, arm);
self.ignore_variant_stack.truncate(len);
} else {
visit::walk_arm(self, arm);
}
}
fn visit_pat(&mut self, pat: &ast::Pat) { fn visit_pat(&mut self, pat: &ast::Pat) {
let def_map = &self.tcx.def_map; let def_map = &self.tcx.def_map;
match pat.node { match pat.node {
@ -397,6 +418,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
worklist.push(*id); worklist.push(*id);
} }
for id in reachable_symbols { for id in reachable_symbols {
// Reachable variants can be dead, because we warn about
// variants never constructed, not variants never used.
if let Some(ast_map::NodeVariant(..)) = tcx.map.find(*id) {
continue;
}
worklist.push(*id); worklist.push(*id);
} }

View File

@ -155,3 +155,27 @@ pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
span: DUMMY_SP, span: DUMMY_SP,
}) })
} }
/// Return variants that are necessary to exist for the pattern to match.
pub fn necessary_variants(dm: &DefMap, pat: &ast::Pat) -> Vec<ast::NodeId> {
let mut variants = vec![];
walk_pat(pat, |p| {
match p.node {
ast::PatEnum(_, _) |
ast::PatIdent(_, _, None) |
ast::PatStruct(..) => {
match dm.borrow().get(&p.id) {
Some(&PathResolution {base_def: DefVariant(_, id, _), ..}) => {
variants.push(id.node);
}
_ => ()
}
}
_ => ()
}
true
});
variants.sort();
variants.dedup();
variants
}

View File

@ -33,7 +33,7 @@ use super::ModuleTranslation;
use back::link::{mangle_exported_name}; use back::link::{mangle_exported_name};
use back::{link, abi}; use back::{link, abi};
use lint; use lint;
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param}; use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
use llvm; use llvm;
use metadata::{csearch, encoder, loader}; use metadata::{csearch, encoder, loader};
use middle::astencode; use middle::astencode;
@ -456,6 +456,9 @@ pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: Val
llvm::FunctionIndex as c_uint, llvm::FunctionIndex as c_uint,
llvm::ColdAttribute as uint64_t) llvm::ColdAttribute as uint64_t)
}, },
"allocator" => {
llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
}
_ => used = false, _ => used = false,
} }
if used { if used {
@ -903,8 +906,10 @@ pub fn trans_external_path<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ccx.sess().bug("unexpected intrinsic in trans_external_path") ccx.sess().bug("unexpected intrinsic in trans_external_path")
} }
_ => { _ => {
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &name[..]);
&name[..]) let attrs = csearch::get_item_attrs(&ccx.sess().cstore, did);
set_llvm_fn_attrs(ccx, &attrs, llfn);
llfn
} }
} }
} }
@ -2841,7 +2846,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
let abi = ccx.tcx().map.get_foreign_abi(id); let abi = ccx.tcx().map.get_foreign_abi(id);
let ty = ty::node_id_to_type(ccx.tcx(), ni.id); let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
let name = foreign::link_name(&*ni); let name = foreign::link_name(&*ni);
foreign::register_foreign_item_fn(ccx, abi, ty, &name) let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
set_llvm_fn_attrs(ccx, &ni.attrs, llfn);
llfn
} }
ast::ForeignItemStatic(..) => { ast::ForeignItemStatic(..) => {
foreign::register_static(ccx, &*ni) foreign::register_static(ccx, &*ni)

View File

@ -470,8 +470,8 @@ pub fn trans_foreign_mod(ccx: &CrateContext, foreign_mod: &ast::ForeignMod) {
"foreign fn's sty isn't a bare_fn_ty?") "foreign fn's sty isn't a bare_fn_ty?")
} }
register_foreign_item_fn(ccx, abi, ty, let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
&lname); base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn);
// Unlike for other items, we shouldn't call // Unlike for other items, we shouldn't call
// `base::update_linkage` here. Foreign items have // `base::update_linkage` here. Foreign items have
// special linkage requirements, which are handled // special linkage requirements, which are handled

View File

@ -259,26 +259,43 @@ fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
impls.into_iter().filter_map(|a| a).collect() impls.into_iter().filter_map(|a| a).collect()
} }
fn build_impl(cx: &DocContext, tcx: &ty::ctxt, fn build_impl(cx: &DocContext,
tcx: &ty::ctxt,
did: ast::DefId) -> Option<clean::Item> { did: ast::DefId) -> Option<clean::Item> {
if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) { if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
return None return None
} }
let attrs = load_attrs(cx, tcx, did);
let associated_trait = csearch::get_impl_trait(tcx, did); let associated_trait = csearch::get_impl_trait(tcx, did);
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline it. if let Some(ref t) = associated_trait {
match associated_trait { // If this is an impl for a #[doc(hidden)] trait, be sure to not inline
Some(ref t) => {
let trait_attrs = load_attrs(cx, tcx, t.def_id); let trait_attrs = load_attrs(cx, tcx, t.def_id);
if trait_attrs.iter().any(|a| is_doc_hidden(a)) { if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
return None return None
} }
} }
None => {}
// If this is a defaulted impl, then bail out early here
if csearch::is_default_impl(&tcx.sess.cstore, did) {
return Some(clean::Item {
inner: clean::DefaultImplItem(clean::DefaultImpl {
// FIXME: this should be decoded
unsafety: ast::Unsafety::Normal,
trait_: match associated_trait.as_ref().unwrap().clean(cx) {
clean::TraitBound(polyt, _) => polyt.trait_,
clean::RegionBound(..) => unreachable!(),
},
}),
source: clean::Span::empty(),
name: None,
attrs: attrs,
visibility: Some(ast::Inherited),
stability: stability::lookup(tcx, did).clean(cx),
def_id: did,
});
} }
let attrs = load_attrs(cx, tcx, did);
let ty = ty::lookup_item_type(tcx, did);
let predicates = ty::lookup_predicates(tcx, did); let predicates = ty::lookup_predicates(tcx, did);
let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did) let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
.iter() .iter()
@ -330,8 +347,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
} }
}).collect(); }).collect();
let polarity = csearch::get_impl_polarity(tcx, did); let polarity = csearch::get_impl_polarity(tcx, did);
let ty = ty::lookup_item_type(tcx, did);
return Some(clean::Item { return Some(clean::Item {
inner: clean::ImplItem(clean::Impl { inner: clean::ImplItem(clean::Impl {
unsafety: ast::Unsafety::Normal, // FIXME: this should be decoded
derived: clean::detect_derived(&attrs), derived: clean::detect_derived(&attrs),
trait_: associated_trait.clean(cx).map(|bound| { trait_: associated_trait.clean(cx).map(|bound| {
match bound { match bound {

View File

@ -337,6 +337,7 @@ pub enum ItemEnum {
MacroItem(Macro), MacroItem(Macro),
PrimitiveItem(PrimitiveType), PrimitiveItem(PrimitiveType),
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>), AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
DefaultImplItem(DefaultImpl),
} }
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
@ -367,6 +368,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.traits.iter().map(|x| x.clean(cx))); items.extend(self.traits.iter().map(|x| x.clean(cx)));
items.extend(self.impls.iter().map(|x| x.clean(cx))); items.extend(self.impls.iter().map(|x| x.clean(cx)));
items.extend(self.macros.iter().map(|x| x.clean(cx))); items.extend(self.macros.iter().map(|x| x.clean(cx)));
items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
// determine if we should display the inner contents or // determine if we should display the inner contents or
// the outer `mod` item for the source code. // the outer `mod` item for the source code.
@ -2079,6 +2081,7 @@ impl Clean<ImplPolarity> for ast::ImplPolarity {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Impl { pub struct Impl {
pub unsafety: ast::Unsafety,
pub generics: Generics, pub generics: Generics,
pub trait_: Option<Type>, pub trait_: Option<Type>,
pub for_: Type, pub for_: Type,
@ -2101,6 +2104,7 @@ impl Clean<Item> for doctree::Impl {
visibility: self.vis.clean(cx), visibility: self.vis.clean(cx),
stability: self.stab.clean(cx), stability: self.stab.clean(cx),
inner: ImplItem(Impl { inner: ImplItem(Impl {
unsafety: self.unsafety,
generics: self.generics.clean(cx), generics: self.generics.clean(cx),
trait_: self.trait_.clean(cx), trait_: self.trait_.clean(cx),
for_: self.for_.clean(cx), for_: self.for_.clean(cx),
@ -2112,6 +2116,29 @@ impl Clean<Item> for doctree::Impl {
} }
} }
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct DefaultImpl {
pub unsafety: ast::Unsafety,
pub trait_: Type,
}
impl Clean<Item> for doctree::DefaultImpl {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: ast_util::local_def(self.id),
visibility: Some(ast::Public),
stability: None,
inner: DefaultImplItem(DefaultImpl {
unsafety: self.unsafety,
trait_: self.trait_.clean(cx),
}),
}
}
}
impl Clean<Item> for doctree::ExternCrate { impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item { fn clean(&self, cx: &DocContext) -> Item {
Item { Item {

View File

@ -202,6 +202,8 @@ pub struct DefaultImpl {
pub unsafety: ast::Unsafety, pub unsafety: ast::Unsafety,
pub trait_: ast::TraitRef, pub trait_: ast::TraitRef,
pub id: ast::NodeId, pub id: ast::NodeId,
pub attrs: Vec<ast::Attribute>,
pub whence: Span,
} }
pub struct Macro { pub struct Macro {

View File

@ -64,6 +64,7 @@ impl ItemType {
clean::MacroItem(..) => ItemType::Macro, clean::MacroItem(..) => ItemType::Macro,
clean::PrimitiveItem(..) => ItemType::Primitive, clean::PrimitiveItem(..) => ItemType::Primitive,
clean::AssociatedTypeItem(..) => ItemType::AssociatedType, clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
clean::DefaultImplItem(..) => ItemType::Impl,
} }
} }

View File

@ -176,7 +176,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
return None; return None;
} }
} }
clean::ImplItem(..) => {} clean::DefaultImplItem(..) | clean::ImplItem(..) => {}
// tymethods/macros have no control over privacy // tymethods/macros have no control over privacy
clean::MacroItem(..) | clean::TyMethodItem(..) => {} clean::MacroItem(..) | clean::TyMethodItem(..) => {}

View File

@ -362,7 +362,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let i = DefaultImpl { let i = DefaultImpl {
unsafety: unsafety, unsafety: unsafety,
trait_: trait_ref.clone(), trait_: trait_ref.clone(),
id: item.id id: item.id,
attrs: item.attrs.clone(),
whence: item.span,
}; };
om.def_traits.push(i); om.def_traits.push(i);
} }

View File

@ -83,6 +83,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
("box_syntax", "1.0.0", Active), ("box_syntax", "1.0.0", Active),
("on_unimplemented", "1.0.0", Active), ("on_unimplemented", "1.0.0", Active),
("simd_ffi", "1.0.0", Active), ("simd_ffi", "1.0.0", Active),
("allocator", "1.0.0", Active),
("if_let", "1.0.0", Accepted), ("if_let", "1.0.0", Accepted),
("while_let", "1.0.0", Accepted), ("while_let", "1.0.0", Accepted),
@ -230,6 +231,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
("rustc_on_unimplemented", Gated("on_unimplemented", ("rustc_on_unimplemented", Gated("on_unimplemented",
"the `#[rustc_on_unimplemented]` attribute \ "the `#[rustc_on_unimplemented]` attribute \
is an experimental feature")), is an experimental feature")),
("allocator", Gated("allocator",
"the `#[allocator]` attribute is an experimental feature")),
("rustc_variance", Gated("rustc_attrs", ("rustc_variance", Gated("rustc_attrs",
"the `#[rustc_variance]` attribute \ "the `#[rustc_variance]` attribute \
is an experimental feature")), is an experimental feature")),

View File

@ -754,7 +754,6 @@ pub fn integer_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) ->
mod test { mod test {
use super::*; use super::*;
use std::rc::Rc; use std::rc::Rc;
use serialize::json;
use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION}; use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
use ast; use ast;

View File

@ -121,6 +121,7 @@ impl fmt::Display for TestName {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
enum NamePadding { enum NamePadding {
PadNone, PadNone,
#[allow(dead_code)]
PadOnLeft, PadOnLeft,
PadOnRight, PadOnRight,
} }

View File

@ -0,0 +1,42 @@
// Copyright 2015 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.
#![deny(dead_code)]
#[derive(Copy)]
enum Enum {
Variant1, //~ ERROR: variant is never used
Variant2,
Variant3,
}
fn copy(e: Enum) -> Enum {
use Enum::*;
match e {
Variant1 => Variant1,
Variant2 => Variant2,
Variant3 => Variant3,
}
}
fn max(e: Enum) -> Enum {
use Enum::*;
match e {
Variant1 => Variant3,
Variant2 => Variant3,
Variant3 => Variant3,
}
}
fn main() {
let e = Enum::Variant2;
copy(e);
max(e);
}

View File

@ -0,0 +1,60 @@
// Copyright 2013-2015 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.
// ignore-windows failing on win32 bot
// ignore-freebsd: gdb package too new
// ignore-tidy-linelength
// ignore-lldb
// ignore-android: FIXME(#10381)
// compile-flags:-g
// min-gdb-version 7.7
// gdb-command: run
// gdb-command: print slice
// gdb-check:$1 = &[i32](len: 4) = {0, 1, 2, 3}
// gdb-command: print vec
// gdb-check:$2 = Vec<u64>(len: 4, cap: [...]) = {4, 5, 6, 7}
// gdb-command: print str_slice
// gdb-check:$3 = "IAMA string slice!"
// gdb-command: print string
// gdb-check:$4 = "IAMA string!"
// gdb-command: print some
// gdb-check:$5 = Some = {8}
// gdb-command: print none
// gdb-check:$6 = None
fn main() {
// &[]
let slice: &[i32] = &[0, 1, 2, 3];
// Vec
let vec = vec![4u64, 5, 6, 7];
// &str
let str_slice = "IAMA string slice!";
// String
let string = "IAMA string!".to_string();
// Option
let some = Some(8i16);
let none: Option<i64> = None;
zzz(); // #break
}
fn zzz() { () }

View File

@ -0,0 +1,5 @@
-include ../tools.mk
all: foo.rs bar.rs
$(RUSTC) foo.rs --crate-type lib
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc bar.rs -L $(TMPDIR)

View File

@ -0,0 +1,17 @@
// Copyright 2015 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.
extern crate foo;
pub use foo::bar;
pub fn wut<T: bar::Bar>() {
}

View File

@ -0,0 +1,33 @@
// Copyright 2015 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.
pub mod bar {
use std::marker;
pub trait Bar: marker::MarkerTrait + 'static {}
impl Bar for .. {}
pub trait Foo {
fn foo(&self) {}
}
impl Foo {
pub fn test<T: Bar>(&self) {}
}
pub struct TypeId;
impl TypeId {
pub fn of<T: Bar + ?Sized>() -> TypeId {
panic!()
}
}
}