]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #31828 - frewsxcv:sepseq-associated-function, r=alexcrichton
authorbors <bors@rust-lang.org>
Wed, 24 Feb 2016 11:29:31 +0000 (11:29 +0000)
committerbors <bors@rust-lang.org>
Wed, 24 Feb 2016 11:29:31 +0000 (11:29 +0000)
None

43 files changed:
mk/cfg/armv7-unknown-linux-gnueabihf.mk
src/etc/licenseck.py
src/etc/tidy.py
src/libcollections/borrow.rs
src/libcollections/btree/map.rs
src/libcore/intrinsics.rs
src/libcore/option.rs
src/libcore/result.rs
src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs
src/librustc_data_structures/bitvec.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/simplify_cfg.rs
src/librustc_mir/transform/util.rs [deleted file]
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.js
src/librustdoc/html/static/styles/main.css
src/libstd/collections/hash/map.rs
src/libstd/env.rs
src/libstd/ffi/c_str.rs
src/libstd/ffi/os_str.rs
src/libstd/io/mod.rs
src/libstd/net/addr.rs
src/libstd/net/ip.rs
src/libstd/path.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sys/common/poison.rs
src/libstd/sys/common/unwind/gcc.rs
src/libstd/sys/common/unwind/mod.rs
src/libstd/sys/common/unwind/seh.rs
src/libstd/sys/common/unwind/seh64_gnu.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/handle.rs
src/libstd/sys/windows/printing/msvc.rs
src/libstd/sys/windows/thread_local.rs
src/libsyntax_ext/deriving/clone.rs
src/libsyntax_ext/deriving/debug.rs
src/libsyntax_ext/deriving/encodable.rs
src/libsyntax_ext/deriving/generic/mod.rs
src/libsyntax_ext/deriving/hash.rs
src/snapshots.txt
src/test/auxiliary/custom_derive_plugin_attr.rs
src/test/run-pass/empty-struct-braces-derive.rs [new file with mode: 0644]

index 3efbad8642b8303afc65e29b6e3e802b620b4f23..a8e39668ded5e3cfd88e0a8b07ce9f1ed0029e76 100644 (file)
@@ -21,6 +21,6 @@ CFG_UNIXY_armv7-unknown-linux-gnueabihf := 1
 CFG_LDPATH_armv7-unknown-linux-gnueabihf :=
 CFG_RUN_armv7-unknown-linux-gnueabihf=$(2)
 CFG_RUN_TARG_armv7-unknown-linux-gnueabihf=$(call CFG_RUN_armv7-unknown-linux-gnueabihf,,$(2))
-RUSTC_FLAGS_armv7-unknown-linux-gnueabihf := -C target-feature=+v7,+vfp2,+neon
+RUSTC_FLAGS_armv7-unknown-linux-gnueabihf :=
 RUSTC_CROSS_FLAGS_armv7-unknown-linux-gnueabihf :=
 CFG_GNU_TRIPLE_armv7-unknown-linux-gnueabihf := armv7-unknown-linux-gnueabihf
index 889b2c95a7ea88c5a740c8a4bfda2e607801d006..aa2a00beae58365c2b1ad0c13ee0836e5abdb36b 100644 (file)
@@ -9,6 +9,7 @@
 # except according to those terms.
 
 import re
+import os
 
 license_re = re.compile(
 u"""(#|//) Copyright .* The Rust Project Developers. See the COPYRIGHT
@@ -40,8 +41,9 @@ exceptions = [
 ]
 
 def check_license(name, contents):
+    name = os.path.normpath(name)
     # Whitelist check
-    if any(name.endswith(e) for e in exceptions):
+    if any(name.endswith(os.path.normpath(e)) for e in exceptions):
         return True
 
     # Xfail check
index ea34a803ccb4054a18c133ca8436cbb3cd920f08..ce774d31b081fe2a34d727e8d17d291a30376b7a 100644 (file)
@@ -122,7 +122,8 @@ try:
             'src/liblibc',
         }
 
-        if any(d in dirpath for d in skippable_dirs):
+        dirpath = os.path.normpath(dirpath)
+        if any(os.path.normpath(d) in dirpath for d in skippable_dirs):
             continue
 
         file_names = [os.path.join(dirpath, f) for f in filenames
index f174cc09bcd3525a324bf64635912b9fd7742c91..ce20a25d13af38ac38f8402669e6f4d5582f2ef4 100644 (file)
@@ -95,12 +95,12 @@ pub enum Cow<'a, B: ?Sized + 'a>
 {
     /// Borrowed data.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Borrowed(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a B),
+    Borrowed(#[stable(feature = "rust1", since = "1.0.0")] &'a B),
 
     /// Owned data.
     #[stable(feature = "rust1", since = "1.0.0")]
     Owned(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] <B as ToOwned>::Owned
+        #[stable(feature = "rust1", since = "1.0.0")] <B as ToOwned>::Owned
     ),
 }
 
index 7207e7b151c1eae3966022d942574d4cc9a672c2..2a950ce0ab72d58404aa0981513ceb1fa9effbee 100644 (file)
@@ -238,13 +238,13 @@ pub enum Entry<'a, K: 'a, V: 'a> {
     /// A vacant Entry
     #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] VacantEntry<'a, K, V>
+        #[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>
     ),
 
     /// An occupied Entry
     #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] OccupiedEntry<'a, K, V>
+        #[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>
     ),
 }
 
index 47f5d68f311588d66584dbfbfe846912408face8..b0dcb0d539989ed90557518790e24bfb440ddd28 100644 (file)
@@ -586,8 +586,5 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// platforms this is a `*mut *mut T` which is filled in by the compiler and
     /// on MSVC it's `*mut [usize; 2]`. For more information see the compiler's
     /// source as well as std's catch implementation.
-    #[cfg(not(stage0))]
     pub fn try(f: fn(*mut u8), data: *mut u8, local_ptr: *mut u8) -> i32;
-    #[cfg(stage0)]
-    pub fn try(f: fn(*mut u8), data: *mut u8) -> *mut u8;
 }
index eeb0c173b9b7b8238f872abdc042402b572f9a74..e38cf9af010b9f9953fff8c59a0def8c0c36283e 100644 (file)
@@ -169,7 +169,7 @@ pub enum Option<T> {
     None,
     /// Some value `T`
     #[stable(feature = "rust1", since = "1.0.0")]
-    Some(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T)
+    Some(#[stable(feature = "rust1", since = "1.0.0")] T)
 }
 
 /////////////////////////////////////////////////////////////////////////////
index 9bd6ed12798a5efc58703e91519ce5696e5c26f5..f6703d16ad997e988e347bb45720356985b5c572 100644 (file)
 pub enum Result<T, E> {
     /// Contains the success value
     #[stable(feature = "rust1", since = "1.0.0")]
-    Ok(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T),
+    Ok(#[stable(feature = "rust1", since = "1.0.0")] T),
 
     /// Contains the error value
     #[stable(feature = "rust1", since = "1.0.0")]
-    Err(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] E)
+    Err(#[stable(feature = "rust1", since = "1.0.0")] E)
 }
 
 /////////////////////////////////////////////////////////////////////////////
index dd61bd8757375467754491fe54d6873f64d0bf84..d7dcd714a10b759c9b38564cb3b49580f4fe74e9 100644 (file)
@@ -22,7 +22,7 @@ pub fn target() -> Target {
         target_vendor: "unknown".to_string(),
 
         options: TargetOptions {
-            features: "+v7,+vfp2,+neon".to_string(),
+            features: "+v7,+vfp3,+neon".to_string(),
             cpu: "cortex-a8".to_string(),
             .. base
         }
index 70f50b4c042b13c17f75447d974b18e03af602cb..7b5dacece8c203b275d42f99f162c2067a3c6dc1 100644 (file)
@@ -50,6 +50,45 @@ pub fn grow(&mut self, num_bits: usize) {
         let extra_words = self.data.len() - num_words;
         self.data.extend((0..extra_words).map(|_| 0));
     }
+
+    /// Iterates over indexes of set bits in a sorted order
+    pub fn iter<'a>(&'a self) -> BitVectorIter<'a> {
+        BitVectorIter {
+            iter: self.data.iter(),
+            current: 0,
+            idx: 0
+        }
+    }
+}
+
+pub struct BitVectorIter<'a> {
+    iter: ::std::slice::Iter<'a, u64>,
+    current: u64,
+    idx: usize
+}
+
+impl<'a> Iterator for BitVectorIter<'a> {
+    type Item = usize;
+    fn next(&mut self) -> Option<usize> {
+        while self.current == 0 {
+            self.current = if let Some(&i) = self.iter.next() {
+                if i == 0 {
+                    self.idx += 64;
+                    continue;
+                } else {
+                    self.idx = u64s(self.idx) * 64;
+                    i
+                }
+            } else {
+                return None;
+            }
+        }
+        let offset = self.current.trailing_zeros() as usize;
+        self.current >>= offset;
+        self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000
+        self.idx += offset + 1;
+        return Some(self.idx - 1);
+    }
 }
 
 /// A "bit matrix" is basically a square matrix of booleans
@@ -153,6 +192,46 @@ fn word_mask(index: usize) -> (usize, u64) {
     (word, mask)
 }
 
+#[test]
+fn bitvec_iter_works() {
+    let mut bitvec = BitVector::new(100);
+    bitvec.insert(1);
+    bitvec.insert(10);
+    bitvec.insert(19);
+    bitvec.insert(62);
+    bitvec.insert(63);
+    bitvec.insert(64);
+    bitvec.insert(65);
+    bitvec.insert(66);
+    bitvec.insert(99);
+    assert_eq!(bitvec.iter().collect::<Vec<_>>(), [1, 10, 19, 62, 63, 64, 65, 66, 99]);
+}
+
+#[test]
+fn bitvec_iter_works_2() {
+    let mut bitvec = BitVector::new(300);
+    bitvec.insert(1);
+    bitvec.insert(10);
+    bitvec.insert(19);
+    bitvec.insert(62);
+    bitvec.insert(66);
+    bitvec.insert(99);
+    bitvec.insert(299);
+    assert_eq!(bitvec.iter().collect::<Vec<_>>(), [1, 10, 19, 62, 66, 99, 299]);
+
+}
+
+#[test]
+fn bitvec_iter_works_3() {
+    let mut bitvec = BitVector::new(319);
+    bitvec.insert(0);
+    bitvec.insert(127);
+    bitvec.insert(191);
+    bitvec.insert(255);
+    bitvec.insert(319);
+    assert_eq!(bitvec.iter().collect::<Vec<_>>(), [0, 127, 191, 255, 319]);
+}
+
 #[test]
 fn union_two_vecs() {
     let mut vec1 = BitVector::new(65);
index d27c208041faf658eefc0aba6bffd0e4ed90fba4..adca68114fd0152e929c8719ab5077fd064f95df 100644 (file)
@@ -13,4 +13,3 @@
 pub mod erase_regions;
 pub mod no_landing_pads;
 pub mod type_check;
-mod util;
index 16d12324202f33c8f1bbf05e346cad613caa615a..785e6db57a53843f8089deecb23414064beac26d 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use rustc_data_structures::bitvec::BitVector;
 use rustc::middle::const_eval::ConstVal;
 use rustc::middle::infer;
 use rustc::mir::repr::*;
-use transform::util;
 use rustc::mir::transform::MirPass;
 
 pub struct SimplifyCfg;
@@ -22,23 +22,21 @@ pub fn new() -> SimplifyCfg {
     }
 
     fn remove_dead_blocks(&self, mir: &mut Mir) {
-        let mut seen = vec![false; mir.basic_blocks.len()];
-
+        let mut seen = BitVector::new(mir.basic_blocks.len());
         // These blocks are always required.
-        seen[START_BLOCK.index()] = true;
-        seen[END_BLOCK.index()] = true;
+        seen.insert(START_BLOCK.index());
+        seen.insert(END_BLOCK.index());
 
-        let mut worklist = vec![START_BLOCK];
+        let mut worklist = Vec::with_capacity(4);
+        worklist.push(START_BLOCK);
         while let Some(bb) = worklist.pop() {
             for succ in mir.basic_block_data(bb).terminator().successors().iter() {
-                if !seen[succ.index()] {
-                    seen[succ.index()] = true;
+                if seen.insert(succ.index()) {
                     worklist.push(*succ);
                 }
             }
         }
-
-        util::retain_basic_blocks(mir, &seen);
+        retain_basic_blocks(mir, &seen);
     }
 
     fn remove_goto_chains(&self, mir: &mut Mir) -> bool {
@@ -90,12 +88,12 @@ fn simplify_branches(&self, mir: &mut Mir) -> bool {
         for bb in mir.all_basic_blocks() {
             let basic_block = mir.basic_block_data_mut(bb);
             let mut terminator = basic_block.terminator_mut();
-
             *terminator = match *terminator {
                 Terminator::If { ref targets, .. } if targets.0 == targets.1 => {
                     changed = true;
                     Terminator::Goto { target: targets.0 }
                 }
+
                 Terminator::If { ref targets, cond: Operand::Constant(Constant {
                     literal: Literal::Value {
                         value: ConstVal::Bool(cond)
@@ -108,6 +106,7 @@ fn simplify_branches(&self, mir: &mut Mir) -> bool {
                         Terminator::Goto { target: targets.1 }
                     }
                 }
+
                 Terminator::SwitchInt { ref targets, .. }  if targets.len() == 1 => {
                     Terminator::Goto { target: targets[0] }
                 }
@@ -131,3 +130,27 @@ fn run_on_mir<'a, 'tcx>(&mut self, mir: &mut Mir<'tcx>, _: &infer::InferCtxt<'a,
         mir.basic_blocks.shrink_to_fit();
     }
 }
+
+/// Mass removal of basic blocks to keep the ID-remapping cheap.
+fn retain_basic_blocks(mir: &mut Mir, keep: &BitVector) {
+    let num_blocks = mir.basic_blocks.len();
+
+    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
+    let mut used_blocks = 0;
+    for alive_index in keep.iter() {
+        replacements[alive_index] = BasicBlock::new(used_blocks);
+        if alive_index != used_blocks {
+            // Swap the next alive block data with the current available slot. Since alive_index is
+            // non-decreasing this is a valid operation.
+            mir.basic_blocks.swap(alive_index, used_blocks);
+        }
+        used_blocks += 1;
+    }
+    mir.basic_blocks.truncate(used_blocks);
+
+    for bb in mir.all_basic_blocks() {
+        for target in mir.basic_block_data_mut(bb).terminator_mut().successors_mut() {
+            *target = replacements[target.index()];
+        }
+    }
+}
diff --git a/src/librustc_mir/transform/util.rs b/src/librustc_mir/transform/util.rs
deleted file mode 100644 (file)
index 7e44beb..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-// 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.
-
-use rustc::mir::repr::*;
-
-/// Update basic block ids in all terminators using the given replacements,
-/// useful e.g. after removal of several basic blocks to update all terminators
-/// in a single pass
-pub fn update_basic_block_ids(mir: &mut Mir, replacements: &[BasicBlock]) {
-    for bb in mir.all_basic_blocks() {
-        for target in mir.basic_block_data_mut(bb).terminator_mut().successors_mut() {
-            *target = replacements[target.index()];
-        }
-    }
-}
-
-/// Mass removal of basic blocks to keep the ID-remapping cheap.
-pub fn retain_basic_blocks(mir: &mut Mir, keep: &[bool]) {
-    let num_blocks = mir.basic_blocks.len();
-
-    // Check that we have a usage flag for every block
-    assert_eq!(num_blocks, keep.len());
-
-    let first_dead = match keep.iter().position(|&k| !k) {
-        None => return,
-        Some(first_dead) => first_dead,
-    };
-
-    // `replacements` maps the old block ids to the new ones
-    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
-
-    let mut dead = 0;
-    for i in first_dead..num_blocks {
-        if keep[i] {
-            replacements[i] = BasicBlock::new(i - dead);
-            mir.basic_blocks.swap(i, i - dead);
-        } else {
-            dead += 1;
-        }
-    }
-    mir.basic_blocks.truncate(num_blocks - dead);
-
-    update_basic_block_ids(mir, &replacements);
-}
index 2053fc73e8fc2c2c2d025fabfa89dca5b4b026e2..692d230446cda7b356b028021237f610c28bb141 100644 (file)
@@ -52,7 +52,7 @@
 
 use externalfiles::ExternalHtml;
 
-use serialize::json::{self, ToJson};
+use serialize::json::{ToJson, Json, as_json};
 use syntax::{abi, ast};
 use syntax::feature_gate::UnstableFeatures;
 use rustc::middle::cstore::LOCAL_CRATE;
@@ -290,22 +290,40 @@ struct IndexItem {
     path: String,
     desc: String,
     parent: Option<DefId>,
+    parent_idx: Option<usize>,
     search_type: Option<IndexItemFunctionType>,
 }
 
+impl ToJson for IndexItem {
+    fn to_json(&self) -> Json {
+        assert_eq!(self.parent.is_some(), self.parent_idx.is_some());
+
+        let mut data = Vec::with_capacity(6);
+        data.push((self.ty as usize).to_json());
+        data.push(self.name.to_json());
+        data.push(self.path.to_json());
+        data.push(self.desc.to_json());
+        data.push(self.parent_idx.to_json());
+        data.push(self.search_type.to_json());
+
+        Json::Array(data)
+    }
+}
+
 /// A type used for the search index.
 struct Type {
     name: Option<String>,
 }
 
-impl fmt::Display for Type {
-    /// Formats type as {name: $name}.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        // Wrapping struct fmt should never call us when self.name is None,
-        // but just to be safe we write `null` in that case.
+impl ToJson for Type {
+    fn to_json(&self) -> Json {
         match self.name {
-            Some(ref n) => write!(f, "{{\"name\":\"{}\"}}", n),
-            None => write!(f, "null")
+            Some(ref name) => {
+                let mut data = BTreeMap::new();
+                data.insert("name".to_owned(), name.to_json());
+                Json::Object(data)
+            },
+            None => Json::Null
         }
     }
 }
@@ -316,26 +334,17 @@ struct IndexItemFunctionType {
     output: Option<Type>
 }
 
-impl fmt::Display for IndexItemFunctionType {
-    /// Formats a full fn type as a JSON {inputs: [Type], outputs: Type/null}.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+impl ToJson for IndexItemFunctionType {
+    fn to_json(&self) -> Json {
         // If we couldn't figure out a type, just write `null`.
-        if self.inputs.iter().any(|ref i| i.name.is_none()) ||
-           (self.output.is_some() && self.output.as_ref().unwrap().name.is_none()) {
-            return write!(f, "null")
+        if self.inputs.iter().chain(self.output.iter()).any(|ref i| i.name.is_none()) {
+            Json::Null
+        } else {
+            let mut data = BTreeMap::new();
+            data.insert("inputs".to_owned(), self.inputs.to_json());
+            data.insert("output".to_owned(), self.output.to_json());
+            Json::Object(data)
         }
-
-        let inputs: Vec<String> = self.inputs.iter().map(|ref t| {
-            format!("{}", t)
-        }).collect();
-        try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.join(",")));
-
-        match self.output {
-            Some(ref t) => try!(write!(f, "{}", t)),
-            None => try!(write!(f, "null"))
-        };
-
-        Ok(try!(write!(f, "}}")))
     }
 }
 
@@ -534,101 +543,79 @@ pub fn run(mut krate: clean::Crate,
     cx.krate(krate)
 }
 
+/// Build the search index from the collected metadata
 fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
-    // Build the search index from the collected metadata
     let mut nodeid_to_pathid = HashMap::new();
-    let mut pathid_to_nodeid = Vec::new();
-    {
-        let Cache { ref mut search_index,
-                    ref orphan_methods,
-                    ref mut paths, .. } = *cache;
-
-        // Attach all orphan methods to the type's definition if the type
-        // has since been learned.
-        for &(did, ref item) in orphan_methods {
-            match paths.get(&did) {
-                Some(&(ref fqp, _)) => {
-                    // Needed to determine `self` type.
-                    let parent_basename = Some(fqp[fqp.len() - 1].clone());
-                    search_index.push(IndexItem {
-                        ty: shortty(item),
-                        name: item.name.clone().unwrap(),
-                        path: fqp[..fqp.len() - 1].join("::"),
-                        desc: Escape(&shorter(item.doc_value())).to_string(),
-                        parent: Some(did),
-                        search_type: get_index_search_type(&item, parent_basename),
-                    });
-                },
-                None => {}
-            }
-        }
-
-        // Reduce `NodeId` in paths into smaller sequential numbers,
-        // and prune the paths that do not appear in the index.
-        for item in search_index.iter() {
-            match item.parent {
-                Some(nodeid) => {
-                    if !nodeid_to_pathid.contains_key(&nodeid) {
-                        let pathid = pathid_to_nodeid.len();
-                        nodeid_to_pathid.insert(nodeid, pathid);
-                        pathid_to_nodeid.push(nodeid);
-                    }
-                }
-                None => {}
-            }
+    let mut crate_items = Vec::with_capacity(cache.search_index.len());
+    let mut crate_paths = Vec::<Json>::new();
+
+    let Cache { ref mut search_index,
+                ref orphan_methods,
+                ref mut paths, .. } = *cache;
+
+    // Attach all orphan methods to the type's definition if the type
+    // has since been learned.
+    for &(did, ref item) in orphan_methods {
+        match paths.get(&did) {
+            Some(&(ref fqp, _)) => {
+                // Needed to determine `self` type.
+                let parent_basename = Some(fqp[fqp.len() - 1].clone());
+                search_index.push(IndexItem {
+                    ty: shortty(item),
+                    name: item.name.clone().unwrap(),
+                    path: fqp[..fqp.len() - 1].join("::"),
+                    desc: Escape(&shorter(item.doc_value())).to_string(),
+                    parent: Some(did),
+                    parent_idx: None,
+                    search_type: get_index_search_type(&item, parent_basename),
+                });
+            },
+            None => {}
         }
-        assert_eq!(nodeid_to_pathid.len(), pathid_to_nodeid.len());
     }
 
-    // Collect the index into a string
-    let mut w = io::Cursor::new(Vec::new());
-    write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name).unwrap();
+    // Reduce `NodeId` in paths into smaller sequential numbers,
+    // and prune the paths that do not appear in the index.
+    let mut lastpath = String::new();
+    let mut lastpathid = 0usize;
 
-    let mut lastpath = "".to_string();
-    for (i, item) in cache.search_index.iter().enumerate() {
-        // Omit the path if it is same to that of the prior item.
-        let path;
-        if lastpath == item.path {
-            path = "";
-        } else {
-            lastpath = item.path.to_string();
-            path = &item.path;
-        };
+    for item in search_index {
+        item.parent_idx = item.parent.map(|nodeid| {
+            if nodeid_to_pathid.contains_key(&nodeid) {
+                *nodeid_to_pathid.get(&nodeid).unwrap()
+            } else {
+                let pathid = lastpathid;
+                nodeid_to_pathid.insert(nodeid, pathid);
+                lastpathid += 1;
 
-        if i > 0 {
-            write!(&mut w, ",").unwrap();
-        }
-        write!(&mut w, r#"[{},"{}","{}",{}"#,
-               item.ty as usize, item.name, path,
-               item.desc.to_json().to_string()).unwrap();
-        match item.parent {
-            Some(nodeid) => {
-                let pathid = *nodeid_to_pathid.get(&nodeid).unwrap();
-                write!(&mut w, ",{}", pathid).unwrap();
+                let &(ref fqp, short) = paths.get(&nodeid).unwrap();
+                crate_paths.push(((short as usize), fqp.last().unwrap().clone()).to_json());
+                pathid
             }
-            None => write!(&mut w, ",null").unwrap()
-        }
-        match item.search_type {
-            Some(ref t) => write!(&mut w, ",{}", t).unwrap(),
-            None => write!(&mut w, ",null").unwrap()
-        }
-        write!(&mut w, "]").unwrap();
-    }
-
-    write!(&mut w, r#"],"paths":["#).unwrap();
+        });
 
-    for (i, &did) in pathid_to_nodeid.iter().enumerate() {
-        let &(ref fqp, short) = cache.paths.get(&did).unwrap();
-        if i > 0 {
-            write!(&mut w, ",").unwrap();
+        // Omit the parent path if it is same to that of the prior item.
+        if lastpath == item.path {
+            item.path.clear();
+        } else {
+            lastpath = item.path.clone();
         }
-        write!(&mut w, r#"[{},"{}"]"#,
-               short as usize, *fqp.last().unwrap()).unwrap();
+        crate_items.push(item.to_json());
     }
 
-    write!(&mut w, "]}};").unwrap();
+    let crate_doc = krate.module.as_ref().map(|module| {
+        Escape(&shorter(module.doc_value())).to_string()
+    }).unwrap_or(String::new());
 
-    String::from_utf8(w.into_inner()).unwrap()
+    let mut crate_data = BTreeMap::new();
+    crate_data.insert("doc".to_owned(), Json::String(crate_doc));
+    crate_data.insert("items".to_owned(), Json::Array(crate_items));
+    crate_data.insert("paths".to_owned(), Json::Array(crate_paths));
+
+    // Collect the index into a string
+    format!("searchIndex[{}] = {};",
+            as_json(&krate.name),
+            Json::Object(crate_data))
 }
 
 fn write_shared(cx: &Context,
@@ -693,7 +680,7 @@ fn collect(path: &Path, krate: &str,
                 if !line.starts_with(key) {
                     continue
                 }
-                if line.starts_with(&format!("{}['{}']", key, krate)) {
+                if line.starts_with(&format!(r#"{}["{}"]"#, key, krate)) {
                     continue
                 }
                 ret.push(line.to_string());
@@ -1067,6 +1054,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                             path: path.join("::").to_string(),
                             desc: Escape(&shorter(item.doc_value())).to_string(),
                             parent: parent,
+                            parent_idx: None,
                             search_type: get_index_search_type(&item, parent_basename),
                         });
                     }
@@ -1387,7 +1375,7 @@ fn render(w: File, cx: &Context, it: &clean::Item,
                         let js_dst = this.dst.join("sidebar-items.js");
                         let mut js_out = BufWriter::new(try_err!(File::create(&js_dst), &js_dst));
                         try_err!(write!(&mut js_out, "initSidebarItems({});",
-                                    json::as_json(&items)), &js_dst);
+                                    as_json(&items)), &js_dst);
                     }
 
                     for item in m.items {
index 08f70ae9ce7a0ec1896c7442a2cf50b43566ddfa..f3efbcb1db3080f107e3fe7ca3250a810bf71b14 100644 (file)
                         displayPath = "";
                         href = rootPath + item.path.replace(/::/g, '/') +
                                '/' + type + '.' + name + '.html';
+                    } else if (type === "externcrate") {
+                        displayPath = "";
+                        href = rootPath + name + '/index.html';
                     } else if (item.parent !== undefined) {
                         var myparent = item.parent;
                         var anchor = '#' + type + '.' + name;
             for (var crate in rawSearchIndex) {
                 if (!rawSearchIndex.hasOwnProperty(crate)) { continue; }
 
+                searchWords.push(crate);
+                searchIndex.push({
+                    crate: crate,
+                    ty: 1, // == ExternCrate
+                    name: crate,
+                    path: "",
+                    desc: rawSearchIndex[crate].doc,
+                    type: null,
+                });
+
                 // an array of [(Number) item type,
                 //              (String) name,
                 //              (String) full path or empty string for previous path,
index 02bb5221886df4c21e7466d21526f415b6245cb5..5c073860f08ca78c5b6a3958e68fffe72ec5a3c1 100644 (file)
@@ -82,7 +82,7 @@ pre {
 }
 
 .content a.primitive { color: #39a7bf; }
-.content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; }
+.content span.externcrate, span.mod, .content a.mod, block a.current.mod { color: #4d76ae; }
 .content span.fn, .content a.fn, .block a.current.fn,
 .content span.method, .content a.method, .block a.current.method,
 .content span.tymethod, .content a.tymethod, .block a.current.tymethod,
index 7220690469c2a62080bb6170efdf23f7e2f2baa8..051829fbafb01933104037a36f8851a8cff3e2d0 100644 (file)
@@ -1402,13 +1402,13 @@ pub enum Entry<'a, K: 'a, V: 'a> {
     /// An occupied Entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     Occupied(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] OccupiedEntry<'a, K, V>
+        #[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>
     ),
 
     /// A vacant Entry.
     #[stable(feature = "rust1", since = "1.0.0")]
     Vacant(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] VacantEntry<'a, K, V>
+        #[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>
     ),
 }
 
index f7e13a35e9e502ea57422bdcd70c2d51eb7eb86c..aa6a6d548b31a0026d6962eb8e585f74f65bb3b5 100644 (file)
@@ -218,7 +218,7 @@ pub enum VarError {
     /// valid unicode data. The found data is returned as a payload of this
     /// variant.
     #[stable(feature = "env", since = "1.0.0")]
-    NotUnicode(#[cfg_attr(not(stage0), stable(feature = "env", since = "1.0.0"))] OsString),
+    NotUnicode(#[stable(feature = "env", since = "1.0.0")] OsString),
 }
 
 #[stable(feature = "env", since = "1.0.0")]
index ee744b868dd73065fec84300d6fcede236cc92c8..1db45764552392a494217ee3b9d010527b834e58 100644 (file)
@@ -436,6 +436,57 @@ pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
         mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
     }
 
+    /// Creates a C string wrapper from a byte slice.
+    ///
+    /// This function will cast the provided `bytes` to a `CStr` wrapper after
+    /// ensuring that it is null terminated and does not contain any interior
+    /// nul bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(cstr_from_bytes)]
+    /// use std::ffi::CStr;
+    ///
+    /// # fn main() {
+    /// let cstr = CStr::from_bytes_with_nul(b"hello\0");
+    /// assert!(cstr.is_some());
+    /// # }
+    /// ```
+    #[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
+    pub fn from_bytes_with_nul(bytes: &[u8]) -> Option<&CStr> {
+        if bytes.is_empty() || memchr::memchr(0, &bytes) != Some(bytes.len() - 1) {
+            None
+        } else {
+            Some(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
+        }
+    }
+
+    /// Unsafely creates a C string wrapper from a byte slice.
+    ///
+    /// This function will cast the provided `bytes` to a `CStr` wrapper without
+    /// performing any sanity checks. The provided slice must be null terminated
+    /// and not contain any interior nul bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// # #![feature(cstr_from_bytes)]
+    /// use std::ffi::{CStr, CString};
+    ///
+    /// # fn main() {
+    /// unsafe {
+    ///     let cstring = CString::new("hello").unwrap();
+    ///     let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul());
+    ///     assert_eq!(cstr, &*cstring);
+    /// }
+    /// # }
+    /// ```
+    #[unstable(feature = "cstr_from_bytes", reason = "recently added", issue = "31190")]
+    pub unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
+        mem::transmute(bytes)
+    }
+
     /// Returns the inner pointer to this C string.
     ///
     /// The returned pointer will be valid for as long as `self` is and points
@@ -670,4 +721,31 @@ fn equal_hash() {
 
         assert_eq!(cstr_hash, cstring_hash);
     }
+
+    #[test]
+    fn from_bytes_with_nul() {
+        let data = b"123\0";
+        let cstr = CStr::from_bytes_with_nul(data);
+        assert_eq!(cstr.map(CStr::to_bytes), Some(&b"123"[..]));
+        assert_eq!(cstr.map(CStr::to_bytes_with_nul), Some(&b"123\0"[..]));
+
+        unsafe {
+            let cstr_unchecked = CStr::from_bytes_with_nul_unchecked(data);
+            assert_eq!(cstr, Some(cstr_unchecked));
+        }
+    }
+
+    #[test]
+    fn from_bytes_with_nul_unterminated() {
+        let data = b"123";
+        let cstr = CStr::from_bytes_with_nul(data);
+        assert!(cstr.is_none());
+    }
+
+    #[test]
+    fn from_bytes_with_nul_interior() {
+        let data = b"1\023\0";
+        let cstr = CStr::from_bytes_with_nul(data);
+        assert!(cstr.is_none());
+    }
 }
index 90ea7396a8ab37e03501e3c31ee2a44db96fa3aa..cf4f4bdf291bca273af64c878588d0c87e0ec973 100644 (file)
@@ -411,6 +411,44 @@ impl Ord for OsStr {
     fn cmp(&self, other: &OsStr) -> cmp::Ordering { self.bytes().cmp(other.bytes()) }
 }
 
+macro_rules! impl_cmp {
+    ($lhs:ty, $rhs: ty) => {
+        #[stable(feature = "cmp_os_str", since = "1.8.0")]
+        impl<'a, 'b> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
+        }
+
+        #[stable(feature = "cmp_os_str", since = "1.8.0")]
+        impl<'a, 'b> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool { <OsStr as PartialEq>::eq(self, other) }
+        }
+
+        #[stable(feature = "cmp_os_str", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
+                <OsStr as PartialOrd>::partial_cmp(self, other)
+            }
+        }
+
+        #[stable(feature = "cmp_os_str", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
+                <OsStr as PartialOrd>::partial_cmp(self, other)
+            }
+        }
+    }
+}
+
+impl_cmp!(OsString, OsStr);
+impl_cmp!(OsString, &'a OsStr);
+impl_cmp!(Cow<'a, OsStr>, OsStr);
+impl_cmp!(Cow<'a, OsStr>, &'b OsStr);
+impl_cmp!(Cow<'a, OsStr>, OsString);
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Hash for OsStr {
     #[inline]
index abb47b694184c2b1ee3c8901bfe5d62df1619fd8..6bdfdcd364aa703435c5e55b9444c9efc034a2f2 100644 (file)
@@ -1175,7 +1175,7 @@ pub trait Seek {
 pub enum SeekFrom {
     /// Set the offset to the provided number of bytes.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Start(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u64),
+    Start(#[stable(feature = "rust1", since = "1.0.0")] u64),
 
     /// Set the offset to the size of this object plus the specified number of
     /// bytes.
@@ -1183,7 +1183,7 @@ pub enum SeekFrom {
     /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
-    End(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] i64),
+    End(#[stable(feature = "rust1", since = "1.0.0")] i64),
 
     /// Set the offset to the current position plus the specified number of
     /// bytes.
@@ -1191,7 +1191,7 @@ pub enum SeekFrom {
     /// It is possible to seek beyond the end of an object, but it's an error to
     /// seek before byte 0.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Current(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] i64),
+    Current(#[stable(feature = "rust1", since = "1.0.0")] i64),
 }
 
 fn read_until<R: BufRead + ?Sized>(r: &mut R, delim: u8, buf: &mut Vec<u8>)
index 89c51c70843533a155240488a1c8764db9043a01..6ce6777d11eff54d8c5dbe8f247363250f3c9117 100644 (file)
 pub enum SocketAddr {
     /// An IPv4 socket address which is a (ip, port) combination.
     #[stable(feature = "rust1", since = "1.0.0")]
-    V4(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] SocketAddrV4),
+    V4(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV4),
     /// An IPv6 socket address
     #[stable(feature = "rust1", since = "1.0.0")]
-    V6(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] SocketAddrV6),
+    V6(#[stable(feature = "rust1", since = "1.0.0")] SocketAddrV6),
 }
 
 /// An IPv4 socket address which is a (ip, port) combination.
index 8a4d7e3e2c2a5dfa00beb52de633176e3d5c46da..68075af61cf5e8e0e570b61bd3bf07484997883d 100644 (file)
 pub enum IpAddr {
     /// Representation of an IPv4 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
-    V4(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.7.0"))] Ipv4Addr),
+    V4(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv4Addr),
     /// Representation of an IPv6 address.
     #[stable(feature = "ip_addr", since = "1.7.0")]
-    V6(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.7.0"))] Ipv6Addr),
+    V6(#[stable(feature = "ip_addr", since = "1.7.0")] Ipv6Addr),
 }
 
 /// Representation of an IPv4 address.
index 3798fb76ad6a5784c8c7118d2004c9dcafd7601d..35118bde96bb9a6af078d88858ee45170a1b1bda 100644 (file)
@@ -268,33 +268,33 @@ fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])>
 pub enum Prefix<'a> {
     /// Prefix `\\?\`, together with the given component immediately following it.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Verbatim(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
+    Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 
     /// Prefix `\\?\UNC\`, with the "server" and "share" components following it.
     #[stable(feature = "rust1", since = "1.0.0")]
     VerbatimUNC(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
+        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
     ),
 
     /// Prefix like `\\?\C:\`, for the given drive letter
     #[stable(feature = "rust1", since = "1.0.0")]
-    VerbatimDisk(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u8),
+    VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8),
 
     /// Prefix `\\.\`, together with the given component immediately following it.
     #[stable(feature = "rust1", since = "1.0.0")]
-    DeviceNS(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
+    DeviceNS(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 
     /// Prefix `\\server\share`, with the given "server" and "share" components.
     #[stable(feature = "rust1", since = "1.0.0")]
     UNC(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr,
+        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
+        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
     ),
 
     /// Prefix `C:` for the given disk drive.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Disk(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] u8),
+    Disk(#[stable(feature = "rust1", since = "1.0.0")] u8),
 }
 
 impl<'a> Prefix<'a> {
@@ -537,7 +537,7 @@ pub enum Component<'a> {
     /// Does not occur on Unix.
     #[stable(feature = "rust1", since = "1.0.0")]
     Prefix(
-        #[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PrefixComponent<'a>
+        #[stable(feature = "rust1", since = "1.0.0")] PrefixComponent<'a>
     ),
 
     /// The root directory component, appears after any prefix and before anything else
@@ -554,7 +554,7 @@ pub enum Component<'a> {
 
     /// A normal component, i.e. `a` and `b` in `a/b`
     #[stable(feature = "rust1", since = "1.0.0")]
-    Normal(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] &'a OsStr),
+    Normal(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
 }
 
 impl<'a> Component<'a> {
@@ -2004,6 +2004,13 @@ fn as_ref(&self) -> &Path {
     }
 }
 
+#[stable(feature = "cow_os_str_as_ref_path", since = "1.8.0")]
+impl<'a> AsRef<Path> for Cow<'a, OsStr> {
+    fn as_ref(&self) -> &Path {
+        Path::new(self)
+    }
+}
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<Path> for OsString {
     fn as_ref(&self) -> &Path {
@@ -2046,7 +2053,7 @@ impl<'a> IntoIterator for &'a Path {
     fn into_iter(self) -> Iter<'a> { self.iter() }
 }
 
-macro_rules! impl_eq {
+macro_rules! impl_cmp {
     ($lhs:ty, $rhs: ty) => {
         #[stable(feature = "partialeq_path", since = "1.6.0")]
         impl<'a, 'b> PartialEq<$rhs> for $lhs {
@@ -2060,14 +2067,76 @@ impl<'a, 'b> PartialEq<$lhs> for $rhs {
             fn eq(&self, other: &$lhs) -> bool { <Path as PartialEq>::eq(self, other) }
         }
 
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
+                <Path as PartialOrd>::partial_cmp(self, other)
+            }
+        }
+
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
+                <Path as PartialOrd>::partial_cmp(self, other)
+            }
+        }
+    }
+}
+
+impl_cmp!(PathBuf, Path);
+impl_cmp!(PathBuf, &'a Path);
+impl_cmp!(Cow<'a, Path>, Path);
+impl_cmp!(Cow<'a, Path>, &'b Path);
+impl_cmp!(Cow<'a, Path>, PathBuf);
+
+macro_rules! impl_cmp_os_str {
+    ($lhs:ty, $rhs: ty) => {
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialEq<$rhs> for $lhs {
+            #[inline]
+            fn eq(&self, other: &$rhs) -> bool { <Path as PartialEq>::eq(self, other.as_ref()) }
+        }
+
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialEq<$lhs> for $rhs {
+            #[inline]
+            fn eq(&self, other: &$lhs) -> bool { <Path as PartialEq>::eq(self.as_ref(), other) }
+        }
+
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$rhs> for $lhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
+                <Path as PartialOrd>::partial_cmp(self, other.as_ref())
+            }
+        }
+
+        #[stable(feature = "cmp_path", since = "1.8.0")]
+        impl<'a, 'b> PartialOrd<$lhs> for $rhs {
+            #[inline]
+            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
+                <Path as PartialOrd>::partial_cmp(self.as_ref(), other)
+            }
+        }
     }
 }
 
-impl_eq!(PathBuf, Path);
-impl_eq!(PathBuf, &'a Path);
-impl_eq!(Cow<'a, Path>, Path);
-impl_eq!(Cow<'a, Path>, &'b Path);
-impl_eq!(Cow<'a, Path>, PathBuf);
+impl_cmp_os_str!(PathBuf, OsStr);
+impl_cmp_os_str!(PathBuf, &'a OsStr);
+impl_cmp_os_str!(PathBuf, Cow<'a, OsStr>);
+impl_cmp_os_str!(PathBuf, OsString);
+impl_cmp_os_str!(Path, OsStr);
+impl_cmp_os_str!(Path, &'a OsStr);
+impl_cmp_os_str!(Path, Cow<'a, OsStr>);
+impl_cmp_os_str!(Path, OsString);
+impl_cmp_os_str!(&'a Path, OsStr);
+impl_cmp_os_str!(&'a Path, Cow<'b, OsStr>);
+impl_cmp_os_str!(&'a Path, OsString);
+impl_cmp_os_str!(Cow<'a, Path>, OsStr);
+impl_cmp_os_str!(Cow<'a, Path>, &'b OsStr);
+impl_cmp_os_str!(Cow<'a, Path>, OsString);
 
 #[stable(since = "1.7.0", feature = "strip_prefix")]
 impl fmt::Display for StripPrefixError {
index 9487295fd1ad66f9079678f80684c3c8853b1827..fadca390986ceb3f7f5a87751a627cb64f9ac2f7 100644 (file)
@@ -385,12 +385,12 @@ pub enum TrySendError<T> {
     /// this is not a buffered channel, then there is no receiver available to
     /// acquire the data.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Full(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T),
+    Full(#[stable(feature = "rust1", since = "1.0.0")] T),
 
     /// This channel's receiving half has disconnected, so the data could not be
     /// sent. The data is returned back to the callee in this case.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Disconnected(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] T),
+    Disconnected(#[stable(feature = "rust1", since = "1.0.0")] T),
 }
 
 enum Flavor<T> {
index d858c0027558ced777dcfddd0fbe84e9ff5a7801..83780a31cceb121437729e00d5d0917b50794013 100644 (file)
@@ -71,7 +71,7 @@ pub enum TryLockError<T> {
     /// The lock could not be acquired because another thread failed while holding
     /// the lock.
     #[stable(feature = "rust1", since = "1.0.0")]
-    Poisoned(#[cfg_attr(not(stage0), stable(feature = "rust1", since = "1.0.0"))] PoisonError<T>),
+    Poisoned(#[stable(feature = "rust1", since = "1.0.0")] PoisonError<T>),
     /// The lock could not be acquired at this time because the operation would
     /// otherwise block.
     #[stable(feature = "rust1", since = "1.0.0")]
index 7cf9e2a54bd900ff7d575dd0ecded2fe9cffc3f7..ff6a11951dc5e57f59615394758c2cdedd8fe5bc 100644 (file)
@@ -41,7 +41,6 @@ pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
     }
 }
 
-#[cfg(not(stage0))]
 pub fn payload() -> *mut u8 {
     0 as *mut u8
 }
index d9641e63760e5c102c4ec68a3735ebae33cbd3e9..527c2e63030d59bc9ddf0a82bba19112e6da53a9 100644 (file)
@@ -128,7 +128,6 @@ fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
     }
 }
 
-#[cfg(not(stage0))]
 unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
                     -> Result<(), Box<Any + Send>> {
     PANIC_COUNT.with(|s| {
@@ -156,22 +155,6 @@ unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
     })
 }
 
-#[cfg(stage0)]
-unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
-                    -> Result<(), Box<Any + Send>> {
-    PANIC_COUNT.with(|s| {
-        let prev = s.get();
-        s.set(0);
-        let ep = intrinsics::try(f, data);
-        s.set(prev);
-        if ep.is_null() {
-            Ok(())
-        } else {
-            Err(imp::cleanup(ep))
-        }
-    })
-}
-
 /// Determines whether the current thread is unwinding because of panic.
 pub fn panicking() -> bool {
     PANIC_COUNT.with(|s| s.get() != 0)
index f8d3a92b3b65ba48c8f887d5083f2a5c77f9829d..94da42f0092f5092a984f71b5b24368c1df83330 100644 (file)
 
 pub use self::imp::*;
 
-#[cfg(stage0)]
-mod imp {
-    use prelude::v1::*;
-    use any::Any;
-
-    pub unsafe fn panic(_data: Box<Any + Send + 'static>) -> ! {
-        rtabort!("cannot unwind SEH in stage0")
-    }
-
-    pub unsafe fn cleanup(_ptr: *mut u8) -> Box<Any + Send + 'static> {
-        rtabort!("can't cleanup SEH in stage0")
-    }
-
-    #[lang = "msvc_try_filter"]
-    #[linkage = "external"]
-    unsafe extern fn __rust_try_filter() -> i32 {
-        0
-    }
-
-    #[lang = "eh_unwind_resume"]
-    #[unwind]
-    unsafe extern fn rust_eh_unwind_resume(_ptr: *mut u8) -> ! {
-        rtabort!("can't resume unwind SEH in stage0")
-    }
-    #[lang = "eh_personality_catch"]
-    unsafe extern fn rust_eh_personality_catch() {}
-}
-
-#[cfg(not(stage0))]
 mod imp {
     use prelude::v1::*;
 
index 8afef081673d000fa9275f3ef6da803a0bd6b804..57281d67ebb406ecd6ca27382de2db8bd3d71f7e 100644 (file)
@@ -50,7 +50,6 @@ pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
     rtabort!("could not unwind stack");
 }
 
-#[cfg(not(stage0))]
 pub fn payload() -> *mut u8 {
     0 as *mut u8
 }
index d106bc3285cb1a461a793783a782d1828d836ac5..80ff0cb0453ad1570c6cc14f275daa540f57edb4 100644 (file)
@@ -22,7 +22,7 @@
 //! copy of that function in my mingw install (maybe it was broken?). Instead,
 //! this takes the route of using StackWalk64 in order to walk the stack.
 
-#![allow(dead_code, deprecated)]
+#![allow(deprecated)] // dynamic_lib
 
 use io::prelude::*;
 
@@ -51,12 +51,6 @@ macro_rules! sym{ ($lib:expr, $e:expr, $t:ident) => (unsafe {
 #[path = "printing/gnu.rs"]
 mod printing;
 
-type SymFromAddrFn =
-    extern "system" fn(c::HANDLE, u64, *mut u64,
-                       *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymGetLineFromAddr64Fn =
-    extern "system" fn(c::HANDLE, u64, *mut u32,
-                       *mut c::IMAGEHLP_LINE64) -> c::BOOL;
 type SymInitializeFn =
     extern "system" fn(c::HANDLE, *mut c_void,
                        c::BOOL) -> c::BOOL;
index d25d8e0b8048d9ba6f9b7ef03759312d2df8f376..5cbfec01bedaa897f1885bf7b596bda55b663329 100644 (file)
 
 //! C definitions used by libnative that don't belong in liblibc
 
-#![allow(bad_style, overflowing_literals, dead_code, deprecated, unused_imports)]
+#![allow(bad_style)]
+#![cfg_attr(test, allow(dead_code))]
 
 use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort};
-use os::raw::{c_char, c_short, c_ulonglong};
+use os::raw::{c_char, c_ulonglong};
 use libc::{wchar_t, size_t, c_void};
 use ptr;
 
 #[repr(simd)]
 #[repr(C)]
+#[cfg(target_arch = "x86_64")]
 struct u64x2(u64, u64);
 
-pub use self::GET_FILEEX_INFO_LEVELS::*;
 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
 pub use self::EXCEPTION_DISPOSITION::*;
 
@@ -64,7 +65,6 @@
 pub type LPWCH = *mut WCHAR;
 pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW;
 pub type LPWSADATA = *mut WSADATA;
-pub type LPWSANETWORKEVENTS = *mut WSANETWORKEVENTS;
 pub type LPWSAPROTOCOLCHAIN = *mut WSAPROTOCOLCHAIN;
 pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
 pub type LPWSTR = *mut WCHAR;
 
 pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
 pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
-pub const FILE_ATTRIBUTE_NORMAL: DWORD = 0x80;
 pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
+
 pub const FILE_SHARE_DELETE: DWORD = 0x4;
 pub const FILE_SHARE_READ: DWORD = 0x1;
 pub const FILE_SHARE_WRITE: DWORD = 0x2;
+
 pub const CREATE_ALWAYS: DWORD = 2;
 pub const CREATE_NEW: DWORD = 1;
 pub const OPEN_ALWAYS: DWORD = 4;
 pub const OPEN_EXISTING: DWORD = 3;
 pub const TRUNCATE_EXISTING: DWORD = 5;
 
-pub const FILE_READ_DATA: DWORD = 0x00000001;
 pub const FILE_WRITE_DATA: DWORD = 0x00000002;
 pub const FILE_APPEND_DATA: DWORD = 0x00000004;
-pub const FILE_READ_EA: DWORD = 0x00000008;
 pub const FILE_WRITE_EA: DWORD = 0x00000010;
-pub const FILE_EXECUTE: DWORD = 0x00000020;
-pub const FILE_READ_ATTRIBUTES: DWORD = 0x00000080;
 pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
-
-pub const DELETE: DWORD = 0x00008000;
 pub const READ_CONTROL: DWORD = 0x00020000;
-pub const WRITE_DAC: DWORD = 0x00040000;
-pub const WRITE_OWNER: DWORD = 0x00080000;
 pub const SYNCHRONIZE: DWORD = 0x00100000;
-
 pub const GENERIC_READ: DWORD = 0x80000000;
 pub const GENERIC_WRITE: DWORD = 0x40000000;
-pub const GENERIC_EXECUTE: DWORD = 0x20000000;
-pub const GENERIC_ALL: DWORD = 0x10000000;
-
-pub const STANDARD_RIGHTS_READ: DWORD = READ_CONTROL;
 pub const STANDARD_RIGHTS_WRITE: DWORD = READ_CONTROL;
-pub const STANDARD_RIGHTS_EXECUTE: DWORD = READ_CONTROL;
-pub const FILE_GENERIC_READ: DWORD = STANDARD_RIGHTS_READ | FILE_READ_DATA |
-                                     FILE_READ_ATTRIBUTES |
-                                     FILE_READ_EA |
-                                     SYNCHRONIZE;
 pub const FILE_GENERIC_WRITE: DWORD = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA |
                                       FILE_WRITE_ATTRIBUTES |
                                       FILE_WRITE_EA |
                                       FILE_APPEND_DATA |
                                       SYNCHRONIZE;
 
-pub const SECURITY_ANONYMOUS: DWORD = 0 << 16;
-pub const SECURITY_IDENTIFICATION: DWORD = 1 << 16;
-pub const SECURITY_IMPERSONATION: DWORD = 2 << 16;
-pub const SECURITY_DELEGATION: DWORD = 3 << 16;
-pub const SECURITY_CONTEXT_TRACKING: DWORD = 0x00040000;
-pub const SECURITY_EFFECTIVE_ONLY: DWORD = 0x00080000;
+pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
+pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
 pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
 
 #[repr(C)]
@@ -153,96 +132,36 @@ impl Clone for WIN32_FIND_DATAW {
     fn clone(&self) -> Self { *self }
 }
 
-pub const FIONBIO: c_long = 0x8004667e;
-pub const FD_SETSIZE: usize = 64;
-pub const MSG_DONTWAIT: c_int = 0;
-pub const ENABLE_ECHO_INPUT: DWORD = 0x4;
-pub const ENABLE_EXTENDED_FLAGS: DWORD = 0x80;
-pub const ENABLE_INSERT_MODE: DWORD = 0x20;
-pub const ENABLE_LINE_INPUT: DWORD = 0x2;
-pub const ENABLE_PROCESSED_INPUT: DWORD = 0x1;
-pub const ENABLE_QUICK_EDIT_MODE: DWORD = 0x40;
-
-pub const FD_ACCEPT: c_long = 0x08;
-pub const FD_MAX_EVENTS: usize = 10;
-
-pub const WSA_INVALID_EVENT: WSAEVENT = 0 as WSAEVENT;
-pub const WSA_INFINITE: DWORD = INFINITE;
-pub const WSA_WAIT_TIMEOUT: DWORD = WAIT_TIMEOUT;
-pub const WSA_WAIT_EVENT_0: DWORD = WAIT_OBJECT_0;
-pub const WSA_WAIT_FAILED: DWORD = WAIT_FAILED;
 pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
-pub const WSA_FLAG_NO_HANDLE_INHERIT: DWORD = 0x80;
 
 pub const WSADESCRIPTION_LEN: usize = 256;
 pub const WSASYS_STATUS_LEN: usize = 128;
 pub const WSAPROTOCOL_LEN: DWORD = 255;
 pub const INVALID_SOCKET: SOCKET = !0;
 
-pub const WSAEINTR: c_int = 10004;
-pub const WSAEBADF: c_int = 10009;
 pub const WSAEACCES: c_int = 10013;
-pub const WSAEFAULT: c_int = 10014;
 pub const WSAEINVAL: c_int = 10022;
-pub const WSAEMFILE: c_int = 10024;
 pub const WSAEWOULDBLOCK: c_int = 10035;
-pub const WSAEINPROGRESS: c_int = 10036;
-pub const WSAEALREADY: c_int = 10037;
-pub const WSAENOTSOCK: c_int = 10038;
-pub const WSAEDESTADDRREQ: c_int = 10039;
-pub const WSAEMSGSIZE: c_int = 10040;
-pub const WSAEPROTOTYPE: c_int = 10041;
-pub const WSAENOPROTOOPT: c_int = 10042;
-pub const WSAEPROTONOSUPPORT: c_int = 10043;
-pub const WSAESOCKTNOSUPPORT: c_int = 10044;
-pub const WSAEOPNOTSUPP: c_int = 10045;
-pub const WSAEPFNOSUPPORT: c_int = 10046;
-pub const WSAEAFNOSUPPORT: c_int = 10047;
 pub const WSAEADDRINUSE: c_int = 10048;
 pub const WSAEADDRNOTAVAIL: c_int = 10049;
-pub const WSAENETDOWN: c_int = 10050;
-pub const WSAENETUNREACH: c_int = 10051;
-pub const WSAENETRESET: c_int = 10052;
 pub const WSAECONNABORTED: c_int = 10053;
 pub const WSAECONNRESET: c_int = 10054;
-pub const WSAENOBUFS: c_int = 10055;
-pub const WSAEISCONN: c_int = 10056;
 pub const WSAENOTCONN: c_int = 10057;
 pub const WSAESHUTDOWN: c_int = 10058;
-pub const WSAETOOMANYREFS: c_int = 10059;
 pub const WSAETIMEDOUT: c_int = 10060;
 pub const WSAECONNREFUSED: c_int = 10061;
-pub const WSAELOOP: c_int = 10062;
-pub const WSAENAMETOOLONG: c_int = 10063;
-pub const WSAEHOSTDOWN: c_int = 10064;
-pub const WSAEHOSTUNREACH: c_int = 10065;
-pub const WSAENOTEMPTY: c_int = 10066;
-pub const WSAEPROCLIM: c_int = 10067;
-pub const WSAEUSERS: c_int = 10068;
-pub const WSAEDQUOT: c_int = 10069;
-pub const WSAESTALE: c_int = 10070;
-pub const WSAEREMOTE: c_int = 10071;
-pub const WSASYSNOTREADY: c_int = 10091;
-pub const WSAVERNOTSUPPORTED: c_int = 10092;
-pub const WSANOTINITIALISED: c_int = 10093;
-pub const WSAEDISCON: c_int = 10101;
-pub const WSAENOMORE: c_int = 10102;
-pub const WSAECANCELLED: c_int = 10103;
-pub const WSAEINVALIDPROCTABLE: c_int = 10104;
+
 pub const NI_MAXHOST: DWORD = 1025;
 
 pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
 
 pub const TOKEN_READ: DWORD = 0x20008;
-pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
-pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
 pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
 pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
 pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
 pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
 pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
 pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
-pub const FSCTL_DELETE_REPARSE_POINT: DWORD = 0x900ac;
 
 pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
 
@@ -254,38 +173,19 @@ fn clone(&self) -> Self { *self }
 pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
 
 pub const PROGRESS_CONTINUE: DWORD = 0;
-pub const PROGRESS_CANCEL: DWORD = 1;
-pub const PROGRESS_STOP: DWORD = 2;
-pub const PROGRESS_QUIET: DWORD = 3;
-
-pub const TOKEN_ADJUST_PRIVILEGES: DWORD = 0x0020;
-pub const SE_PRIVILEGE_ENABLED: DWORD = 2;
 
-
-pub const ERROR_SUCCESS: DWORD = 0;
-pub const ERROR_INVALID_FUNCTION: DWORD = 1;
 pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
 pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
 pub const ERROR_ACCESS_DENIED: DWORD = 5;
 pub const ERROR_INVALID_HANDLE: DWORD = 6;
 pub const ERROR_NO_MORE_FILES: DWORD = 18;
 pub const ERROR_BROKEN_PIPE: DWORD = 109;
-pub const ERROR_DISK_FULL: DWORD = 112;
 pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
 pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
-pub const ERROR_INVALID_NAME: DWORD = 123;
 pub const ERROR_ALREADY_EXISTS: DWORD = 183;
-pub const ERROR_PIPE_BUSY: DWORD = 231;
 pub const ERROR_NO_DATA: DWORD = 232;
-pub const ERROR_INVALID_ADDRESS: DWORD = 487;
-pub const ERROR_PIPE_CONNECTED: DWORD = 535;
-pub const ERROR_ILLEGAL_CHARACTER: DWORD = 582;
 pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
-pub const ERROR_NOTHING_TO_TERMINATE: DWORD = 758;
 pub const ERROR_OPERATION_ABORTED: DWORD = 995;
-pub const ERROR_IO_PENDING: DWORD = 997;
-pub const ERROR_FILE_INVALID: DWORD = 1006;
-pub const ERROR_NOT_FOUND: DWORD = 1168;
 pub const ERROR_TIMEOUT: DWORD = 0x5B4;
 
 pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
@@ -307,8 +207,6 @@ fn clone(&self) -> Self { *self }
 };
 pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() };
 
-pub const STILL_ACTIVE: DWORD = 259;
-
 pub const DETACHED_PROCESS: DWORD = 0x00000008;
 pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
 pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
@@ -333,14 +231,13 @@ fn clone(&self) -> Self { *self }
 pub const FILE_CURRENT: DWORD = 1;
 pub const FILE_END: DWORD = 2;
 
-pub const WAIT_ABANDONED: DWORD = 0x00000080;
 pub const WAIT_OBJECT_0: DWORD = 0x00000000;
-pub const WAIT_TIMEOUT: DWORD = 0x00000102;
-pub const WAIT_FAILED: DWORD = !0;
 
+#[cfg(target_env = "msvc")]
 pub const MAX_SYM_NAME: usize = 2000;
+#[cfg(target_arch = "x86")]
 pub const IMAGE_FILE_MACHINE_I386: DWORD = 0x014c;
-pub const IMAGE_FILE_MACHINE_IA64: DWORD = 0x0200;
+#[cfg(target_arch = "x86_64")]
 pub const IMAGE_FILE_MACHINE_AMD64: DWORD = 0x8664;
 
 pub const PROV_RSA_FULL: DWORD = 1;
@@ -350,13 +247,17 @@ fn clone(&self) -> Self { *self }
 pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
 pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
 pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_NONCONTINUABLE: DWORD = 0x1;   // Noncontinuable exception
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_UNWINDING: DWORD = 0x2;        // Unwind is in progress
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_EXIT_UNWIND: DWORD = 0x4;      // Exit unwind is in progress
-pub const EXCEPTION_STACK_INVALID: DWORD = 0x8;    // Stack out of limits or unaligned
-pub const EXCEPTION_NESTED_CALL: DWORD = 0x10;     // Nested exception handler call
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20;   // Target unwind in progress
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
                                     EXCEPTION_EXIT_UNWIND |
                                     EXCEPTION_TARGET_UNWIND |
@@ -385,12 +286,6 @@ pub struct WSADATA {
     pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
 }
 
-#[repr(C)]
-pub struct WSANETWORKEVENTS {
-    pub lNetworkEvents: c_long,
-    pub iErrorCode: [c_int; FD_MAX_EVENTS],
-}
-
 pub type WSAEVENT = HANDLE;
 
 #[repr(C)]
@@ -417,43 +312,6 @@ pub struct WSAPROTOCOL_INFO {
     pub szProtocol: [u16; (WSAPROTOCOL_LEN as usize) + 1],
 }
 
-#[repr(C)]
-pub struct fd_set {
-    fd_count: c_uint,
-    fd_array: [SOCKET; FD_SETSIZE],
-}
-
-pub fn fd_set(set: &mut fd_set, s: SOCKET) {
-    set.fd_array[set.fd_count as usize] = s;
-    set.fd_count += 1;
-}
-
-pub type SHORT = c_short;
-
-#[repr(C)]
-pub struct COORD {
-    pub X: SHORT,
-    pub Y: SHORT,
-}
-
-#[repr(C)]
-pub struct SMALL_RECT {
-    pub Left: SHORT,
-    pub Top: SHORT,
-    pub Right: SHORT,
-    pub Bottom: SHORT,
-}
-
-#[repr(C)]
-pub struct CONSOLE_SCREEN_BUFFER_INFO {
-    pub dwSize: COORD,
-    pub dwCursorPosition: COORD,
-    pub wAttributes: WORD,
-    pub srWindow: SMALL_RECT,
-    pub dwMaximumWindowSize: COORD,
-}
-pub type PCONSOLE_SCREEN_BUFFER_INFO = *mut CONSOLE_SCREEN_BUFFER_INFO;
-
 #[repr(C)]
 #[derive(Copy, Clone)]
 pub struct WIN32_FILE_ATTRIBUTE_DATA {
@@ -480,12 +338,7 @@ pub struct BY_HANDLE_FILE_INFORMATION {
 }
 
 #[repr(C)]
-pub enum GET_FILEEX_INFO_LEVELS {
-    GetFileExInfoStandard,
-    GetFileExMaxInfoLevel
-}
-
-#[repr(C)]
+#[allow(dead_code)] // we only use some variants
 pub enum FILE_INFO_BY_HANDLE_CLASS {
     FileBasicInfo                   = 0,
     FileStandardInfo                = 1,
@@ -569,28 +422,6 @@ pub struct CRITICAL_SECTION {
     SpinCount: ULONG_PTR
 }
 
-#[repr(C)]
-pub struct LUID {
-    pub LowPart: DWORD,
-    pub HighPart: c_long,
-}
-
-pub type PLUID = *mut LUID;
-
-#[repr(C)]
-pub struct TOKEN_PRIVILEGES {
-    pub PrivilegeCount: DWORD,
-    pub Privileges: [LUID_AND_ATTRIBUTES; 1],
-}
-
-pub type PTOKEN_PRIVILEGES = *mut TOKEN_PRIVILEGES;
-
-#[repr(C)]
-pub struct LUID_AND_ATTRIBUTES {
-    pub Luid: LUID,
-    pub Attributes: DWORD,
-}
-
 #[repr(C)]
 pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
     pub ReparseTag: DWORD,
@@ -695,6 +526,7 @@ pub struct OVERLAPPED {
 }
 
 #[repr(C)]
+#[cfg(target_env = "msvc")]
 pub struct SYMBOL_INFO {
     pub SizeOfStruct: c_ulong,
     pub TypeIndex: c_ulong,
@@ -717,6 +549,7 @@ pub struct SYMBOL_INFO {
 }
 
 #[repr(C)]
+#[cfg(target_env = "msvc")]
 pub struct IMAGEHLP_LINE64 {
     pub SizeOfStruct: u32,
     pub Key: *const c_void,
@@ -726,6 +559,7 @@ pub struct IMAGEHLP_LINE64 {
 }
 
 #[repr(C)]
+#[allow(dead_code)] // we only use some variants
 pub enum ADDRESS_MODE {
     AddrMode1616,
     AddrMode1632,
@@ -941,9 +775,11 @@ pub struct in6_addr {
     pub s6_addr: [u8; 16],
 }
 
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub enum UNWIND_HISTORY_TABLE {}
 
 #[repr(C)]
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub struct RUNTIME_FUNCTION {
     pub BeginAddress: DWORD,
     pub EndAddress: DWORD,
@@ -951,6 +787,7 @@ pub struct RUNTIME_FUNCTION {
 }
 
 #[repr(C)]
+#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
 pub struct DISPATCHER_CONTEXT {
     pub ControlPc: LPVOID,
     pub ImageBase: LPVOID,
@@ -965,6 +802,7 @@ pub struct DISPATCHER_CONTEXT {
 
 #[repr(C)]
 #[derive(Copy, Clone)]
+#[allow(dead_code)] // we only use some variants
 pub enum EXCEPTION_DISPOSITION {
     ExceptionContinueExecution,
     ExceptionContinueSearch,
@@ -1016,9 +854,6 @@ pub fn WriteConsoleW(hConsoleOutput: HANDLE,
 
     pub fn GetConsoleMode(hConsoleHandle: HANDLE,
                           lpMode: LPDWORD) -> BOOL;
-    pub fn GetFileAttributesExW(lpFileName: LPCWSTR,
-                                fInfoLevelId: GET_FILEEX_INFO_LEVELS,
-                                lpFileInformation: LPVOID) -> BOOL;
     pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
     pub fn SetFileAttributesW(lpFileName: LPCWSTR,
                               dwFileAttributes: DWORD) -> BOOL;
@@ -1076,15 +911,6 @@ pub fn CopyFileExW(lpExistingFileName: LPCWSTR,
                        lpData: LPVOID,
                        pbCancel: LPBOOL,
                        dwCopyFlags: DWORD) -> BOOL;
-    pub fn LookupPrivilegeValueW(lpSystemName: LPCWSTR,
-                                 lpName: LPCWSTR,
-                                 lpLuid: PLUID) -> BOOL;
-    pub fn AdjustTokenPrivileges(TokenHandle: HANDLE,
-                                 DisableAllPrivileges: BOOL,
-                                 NewState: PTOKEN_PRIVILEGES,
-                                 BufferLength: DWORD,
-                                 PreviousState: PTOKEN_PRIVILEGES,
-                                 ReturnLength: *mut DWORD) -> BOOL;
     pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
                                        VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
                                        -> LPVOID;
@@ -1260,10 +1086,12 @@ pub fn CryptGenRandom(hProv: HCRYPTPROV,
     pub fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
 
     #[unwind]
+    #[cfg(any(target_arch = "x86_64", target_env = "msvc"))]
     pub fn RaiseException(dwExceptionCode: DWORD,
                           dwExceptionFlags: DWORD,
                           nNumberOfArguments: DWORD,
                           lpArguments: *const ULONG_PTR);
+    #[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
     pub fn RtlUnwindEx(TargetFrame: LPVOID,
                        TargetIp: LPVOID,
                        ExceptionRecord: *const EXCEPTION_RECORD,
index cb41b05daaea26c48afe08bea8f5bb343db0f9d4..47676a927f65877ab02e386ace0fc98e974b46ea 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use cmp;
 use io::ErrorKind;
 use io;
 use mem;
@@ -15,6 +16,7 @@
 use ptr;
 use sys::c;
 use sys::cvt;
+use u32;
 
 /// An owned container for `HANDLE` object, closing them on Drop.
 ///
@@ -64,10 +66,12 @@ pub fn raw(&self) -> c::HANDLE { self.0 }
 
     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
         let mut read = 0;
+        // ReadFile takes a DWORD (u32) for the length so it only supports
+        // reading u32::MAX bytes at a time.
+        let len = cmp::min(buf.len(), u32::MAX as usize) as c::DWORD;
         let res = cvt(unsafe {
-            c::ReadFile(self.0, buf.as_ptr() as c::LPVOID,
-                           buf.len() as c::DWORD, &mut read,
-                           ptr::null_mut())
+            c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID,
+                        len, &mut read, ptr::null_mut())
         });
 
         match res {
@@ -85,10 +89,12 @@ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
 
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         let mut amt = 0;
+        // WriteFile takes a DWORD (u32) for the length so it only supports
+        // writing u32::MAX bytes at a time.
+        let len = cmp::min(buf.len(), u32::MAX as usize) as c::DWORD;
         try!(cvt(unsafe {
             c::WriteFile(self.0, buf.as_ptr() as c::LPVOID,
-                            buf.len() as c::DWORD, &mut amt,
-                            ptr::null_mut())
+                         len, &mut amt, ptr::null_mut())
         }));
         Ok(amt as usize)
     }
index d04691a6a4783c0db625e5ff9bffdeccec026b06..255c645c3fbf19d1a0d454724e861d04cee15f2c 100644 (file)
 use io;
 use libc::{c_ulong, c_int, c_char, c_void};
 use mem;
-use super::{SymFromAddrFn, SymGetLineFromAddr64Fn};
 use sys::c;
 use sys_common::backtrace::{output, output_fileline};
 
+type SymFromAddrFn =
+    extern "system" fn(c::HANDLE, u64, *mut u64,
+                       *mut c::SYMBOL_INFO) -> c::BOOL;
+type SymGetLineFromAddr64Fn =
+    extern "system" fn(c::HANDLE, u64, *mut u32,
+                       *mut c::IMAGEHLP_LINE64) -> c::BOOL;
+
 pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary,
              process: c::HANDLE) -> io::Result<()> {
     let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn);
index db2ad1d89c4d867c033a18adfca19b9b6d5bd2e9..6a5c38ed9d0daf0c47bbba3e81725297cca86363 100644 (file)
@@ -233,12 +233,12 @@ unsafe fn unregister_dtor(key: Key) -> bool {
 
 #[link_section = ".CRT$XLB"]
 #[linkage = "external"]
-#[allow(warnings)]
+#[allow(dead_code, unused_variables)]
 pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD,
                                                         c::LPVOID) =
         on_tls_callback;
 
-#[allow(warnings)]
+#[allow(dead_code, unused_variables)]
 unsafe extern "system" fn on_tls_callback(h: c::LPVOID,
                                           dwReason: c::DWORD,
                                           pv: c::LPVOID) {
index 1825c3d347eeba61caac01f21e9ce46f49dc5db2..0085182d1ac2af018d5bff4821b4b8265d177eb3 100644 (file)
@@ -11,7 +11,7 @@
 use deriving::generic::*;
 use deriving::generic::ty::*;
 
-use syntax::ast::{MetaItem, Expr};
+use syntax::ast::{MetaItem, Expr, VariantData};
 use syntax::codemap::Span;
 use syntax::ext::base::{ExtCtxt, Annotatable};
 use syntax::ext::build::AstBuilder;
@@ -66,14 +66,17 @@ fn cs_clone(
         cx.expr_call_global(field.span, fn_path.clone(), args)
     };
 
+    let vdata;
     match *substr.fields {
-        Struct(ref af) => {
+        Struct(vdata_, ref af) => {
             ctor_path = cx.path(trait_span, vec![substr.type_ident]);
             all_fields = af;
+            vdata = vdata_;
         }
         EnumMatching(_, variant, ref af) => {
             ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.node.name]);
             all_fields = af;
+            vdata = &variant.node.data;
         },
         EnumNonMatchingCollapsed (..) => {
             cx.span_bug(trait_span,
@@ -86,30 +89,29 @@ fn cs_clone(
         }
     }
 
-    if !all_fields.is_empty() && all_fields[0].name.is_none() {
-        // enum-like
-        let subcalls = all_fields.iter().map(subcall).collect();
-        let path = cx.expr_path(ctor_path);
-        cx.expr_call(trait_span, path, subcalls)
-    } else {
-        // struct-like
-        let fields = all_fields.iter().map(|field| {
-            let ident = match field.name {
-                Some(i) => i,
-                None => {
-                    cx.span_bug(trait_span,
-                                &format!("unnamed field in normal struct in \
-                                         `derive({})`", name))
-                }
-            };
-            cx.field_imm(field.span, ident, subcall(field))
-        }).collect::<Vec<_>>();
+    match *vdata {
+        VariantData::Struct(..) => {
+            let fields = all_fields.iter().map(|field| {
+                let ident = match field.name {
+                    Some(i) => i,
+                    None => {
+                        cx.span_bug(trait_span,
+                                    &format!("unnamed field in normal struct in \
+                                             `derive({})`", name))
+                    }
+                };
+                cx.field_imm(field.span, ident, subcall(field))
+            }).collect::<Vec<_>>();
 
-        if fields.is_empty() {
-            // no fields, so construct like `None`
-            cx.expr_path(ctor_path)
-        } else {
             cx.expr_struct(trait_span, ctor_path, fields)
         }
+        VariantData::Tuple(..) => {
+            let subcalls = all_fields.iter().map(subcall).collect();
+            let path = cx.expr_path(ctor_path);
+            cx.expr_call(trait_span, path, subcalls)
+        }
+        VariantData::Unit(..) => {
+            cx.expr_path(ctor_path)
+        }
     }
 }
index 6439e9aa498698c580c962c1769aadc7fcc6bc18..323c6c388fb64d4042ae582632f37c0600d99984 100644 (file)
@@ -61,9 +61,9 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     // build fmt.debug_struct(<name>).field(<fieldname>, &<fieldval>)....build()
     // or fmt.debug_tuple(<name>).field(&<fieldval>)....build()
     // based on the "shape".
-    let ident = match *substr.fields {
-        Struct(_) => substr.type_ident,
-        EnumMatching(_, v, _) => v.node.name,
+    let (ident, is_struct) = match *substr.fields {
+        Struct(vdata, _) => (substr.type_ident, vdata.is_struct()),
+        EnumMatching(_, v, _) => (v.node.name, v.node.data.is_struct()),
         EnumNonMatchingCollapsed(..) | StaticStruct(..) | StaticEnum(..) => {
             cx.span_bug(span, "nonsensical .fields in `#[derive(Debug)]`")
         }
@@ -78,9 +78,9 @@ fn show_substructure(cx: &mut ExtCtxt, span: Span,
     let fmt = substr.nonself_args[0].clone();
 
     let stmts = match *substr.fields {
-        Struct(ref fields) | EnumMatching(_, _, ref fields) => {
+        Struct(_, ref fields) | EnumMatching(_, _, ref fields) => {
             let mut stmts = vec![];
-            if fields.is_empty() || fields[0].name.is_none() {
+            if !is_struct {
                 // tuple struct/"normal" variant
                 let expr = cx.expr_method_call(span,
                                                fmt,
index 614a6381962384a2a7d5570f4dc43949a9a18feb..8262a04e9ce179350db8cd8437d201383382d2ac 100644 (file)
@@ -179,7 +179,7 @@ fn encodable_substructure(cx: &mut ExtCtxt, trait_span: Span,
     let encode = cx.ident_of("encode");
 
     return match *substr.fields {
-        Struct(ref fields) => {
+        Struct(_, ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = Vec::new();
             for (i, &FieldInfo {
index bdba49f2f294ba3cf927dbc86c591f1ebaa695e1..c0237a5d29a4103dbf8e535ba9800cc474929fca 100644 (file)
@@ -300,7 +300,7 @@ pub enum StaticFields {
 
 /// A summary of the possible sets of fields.
 pub enum SubstructureFields<'a> {
-    Struct(Vec<FieldInfo<'a>>),
+    Struct(&'a ast::VariantData, Vec<FieldInfo<'a>>),
     /// Matching variants of the enum: variant index, ast::Variant,
     /// fields: the field name is only non-`None` in the case of a struct
     /// variant.
@@ -981,7 +981,7 @@ fn expand_struct_method_body<'b>(&self,
             type_ident,
             self_args,
             nonself_args,
-            &Struct(fields));
+            &Struct(struct_def, fields));
 
         // make a series of nested matches, to destructure the
         // structs. This is actually right-to-left, but it shouldn't
@@ -1460,8 +1460,9 @@ fn summarise_struct(&self,
                                           fields in generic `derive`"),
             // named fields
             (_, false) => Named(named_idents),
-            // tuple structs (includes empty structs)
-            (_, _)     => Unnamed(just_spans)
+            // empty structs
+            _ if struct_def.is_struct() => Named(named_idents),
+            _ => Unnamed(just_spans),
         }
     }
 
@@ -1486,7 +1487,11 @@ fn create_struct_pattern(&self,
                                                    P<Expr>,
                                                    &'a [ast::Attribute])>) {
         if struct_def.fields().is_empty() {
-            return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
+            if struct_def.is_struct() {
+                return (cx.pat_struct(self.span, struct_path, vec![]), vec![]);
+            } else {
+                return (cx.pat_enum(self.span, struct_path, vec![]), vec![]);
+            }
         }
 
         let mut paths = Vec::new();
@@ -1521,7 +1526,7 @@ fn create_struct_pattern(&self,
 
         // struct_type is definitely not Unknown, since struct_def.fields
         // must be nonempty to reach here
-        let pattern = if struct_type == Record {
+        let pattern = if struct_def.is_struct() {
             let field_pats = subpats.into_iter().zip(&ident_expr)
                                     .map(|(pat, &(_, id, _, _))| {
                 // id is guaranteed to be Some
@@ -1566,7 +1571,7 @@ pub fn cs_fold<F>(use_foldl: bool,
     F: FnMut(&mut ExtCtxt, Span, P<Expr>, P<Expr>, &[P<Expr>]) -> P<Expr>,
 {
     match *substructure.fields {
-        EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
+        EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
             if use_foldl {
                 all_fields.iter().fold(base, |old, field| {
                     f(cx,
@@ -1612,7 +1617,7 @@ pub fn cs_same_method<F>(f: F,
     F: FnOnce(&mut ExtCtxt, Span, Vec<P<Expr>>) -> P<Expr>,
 {
     match *substructure.fields {
-        EnumMatching(_, _, ref all_fields) | Struct(ref all_fields) => {
+        EnumMatching(_, _, ref all_fields) | Struct(_, ref all_fields) => {
             // call self_n.method(other_1_n, other_2_n, ...)
             let called = all_fields.iter().map(|field| {
                 cx.expr_method_call(field.span,
index 371ba732b48965aac9905e83aa3ee1016b560043..bf8aa8fb23debd071fceabb07f5a016e98771797 100644 (file)
@@ -76,7 +76,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
     let mut stmts = Vec::new();
 
     let fields = match *substr.fields {
-        Struct(ref fs) => fs,
+        Struct(_, ref fs) => fs,
         EnumMatching(index, variant, ref fs) => {
             // Determine the discriminant. We will feed this value to the byte
             // iteration function.
index f64c9d36025a3f847d6bcb97285567e13c8c8576..9b3390d7747285eec0784bf04860f863efb4bce3 100644 (file)
@@ -1,3 +1,12 @@
+S 2016-02-17 4d3eebf
+  linux-i386 5f194aa7628c0703f0fd48adc4ec7f3cc64b98c7
+  linux-x86_64 d29b7607d13d64078b6324aec82926fb493f59ba
+  macos-i386 4c8e42dd649e247f3576bf9dfa273327b4907f9c
+  macos-x86_64 411a41363f922d1d93fa62ff2fedf5c35e9cccb2
+  winnt-i386 0c336d794a65f8e285c121866c7d59aa2dd0d1e1
+  winnt-x86_64 27e75b1bf99770b3564bcebd7f3230be01135a92
+  openbsd-x86_64 ac957c6b84de2bd67f01df085d9ea515f96e22f3
+
 S 2015-12-18 3391630
   bitrig-x86_64 6476e1562df02389b55553b4c88b1f4fd121cd40
   freebsd-i386 7e624c50494402e1feb14c743d659fbd71b448f5
index ba216289fd4c012c1e72e4ccebade88f22817bcd..2878674f0ea61fbb0e80140be2dd3025bad995a8 100644 (file)
@@ -73,7 +73,7 @@ fn expand(cx: &mut ExtCtxt,
 fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span,
                          substr: &Substructure) -> P<ast::Expr> {
     let fields = match *substr.fields {
-        Struct(ref fs) | EnumMatching(_, _, ref fs) => fs,
+        Struct(_, ref fs) | EnumMatching(_, _, ref fs) => fs,
         _ => cx.span_bug(trait_span, "impossible substructure")
     };
 
diff --git a/src/test/run-pass/empty-struct-braces-derive.rs b/src/test/run-pass/empty-struct-braces-derive.rs
new file mode 100644 (file)
index 0000000..e54a824
--- /dev/null
@@ -0,0 +1,45 @@
+// 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.
+
+// `#[derive(Trait)]` works for empty structs/variants with braces
+
+#![feature(braced_empty_structs)]
+#![feature(rustc_private)]
+
+extern crate serialize as rustc_serialize;
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
+         Default, Debug, RustcEncodable, RustcDecodable)]
+struct S {}
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
+         Debug, RustcEncodable, RustcDecodable)]
+enum E {
+    V {},
+    U,
+}
+
+fn main() {
+    let s = S {};
+    let s1 = s;
+    let s2 = s.clone();
+    assert_eq!(s, s1);
+    assert_eq!(s, s2);
+    assert!(!(s < s1));
+    assert_eq!(format!("{:?}", s), "S");
+
+    let e = E::V {};
+    let e1 = e;
+    let e2 = e.clone();
+    assert_eq!(e, e1);
+    assert_eq!(e, e2);
+    assert!(!(e < e1));
+    assert_eq!(format!("{:?}", e), "V");
+}