mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Auto merge of #23337 - Manishearth:rollup, r=Manishearth
r? @Manishearth
This commit is contained in:
commit
9eb69abad8
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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) \
|
||||||
|
@ -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`.
|
||||||
|
|
||||||
|
@ -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)
|
@ -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;
|
||||||
|
@ -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)]
|
||||||
|
@ -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.
|
||||||
|
@ -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));
|
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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(..) => {}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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")),
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
42
src/test/compile-fail/lint-dead-code-variant.rs
Normal file
42
src/test/compile-fail/lint-dead-code-variant.rs
Normal 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);
|
||||||
|
}
|
60
src/test/debuginfo/gdb-pretty-std.rs
Normal file
60
src/test/debuginfo/gdb-pretty-std.rs
Normal 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() { () }
|
5
src/test/run-make/rustdoc-default-impl/Makefile
Normal file
5
src/test/run-make/rustdoc-default-impl/Makefile
Normal 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)
|
17
src/test/run-make/rustdoc-default-impl/bar.rs
Normal file
17
src/test/run-make/rustdoc-default-impl/bar.rs
Normal 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>() {
|
||||||
|
}
|
||||||
|
|
33
src/test/run-make/rustdoc-default-impl/foo.rs
Normal file
33
src/test/run-make/rustdoc-default-impl/foo.rs
Normal 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!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user