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
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-print-file-name=libstdc++.a)
LLVM_STDCPP_RUSTFLAGS_$(1) = -L "$$(dir $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
-print-file-name=libstdc++.a))"
else
LLVM_STDCPP_LOCATION_$(1) =
LLVM_STDCPP_RUSTFLAGS_$(1) =
endif

View File

@ -30,8 +30,8 @@ CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
CFG_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),beta)
CFG_RELEASE=$(CFG_RELEASE_NUM)-beta(CFG_PRERELEASE_VERSION)
CFG_PACKAGE_VERS=$(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_DISABLE_UNSTABLE_FEATURES=1
endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly)

View File

@ -85,7 +85,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
$$(RUST_LIB_FLAGS_ST$(1)) \
-L "$$(RT_OUTPUT_DIR_$(2))" \
-L "$$(LLVM_LIBDIR_$(2))" \
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
$$(LLVM_STDCPP_RUSTFLAGS_$(2)) \
$$(RUSTFLAGS_$(4)) \
--out-dir $$(@D) \
-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
`./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
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
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`.

View File

@ -27,9 +27,18 @@ def rust_pretty_printer_lookup_function(val):
if type_code == gdb.TYPE_CODE_STRUCT:
struct_kind = classify_struct(val.type)
if struct_kind == STRUCT_KIND_SLICE:
return RustSlicePrinter(val)
if struct_kind == STRUCT_KIND_STR_SLICE:
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:
return RustTuplePrinter(val)
@ -172,6 +181,28 @@ class RustTupleStructPrinter:
def display_hint(self):
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:
def __init__(self, val):
@ -181,6 +212,35 @@ class RustStringSlicePrinter:
slice_byte_len = self.val["length"]
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:
def __init__(self, val):
@ -204,19 +264,38 @@ STRUCT_KIND_TUPLE = 2
STRUCT_KIND_TUPLE_VARIANT = 3
STRUCT_KIND_STRUCT_VARIANT = 4
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):
# print("\nclassify_struct: tag=%s\n" % type.tag)
if type.tag == "&str":
return STRUCT_KIND_STR_SLICE
if type.tag.startswith("&[") and type.tag.endswith("]"):
return STRUCT_KIND_SLICE
fields = list(type.fields())
field_count = len(fields)
if field_count == 0:
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 field_count == 1:
return STRUCT_KIND_CSTYLE_VARIANT
@ -254,3 +333,11 @@ def get_field_at_index(val, index):
return field
i += 1
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 {
#[allocator]
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_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)]
#![no_std]
#![feature(allocator)]
#![feature(lang_items, unsafe_destructor)]
#![feature(box_syntax)]
#![feature(optin_builtin_traits)]

View File

@ -70,9 +70,7 @@ mod sip;
/// A hashable type.
///
/// 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
/// for particular instances of `H` in order to be able to optimize the hashing
/// behavior.
/// to compute the hash.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Hash {
/// 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;
//! ```
//!
//! 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
//! and requires no resource management later,
//! 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
//! and returns it as whatever type is requested, as long as the
//! 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.
//! The `into_raw` function consumes a box and returns
//! the raw pointer. It doesn't destroy `T` or deallocate any memory.
//!
//! ```
//! use std::mem;
//! use std::boxed;
//!
//! 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: *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
//! // we are obligated to transmute it back later to be destroyed.
//! drop(mem::transmute::<_, Box<i32>>(my_speed));
//! drop(mem::transmute::<_, Box<i32>>(my_num));
//! // we are obligated to put it together later to be destroyed.
//! drop(Box::from_raw(my_speed));
//! }
//! ```
//!

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);
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());
assert!(item_family(trait_doc) == Family::Trait);
let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
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> {
let crate_doc = rbml::Doc::new(metadata);
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,
ignore_non_const_paths: bool,
inherited_pub_visibility: bool,
ignore_variant_stack: Vec<ast::NodeId>,
}
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
@ -59,6 +60,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
struct_has_extern_repr: false,
ignore_non_const_paths: false,
inherited_pub_visibility: false,
ignore_variant_stack: vec![],
}
}
@ -79,7 +81,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
def::DefPrimTy(_) => (),
def::DefVariant(enum_id, variant_id, _) => {
self.check_def_id(enum_id);
self.check_def_id(variant_id);
if !self.ignore_variant_stack.contains(&variant_id.node) {
self.check_def_id(variant_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);
}
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) {
let def_map = &self.tcx.def_map;
match pat.node {
@ -397,6 +418,11 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
worklist.push(*id);
}
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);
}

View File

@ -155,3 +155,27 @@ pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
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, abi};
use lint;
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
use llvm::{AttrHelper, BasicBlockRef, Linkage, ValueRef, Vector, get_param};
use llvm;
use metadata::{csearch, encoder, loader};
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::ColdAttribute as uint64_t)
},
"allocator" => {
llvm::NoAliasAttribute.apply_llfn(llvm::ReturnIndex as c_uint, llfn);
}
_ => used = false,
}
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")
}
_ => {
foreign::register_foreign_item_fn(ccx, fn_ty.abi, t,
&name[..])
let llfn = foreign::register_foreign_item_fn(ccx, fn_ty.abi, t, &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 ty = ty::node_id_to_type(ccx.tcx(), ni.id);
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(..) => {
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?")
}
register_foreign_item_fn(ccx, abi, ty,
&lname);
let llfn = register_foreign_item_fn(ccx, abi, ty, &lname);
base::set_llvm_fn_attrs(ccx, &foreign_item.attrs, llfn);
// Unlike for other items, we shouldn't call
// `base::update_linkage` here. Foreign items have
// 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()
}
fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
fn build_impl(cx: &DocContext,
tcx: &ty::ctxt,
did: ast::DefId) -> Option<clean::Item> {
if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
return None
}
let attrs = load_attrs(cx, 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.
match associated_trait {
Some(ref t) => {
let trait_attrs = load_attrs(cx, tcx, t.def_id);
if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
return None
}
if let Some(ref t) = associated_trait {
// If this is an impl for a #[doc(hidden)] trait, be sure to not inline
let trait_attrs = load_attrs(cx, tcx, t.def_id);
if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
return None
}
None => {}
}
let attrs = load_attrs(cx, tcx, did);
let ty = ty::lookup_item_type(tcx, did);
// 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 predicates = ty::lookup_predicates(tcx, did);
let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
.iter()
@ -330,8 +347,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
}
}).collect();
let polarity = csearch::get_impl_polarity(tcx, did);
let ty = ty::lookup_item_type(tcx, did);
return Some(clean::Item {
inner: clean::ImplItem(clean::Impl {
unsafety: ast::Unsafety::Normal, // FIXME: this should be decoded
derived: clean::detect_derived(&attrs),
trait_: associated_trait.clean(cx).map(|bound| {
match bound {

View File

@ -337,6 +337,7 @@ pub enum ItemEnum {
MacroItem(Macro),
PrimitiveItem(PrimitiveType),
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
DefaultImplItem(DefaultImpl),
}
#[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.impls.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
// the outer `mod` item for the source code.
@ -2079,6 +2081,7 @@ impl Clean<ImplPolarity> for ast::ImplPolarity {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Impl {
pub unsafety: ast::Unsafety,
pub generics: Generics,
pub trait_: Option<Type>,
pub for_: Type,
@ -2101,6 +2104,7 @@ impl Clean<Item> for doctree::Impl {
visibility: self.vis.clean(cx),
stability: self.stab.clean(cx),
inner: ImplItem(Impl {
unsafety: self.unsafety,
generics: self.generics.clean(cx),
trait_: self.trait_.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 {
fn clean(&self, cx: &DocContext) -> Item {
Item {

View File

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

View File

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

View File

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

View File

@ -362,7 +362,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
let i = DefaultImpl {
unsafety: unsafety,
trait_: trait_ref.clone(),
id: item.id
id: item.id,
attrs: item.attrs.clone(),
whence: item.span,
};
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),
("on_unimplemented", "1.0.0", Active),
("simd_ffi", "1.0.0", Active),
("allocator", "1.0.0", Active),
("if_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",
"the `#[rustc_on_unimplemented]` attribute \
is an experimental feature")),
("allocator", Gated("allocator",
"the `#[allocator]` attribute is an experimental feature")),
("rustc_variance", Gated("rustc_attrs",
"the `#[rustc_variance]` attribute \
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 {
use super::*;
use std::rc::Rc;
use serialize::json;
use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
use owned_slice::OwnedSlice;
use ast;

View File

@ -121,6 +121,7 @@ impl fmt::Display for TestName {
#[derive(Clone, Copy)]
enum NamePadding {
PadNone,
#[allow(dead_code)]
PadOnLeft,
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!()
}
}
}