| cut -d ' ' -f 2)
case $CFG_CLANG_VERSION in
- (3.0svn | 3.0 | 3.1* | 3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
+ (3.2* | 3.3* | 3.4* | 3.5* | 3.6*)
step_msg "found ok version of CLANG: $CFG_CLANG_VERSION"
if [ -z "$CC" ]
then
numbers[0] is 2
```
-Each time, we can get a slithtly different output because the threads
-are not quaranteed to run in any set order. If you get the same order
-every time it is because each of these threads are very small and
-complete too fast for their indeterminate behavior to surface.
+Each time, we can get a slightly different output because the threads are not
+guaranteed to run in any set order. If you get the same order every time it is
+because each of these threads are very small and complete too fast for their
+indeterminate behavior to surface.
The important part here is that the Rust compiler was able to use ownership to
give us assurance _at compile time_ that we weren't doing something incorrect
impl<T> Arc<T> {
#[inline]
fn inner(&self) -> &ArcInner<T> {
- // This unsafety is ok because while this arc is alive we're guaranteed that the inner
- // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
- // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
- // to these contents.
+ // This unsafety is ok because while this arc is alive we're guaranteed
+ // that the inner pointer is valid. Furthermore, we know that the
+ // `ArcInner` structure itself is `Sync` because the inner data is
+ // `Sync` as well, so we're ok loaning out an immutable pointer to these
+ // contents.
unsafe { &**self._ptr }
}
}
/// ```
#[inline]
fn clone(&self) -> Arc<T> {
- // Using a relaxed ordering is alright here, as knowledge of the original reference
- // prevents other threads from erroneously deleting the object.
+ // Using a relaxed ordering is alright here, as knowledge of the
+ // original reference prevents other threads from erroneously deleting
+ // the object.
//
- // As explained in the [Boost documentation][1], Increasing the reference counter can
- // always be done with memory_order_relaxed: New references to an object can only be formed
- // from an existing reference, and passing an existing reference from one thread to another
- // must already provide any required synchronization.
+ // As explained in the [Boost documentation][1], Increasing the
+ // reference counter can always be done with memory_order_relaxed: New
+ // references to an object can only be formed from an existing
+ // reference, and passing an existing reference from one thread to
+ // another must already provide any required synchronization.
//
// [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
self.inner().strong.fetch_add(1, Relaxed);
///
/// `is_cjk` determines behavior for characters in the Ambiguous category: if `is_cjk` is
/// `true`, these are 2 columns wide; otherwise, they are 1. In CJK locales, `is_cjk` should be
- /// `true`, else it should be `false`. [Unicode Standard Annex
- /// #11](http://www.unicode.org/reports/tr11/) recommends that these characters be treated as 1
- /// column (i.e., `is_cjk` = `false`) if the locale is unknown.
+ /// `true`, else it should be `false`.
+ /// [Unicode Standard Annex #11](http://www.unicode.org/reports/tr11/) recommends that these
+ /// characters be treated as 1 column (i.e., `is_cjk = false`) if the locale is unknown.
#[unstable(feature = "collections",
reason = "this functionality may only be provided by libunicode")]
fn width(&self, is_cjk: bool) -> usize {
impl<T> Pointer for *const T {
fn fmt(&self, f: &mut Formatter) -> Result {
f.flags |= 1 << (FlagV1::Alternate as u32);
- let ret = LowerHex::fmt(&(*self as u32), f);
+ let ret = LowerHex::fmt(&(*self as usize), f);
f.flags &= !(1 << (FlagV1::Alternate as u32));
ret
}
use ops::{Add, Deref, FnMut};
use option::Option;
use option::Option::{Some, None};
-use marker::{Send, Sized, Sync};
+use marker::Sized;
use usize;
/// An interface for dealing with "external iterators". These types of iterators
peeked: Option<I::Item>,
}
-// FIXME: after #22828 being fixed, the following unsafe impl should be removed
-unsafe impl<I: Iterator> Sync for Peekable<I> where I: Sync, I::Item: Sync {}
-unsafe impl<I: Iterator> Send for Peekable<I> where I: Send, I::Item: Send {}
-
impl<I: Iterator + Clone> Clone for Peekable<I> where I::Item: Clone {
fn clone(&self) -> Peekable<I> {
Peekable {
//! distribution.
//!
//! * `rust_begin_unwind` - This function takes three arguments, a
-//! `fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
+//! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate
//! the panic message, the file at which panic was invoked, and the line.
//! It is up to consumers of this core library to define this panic
//! function; it is only required to never return.
#[macro_use]
mod uint_macros;
-#[path = "num/int.rs"] pub mod int;
#[path = "num/isize.rs"] pub mod isize;
#[path = "num/i8.rs"] pub mod i8;
#[path = "num/i16.rs"] pub mod i16;
#[path = "num/i32.rs"] pub mod i32;
#[path = "num/i64.rs"] pub mod i64;
-#[path = "num/uint.rs"] pub mod uint;
#[path = "num/usize.rs"] pub mod usize;
#[path = "num/u8.rs"] pub mod u8;
#[path = "num/u16.rs"] pub mod u16;
+++ /dev/null
-// Copyright 2012-2014 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.
-
-//! Deprecated: replaced by `isize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by isize")]
-
-#[cfg(target_pointer_width = "32")] int_module! { int, 32 }
-#[cfg(target_pointer_width = "64")] int_module! { int, 64 }
#[unstable(feature = "core",
reason = "pending integer conventions")]
#[inline]
- fn pow(self, mut exp: uint) -> Self {
+ fn pow(self, mut exp: u32) -> Self {
let mut base = self;
let mut acc: Self = Int::one();
+
while exp > 0 {
if (exp & 1) == 1 {
acc = acc * base;
+++ /dev/null
-// Copyright 2012-2014 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.
-
-//! Deprecated: replaced by `usize`.
-//!
-//! The rollout of the new type will gradually take place over the
-//! alpha cycle along with the development of clearer conventions
-//! around integer types.
-
-#![unstable(feature = "core")]
-#![deprecated(since = "1.0.0", reason = "replaced by usize")]
-
-uint_module! { uint, int, ::int::BITS }
use core::iter::order::*;
use core::iter::MinMaxResult::*;
use core::num::SignedInt;
-use core::uint;
+use core::usize;
use core::cmp;
use test::Bencher;
fn test_cycle() {
let cycle_len = 3;
let it = count(0, 1).take(cycle_len).cycle();
- assert_eq!(it.size_hint(), (uint::MAX, None));
+ assert_eq!(it.size_hint(), (usize::MAX, None));
for (i, x) in it.take(100).enumerate() {
assert_eq!(i % cycle_len, x);
}
let v2 = &[10, 11, 12];
let vi = v.iter();
- assert_eq!(c.size_hint(), (uint::MAX, None));
+ assert_eq!(c.size_hint(), (usize::MAX, None));
assert_eq!(vi.clone().size_hint(), (10, Some(10)));
assert_eq!(c.clone().take(5).size_hint(), (5, Some(5)));
assert_eq!(c.clone().skip(5).size_hint().1, None);
assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None));
assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None));
- assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None));
- assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None));
+ assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None));
+ assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None));
assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10)));
assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None));
assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None));
- assert_eq!(c.clone().map(|_| 0).size_hint(), (uint::MAX, None));
+ assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None));
assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None));
assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5)));
assert_eq!((0..100).size_hint(), (100, Some(100)));
// this test is only meaningful when sizeof uint < sizeof u64
- assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1)));
+ assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
assert_eq!((-10..-1).size_hint(), (9, Some(9)));
assert_eq!((-1..-10).size_hint(), (0, Some(0)));
}
+++ /dev/null
-// Copyright 2014 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.
-
-int_module!(int, int);
#[cfg(test)]
mod tests {
use core::$T_i::*;
- use core::int;
+ use core::isize;
use core::num::{FromStrRadix, Int, SignedInt};
use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr};
use num;
fn test_signed_checked_div() {
assert!(10.checked_div(2) == Some(5));
assert!(5.checked_div(0) == None);
- assert!(int::MIN.checked_div(-1) == None);
+ assert!(isize::MIN.checked_div(-1) == None);
}
#[test]
assert_eq!(FromStrRadix::from_str_radix("Z", 35).ok(), None::<$T>);
assert_eq!(FromStrRadix::from_str_radix("-9", 2).ok(), None::<$T>);
}
+
+ #[test]
+ fn test_pow() {
+ let mut r = 2 as $T;
+
+ assert_eq!(r.pow(2u32), 4 as $T);
+ assert_eq!(r.pow(0u32), 1 as $T);
+ r = -2 as $T;
+ assert_eq!(r.pow(2u32), 4 as $T);
+ assert_eq!(r.pow(3u32), -8 as $T);
+ }
}
)}
mod i16;
mod i32;
mod i64;
-mod int;
#[macro_use]
mod uint_macros;
mod u16;
mod u32;
mod u64;
-mod uint;
/// Helper function for testing numeric operations
pub fn test_num<T>(ten: T, two: T) where
+++ /dev/null
-// Copyright 2014 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.
-
-uint_module!(uint, uint);
"little lamb".to_string(),
"Little lamb".to_string()
]);
- t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX,
+ t("\nMary had a little lamb\nLittle lamb\n", ::std::usize::MAX,
&["Mary had a little lamb\nLittle lamb".to_string()]);
}
pub mod posix88 {
pub type off_t = i64;
pub type dev_t = u32;
- pub type ino_t = u32;
pub type pid_t = i32;
pub type uid_t = u32;
pub type gid_t = u32;
use core::prelude::*;
use core::char;
-use core::int;
-use core::uint;
+use core::isize;
+use core::usize;
use {Rand,Rng};
-impl Rand for int {
+impl Rand for isize {
#[inline]
- fn rand<R: Rng>(rng: &mut R) -> int {
- if int::BITS == 32 {
- rng.gen::<i32>() as int
+ fn rand<R: Rng>(rng: &mut R) -> isize {
+ if isize::BITS == 32 {
+ rng.gen::<i32>() as isize
} else {
- rng.gen::<i64>() as int
+ rng.gen::<i64>() as isize
}
}
}
}
}
-impl Rand for uint {
+impl Rand for usize {
#[inline]
- fn rand<R: Rng>(rng: &mut R) -> uint {
- if uint::BITS == 32 {
- rng.gen::<u32>() as uint
+ fn rand<R: Rng>(rng: &mut R) -> usize {
+ if usize::BITS == 32 {
+ rng.gen::<u32>() as usize
} else {
- rng.gen::<u64>() as uint
+ rng.gen::<u64>() as usize
}
}
}
use std::char;
use std::isize;
- use std::old_io::extensions::u64_from_be_bytes;
use std::mem::transmute;
use std::num::Int;
- use std::option::Option;
- use std::option::Option::{None, Some};
+ use std::slice::bytes;
use serialize;
return vuint_at_slow(data, start);
}
- // Lookup table for parsing EBML Element IDs as per http://ebml.sourceforge.net/specs/
- // The Element IDs are parsed by reading a big endian u32 positioned at data[start].
- // Using the four most significant bits of the u32 we lookup in the table below how the
- // element ID should be derived from it.
+ // Lookup table for parsing EBML Element IDs as per
+ // http://ebml.sourceforge.net/specs/ The Element IDs are parsed by
+ // reading a big endian u32 positioned at data[start]. Using the four
+ // most significant bits of the u32 we lookup in the table below how
+ // the element ID should be derived from it.
//
- // The table stores tuples (shift, mask) where shift is the number the u32 should be right
- // shifted with and mask is the value the right shifted value should be masked with.
- // If for example the most significant bit is set this means it's a class A ID and the u32
- // should be right shifted with 24 and masked with 0x7f. Therefore we store (24, 0x7f) at
- // index 0x8 - 0xF (four bit numbers where the most significant bit is set).
+ // The table stores tuples (shift, mask) where shift is the number the
+ // u32 should be right shifted with and mask is the value the right
+ // shifted value should be masked with. If for example the most
+ // significant bit is set this means it's a class A ID and the u32
+ // should be right shifted with 24 and masked with 0x7f. Therefore we
+ // store (24, 0x7f) at index 0x8 - 0xF (four bit numbers where the most
+ // significant bit is set).
//
- // By storing the number of shifts and masks in a table instead of checking in order if
- // the most significant bit is set, the second most significant bit is set etc. we can
- // replace up to three "and+branch" with a single table lookup which gives us a measured
+ // By storing the number of shifts and masks in a table instead of
+ // checking in order if the most significant bit is set, the second
+ // most significant bit is set etc. we can replace up to three
+ // "and+branch" with a single table lookup which gives us a measured
// speedup of around 2x on x86_64.
static SHIFT_MASK_TABLE: [(uint, u32); 16] = [
(0, 0x0), (0, 0x0fffffff),
pub fn doc_as_u16(d: Doc) -> u16 {
assert_eq!(d.end, d.start + 2);
- u64_from_be_bytes(d.data, d.start, 2) as u16
+ let mut b = [0; 2];
+ bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+ unsafe { (*(b.as_ptr() as *const u16)).to_be() }
}
pub fn doc_as_u32(d: Doc) -> u32 {
assert_eq!(d.end, d.start + 4);
- u64_from_be_bytes(d.data, d.start, 4) as u32
+ let mut b = [0; 4];
+ bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+ unsafe { (*(b.as_ptr() as *const u32)).to_be() }
}
pub fn doc_as_u64(d: Doc) -> u64 {
assert_eq!(d.end, d.start + 8);
- u64_from_be_bytes(d.data, d.start, 8)
+ let mut b = [0; 8];
+ bytes::copy_memory(&mut b, &d.data[d.start..d.end]);
+ unsafe { (*(b.as_ptr() as *const u64)).to_be() }
}
pub fn doc_as_i8(d: Doc) -> i8 { doc_as_u8(d) as i8 }
}
pub mod writer {
- use std::clone::Clone;
- use std::old_io::extensions::u64_to_be_bytes;
+ use std::mem;
+ use std::num::Int;
use std::old_io::{Writer, Seek};
use std::old_io;
- use std::mem;
use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
}
pub fn wr_tagged_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
- u64_to_be_bytes(v, 8, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_bytes(tag_id, &bytes)
}
pub fn wr_tagged_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
- u64_to_be_bytes(v as u64, 4, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_bytes(tag_id, &bytes)
}
pub fn wr_tagged_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
- u64_to_be_bytes(v as u64, 2, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_bytes(tag_id, &bytes)
}
pub fn wr_tagged_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
}
pub fn wr_tagged_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
- u64_to_be_bytes(v as u64, 8, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ self.wr_tagged_u64(tag_id, v as u64)
}
pub fn wr_tagged_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
- u64_to_be_bytes(v as u64, 4, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ self.wr_tagged_u32(tag_id, v as u32)
}
pub fn wr_tagged_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
- u64_to_be_bytes(v as u64, 2, |v| {
- self.wr_tagged_bytes(tag_id, v)
- })
+ self.wr_tagged_u16(tag_id, v as u16)
}
pub fn wr_tagged_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
}
fn visit_trait_item(&mut self, m: &ast::TraitItem) {
- run_lints!(self, check_trait_method, m);
+ run_lints!(self, check_trait_item, m);
visit::walk_trait_item(self, m);
}
fn check_fn(&mut self, _: &Context,
_: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
- fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
+ fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { }
fn check_struct_def(&mut self, _: &Context,
_: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
fn check_struct_def_post(&mut self, _: &Context,
use std::collections::HashMap;
use std::hash::{self, Hash, SipHasher};
-use std::old_io::extensions::u64_from_be_bytes;
-use std::old_io;
use std::num::FromPrimitive;
+use std::num::Int;
+use std::old_io;
use std::rc::Rc;
+use std::slice::bytes;
use std::str;
use rbml::reader;
// what crate that's in and give us a def_id that makes sense for the current
// build.
+fn u32_from_be_bytes(bytes: &[u8]) -> u32 {
+ let mut b = [0; 4];
+ bytes::copy_memory(&mut b, &bytes[..4]);
+ unsafe { (*(b.as_ptr() as *const u32)).to_be() }
+}
+
fn lookup_hash<'a, F>(d: rbml::Doc<'a>, mut eq_fn: F, hash: u64) -> Option<rbml::Doc<'a>> where
F: FnMut(&[u8]) -> bool,
{
let index = reader::get_doc(d, tag_index);
let table = reader::get_doc(index, tag_index_table);
let hash_pos = table.start + (hash % 256 * 4) as uint;
- let pos = u64_from_be_bytes(d.data, hash_pos, 4) as uint;
+ let pos = u32_from_be_bytes(&d.data[hash_pos..]) as uint;
let tagged_doc = reader::doc_at(d.data, pos).unwrap();
let belt = tag_index_buckets_bucket_elt;
let mut ret = None;
reader::tagged_docs(tagged_doc.doc, belt, |elt| {
- let pos = u64_from_be_bytes(elt.data, elt.start, 4) as uint;
+ let pos = u32_from_be_bytes(&elt.data[elt.start..]) as uint;
if eq_fn(&elt.data[elt.start + 4 .. elt.end]) {
ret = Some(reader::doc_at(d.data, pos).unwrap().doc);
false
pub fn maybe_find_item<'a>(item_id: ast::NodeId,
items: rbml::Doc<'a>) -> Option<rbml::Doc<'a>> {
fn eq_item(bytes: &[u8], item_id: ast::NodeId) -> bool {
- return u64_from_be_bytes(
- &bytes[0..4], 0, 4) as ast::NodeId
- == item_id;
+ u32_from_be_bytes(bytes) == item_id
}
lookup_hash(items,
|a| eq_item(a, item_id),
//! enclosing function. On the way down the tree, it identifies those AST
//! nodes and variable IDs that will be needed for the liveness analysis
//! and assigns them contiguous IDs. The liveness id for an AST node is
-//! called a `live_node` (it's a newtype'd uint) and the id for a variable
-//! is called a `variable` (another newtype'd uint).
+//! called a `live_node` (it's a newtype'd usize) and the id for a variable
+//! is called a `variable` (another newtype'd usize).
//!
//! On the way back up the tree, as we are about to exit from a function
//! declaration we allocate a `liveness` instance. Now that we know
use lint;
use util::nodemap::NodeMap;
-use std::{fmt, old_io, uint};
+use std::{fmt, old_io, usize};
use std::rc::Rc;
use std::iter::repeat;
use syntax::ast::{self, NodeId, Expr};
}
#[derive(Copy, PartialEq)]
-struct Variable(uint);
+struct Variable(usize);
#[derive(Copy, PartialEq)]
-struct LiveNode(uint);
+struct LiveNode(usize);
impl Variable {
- fn get(&self) -> uint { let Variable(v) = *self; v }
+ fn get(&self) -> usize { let Variable(v) = *self; v }
}
impl LiveNode {
- fn get(&self) -> uint { let LiveNode(v) = *self; v }
+ fn get(&self) -> usize { let LiveNode(v) = *self; v }
}
impl Clone for LiveNode {
impl LiveNode {
fn is_valid(&self) -> bool {
- self.get() != uint::MAX
+ self.get() != usize::MAX
}
}
-fn invalid_node() -> LiveNode { LiveNode(uint::MAX) }
+fn invalid_node() -> LiveNode { LiveNode(usize::MAX) }
struct CaptureInfo {
ln: LiveNode,
struct IrMaps<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
- num_live_nodes: uint,
- num_vars: uint,
+ num_live_nodes: usize,
+ num_vars: usize,
live_node_map: NodeMap<LiveNode>,
variable_map: NodeMap<Variable>,
capture_info_map: NodeMap<Rc<Vec<CaptureInfo>>>,
clean_exit_var: Variable
}
-static ACC_READ: uint = 1;
-static ACC_WRITE: uint = 2;
-static ACC_USE: uint = 4;
+static ACC_READ: u32 = 1;
+static ACC_WRITE: u32 = 2;
+static ACC_USE: u32 = 4;
struct Liveness<'a, 'tcx: 'a> {
ir: &'a mut IrMaps<'a, 'tcx>,
succ
}
- fn idx(&self, ln: LiveNode, var: Variable) -> uint {
+ fn idx(&self, ln: LiveNode, var: Variable) -> usize {
ln.get() * self.ir.num_vars + var.get()
}
}
fn indices2<F>(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where
- F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint),
+ F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize),
{
let node_base_idx = self.idx(ln, Variable(0));
let succ_base_idx = self.idx(succ_ln, Variable(0));
ln: LiveNode,
mut test: F)
-> old_io::IoResult<()> where
- F: FnMut(uint) -> LiveNode,
+ F: FnMut(usize) -> LiveNode,
{
let node_base_idx = self.idx(ln, Variable(0));
for var_idx in 0..self.ir.num_vars {
}
// Either read, write, or both depending on the acc bitset
- fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) {
+ fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) {
debug!("{:?} accesses[{:x}] {:?}: {}",
ln, acc, var, self.ln_str(ln));
}
// see comment on propagate_through_lvalue()
- fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+ fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
-> LiveNode {
match expr.node {
ast::ExprPath(..) => {
}
}
- fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint)
+ fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
-> LiveNode {
match self.ir.tcx.def_map.borrow()[expr.id].full_def() {
DefLocal(nid) => {
//! Use the former for unit-like structs and the latter for structs with
//! a `pub fn new()`.
-use self::MethodContext::*;
-
use metadata::{csearch, decoder};
use middle::def::*;
use middle::subst::Substs;
ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => {
let int_type = if let ast::TyIs(_) = t {
cx.sess().target.int_type
- } else { t };
+ } else {
+ t
+ };
let (min, max) = int_ty_range(int_type);
let negative = self.negated_expr_id == e.id;
ty::ty_uint(t) => {
let uint_type = if let ast::TyUs(_) = t {
cx.sess().target.uint_type
- } else { t };
+ } else {
+ t
+ };
let (min, max) = uint_ty_range(uint_type);
let lit_val: u64 = match lit.node {
ast::LitByte(_v) => return, // _v is u8, within range by definition
ast::LitInt(v, _) => v,
_ => panic!()
};
- if lit_val < min || lit_val > max {
+ if lit_val < min || lit_val > max {
cx.span_lint(OVERFLOWING_LITERALS, e.span,
&*format!("literal out of range for {:?}", t));
}
let lit_val: f64 = match lit.node {
ast::LitFloat(ref v, _) |
ast::LitFloatUnsuffixed(ref v) => {
- match v.parse().ok() {
- Some(f) => f,
- None => return
+ match v.parse() {
+ Ok(f) => f,
+ Err(_) => return
}
}
_ => panic!()
})
}
- // for int & uint, be conservative with the warnings, so that the
+ // for isize & usize, be conservative with the warnings, so that the
// warnings are consistent between 32- and 64-bit platforms
fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) {
match int_ty {
- ast::TyIs(_) => (i64::MIN, i64::MAX),
- ast::TyI8 => (i8::MIN as i64, i8::MAX as i64),
- ast::TyI16 => (i16::MIN as i64, i16::MAX as i64),
- ast::TyI32 => (i32::MIN as i64, i32::MAX as i64),
- ast::TyI64 => (i64::MIN, i64::MAX)
+ ast::TyIs(_) => (i64::MIN, i64::MAX),
+ ast::TyI8 => (i8::MIN as i64, i8::MAX as i64),
+ ast::TyI16 => (i16::MIN as i64, i16::MAX as i64),
+ ast::TyI32 => (i32::MIN as i64, i32::MAX as i64),
+ ast::TyI64 => (i64::MIN, i64::MAX)
}
}
fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) {
match uint_ty {
- ast::TyUs(_) => (u64::MIN, u64::MAX),
- ast::TyU8 => (u8::MIN as u64, u8::MAX as u64),
- ast::TyU16 => (u16::MIN as u64, u16::MAX as u64),
- ast::TyU32 => (u32::MIN as u64, u32::MAX as u64),
- ast::TyU64 => (u64::MIN, u64::MAX)
+ ast::TyUs(_) => (u64::MIN, u64::MAX),
+ ast::TyU8 => (u8::MIN as u64, u8::MAX as u64),
+ ast::TyU16 => (u16::MIN as u64, u16::MAX as u64),
+ ast::TyU32 => (u32::MIN as u64, u32::MAX as u64),
+ ast::TyU64 => (u64::MIN, u64::MAX)
}
}
fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) {
match float_ty {
- ast::TyF32 => (f32::MIN as f64, f32::MAX as f64),
- ast::TyF64 => (f64::MIN, f64::MAX)
+ ast::TyF32 => (f32::MIN as f64, f32::MAX as f64),
+ ast::TyF64 => (f64::MIN, f64::MAX)
}
}
fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 {
match int_ty {
- ast::TyIs(_) => int_ty_bits(target_int_ty, target_int_ty),
- ast::TyI8 => i8::BITS as u64,
- ast::TyI16 => i16::BITS as u64,
- ast::TyI32 => i32::BITS as u64,
- ast::TyI64 => i64::BITS as u64
+ ast::TyIs(_) => int_ty_bits(target_int_ty, target_int_ty),
+ ast::TyI8 => i8::BITS as u64,
+ ast::TyI16 => i16::BITS as u64,
+ ast::TyI32 => i32::BITS as u64,
+ ast::TyI64 => i64::BITS as u64
}
}
fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 {
match uint_ty {
- ast::TyUs(_) => uint_ty_bits(target_uint_ty, target_uint_ty),
- ast::TyU8 => u8::BITS as u64,
- ast::TyU16 => u16::BITS as u64,
- ast::TyU32 => u32::BITS as u64,
- ast::TyU64 => u64::BITS as u64
+ ast::TyUs(_) => uint_ty_bits(target_uint_ty, target_uint_ty),
+ ast::TyU8 => u8::BITS as u64,
+ ast::TyU16 => u16::BITS as u64,
+ ast::TyU32 => u32::BITS as u64,
+ ast::TyU64 => u64::BITS as u64
}
}
};
// Normalize the binop so that the literal is always on the RHS in
// the comparison
- let norm_binop = if swap { rev_binop(binop) } else { binop };
+ let norm_binop = if swap {
+ rev_binop(binop)
+ } else {
+ binop
+ };
match ty::expr_ty(tcx, expr).sty {
ty::ty_int(int_ty) => {
let (min, max) = int_ty_range(int_ty);
if !ty::is_ffi_safe(self.cx.tcx, tty) {
self.cx.span_lint(IMPROPER_CTYPES, sp,
- "found type without foreign-function-safe
- representation annotation in foreign module, consider \
- adding a #[repr(...)] attribute to the type");
+ "found type without foreign-function-safe \
+ representation annotation in foreign module, consider \
+ adding a #[repr(...)] attribute to the type");
}
}
_ => ()
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
if !attr::contains_name(&item.attrs, "automatically_derived") {
- return
+ return;
}
let did = match item.node {
ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
if let &Some(ref trait_ref) = t_ref_opt {
let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
if Some(def_id) == cx.tcx.lang_items.copy_trait() {
- return
+ return;
}
}
}
_ => return,
};
- if !ast_util::is_local(did) { return }
+ if !ast_util::is_local(did) {
+ return;
+ }
let item = match cx.tcx.map.find(did.node) {
Some(ast_map::NodeItem(item)) => item,
_ => return,
};
- if !self.checked_raw_pointers.insert(item.id) { return }
+ if !self.checked_raw_pointers.insert(item.id) {
+ return;
+ }
match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => {
let mut visitor = RawPtrDeriveVisitor { cx: cx };
}
fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
+ // Note that check_name() marks the attribute as used if it matches.
for &(ref name, ty) in KNOWN_ATTRIBUTES {
match ty {
AttributeType::Whitelisted
}
let t = ty::expr_ty(cx.tcx, expr);
- let mut warned = false;
- match t.sty {
+ let warned = match t.sty {
ty::ty_tup(ref tys) if tys.is_empty() => return,
ty::ty_bool => return,
ty::ty_struct(did, _) |
ty::ty_enum(did, _) => {
if ast_util::is_local(did) {
if let ast_map::NodeItem(it) = cx.tcx.map.get(did.node) {
- warned |= check_must_use(cx, &it.attrs, s.span);
+ check_must_use(cx, &it.attrs, s.span)
+ } else {
+ false
}
} else {
let attrs = csearch::get_item_attrs(&cx.sess().cstore, did);
- warned |= check_must_use(cx, &attrs[..], s.span);
+ check_must_use(cx, &attrs[..], s.span)
}
}
- _ => {}
- }
+ _ => false,
+ };
if !warned {
cx.span_lint(UNUSED_RESULTS, s.span, "unused result");
}
fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_camel_case(ident: ast::Ident) -> bool {
let ident = token::get_ident(ident);
- if ident.is_empty() { return true; }
+ if ident.is_empty() {
+ return true;
+ }
let ident = ident.trim_matches('_');
// start with a non-lowercase letter rather than non-uppercase
fn to_camel_case(s: &str) -> String {
s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)|
- if i == 0 { c.to_uppercase() }
- else { c }
+ if i == 0 {
+ c.to_uppercase()
+ } else {
+ c
+ }
)).collect()
}
}
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
- let has_extern_repr = it.attrs.iter().map(|attr| {
+ let has_extern_repr = it.attrs.iter().any(|attr| {
attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter()
.any(|r| r == &attr::ReprExtern)
- }).any(|x| x);
- if has_extern_repr { return }
+ });
+ if has_extern_repr {
+ return;
+ }
match it.node {
ast::ItemTy(..) | ast::ItemStruct(..) => {
self.check_case(cx, "trait", it.ident, it.span)
}
ast::ItemEnum(ref enum_definition, _) => {
- if has_extern_repr { return }
+ if has_extern_repr {
+ return;
+ }
self.check_case(cx, "type", it.ident, it.span);
for variant in &enum_definition.variants {
self.check_case(cx, "variant", variant.node.name, variant.span);
match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() {
None => cx.sess().span_bug(m.span, "missing method descriptor?!"),
- Some(md) => {
- match md {
- ty::MethodTraitItem(md) => {
- match md.container {
- ty::TraitContainer(..) => TraitDefaultImpl,
- ty::ImplContainer(cid) => {
- match ty::impl_trait_ref(cx.tcx, cid) {
- Some(..) => TraitImpl,
- None => PlainImpl
- }
- }
+ Some(ty::MethodTraitItem(md)) => {
+ match md.container {
+ ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+ ty::ImplContainer(cid) => {
+ match ty::impl_trait_ref(cx.tcx, cid) {
+ Some(..) => MethodContext::TraitImpl,
+ None => MethodContext::PlainImpl
}
}
- ty::TypeTraitItem(typedef) => {
- match typedef.container {
- ty::TraitContainer(..) => TraitDefaultImpl,
- ty::ImplContainer(cid) => {
- match ty::impl_trait_ref(cx.tcx, cid) {
- Some(..) => TraitImpl,
- None => PlainImpl
- }
- }
+ }
+ },
+ Some(ty::TypeTraitItem(typedef)) => {
+ match typedef.container {
+ ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
+ ty::ImplContainer(cid) => {
+ match ty::impl_trait_ref(cx.tcx, cid) {
+ Some(..) => MethodContext::TraitImpl,
+ None => MethodContext::PlainImpl
}
}
}
- }
+ },
}
}
if c == '_' {
words.push(String::new());
true
- } else { false }
+ } else {
+ false
+ }
});
for s in str.split('_') {
let mut last_upper = false;
let mut buf = String::new();
- if s.is_empty() { continue; }
+ if s.is_empty() {
+ continue;
+ }
for ch in s.chars() {
if !buf.is_empty() && buf != "'"
&& ch.is_uppercase()
fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
fn is_snake_case(ident: ast::Ident) -> bool {
let ident = token::get_ident(ident);
- if ident.is_empty() { return true; }
+ if ident.is_empty() {
+ return true;
+ }
let ident = ident.trim_left_matches('\'');
let ident = ident.trim_matches('_');
_: &ast::Block, span: Span, _: ast::NodeId) {
match fk {
visit::FkMethod(ident, _, m) => match method_context(cx, m) {
- PlainImpl
- => self.check_snake_case(cx, "method", ident, span),
- TraitDefaultImpl
- => self.check_snake_case(cx, "trait method", ident, span),
+ MethodContext::PlainImpl => {
+ self.check_snake_case(cx, "method", ident, span)
+ },
+ MethodContext::TraitDefaultImpl => {
+ self.check_snake_case(cx, "trait method", ident, span)
+ },
_ => (),
},
- visit::FkItemFn(ident, _, _, _)
- => self.check_snake_case(cx, "function", ident, span),
+ visit::FkItemFn(ident, _, _, _) => {
+ self.check_snake_case(cx, "function", ident, span)
+ },
_ => (),
}
}
}
fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef,
- _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
+ _: ast::Ident, _: &ast::Generics, _: ast::NodeId) {
for sf in &s.fields {
if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node {
self.check_snake_case(cx, "structure field", ident, sf.span);
impl UnusedParens {
fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
- struct_lit_needs_parens: bool) {
+ struct_lit_needs_parens: bool) {
if let ast::ExprParen(ref inner) = value.node {
let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner);
if !necessary {
cx.span_lint(UNUSED_PARENS, value.span,
- &format!("unnecessary parentheses around {}",
- msg))
+ &format!("unnecessary parentheses around {}", msg))
}
}
}
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
- match item.node {
- ast::ItemUse(ref view_path) => {
- match view_path.node {
- ast::ViewPathList(_, ref items) => {
- if items.len() == 1 {
- match items[0].node {
- ast::PathListIdent {ref name, ..} => {
- let m = format!("braces around {} is unnecessary",
- &token::get_ident(*name));
- cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
- &m[..]);
- },
- _ => ()
- }
- }
+ if let ast::ItemUse(ref view_path) = item.node {
+ if let ast::ViewPathList(_, ref items) = view_path.node {
+ if items.len() == 1 {
+ if let ast::PathListIdent {ref name, ..} = items[0].node {
+ let m = format!("braces around {} is unnecessary",
+ &token::get_ident(*name));
+ cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
+ &m[..]);
}
- _ => ()
}
- },
- _ => ()
+ }
}
}
}
fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) {
let def_map = cx.tcx.def_map.borrow();
if let ast::PatStruct(_, ref v, _) = pat.node {
- let field_pats = v.iter()
- .filter(|fieldpat| !fieldpat.node.is_shorthand)
- .filter(|fieldpat| {
+ let field_pats = v.iter().filter(|fieldpat| {
+ if fieldpat.node.is_shorthand {
+ return false;
+ }
let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def());
def == Some(def::DefLocal(fieldpat.node.pat.id))
});
desc: &'static str) {
// If we're building a test harness, then warning about
// documentation is probably not really relevant right now.
- if cx.sess().opts.test { return }
+ if cx.sess().opts.test {
+ return;
+ }
// `#[doc(hidden)]` disables missing_docs check.
- if self.doc_hidden() { return }
+ if self.doc_hidden() {
+ return;
+ }
// Only check publicly-visible items, using the result from the privacy pass.
// It's an option so the crate root can also use this function (it doesn't
});
if !has_doc {
cx.span_lint(MISSING_DOCS, sp,
- &format!("missing documentation for {}", desc));
+ &format!("missing documentation for {}", desc));
}
}
}
self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
}
- fn check_struct_def(&mut self, _: &Context,
- _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+ fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef,
+ _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
self.struct_def_stack.push(id);
}
- fn check_struct_def_post(&mut self, _: &Context,
- _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
+ fn check_struct_def_post(&mut self, _: &Context, _: &ast::StructDef,
+ _: ast::Ident, _: &ast::Generics, id: ast::NodeId) {
let popped = self.struct_def_stack.pop().expect("empty struct_def_stack");
assert!(popped == id);
}
fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
- self.check_missing_docs_attrs(cx, None, &krate.attrs,
- krate.span, "crate");
+ self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate");
}
fn check_item(&mut self, cx: &Context, it: &ast::Item) {
ast::ItemTy(..) => "a type alias",
_ => return
};
- self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs,
- it.span, desc);
+ self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc);
}
- fn check_fn(&mut self, cx: &Context,
- fk: visit::FnKind, _: &ast::FnDecl,
- _: &ast::Block, _: Span, _: ast::NodeId) {
+ fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
+ _: &ast::Block, _: Span, _: ast::NodeId) {
if let visit::FkMethod(_, _, m) = fk {
// If the method is an impl for a trait, don't doc.
- if method_context(cx, m) == TraitImpl { return; }
+ if method_context(cx, m) == MethodContext::TraitImpl {
+ return;
+ }
// Otherwise, doc according to privacy. This will also check
// doc for default methods defined on traits.
- self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs,
- m.span, "a method");
+ self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method");
}
}
fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) {
- self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs,
- tm.span, "a type method");
+ self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method");
}
- fn check_trait_method(&mut self, cx: &Context, it: &ast::TraitItem) {
+ fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) {
if let ast::TraitItem::TypeTraitItem(ref ty) = *it {
let assoc_ty = &ty.ty_param;
self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs,
}
fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) {
- self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs,
- v.span, "a variant");
+ self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, v.span, "a variant");
assert!(!self.in_variant);
self.in_variant = true;
}
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
if !cx.exported_items.contains(&item.id) {
- return
+ return;
}
if cx.tcx
.destructor_for_type
.borrow()
.contains_key(&ast_util::local_def(item.id)) {
- return
+ return;
}
let ty = match item.node {
ast::ItemStruct(_, ref ast_generics) => {
if ast_generics.is_parameterized() {
- return
+ return;
}
ty::mk_struct(cx.tcx,
ast_util::local_def(item.id),
}
ast::ItemEnum(_, ref ast_generics) => {
if ast_generics.is_parameterized() {
- return
+ return;
}
ty::mk_enum(cx.tcx,
ast_util::local_def(item.id),
};
let parameter_environment = ty::empty_parameter_environment(cx.tcx);
if !ty::type_moves_by_default(¶meter_environment, item.span, ty) {
- return
+ return;
}
if ty::can_type_implement_copy(¶meter_environment, item.span, ty).is_ok() {
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
let impls = match impls.get(&debug) {
Some(impls) => {
impls.borrow().iter()
- .filter(|d| d.krate == ast::LOCAL_CRATE)
- .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
- .map(|d| d.node)
- .collect()
+ .filter(|d| d.krate == ast::LOCAL_CRATE)
+ .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)))
+ .map(|d| d.node)
+ .collect()
}
None => NodeSet(),
};
impl Stability {
fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option<attr::Stability>) {
-
- // deprecated attributes apply in-crate and cross-crate
+ // Deprecated attributes apply in-crate and cross-crate.
let (lint, label) = match *stability {
Some(attr::Stability { deprecated_since: Some(_), .. }) =>
(DEPRECATED, "deprecated"),
let mut visited = BitSet::new();
while let Some(idx) = work_queue.pop() {
- let cfg_id = idx.node_id();
if idx == cfg.exit {
// found a path!
reached_exit_without_self_call = true;
- break
- } else if visited.contains(&cfg_id) {
+ break;
+ }
+
+ let cfg_id = idx.node_id();
+ if visited.contains(&cfg_id) {
// already done
- continue
+ continue;
}
visited.insert(cfg_id);
+
let node_id = cfg.graph.node_data(idx).id();
// is this a recursive call?
if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) {
-
self_call_spans.push(cx.tcx.map.span(node_id));
// this is a self call, so we shouldn't explore past
// this node in the CFG.
- continue
+ continue;
}
// add the successors of this node to explore the graph further.
cfg.graph.each_outgoing_edge(idx, |_, edge| {
});
}
- // check the number of sell calls because a function that
+ // Check the number of self calls because a function that
// doesn't return (e.g. calls a `-> !` function or `loop { /*
// no break */ }`) shouldn't be linted unless it actually
// recurs.
_: ast::Ident,
id: ast::NodeId) -> bool {
tcx.def_map.borrow().get(&id)
- .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
+ .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id))
}
// check if the method call `id` refers to method `method_id`
tcx.map.span(id),
"non-method call expr behaving like a method call?")
};
- // it matches if it comes from the same impl,
+ // It matches if it comes from the same impl,
// and has the same method name.
return ast_util::is_local(impl_def_id)
&& impl_def_id.node == impl_id
if decoder::get_plugin_registrar_fn(md.data()).is_some() {
cx.span_lint(PLUGIN_AS_LIBRARY, it.span,
- "compiler plugin used as an ordinary library");
+ "compiler plugin used as an ordinary library");
}
}
}
// Const items do not refer to a particular location in memory, and therefore
// don't have anything to attach a symbol to
let msg = "const items should never be #[no_mangle], consider instead using \
- `pub static`";
+ `pub static`";
cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);
}
}
#[derive(Copy)]
pub struct UnstableFeatures;
-declare_lint!(UNSTABLE_FEATURES, Allow,
- "enabling unstable features");
+declare_lint! {
+ UNSTABLE_FEATURES,
+ Allow,
+ "enabling unstable features"
+}
impl LintPass for UnstableFeatures {
fn get_lints(&self) -> LintArray {
lint_array!(UNSTABLE_FEATURES)
}
fn check_attribute(&mut self, ctx: &Context, attr: &ast::Attribute) {
- use syntax::attr;
if attr::contains_name(&[attr.node.value.clone()], "feature") {
ctx.span_lint(UNSTABLE_FEATURES, attr.span, "unstable feature");
}
// FIXME: time_llvm_passes support - does this use a global context or
// something?
- //if sess.time_llvm_passes() { llvm::LLVMRustPrintPassTimings(); }
+ if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
+ unsafe { llvm::LLVMRustPrintPassTimings(); }
+ }
}
struct WorkItem {
// Irrefutable columns always go first, they'd only be duplicated in the branches.
if total_score == 0 {
- std::uint::MAX
+ std::usize::MAX
} else {
total_score
}
}
pub fn set_llvm_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) {
- use syntax::attr::*;
+ use syntax::attr::{find_inline_attr, InlineAttr};
// Set the inline hint if there is one
match find_inline_attr(Some(ccx.sess().diagnostic()), attrs) {
- InlineHint => set_inline_hint(llfn),
- InlineAlways => set_always_inline(llfn),
- InlineNever => set_no_inline(llfn),
- InlineNone => { /* fallthrough */ }
+ InlineAttr::Hint => set_inline_hint(llfn),
+ InlineAttr::Always => set_always_inline(llfn),
+ InlineAttr::Never => set_no_inline(llfn),
+ InlineAttr::None => { /* fallthrough */ }
}
for attr in attrs {
// Do static_assert checking. It can't really be done much earlier
// because we need to get the value of the bool out of LLVM
if attr::contains_name(&item.attrs, "static_assert") {
+ if !ty::type_is_bool(ty::expr_ty(ccx.tcx(), expr)) {
+ ccx.sess().span_fatal(expr.span,
+ "can only have static_assert on a static \
+ with type `bool`");
+ }
if m == ast::MutMutable {
ccx.sess().span_fatal(expr.span,
"cannot have static_assert on a mutable \
use middle::ty::{BrAnon, ReLateBound};
let function_type;
- let (fn_sig, abi, has_env) = match fn_ty.sty {
- ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false),
+ let (fn_sig, abi, env_ty) = match fn_ty.sty {
+ ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None),
ty::ty_closure(closure_did, _, substs) => {
let typer = common::NormalizingClosureTyper::new(ccx.tcx());
function_type = typer.closure_type(closure_did, substs);
- (&function_type.sig, RustCall, true)
+ let self_type = self_type_for_closure(ccx, closure_did, fn_ty);
+ (&function_type.sig, RustCall, Some(self_type))
}
_ => ccx.sess().bug("expected closure or function.")
};
let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
- // Since index 0 is the return value of the llvm func, we start
- // at either 1 or 2 depending on whether there's an env slot or not
- let mut first_arg_offset = if has_env { 2 } else { 1 };
let mut attrs = llvm::AttrBuilder::new();
let ret_ty = fn_sig.output;
assert!(abi == RustCall);
match fn_sig.inputs[0].sty {
- ty::ty_tup(ref inputs) => inputs.clone(),
+ ty::ty_tup(ref inputs) => {
+ let mut full_inputs = vec![env_ty.expect("Missing closure environment")];
+ full_inputs.push_all(inputs);
+ full_inputs
+ }
_ => ccx.sess().bug("expected tuple'd inputs")
}
},
_ => fn_sig.inputs.clone()
};
+ // Index 0 is the return value of the llvm func, so we start at 1
+ let mut first_arg_offset = 1;
if let ty::FnConverging(ret_ty) = ret_ty {
// A function pointer is called without the declaration
// available, so we have to apply any attributes with ABI
let _icx = push_ctxt("trans_method_call");
debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx()));
let method_call = MethodCall::expr(call_expr.id);
- let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty;
+ let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) {
+ Some(method) => match method.origin {
+ ty::MethodTraitObject(_) => match method.ty.sty {
+ ty::ty_bare_fn(_, ref fty) => {
+ ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty))
+ }
+ _ => method.ty
+ },
+ _ => method.ty
+ },
+ None => panic!("method not found in trans_method_call")
+ };
trans_call_inner(
bcx,
call_expr.debug_loc(),
tuple_expr.id));
let repr = adt::represent_type(bcx.ccx(), tuple_type);
let repr_ptr = &*repr;
- for i in 0..field_types.len() {
+ llargs.extend(field_types.iter().enumerate().map(|(i, field_type)| {
let arg_datum = tuple_lvalue_datum.get_element(
bcx,
- field_types[i],
+ field_type,
|srcval| {
adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i)
- });
- let arg_datum = arg_datum.to_expr_datum();
- let arg_datum =
- unpack_datum!(bcx, arg_datum.to_rvalue_datum(bcx, "arg"));
- let arg_datum =
- unpack_datum!(bcx, arg_datum.to_appropriate_datum(bcx));
- llargs.push(arg_datum.add_clean(bcx.fcx, arg_cleanup_scope));
- }
+ }).to_expr_datum();
+ unpack_result!(bcx, trans_arg_datum(
+ bcx,
+ field_type,
+ arg_datum,
+ arg_cleanup_scope,
+ DontAutorefArg)
+ )
+ }));
}
_ => {
bcx.sess().span_bug(tuple_expr.span,
};
let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty);
let fty = tcx.mk_bare_fn(fty);
- debug!("trans_object_shim: fty={}", fty.repr(tcx));
+ let method_ty = opaque_method_ty(tcx, fty);
+ debug!("trans_object_shim: fty={} method_ty={}", fty.repr(tcx), method_ty.repr(tcx));
//
- let method_bare_fn_ty =
- ty::mk_bare_fn(tcx, None, fty);
+ let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty);
+ let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty);
let function_name =
- link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim");
+ link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim");
let llfn =
- decl_internal_rust_fn(ccx, method_bare_fn_ty, &function_name);
+ decl_internal_rust_fn(ccx, shim_fn_ty, &function_name);
let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig);
bcx
}
+
+/// Replace the self type (&Self or Box<Self>) with an opaque pointer.
+pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>)
+ -> &'tcx ty::BareFnTy<'tcx> {
+ let mut inputs = method_ty.sig.0.inputs.clone();
+ inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8));
+
+ tcx.mk_bare_fn(ty::BareFnTy {
+ unsafety: method_ty.unsafety,
+ abi: method_ty.abi,
+ sig: ty::Binder(ty::FnSig {
+ inputs: inputs,
+ output: method_ty.sig.0.output,
+ variadic: method_ty.sig.0.variadic,
+ }),
+ })
+}
use middle::region;
use middle::subst;
use middle::ty::{self, Ty};
-use util::ppaux::{Repr};
+use util::ppaux::{Repr, UserString};
+use syntax::ast;
use syntax::codemap::Span;
pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
// types that have been traversed so far by `traverse_type_if_unseen`
let mut breadcrumbs: Vec<Ty<'tcx>> = Vec::new();
- iterate_over_potentially_unsafe_regions_in_type(
+ let result = iterate_over_potentially_unsafe_regions_in_type(
rcx,
&mut breadcrumbs,
+ TypeContext::Root,
typ,
span,
scope,
+ 0,
0);
+ match result {
+ Ok(()) => {}
+ Err(Error::Overflow(ref ctxt, ref detected_on_typ)) => {
+ let tcx = rcx.tcx();
+ span_err!(tcx.sess, span, E0320,
+ "overflow while adding drop-check rules for {}",
+ typ.user_string(rcx.tcx()));
+ match *ctxt {
+ TypeContext::Root => {
+ // no need for an additional note if the overflow
+ // was somehow on the root.
+ }
+ TypeContext::EnumVariant { def_id, variant, arg_index } => {
+ // FIXME (pnkfelix): eventually lookup arg_name
+ // for the given index on struct variants.
+ span_note!(
+ rcx.tcx().sess,
+ span,
+ "overflowed on enum {} variant {} argument {} type: {}",
+ ty::item_path_str(tcx, def_id),
+ variant,
+ arg_index,
+ detected_on_typ.user_string(rcx.tcx()));
+ }
+ TypeContext::Struct { def_id, field } => {
+ span_note!(
+ rcx.tcx().sess,
+ span,
+ "overflowed on struct {} field {} type: {}",
+ ty::item_path_str(tcx, def_id),
+ field,
+ detected_on_typ.user_string(rcx.tcx()));
+ }
+ }
+ }
+ }
+}
+
+enum Error<'tcx> {
+ Overflow(TypeContext, ty::Ty<'tcx>),
+}
+
+enum TypeContext {
+ Root,
+ EnumVariant {
+ def_id: ast::DefId,
+ variant: ast::Name,
+ arg_index: usize,
+ },
+ Struct {
+ def_id: ast::DefId,
+ field: ast::Name,
+ }
}
+// The `depth` counts the number of calls to this function;
+// the `xref_depth` counts the subset of such calls that go
+// across a `Box<T>` or `PhantomData<T>`.
fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
rcx: &mut Rcx<'a, 'tcx>,
breadcrumbs: &mut Vec<Ty<'tcx>>,
+ context: TypeContext,
ty_root: ty::Ty<'tcx>,
span: Span,
scope: region::CodeExtent,
- depth: uint)
+ depth: uint,
+ xref_depth: uint) -> Result<(), Error<'tcx>>
{
+ // Issue #22443: Watch out for overflow. While we are careful to
+ // handle regular types properly, non-regular ones cause problems.
+ let recursion_limit = rcx.tcx().sess.recursion_limit.get();
+ if xref_depth >= recursion_limit {
+ return Err(Error::Overflow(context, ty_root))
+ }
+
let origin = || infer::SubregionOrigin::SafeDestructor(span);
let mut walker = ty_root.walk();
let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data();
let destructor_for_type = rcx.tcx().destructor_for_type.borrow();
+ let xref_depth_orig = xref_depth;
+
while let Some(typ) = walker.next() {
// Avoid recursing forever.
if breadcrumbs.contains(&typ) {
// If we encounter `PhantomData<T>`, then we should replace it
// with `T`, the type it represents as owned by the
// surrounding context, before doing further analysis.
- let typ = if let ty::ty_struct(struct_did, substs) = typ.sty {
- if opt_phantom_data_def_id == Some(struct_did) {
- let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
- let tp_def = item_type.generics.types
- .opt_get(subst::TypeSpace, 0).unwrap();
- let new_typ = substs.type_for_def(tp_def);
- debug!("replacing phantom {} with {}",
+ let (typ, xref_depth) = match typ.sty {
+ ty::ty_struct(struct_did, substs) => {
+ if opt_phantom_data_def_id == Some(struct_did) {
+ let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
+ let tp_def = item_type.generics.types
+ .opt_get(subst::TypeSpace, 0).unwrap();
+ let new_typ = substs.type_for_def(tp_def);
+ debug!("replacing phantom {} with {}",
+ typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
+ (new_typ, xref_depth_orig + 1)
+ } else {
+ (typ, xref_depth_orig)
+ }
+ }
+
+ // Note: When ty_uniq is removed from compiler, the
+ // definition of `Box<T>` must carry a PhantomData that
+ // puts us into the previous case.
+ ty::ty_uniq(new_typ) => {
+ debug!("replacing ty_uniq {} with {}",
typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx()));
- new_typ
- } else {
- typ
+ (new_typ, xref_depth_orig + 1)
+ }
+
+ _ => {
+ (typ, xref_depth_orig)
}
- } else {
- typ
};
let opt_type_did = match typ.sty {
opt_type_did.and_then(|did| destructor_for_type.get(&did));
debug!("iterate_over_potentially_unsafe_regions_in_type \
- {}typ: {} scope: {:?} opt_dtor: {:?}",
+ {}typ: {} scope: {:?} opt_dtor: {:?} xref: {}",
(0..depth).map(|_| ' ').collect::<String>(),
- typ.repr(rcx.tcx()), scope, opt_dtor);
+ typ.repr(rcx.tcx()), scope, opt_dtor, xref_depth);
// If `typ` has a destructor, then we must ensure that all
// borrowed data reachable via `typ` must outlive the parent
match typ.sty {
ty::ty_struct(struct_did, substs) => {
+ debug!("typ: {} is struct; traverse structure and not type-expression",
+ typ.repr(rcx.tcx()));
// Don't recurse; we extract type's substructure,
// so do not process subparts of type expression.
walker.skip_current_subtree();
struct_did,
field.id,
substs);
- iterate_over_potentially_unsafe_regions_in_type(
+ try!(iterate_over_potentially_unsafe_regions_in_type(
rcx,
breadcrumbs,
+ TypeContext::Struct {
+ def_id: struct_did,
+ field: field.name,
+ },
field_type,
span,
scope,
- depth+1)
+ depth+1,
+ xref_depth))
}
}
ty::ty_enum(enum_did, substs) => {
+ debug!("typ: {} is enum; traverse structure and not type-expression",
+ typ.repr(rcx.tcx()));
// Don't recurse; we extract type's substructure,
// so do not process subparts of type expression.
walker.skip_current_subtree();
enum_did,
substs);
for variant_info in all_variant_info.iter() {
- for argument_type in variant_info.args.iter() {
- iterate_over_potentially_unsafe_regions_in_type(
+ for (i, arg_type) in variant_info.args.iter().enumerate() {
+ try!(iterate_over_potentially_unsafe_regions_in_type(
rcx,
breadcrumbs,
- *argument_type,
+ TypeContext::EnumVariant {
+ def_id: enum_did,
+ variant: variant_info.name,
+ arg_index: i,
+ },
+ *arg_type,
span,
scope,
- depth+1)
+ depth+1,
+ xref_depth));
}
}
}
// is done.
}
}
+
+ return Ok(());
}
E0249, // expected constant expr for array length
E0250, // expected constant expr for array length
E0318, // can't create default impls for traits outside their crates
- E0319 // trait impls for defaulted traits allowed just for structs/enums
+ E0319, // trait impls for defaulted traits allowed just for structs/enums
+ E0320 // recursive overflow during dropck
}
__build_diagnostic_array! { DIAGNOSTICS }
--- /dev/null
+// 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 prelude::v1::*;
+
+use boxed;
+use cell::UnsafeCell;
+use rt;
+use sync::{StaticMutex, Arc};
+
+pub struct Lazy<T> {
+ pub lock: StaticMutex,
+ pub ptr: UnsafeCell<*mut Arc<T>>,
+ pub init: fn() -> Arc<T>,
+}
+
+unsafe impl<T> Sync for Lazy<T> {}
+
+macro_rules! lazy_init {
+ ($init:expr) => (::io::lazy::Lazy {
+ lock: ::sync::MUTEX_INIT,
+ ptr: ::cell::UnsafeCell { value: 0 as *mut _ },
+ init: $init,
+ })
+}
+
+impl<T: Send + Sync + 'static> Lazy<T> {
+ pub fn get(&'static self) -> Option<Arc<T>> {
+ let _g = self.lock.lock();
+ unsafe {
+ let mut ptr = *self.ptr.get();
+ if ptr.is_null() {
+ ptr = boxed::into_raw(self.init());
+ *self.ptr.get() = ptr;
+ } else if ptr as usize == 1 {
+ return None
+ }
+ Some((*ptr).clone())
+ }
+ }
+
+ fn init(&'static self) -> Box<Arc<T>> {
+ rt::at_exit(move || unsafe {
+ let g = self.lock.lock();
+ let ptr = *self.ptr.get();
+ *self.ptr.get() = 1 as *mut _;
+ drop(g);
+ drop(Box::from_raw(ptr))
+ });
+ Box::new((self.init)())
+ }
+}
pub use self::cursor::Cursor;
pub use self::error::{Result, Error, ErrorKind};
pub use self::util::{copy, sink, Sink, empty, Empty, repeat, Repeat};
+pub use self::stdio::{stdin, stdout, stderr, Stdin, Stdout, Stderr};
+pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
+
+#[macro_use] mod lazy;
pub mod prelude;
mod buffered;
mod error;
mod impls;
mod util;
+mod stdio;
const DEFAULT_BUF_SIZE: usize = 64 * 1024;
--- /dev/null
+// 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 prelude::v1::*;
+use io::prelude::*;
+
+use cmp;
+use fmt;
+use io::lazy::Lazy;
+use io::{self, BufReader, LineWriter};
+use sync::{Arc, Mutex, MutexGuard};
+use sys::stdio;
+
+/// A handle to a raw instance of the standard input stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdin_raw` function.
+pub struct StdinRaw(stdio::Stdin);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stdout_raw` function.
+pub struct StdoutRaw(stdio::Stdout);
+
+/// A handle to a raw instance of the standard output stream of this process.
+///
+/// This handle is not synchronized or buffered in any fashion. Constructed via
+/// the `std::io::stderr_raw` function.
+pub struct StderrRaw(stdio::Stderr);
+
+/// Construct a new raw handle to the standard input of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
+/// handles is **not** available to raw handles returned from this function.
+///
+/// The returned handle has no external synchronization or buffering.
+pub fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`. Note that data is buffered by the
+/// `std::io::stdin` handles so writes which happen via this raw handle may
+/// appear before previous writes.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+pub fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
+
+/// Construct a new raw handle to the standard input stream of this process.
+///
+/// The returned handle does not interact with any other handles created nor
+/// handles returned by `std::io::stdout`.
+///
+/// The returned handle has no external synchronization or buffering layered on
+/// top.
+pub fn stderr_raw() -> StderrRaw { StderrRaw(stdio::Stderr::new()) }
+
+impl Read for StdinRaw {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+}
+impl Write for StdoutRaw {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+ fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+impl Write for StderrRaw {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
+ fn flush(&mut self) -> io::Result<()> { Ok(()) }
+}
+
+/// A handle to the standard input stream of a process.
+///
+/// Each handle is a shared reference to a global buffer of input data to this
+/// process. A handle can be `lock`'d to gain full access to `BufRead` methods
+/// (e.g. `.lines()`). Writes to this handle are otherwise locked with respect
+/// to other writes.
+///
+/// This handle implements the `Read` trait, but beware that concurrent reads
+/// of `Stdin` must be executed with care.
+pub struct Stdin {
+ inner: Arc<Mutex<BufReader<StdinRaw>>>,
+}
+
+/// A locked reference to the a `Stdin` handle.
+///
+/// This handle implements both the `Read` and `BufRead` traits and is
+/// constructed via the `lock` method on `Stdin`.
+pub struct StdinLock<'a> {
+ inner: MutexGuard<'a, BufReader<StdinRaw>>,
+}
+
+/// Create a new handle to the global standard input stream of this process.
+///
+/// The handle returned refers to a globally shared buffer between all threads.
+/// Access is synchronized and can be explicitly controlled with the `lock()`
+/// method.
+///
+/// The `Read` trait is implemented for the returned value but the `BufRead`
+/// trait is not due to the global nature of the standard input stream. The
+/// locked version, `StdinLock`, implements both `Read` and `BufRead`, however.
+///
+/// To avoid locking and buffering altogether, it is recommended to use the
+/// `stdin_raw` constructor.
+pub fn stdin() -> Stdin {
+ static INSTANCE: Lazy<Mutex<BufReader<StdinRaw>>> = lazy_init!(stdin_init);
+ return Stdin {
+ inner: INSTANCE.get().expect("cannot access stdin during shutdown"),
+ };
+
+ fn stdin_init() -> Arc<Mutex<BufReader<StdinRaw>>> {
+ // The default buffer capacity is 64k, but apparently windows
+ // doesn't like 64k reads on stdin. See #13304 for details, but the
+ // idea is that on windows we use a slightly smaller buffer that's
+ // been seen to be acceptable.
+ Arc::new(Mutex::new(if cfg!(windows) {
+ BufReader::with_capacity(8 * 1024, stdin_raw())
+ } else {
+ BufReader::new(stdin_raw())
+ }))
+ }
+}
+
+impl Stdin {
+ /// Lock this handle to the standard input stream, returning a readable
+ /// guard.
+ ///
+ /// The lock is released when the returned lock goes out of scope. The
+ /// returned guard also implements the `Read` and `BufRead` traits for
+ /// accessing the underlying data.
+ pub fn lock(&self) -> StdinLock {
+ StdinLock { inner: self.inner.lock().unwrap() }
+ }
+}
+
+impl Read for Stdin {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ self.lock().read(buf)
+ }
+
+ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+ self.lock().read_to_end(buf)
+ }
+
+ fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+ self.lock().read_to_string(buf)
+ }
+}
+
+impl<'a> Read for StdinLock<'a> {
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ // Flush stdout so that weird issues like a print!'d prompt not being
+ // shown until after the user hits enter.
+ drop(stdout().flush());
+ self.inner.read(buf)
+ }
+}
+impl<'a> BufRead for StdinLock<'a> {
+ fn fill_buf(&mut self) -> io::Result<&[u8]> { self.inner.fill_buf() }
+ fn consume(&mut self, n: usize) { self.inner.consume(n) }
+}
+
+// As with stdin on windows, stdout often can't handle writes of large
+// sizes. For an example, see #14940. For this reason, don't try to
+// write the entire output buffer on windows. On unix we can just
+// write the whole buffer all at once.
+//
+// For some other references, it appears that this problem has been
+// encountered by others [1] [2]. We choose the number 8KB just because
+// libuv does the same.
+//
+// [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
+// [2]: http://www.mail-archive.com/log4net-dev@logging.apache.org/msg00661.html
+#[cfg(windows)]
+const OUT_MAX: usize = 8192;
+#[cfg(unix)]
+const OUT_MAX: usize = ::usize::MAX;
+
+/// A handle to the global standard output stream of the current process.
+///
+/// Each handle shares a global buffer of data to be written to the standard
+/// output stream. Access is also synchronized via a lock and explicit control
+/// over locking is available via the `lock` method.
+pub struct Stdout {
+ // FIXME: this should be LineWriter or BufWriter depending on the state of
+ // stdout (tty or not). Note that if this is not line buffered it
+ // should also flush-on-panic or some form of flush-on-abort.
+ inner: Arc<Mutex<LineWriter<StdoutRaw>>>,
+}
+
+/// A locked reference to the a `Stdout` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stdout`.
+pub struct StdoutLock<'a> {
+ inner: MutexGuard<'a, LineWriter<StdoutRaw>>,
+}
+
+/// Constructs a new reference to the standard output of the current process.
+///
+/// Each handle returned is a reference to a shared global buffer whose access
+/// is synchronized via a mutex. Explicit control over synchronization is
+/// provided via the `lock` method.
+///
+/// The returned handle implements the `Write` trait.
+///
+/// To avoid locking and buffering altogether, it is recommended to use the
+/// `stdout_raw` constructor.
+pub fn stdout() -> Stdout {
+ static INSTANCE: Lazy<Mutex<LineWriter<StdoutRaw>>> = lazy_init!(stdout_init);
+ return Stdout {
+ inner: INSTANCE.get().expect("cannot access stdout during shutdown"),
+ };
+
+ fn stdout_init() -> Arc<Mutex<LineWriter<StdoutRaw>>> {
+ Arc::new(Mutex::new(LineWriter::new(stdout_raw())))
+ }
+}
+
+impl Stdout {
+ /// Lock this handle to the standard output stream, returning a writable
+ /// guard.
+ ///
+ /// The lock is released when the returned lock goes out of scope. The
+ /// returned guard also implements the `Write` trait for writing data.
+ pub fn lock(&self) -> StdoutLock {
+ StdoutLock { inner: self.inner.lock().unwrap() }
+ }
+}
+
+impl Write for Stdout {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.lock().write(buf)
+ }
+ fn flush(&mut self) -> io::Result<()> {
+ self.lock().flush()
+ }
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ self.lock().write_all(buf)
+ }
+ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+ self.lock().write_fmt(fmt)
+ }
+}
+impl<'a> Write for StdoutLock<'a> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+ }
+ fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
+
+/// A handle to the standard error stream of a process.
+///
+/// For more information, see `stderr`
+pub struct Stderr {
+ inner: Arc<Mutex<StderrRaw>>,
+}
+
+/// A locked reference to the a `Stderr` handle.
+///
+/// This handle implements the `Write` trait and is constructed via the `lock`
+/// method on `Stderr`.
+pub struct StderrLock<'a> {
+ inner: MutexGuard<'a, StderrRaw>,
+}
+
+/// Constructs a new reference to the standard error stream of a process.
+///
+/// Each returned handle is synchronized amongst all other handles created from
+/// this function. No handles are buffered, however.
+///
+/// The returned handle implements the `Write` trait.
+///
+/// To avoid locking altogether, it is recommended to use the `stderr_raw`
+/// constructor.
+pub fn stderr() -> Stderr {
+ static INSTANCE: Lazy<Mutex<StderrRaw>> = lazy_init!(stderr_init);
+ return Stderr {
+ inner: INSTANCE.get().expect("cannot access stderr during shutdown"),
+ };
+
+ fn stderr_init() -> Arc<Mutex<StderrRaw>> {
+ Arc::new(Mutex::new(stderr_raw()))
+ }
+}
+
+impl Stderr {
+ /// Lock this handle to the standard error stream, returning a writable
+ /// guard.
+ ///
+ /// The lock is released when the returned lock goes out of scope. The
+ /// returned guard also implements the `Write` trait for writing data.
+ pub fn lock(&self) -> StderrLock {
+ StderrLock { inner: self.inner.lock().unwrap() }
+ }
+}
+
+impl Write for Stderr {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.lock().write(buf)
+ }
+ fn flush(&mut self) -> io::Result<()> {
+ self.lock().flush()
+ }
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ self.lock().write_all(buf)
+ }
+ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+ self.lock().write_fmt(fmt)
+ }
+}
+impl<'a> Write for StderrLock<'a> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ self.inner.write(&buf[..cmp::min(buf.len(), OUT_MAX)])
+ }
+ fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
+}
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
-#![feature(int_uint)]
+#![feature(hash)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
mod uint_macros;
#[path = "num/isize.rs"] pub mod isize;
-pub use isize as int;
#[path = "num/i8.rs"] pub mod i8;
#[path = "num/i16.rs"] pub mod i16;
#[path = "num/i32.rs"] pub mod i32;
#[path = "num/i64.rs"] pub mod i64;
#[path = "num/usize.rs"] pub mod usize;
-pub use usize as uint;
#[path = "num/u8.rs"] pub mod u8;
#[path = "num/u16.rs"] pub mod u16;
#[path = "num/u32.rs"] pub mod u32;
#[bench]
fn bench_pow_function(b: &mut Bencher) {
let v = (0..1024).collect::<Vec<_>>();
- b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new));});
+ b.iter(|| {v.iter().fold(0, |old, new| old.pow(*new as u32));});
}
}
//! Utility mixins that apply to all Readers and Writers
#![allow(missing_docs)]
+#![unstable(feature = "old_io")]
+#![deprecated(since = "1.0.0",
+ reason = "functionality will be removed with no immediate \
+ replacement")]
// FIXME: Not sure how this should be structured
// FIXME: Iteration should probably be considered separately
unsafe {
ONCE.call_once(|| {
- // The default buffer capacity is 64k, but apparently windows doesn't like
- // 64k reads on stdin. See #13304 for details, but the idea is that on
- // windows we use a slightly smaller buffer that's been seen to be
- // acceptable.
+ // The default buffer capacity is 64k, but apparently windows
+ // doesn't like 64k reads on stdin. See #13304 for details, but the
+ // idea is that on windows we use a slightly smaller buffer that's
+ // been seen to be acceptable.
let stdin = if cfg!(windows) {
BufferedReader::with_capacity(8 * 1024, stdin_raw())
} else {
pub mod timer;
pub mod tty;
pub mod udp;
+pub mod stdio;
pub mod addrinfo {
pub use sys_common::net::get_host_addresses;
--- /dev/null
+// 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 prelude::v1::*;
+
+use io;
+use libc;
+use sys::fd::FileDesc;
+
+pub struct Stdin(());
+pub struct Stdout(());
+pub struct Stderr(());
+
+impl Stdin {
+ pub fn new() -> Stdin { Stdin(()) }
+
+ pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+ let fd = FileDesc::new(libc::STDIN_FILENO);
+ let ret = fd.read(data);
+ fd.into_raw();
+ return ret;
+ }
+}
+
+impl Stdout {
+ pub fn new() -> Stdout { Stdout(()) }
+
+ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+ let fd = FileDesc::new(libc::STDOUT_FILENO);
+ let ret = fd.write(data);
+ fd.into_raw();
+ return ret;
+ }
+}
+
+impl Stderr {
+ pub fn new() -> Stderr { Stderr(()) }
+
+ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+ let fd = FileDesc::new(libc::STDERR_FILENO);
+ let ret = fd.write(data);
+ fd.into_raw();
+ return ret;
+ }
+}
if pthread_main_np() == 1 {
// main thread
- current_stack.ss_sp as uint - current_stack.ss_size as uint + 3 * PAGE_SIZE as uint
+ current_stack.ss_sp as uint - current_stack.ss_size as uint + PAGE_SIZE as uint
} else {
// new thread
pub const ERROR_NO_MORE_FILES: libc::DWORD = 18;
pub const TOKEN_READ: libc::DWORD = 0x20008;
+// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
+pub const STD_INPUT_HANDLE: libc::DWORD = -10;
+pub const STD_OUTPUT_HANDLE: libc::DWORD = -11;
+pub const STD_ERROR_HANDLE: libc::DWORD = -12;
+
#[repr(C)]
#[cfg(target_arch = "x86")]
pub struct WSADATA {
DesiredAccess: libc::DWORD,
TokenHandle: *mut libc::HANDLE) -> libc::BOOL;
pub fn GetCurrentProcess() -> libc::HANDLE;
+ pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
}
#[link(name = "userenv")]
use prelude::v1::*;
-use libc::{self, HANDLE};
-use io;
use io::ErrorKind;
+use io;
+use libc::{self, HANDLE};
+use mem;
use ptr;
use sys::cvt;
pub fn raw(&self) -> HANDLE { self.0 }
+ pub fn into_raw(self) -> HANDLE {
+ let ret = self.0;
+ unsafe { mem::forget(self) }
+ return ret;
+ }
+
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
read(self.0, buf)
}
pub mod timer;
pub mod tty;
pub mod udp;
+pub mod stdio;
pub mod addrinfo {
pub use sys_common::net::get_host_addresses;
--- /dev/null
+// 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 prelude::v1::*;
+use io::prelude::*;
+
+use io::{self, Cursor};
+use iter::repeat;
+use libc;
+use ptr;
+use str;
+use sync::Mutex;
+use sys::c;
+use sys::cvt;
+use sys::handle::Handle;
+
+struct NoClose(Option<Handle>);
+
+enum Output {
+ Console(NoClose),
+ Pipe(NoClose),
+}
+
+pub struct Stdin {
+ handle: Output,
+ utf8: Mutex<io::Cursor<Vec<u8>>>,
+}
+pub struct Stdout(Output);
+pub struct Stderr(Output);
+
+fn get(handle: libc::DWORD) -> io::Result<Output> {
+ let handle = unsafe { c::GetStdHandle(handle) };
+ if handle == libc::INVALID_HANDLE_VALUE {
+ Err(io::Error::last_os_error())
+ } else if handle.is_null() {
+ Err(io::Error::new(io::ErrorKind::Other,
+ "no stdio handle available for this process", None))
+ } else {
+ let ret = NoClose::new(handle);
+ let mut out = 0;
+ match unsafe { c::GetConsoleMode(handle, &mut out) } {
+ 0 => Ok(Output::Pipe(ret)),
+ _ => Ok(Output::Console(ret)),
+ }
+ }
+}
+
+fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
+ let handle = match *out {
+ Output::Console(ref c) => c.get().raw(),
+ Output::Pipe(ref p) => return p.get().write(data),
+ };
+ let utf16 = match str::from_utf8(data).ok() {
+ Some(utf8) => utf8.utf16_units().collect::<Vec<u16>>(),
+ None => return Err(invalid_encoding()),
+ };
+ let mut written = 0;
+ try!(cvt(unsafe {
+ c::WriteConsoleW(handle,
+ utf16.as_ptr() as libc::LPCVOID,
+ utf16.len() as u32,
+ &mut written,
+ ptr::null_mut())
+ }));
+
+ // FIXME if this only partially writes the utf16 buffer then we need to
+ // figure out how many bytes of `data` were actually written
+ assert_eq!(written as usize, utf16.len());
+ Ok(data.len())
+}
+
+impl Stdin {
+ pub fn new() -> Stdin {
+ Stdin {
+ handle: get(c::STD_INPUT_HANDLE).unwrap(),
+ utf8: Mutex::new(Cursor::new(Vec::new())),
+ }
+ }
+
+ pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
+ let handle = match self.handle {
+ Output::Console(ref c) => c.get().raw(),
+ Output::Pipe(ref p) => return p.get().read(buf),
+ };
+ let mut utf8 = self.utf8.lock().unwrap();
+ // Read more if the buffer is empty
+ if utf8.position() as usize == utf8.get_ref().len() {
+ let mut utf16: Vec<u16> = repeat(0u16).take(0x1000).collect();
+ let mut num = 0;
+ try!(cvt(unsafe {
+ c::ReadConsoleW(handle,
+ utf16.as_mut_ptr() as libc::LPVOID,
+ utf16.len() as u32,
+ &mut num,
+ ptr::null_mut())
+ }));
+ utf16.truncate(num as usize);
+ // FIXME: what to do about this data that has already been read?
+ let data = match String::from_utf16(&utf16) {
+ Ok(utf8) => utf8.into_bytes(),
+ Err(..) => return Err(invalid_encoding()),
+ };
+ *utf8 = Cursor::new(data);
+ }
+
+ // MemReader shouldn't error here since we just filled it
+ utf8.read(buf)
+ }
+}
+
+impl Stdout {
+ pub fn new() -> Stdout {
+ Stdout(get(c::STD_OUTPUT_HANDLE).unwrap())
+ }
+
+ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+ write(&self.0, data)
+ }
+}
+
+impl Stderr {
+ pub fn new() -> Stderr {
+ Stderr(get(c::STD_ERROR_HANDLE).unwrap())
+ }
+
+ pub fn write(&self, data: &[u8]) -> io::Result<usize> {
+ write(&self.0, data)
+ }
+}
+
+impl NoClose {
+ fn new(handle: libc::HANDLE) -> NoClose {
+ NoClose(Some(Handle::new(handle)))
+ }
+
+ fn get(&self) -> &Handle { self.0.as_ref().unwrap() }
+}
+
+impl Drop for NoClose {
+ fn drop(&mut self) {
+ self.0.take().unwrap().into_raw();
+ }
+}
+
+fn invalid_encoding() -> io::Error {
+ io::Error::new(io::ErrorKind::InvalidInput, "text was not valid unicode",
+ None)
+}
//! a thread will unwind the stack, running destructors and freeing
//! owned resources. Thread panic is unrecoverable from within
//! the panicking thread (i.e. there is no 'try/catch' in Rust), but
-//! panic may optionally be detected from a different thread. If
-//! the main thread panics the application will exit with a non-zero
+//! the panic may optionally be detected from a different thread. If
+//! the main thread panics, the application will exit with a non-zero
//! exit code.
//!
//! When the main thread of a Rust program terminates, the entire program shuts
//! down, even if other threads are still running. However, this module provides
//! convenient facilities for automatically waiting for the termination of a
-//! child thread (i.e., join), described below.
+//! child thread (i.e., join).
//!
//! ## The `Thread` type
//!
-//! Already-running threads are represented via the `Thread` type, which you can
+//! Threads are represented via the `Thread` type, which you can
//! get in one of two ways:
//!
-//! * By spawning a new thread, e.g. using the `thread::spawn` constructor;
+//! * By spawning a new thread, e.g. using the `thread::spawn` function.
//! * By requesting the current thread, using the `thread::current` function.
//!
//! Threads can be named, and provide some built-in support for low-level
-//! synchronization described below.
+//! synchronization (described below).
//!
//! The `thread::current()` function is available even for threads not spawned
//! by the APIs of this module.
//! use std::thread;
//!
//! thread::spawn(move || {
-//! println!("Hello, World!");
-//! // some computation here
+//! // some work here
//! });
//! ```
//!
//! In this example, the spawned thread is "detached" from the current
-//! thread, meaning that it can outlive the thread that spawned
-//! it. (Note, however, that when the main thread terminates all
-//! detached threads are terminated as well.)
+//! thread. This means that it can outlive its parent (the thread that spawned
+//! it), unless this parent is the main thread.
//!
//! ## Scoped threads
//!
//! Often a parent thread uses a child thread to perform some particular task,
//! and at some point must wait for the child to complete before continuing.
-//! For this scenario, use the `scoped` constructor:
+//! For this scenario, use the `thread::scoped` function:
//!
//! ```rust
//! use std::thread;
//!
//! let guard = thread::scoped(move || {
-//! println!("Hello, World!");
-//! // some computation here
+//! // some work here
//! });
+//!
//! // do some other work in the meantime
//! let output = guard.join();
//! ```
//! terminates) when it is dropped. You can join the child thread in
//! advance by calling the `join` method on the guard, which will also
//! return the result produced by the thread. A handle to the thread
-//! itself is available via the `thread` method on the join guard.
-//!
-//! (Note: eventually, the `scoped` constructor will allow the parent and child
-//! threads to data that lives on the parent thread's stack, but some language
-//! changes are needed before this is possible.)
+//! itself is available via the `thread` method of the join guard.
//!
//! ## Configuring threads
//!
//! use std::thread;
//!
//! thread::Builder::new().name("child1".to_string()).spawn(move || {
-//! println!("Hello, world!")
+//! println!("Hello, world!");
//! });
//! ```
//!
//! initially not present:
//!
//! * The `thread::park()` function blocks the current thread unless or until
-//! the token is available for its thread handle, at which point It atomically
+//! the token is available for its thread handle, at which point it atomically
//! consumes the token. It may also return *spuriously*, without consuming the
//! token. `thread::park_timeout()` does the same, but allows specifying a
//! maximum time to block the thread for.
//! * It avoids the need to allocate mutexes and condvars when building new
//! synchronization primitives; the threads already provide basic blocking/signaling.
//!
-//! * It can be implemented highly efficiently on many platforms.
+//! * It can be implemented very efficiently on many platforms.
#![stable(feature = "rust1", since = "1.0.0")]
// A name for the thread-to-be, for identification in panic messages
name: Option<String>,
// The size of the stack for the spawned thread
- stack_size: Option<uint>,
+ stack_size: Option<usize>,
// Thread-local stdout
stdout: Option<Box<Writer + Send + 'static>>,
// Thread-local stderr
/// Set the size of the stack for the new thread.
#[stable(feature = "rust1", since = "1.0.0")]
- pub fn stack_size(mut self, size: uint) -> Builder {
+ pub fn stack_size(mut self, size: usize) -> Builder {
self.stack_size = Some(size);
self
}
// address at which our stack started).
let main = move || {
let something_around_the_top_of_the_stack = 1;
- let addr = &something_around_the_top_of_the_stack as *const int;
- let my_stack_top = addr as uint;
+ let addr = &something_around_the_top_of_the_stack as *const isize;
+ let my_stack_top = addr as usize;
let my_stack_bottom = my_stack_top - stack_size + 1024;
unsafe {
stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
let (tx, rx) = channel();
- fn f(i: int, tx: Sender<()>) {
+ fn f(i: i32, tx: Sender<()>) {
let tx = tx.clone();
thread::spawn(move|| {
if i == 0 {
}
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
- let (tx, rx) = channel::<uint>();
+ let (tx, rx) = channel::<u32>();
let x = box 1;
- let x_in_parent = (&*x) as *const int as uint;
+ let x_in_parent = (&*x) as *const isize as u32;
spawnfn(Thunk::new(move|| {
- let x_in_child = (&*x) as *const int as uint;
+ let x_in_child = (&*x) as *const isize as u32;
tx.send(x_in_child).unwrap();
}));
// climbing the task tree to dereference each ancestor. (See #1789)
// (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!)
- static GENERATIONS: uint = 16;
- fn child_no(x: uint) -> Thunk<'static> {
+ static GENERATIONS: usize = 16;
+ fn child_no(x: usize) -> Thunk<'static> {
return Thunk::new(move|| {
if x < GENERATIONS {
thread::spawn(move|| child_no(x+1).invoke(()));
// Functions dealing with attributes and meta items
-pub use self::InlineAttr::*;
pub use self::StabilityLevel::*;
pub use self::ReprAttr::*;
pub use self::IntType::*;
#[derive(Copy, PartialEq)]
pub enum InlineAttr {
- InlineNone,
- InlineHint,
- InlineAlways,
- InlineNever,
+ None,
+ Hint,
+ Always,
+ Never,
}
/// Determine what `#[inline]` attribute is present in `attrs`, if any.
pub fn find_inline_attr(diagnostic: Option<&SpanHandler>, attrs: &[Attribute]) -> InlineAttr {
// FIXME (#2809)---validate the usage of #[inline] and #[inline]
- attrs.iter().fold(InlineNone, |ia,attr| {
+ attrs.iter().fold(InlineAttr::None, |ia,attr| {
match attr.node.value.node {
MetaWord(ref n) if *n == "inline" => {
mark_used(attr);
- InlineHint
+ InlineAttr::Hint
}
MetaList(ref n, ref items) if *n == "inline" => {
mark_used(attr);
if items.len() != 1 {
diagnostic.map(|d|{ d.span_err(attr.span, "expected one argument"); });
- InlineNone
+ InlineAttr::None
} else if contains_name(&items[..], "always") {
- InlineAlways
+ InlineAttr::Always
} else if contains_name(&items[..], "never") {
- InlineNever
+ InlineAttr::Never
} else {
diagnostic.map(|d|{ d.span_err((*items[0]).span, "invalid argument"); });
- InlineNone
+ InlineAttr::None
}
}
_ => ia
/// True if `#[inline]` or `#[inline(always)]` is present in `attrs`.
pub fn requests_inline(attrs: &[Attribute]) -> bool {
match find_inline_attr(None, attrs) {
- InlineHint | InlineAlways => true,
- InlineNone | InlineNever => false,
+ InlineAttr::Hint | InlineAttr::Always => true,
+ InlineAttr::None | InlineAttr::Never => false,
}
}
let messages = range_step(min_depth, max_depth + 1, 2).map(|depth| {
use std::num::Int;
- let iterations = 2.pow((max_depth - depth + min_depth) as usize);
+ let iterations = 2.pow((max_depth - depth + min_depth) as u32);
thread::scoped(move || inner(depth, iterations))
}).collect::<Vec<_>>();
#![feature(box_syntax)]
use std::ascii::OwnedAsciiExt;
+use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
use std::slice;
use std::sync::Arc;
use std::thread;
static TABLE: [u8;4] = [ 'A' as u8, 'C' as u8, 'G' as u8, 'T' as u8 ];
-static TABLE_SIZE: uint = 2 << 16;
+static TABLE_SIZE: usize = 2 << 16;
static OCCURRENCES: [&'static str;5] = [
"GGT",
Code((self.hash() << 2) + (pack_symbol(c) as u64))
}
- fn rotate(&self, c: u8, frame: uint) -> Code {
+ fn rotate(&self, c: u8, frame: usize) -> Code {
Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1))
}
string.bytes().fold(Code(0u64), |a, b| a.push_char(b))
}
- fn unpack(&self, frame: uint) -> String {
+ fn unpack(&self, frame: usize) -> String {
let mut key = self.hash();
let mut result = Vec::new();
for _ in 0..frame {
impl TableCallback for PrintCallback {
fn f(&self, entry: &mut Entry) {
let PrintCallback(s) = *self;
- println!("{}\t{}", entry.count as int, s);
+ println!("{}\t{}", entry.count, s);
}
}
struct Entry {
code: Code,
- count: uint,
+ count: usize,
next: Option<Box<Entry>>,
}
let index = key.hash() % (TABLE_SIZE as u64);
{
- if self.items[index as uint].is_none() {
+ if self.items[index as usize].is_none() {
let mut entry = box Entry {
code: key,
count: 0,
next: None,
};
c.f(&mut *entry);
- self.items[index as uint] = Some(entry);
+ self.items[index as usize] = Some(entry);
return;
}
}
{
- let entry = self.items[index as uint].as_mut().unwrap();
+ let entry = self.items[index as usize].as_mut().unwrap();
if entry.code == key {
c.f(&mut **entry);
return;
}
fn unpack_symbol(c: u8) -> u8 {
- TABLE[c as uint]
+ TABLE[c as usize]
}
-fn generate_frequencies(mut input: &[u8], frame: uint) -> Table {
+fn generate_frequencies(mut input: &[u8], frame: usize) -> Table {
let mut frequencies = Table::new();
if input.len() < frame { return frequencies; }
let mut code = Code(0);
frequencies
}
-fn print_frequencies(frequencies: &Table, frame: uint) {
+fn print_frequencies(frequencies: &Table, frame: usize) {
let mut vector = Vec::new();
for entry in frequencies.iter() {
vector.push((entry.count, entry.code));
frequencies.lookup(Code::pack(occurrence), PrintCallback(occurrence))
}
-fn get_sequence<R: Buffer>(r: &mut R, key: &str) -> Vec<u8> {
+fn get_sequence<R: BufRead>(r: &mut R, key: &str) -> Vec<u8> {
let mut res = Vec::new();
- for l in r.lines().map(|l| l.ok().unwrap())
+ for l in r.lines().map(|l| l.unwrap())
.skip_while(|l| key != &l[..key.len()]).skip(1)
{
res.push_all(l.trim().as_bytes());
}
fn main() {
- let input = if std::env::var_os("RUST_BENCH").is_some() {
- let fd = std::old_io::File::open(&Path::new("shootout-k-nucleotide.data"));
- get_sequence(&mut std::old_io::BufferedReader::new(fd), ">THREE")
+ let input = if env::var_os("RUST_BENCH").is_some() {
+ let f = File::open("shootout-k-nucleotide.data").unwrap();
+ get_sequence(&mut io::BufReader::new(f), ">THREE")
} else {
- let mut stdin = std::old_io::stdin();
+ let stdin = io::stdin();
let mut stdin = stdin.lock();
- get_sequence(&mut *stdin, ">THREE")
+ get_sequence(&mut stdin, ">THREE")
};
let input = Arc::new(input);
#![feature(box_syntax)]
#![allow(non_snake_case)]
-use std::old_io::BufferedReader;
-use std::old_io::stdio::StdReader;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
use std::iter::repeat;
use std::num::Int;
use std::env;
//
// internal type of sudoku grids
-type grid = Vec<Vec<u8> > ;
+type grid = Vec<Vec<u8>>;
struct Sudoku {
grid: grid
return Sudoku::new(g)
}
- pub fn read(mut reader: &mut BufferedReader<StdReader>) -> Sudoku {
+ pub fn read(reader: &mut BufRead) -> Sudoku {
/* assert first line is exactly "9,9" */
- assert!(reader.read_line().unwrap() == "9,9".to_string());
+ let mut s = String::new();
+ reader.read_line(&mut s).unwrap();
+ assert_eq!(s, "9,9\n");
let mut g = repeat(vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8])
.take(10).collect::<Vec<_>>();
if comps.len() == 3 {
let row = comps[0].parse::<u8>().unwrap();
let col = comps[1].parse::<u8>().unwrap();
- g[row as uint][col as uint] = comps[2].parse().unwrap();
+ g[row as usize][col as usize] = comps[2].parse().unwrap();
}
else {
panic!("Invalid sudoku file");
return Sudoku::new(g)
}
- pub fn write(&self, writer: &mut old_io::Writer) {
+ pub fn write(&self, writer: &mut Write) {
for row in 0u8..9u8 {
- write!(writer, "{}", self.grid[row as uint][0]);
+ write!(writer, "{}", self.grid[row as usize][0]);
for col in 1u8..9u8 {
- write!(writer, " {}", self.grid[row as uint][col as uint]);
+ write!(writer, " {}", self.grid[row as usize][col as usize]);
}
write!(writer, "\n");
}
let mut work: Vec<(u8, u8)> = Vec::new(); /* queue of uncolored fields */
for row in 0u8..9u8 {
for col in 0u8..9u8 {
- let color = self.grid[row as uint][col as uint];
+ let color = self.grid[row as usize][col as usize];
if color == 0u8 {
work.push((row, col));
}
while ptr < end {
let (row, col) = work[ptr];
// is there another color to try?
- let the_color = self.grid[row as uint][col as uint] +
+ let the_color = self.grid[row as usize][col as usize] +
(1 as u8);
if self.next_color(row, col, the_color) {
// yes: advance work list
// find first remaining color that is available
let next = avail.next();
- self.grid[row as uint][col as uint] = next;
+ self.grid[row as usize][col as usize] = next;
return 0u8 != next;
}
- self.grid[row as uint][col as uint] = 0u8;
+ self.grid[row as usize][col as usize] = 0u8;
return false;
}
fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
for idx in 0u8..9u8 {
/* check same column fields */
- avail.remove(self.grid[idx as uint][col as uint]);
+ avail.remove(self.grid[idx as usize][col as usize]);
/* check same row fields */
- avail.remove(self.grid[row as uint][idx as uint]);
+ avail.remove(self.grid[row as usize][idx as usize]);
}
// check same block fields
let col0 = (col / 3u8) * 3u8;
for alt_row in row0..row0 + 3u8 {
for alt_col in col0..col0 + 3u8 {
- avail.remove(self.grid[alt_row as uint][alt_col as uint]);
+ avail.remove(self.grid[alt_row as usize][alt_col as usize]);
}
}
}
impl Colors {
fn new(start_color: u8) -> Colors {
// Sets bits 9..start_color
- let tails = !0u16 << start_color as uint;
+ let tails = !0u16 << start_color as usize;
return Colors(HEADS & tails);
}
fn remove(&mut self, color: u8) {
if color != 0u8 {
let Colors(val) = *self;
- let mask = !(1u16 << color as uint);
+ let mask = !(1u16 << color as usize);
*self = Colors(val & mask);
}
}
}
fn main() {
- let args = env::args();
+ let args = env::args();
let use_default = args.len() == 1;
let mut sudoku = if use_default {
Sudoku::from_vec(&DEFAULT_SUDOKU)
} else {
- let mut stdin = old_io::stdin();
- let mut stdin = stdin.lock();
- Sudoku::read(&mut *stdin)
+ let stdin = io::stdin();
+ let mut locked = stdin.lock();
+ Sudoku::read(&mut locked)
};
sudoku.solve();
- sudoku.write(&mut old_io::stdout());
+ let out = io::stdout();
+ sudoku.write(&mut out.lock());
}
--- /dev/null
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+ elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+
+enum FingerTree<T:'static> {
+ Single(T),
+ // Bug report said Digit after Box would stack overflow (versus
+ // Digit before Box; see dropck_no_diverge_on_nonregular_2).
+ Deep(
+ Box<FingerTree<Node<T>>>,
+ Digit<T>,
+ )
+}
+
+fn main() {
+ let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+ FingerTree::Single(1);
+ //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
--- /dev/null
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+ elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+ Single(T),
+ // Bug report said Digit before Box would infinite loop (versus
+ // Digit after Box; see dropck_no_diverge_on_nonregular_1).
+ Deep(
+ Digit<T>,
+ Box<FingerTree<Node<T>>>,
+ )
+}
+
+fn main() {
+ let ft = //~ ERROR overflow while adding drop-check rules for FingerTree
+ FingerTree::Single(1);
+ //~^ ERROR overflow while adding drop-check rules for FingerTree
+}
--- /dev/null
+// 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.
+
+// Issue 22443: Reject code using non-regular types that would
+// otherwise cause dropck to loop infinitely.
+//
+// This version is just checking that we still sanely handle a trivial
+// wrapper around the non-regular type. (It also demonstrates how the
+// error messages will report different types depending on which type
+// dropck is analyzing.)
+
+use std::marker::PhantomData;
+
+struct Digit<T> {
+ elem: T
+}
+
+struct Node<T:'static> { m: PhantomData<&'static T> }
+
+enum FingerTree<T:'static> {
+ Single(T),
+ // According to the bug report, Digit before Box would infinite loop.
+ Deep(
+ Digit<T>,
+ Box<FingerTree<Node<T>>>,
+ )
+}
+
+enum Wrapper<T:'static> {
+ Simple,
+ Other(FingerTree<T>),
+}
+
+fn main() {
+ let w = //~ ERROR overflow while adding drop-check rules for core::option
+ Some(Wrapper::Simple::<u32>);
+ //~^ ERROR overflow while adding drop-check rules for core::option::Option
+ //~| ERROR overflow while adding drop-check rules for Wrapper
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::{int, i8, i16, i32, i64};
+use std::{isize, i8, i16, i32, i64};
use std::thread;
fn main() {
- assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err());
+ assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow in a constant expression
assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow in a constant expression
//~^ ERROR attempted to divide by zero in a constant expression
assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero in a constant expression
- assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err());
+ assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
//~^ ERROR attempted remainder with overflow in a constant expression
assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
//~^ ERROR attempted remainder with overflow in a constant expression
--- /dev/null
+// 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.
+
+#![allow(dead_code)]
+
+#[static_assert]
+static E: i32 = 1; //~ ERROR can only have static_assert on a static with type `bool`
+
+fn main() {}
// except according to those terms.
fn main() {
- pub use std::uint; //~ ERROR: visibility has no effect
+ pub use std::usize; //~ ERROR: visibility has no effect
pub struct A; //~ ERROR: visibility has no effect
pub enum B {} //~ ERROR: visibility has no effect
pub trait C { //~ ERROR: visibility has no effect
// error-pattern:index out of bounds: the len is 3 but the index is
-use std::uint;
+use std::usize;
use std::mem::size_of;
fn main() {
let xs = [1, 2, 3];
- xs[uint::MAX / size_of::<int>() + 1];
+ xs[usize::MAX / size_of::<isize>() + 1];
}
// error-pattern:capacity overflow
use std::collections::hash_map::HashMap;
-use std::uint;
+use std::usize;
use std::mem::size_of;
fn main() {
- let threshold = uint::MAX / size_of::<(u64, u64, u64)>();
+ let threshold = usize::MAX / size_of::<(u64, u64, u64)>();
let mut h = HashMap::<u64, u64>::with_capacity(threshold + 100);
h.insert(0, 0);
}
fn main() {
let _ = std::old_io::stdin();
+ let _ = std::io::stdin();
}
#![feature(box_syntax)]
use std::fmt;
+use std::usize;
struct A;
struct B;
t!(format!("{:+10.3e}", 1.2345e6f64), " +1.234e6");
t!(format!("{:+10.3e}", -1.2345e6f64), " -1.234e6");
+ // Test that pointers don't get truncated.
+ {
+ let val = usize::MAX;
+ let exp = format!("{:#x}", val);
+ t!(format!("{:p}", val as *const isize), exp);
+ }
+
// Escaping
t!(format!("{{"), "{");
t!(format!("}}"), "}");
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast
-
use std::env;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
use std::str;
fn main() {
fn parent() {
let args: Vec<String> = env::args().collect();
- let mut p = old_io::process::Command::new(&args[0])
- .arg("child").spawn().unwrap();
- p.stdin.as_mut().unwrap().write_str("test1\ntest2\ntest3").unwrap();
+ let mut p = Command::new(&args[0]).arg("child")
+ .stdout(Stdio::capture())
+ .stdin(Stdio::capture())
+ .spawn().unwrap();
+ p.stdin.as_mut().unwrap().write_all(b"test1\ntest2\ntest3").unwrap();
let out = p.wait_with_output().unwrap();
assert!(out.status.success());
- let s = str::from_utf8(&out.output).unwrap();
- assert_eq!(s, "test1\n\ntest2\n\ntest3\n");
+ let s = str::from_utf8(&out.stdout).unwrap();
+ assert_eq!(s, "test1\ntest2\ntest3\n");
}
fn child() {
- let mut stdin = old_io::stdin();
+ let mut stdin = io::stdin();
for line in stdin.lock().lines() {
println!("{}", line.unwrap());
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-
-use std::old_io::process;
-use std::old_io::Command;
-use std::old_io;
use std::env;
+use std::io::prelude::*;
+use std::io;
+use std::process::{Command, Stdio};
fn main() {
let args: Vec<String> = env::args().collect();
}
test();
-
}
fn child() {
- old_io::stdout().write_line("foo").unwrap();
- old_io::stderr().write_line("bar").unwrap();
- let mut stdin = old_io::stdin();
- assert_eq!(stdin.lock().read_line().err().unwrap().kind, old_io::EndOfFile);
+ writeln!(&mut io::stdout(), "foo").unwrap();
+ writeln!(&mut io::stderr(), "bar").unwrap();
+ let mut stdin = io::stdin();
+ let mut s = String::new();
+ stdin.lock().read_line(&mut s).unwrap();
+ assert_eq!(s.len(), 0);
}
fn test() {
let args: Vec<String> = env::args().collect();
let mut p = Command::new(&args[0]).arg("child")
- .stdin(process::Ignored)
- .stdout(process::Ignored)
- .stderr(process::Ignored)
+ .stdin(Stdio::capture())
+ .stdout(Stdio::capture())
+ .stderr(Stdio::capture())
.spawn().unwrap();
assert!(p.wait().unwrap().success());
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// DON'T REENABLE THIS UNLESS YOU'VE ACTUALLY FIXED THE UNDERLYING ISSUE
+// ignore-android seems to block forever
#![forbid(warnings)]
// A var moved into a proc, that has a mutable loan path should
// not trigger a misleading unused_mut warning.
+use std::io::prelude::*;
use std::thread;
pub fn main() {
- let mut stdin = std::old_io::stdin();
+ let mut stdin = std::io::stdin();
thread::spawn(move|| {
- let _ = stdin.read_to_end();
- });
+ let mut v = Vec::new();
+ let _ = stdin.read_to_end(&mut v);
+ }).join().ok().unwrap();
}
#![allow(unknown_features)]
#![feature(box_syntax)]
-use std::old_io;
+use std::io::{self, Write};
-fn f(wr: &mut Writer) {
- wr.write_str("hello").ok().expect("failed");
+fn f(wr: &mut Write) {
+ wr.write_all(b"hello").ok().expect("failed");
}
fn main() {
- let mut wr = box old_io::stdout() as Box<Writer + 'static>;
+ let mut wr = box io::stdout() as Box<Write>;
f(&mut wr);
}
--- /dev/null
+// 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.
+
+// This test is reduced from libsyntax. It is just checking that we
+// can successfully deal with a "deep" structure, which the drop-check
+// was hitting a recursion limit on at one point.
+
+#![allow(non_camel_case_types)]
+
+pub fn noop_fold_impl_item() -> SmallVector<ImplItem> {
+ loop { }
+}
+
+pub struct SmallVector<T>(P<T>);
+pub struct ImplItem(P<S01_Method>);
+
+struct P<T>(Box<T>);
+
+struct S01_Method(P<S02_Generics>);
+struct S02_Generics(P<S03_TyParam>);
+struct S03_TyParam(P<S04_TyParamBound>);
+struct S04_TyParamBound(S05_PolyTraitRef);
+struct S05_PolyTraitRef(S06_TraitRef);
+struct S06_TraitRef(S07_Path);
+struct S07_Path(Vec<S08_PathSegment>);
+struct S08_PathSegment(S09_PathParameters);
+struct S09_PathParameters(P<S10_ParenthesizedParameterData>);
+struct S10_ParenthesizedParameterData(Option<P<S11_Ty>>);
+struct S11_Ty(P<S12_Expr>);
+struct S12_Expr(P<S13_Block>);
+struct S13_Block(Vec<P<S14_Stmt>>);
+struct S14_Stmt(P<S15_Decl>);
+struct S15_Decl(P<S16_Local>);
+struct S16_Local(P<S17_Pat>);
+struct S17_Pat(P<S18_Mac>);
+struct S18_Mac(Vec<P<S19_TokenTree>>);
+struct S19_TokenTree(P<S20_Token>);
+struct S20_Token(P<S21_Nonterminal>);
+struct S21_Nonterminal(P<S22_Item>);
+struct S22_Item(P<S23_EnumDef>);
+struct S23_EnumDef(Vec<P<S24_Variant>>);
+struct S24_Variant(P<S25_VariantKind>);
+struct S25_VariantKind(P<S26_StructDef>);
+struct S26_StructDef(Vec<P<S27_StructField>>);
+struct S27_StructField(P<S28_StructFieldKind>);
+struct S28_StructFieldKind;
+
+pub fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::old_io;
+use std::io;
pub fn main() {
- let stdout = &mut old_io::stdout() as &mut old_io::Writer;
+ let stdout = &mut io::stdout() as &mut io::Write;
stdout.write(b"Hello!");
}
// ignore-pretty - token trees can't pretty print
+#![feature(custom_attribute)]
+
macro_rules! compiles_fine {
(#[$at:meta]) => {
// test that the different types of attributes work
// non-ASCII characters. The child process ensures all the strings are
// intact.
-use std::old_io;
-use std::old_io::fs;
-use std::old_io::Command;
+use std::io::prelude::*;
+use std::io;
+use std::fs;
+use std::process::Command;
use std::os;
use std::env;
-use std::old_path::Path;
+use std::path::{Path, PathBuf};
fn main() {
let my_args = env::args().collect::<Vec<_>>();
- let my_cwd = os::getcwd().unwrap();
+ let my_cwd = PathBuf::new(os::getcwd().unwrap().as_str().unwrap());
let my_env = env::vars().collect::<Vec<_>>();
- let my_path = Path::new(os::self_exe_name().unwrap());
- let my_dir = my_path.dir_path();
- let my_ext = my_path.extension_str().unwrap_or("");
+ let my_path = PathBuf::new(os::self_exe_name().unwrap().as_str().unwrap());
+ let my_dir = my_path.parent().unwrap();
+ let my_ext = my_path.extension().and_then(|s| s.to_str()).unwrap_or("");
// some non-ASCII characters
- let blah = "\u03c0\u042f\u97f3\u00e6\u221e";
+ let blah = "\u{3c0}\u{42f}\u{97f3}\u{e6}\u{221e}";
let child_name = "child";
let child_dir = format!("process-spawn-with-unicode-params-{}", blah);
// parameters sent to child / expected to be received from parent
let arg = blah;
- let cwd = my_dir.join(Path::new(child_dir.clone()));
+ let cwd = my_dir.join(&child_dir);
let env = ("RUST_TEST_PROC_SPAWN_UNICODE".to_string(), blah.to_string());
// am I the parent or the child?
let child_filestem = Path::new(child_name);
let child_filename = child_filestem.with_extension(my_ext);
- let child_path = cwd.join(child_filename);
+ let child_path = cwd.join(&child_filename);
// make a separate directory for the child
- drop(fs::mkdir(&cwd, old_io::USER_RWX).is_ok());
- assert!(fs::copy(&my_path, &child_path).is_ok());
- let mut my_env = my_env;
- my_env.push(env);
+ let _ = fs::create_dir(&cwd);
+ fs::copy(&my_path, &child_path).unwrap();
// run child
let p = Command::new(&child_path)
.arg(arg)
- .cwd(&cwd)
- .env_set_all(&my_env)
+ .current_dir(&cwd)
+ .env(&env.0, &env.1)
.spawn().unwrap().wait_with_output().unwrap();
// display the output
- assert!(old_io::stdout().write(&p.output).is_ok());
- assert!(old_io::stderr().write(&p.error).is_ok());
+ io::stdout().write_all(&p.stdout).unwrap();
+ io::stderr().write_all(&p.stderr).unwrap();
// make sure the child succeeded
assert!(p.status.success());
} else { // child
// check working directory (don't try to compare with `cwd` here!)
- assert!(my_cwd.ends_with_path(&Path::new(child_dir)));
+ assert!(my_cwd.ends_with(&child_dir));
// check arguments
assert_eq!(&*my_args[1], arg);