diff --git a/AUTHORS.txt b/AUTHORS.txt index 6e79eec3e795b..6e2ed39f875ce 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -8,7 +8,7 @@ Aaron Raimist Aaron Todd Aaron Turon Aaron Weiss -Abhishek Chanda +Abhishek Chanda Adam Bozanich Adam Jacob Adam Roben diff --git a/src/doc/complement-lang-faq.md b/src/doc/complement-lang-faq.md index e51e7d414a891..4d7862788fb2a 100644 --- a/src/doc/complement-lang-faq.md +++ b/src/doc/complement-lang-faq.md @@ -5,8 +5,8 @@ There aren't many large programs yet. The Rust [compiler][rustc], 60,000+ lines at the time of writing, is written in Rust. As the oldest body of Rust code it has gone through many iterations of the language, and some parts are nicer to look at than others. It may not be the best code to learn from, but [borrowck] and [resolve] were written recently. [rustc]: /~https://github.com/rust-lang/rust/tree/master/src/librustc -[resolve]: /~https://github.com/rust-lang/rust/blob/master/src/librustc/middle/resolve.rs -[borrowck]: /~https://github.com/rust-lang/rust/blob/master/src/librustc/middle/borrowck/ +[resolve]: /~https://github.com/rust-lang/rust/tree/master/src/librustc_resolve +[borrowck]: /~https://github.com/rust-lang/rust/tree/master/src/librustc_borrowck/borrowck A research browser engine called [Servo][servo], currently 30,000+ lines across more than a dozen crates, will be exercising a lot of Rust's distinctive type-system and concurrency features, and integrating many native libraries. @@ -20,8 +20,8 @@ Some examples that demonstrate different aspects of the language: * The standard library's [json] module. Enums and pattern matching [sprocketnes]: /~https://github.com/pcwalton/sprocketnes -[hash]: /~https://github.com/rust-lang/rust/blob/master/src/libstd/hash/mod.rs -[HashMap]: /~https://github.com/rust-lang/rust/blob/master/src/libcollections/hashmap.rs +[hash]: /~https://github.com/rust-lang/rust/tree/master/src/libcore/hash +[HashMap]: /~https://github.com/rust-lang/rust/tree/master/src/libstd/collections/hash [json]: /~https://github.com/rust-lang/rust/blob/master/src/libserialize/json.rs You may also be interested in browsing [trending Rust repositories][github-rust] on GitHub. diff --git a/src/doc/trpl/dining-philosophers.md b/src/doc/trpl/dining-philosophers.md index b179c90ceb95f..035f4de9da2a3 100644 --- a/src/doc/trpl/dining-philosophers.md +++ b/src/doc/trpl/dining-philosophers.md @@ -320,7 +320,7 @@ from the standard library, and so we need to `use` it. We now print out two messages, with a `sleep_ms()` in the middle. This will simulate the time it takes a philosopher to eat. -If you run this program, You should see each philosopher eat in turn: +If you run this program, you should see each philosopher eat in turn: ```text Baruch Spinoza is eating. @@ -480,7 +480,7 @@ struct Table { } ``` -This `Table` has an vector of `Mutex`es. A mutex is a way to control +This `Table` has a vector of `Mutex`es. A mutex is a way to control concurrency: only one thread can access the contents at once. This is exactly the property we need with our forks. We use an empty tuple, `()`, inside the mutex, since we’re not actually going to use the value, just hold onto it. diff --git a/src/doc/trpl/installing-rust.md b/src/doc/trpl/installing-rust.md index b8230f060e073..b182ac745b8f4 100644 --- a/src/doc/trpl/installing-rust.md +++ b/src/doc/trpl/installing-rust.md @@ -23,8 +23,8 @@ $ sh rustup.sh If you're on Windows, please download either the [32-bit installer][win32] or the [64-bit installer][win64] and run it. -[win32]: https://static.rust-lang.org/dist/rust-1.0.0-beta-i686-pc-windows-gnu.msi -[win64]: https://static.rust-lang.org/dist/rust-1.0.0-beta-x86_64-pc-windows-gnu.msi +[win32]: https://static.rust-lang.org/dist/rust-1.0.0-i686-pc-windows-gnu.msi +[win64]: https://static.rust-lang.org/dist/rust-1.0.0-x86_64-pc-windows-gnu.msi ## Uninstalling @@ -74,7 +74,7 @@ $ rustc --version You should see the version number, commit hash, commit date and build date: ```bash -rustc 1.0.0-beta (9854143cb 2015-04-02) (built 2015-04-02) +rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14) ``` If you did, Rust has been installed successfully! Congrats! diff --git a/src/doc/trpl/rust-inside-other-languages.md b/src/doc/trpl/rust-inside-other-languages.md index a1ae50a0c5396..868034ab23a31 100644 --- a/src/doc/trpl/rust-inside-other-languages.md +++ b/src/doc/trpl/rust-inside-other-languages.md @@ -104,7 +104,7 @@ fn process() { let handles: Vec<_> = (0..10).map(|_| { thread::spawn(|| { let mut _x = 0; - for _ in (0..5_000_001) { + for _ in (0..5_000_000) { _x += 1 } }) @@ -217,7 +217,7 @@ end Hello.process -puts "done!” +puts "done!" ``` Before we can run this, we need to install the `ffi` gem: diff --git a/src/doc/trpl/strings.md b/src/doc/trpl/strings.md index 61a6ec3eb3f4d..ece2c390be3b7 100644 --- a/src/doc/trpl/strings.md +++ b/src/doc/trpl/strings.md @@ -16,11 +16,11 @@ Rust has two main types of strings: `&str` and `String`. Let’s talk about `&'static str`: ```rust -let string = "Hello there."; // string: &'static str +let greeting = "Hello there."; // greeting: &'static str ``` This string is statically allocated, meaning that it’s saved inside our -compiled program, and exists for the entire duration it runs. The `string` +compiled program, and exists for the entire duration it runs. The `greeting` binding is a reference to this statically allocated string. String slices have a fixed size, and cannot be mutated. diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs index 10b8abfc78606..b9ff39547f3cf 100644 --- a/src/grammar/verify.rs +++ b/src/grammar/verify.rs @@ -287,11 +287,9 @@ fn main() { let options = config::basic_options(); let session = session::build_session(options, None, syntax::diagnostics::registry::Registry::new(&[])); - let filemap = parse::string_to_filemap(&session.parse_sess, - code, - String::from_str("")); + let filemap = session.parse_sess.codemap().new_filemap(String::from_str(""), code); let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap); - let ref cm = lexer.span_diagnostic.cm; + let cm = session.codemap(); // ANTLR let mut token_file = File::open(&Path::new(&args.next().unwrap())).unwrap(); diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 8c3c21a89023d..ff942444a6176 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -77,11 +77,12 @@ use core::atomic; use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; use core::fmt; use core::cmp::Ordering; -use core::mem::{min_align_of, size_of}; +use core::mem::{min_align_of_val, size_of_val}; +use core::intrinsics::drop_in_place; use core::mem; use core::nonzero::NonZero; -use core::ops::Deref; -use core::ptr; +use core::ops::{Deref, CoerceUnsized}; +use core::marker::Unsize; use core::hash::{Hash, Hasher}; use heap::deallocate; @@ -118,15 +119,16 @@ use heap::deallocate; /// ``` #[unsafe_no_drop_flag] #[stable(feature = "rust1", since = "1.0.0")] -pub struct Arc { +pub struct Arc { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref _ptr: NonZero<*mut ArcInner>, } -unsafe impl Send for Arc { } -unsafe impl Sync for Arc { } +unsafe impl Send for Arc { } +unsafe impl Sync for Arc { } +impl, U: ?Sized> CoerceUnsized> for Arc {} /// A weak pointer to an `Arc`. /// @@ -135,30 +137,30 @@ unsafe impl Sync for Arc { } #[unsafe_no_drop_flag] #[unstable(feature = "alloc", reason = "Weak pointers may not belong in this module.")] -pub struct Weak { +pub struct Weak { // FIXME #12808: strange name to try to avoid interfering with // field accesses of the contained type via Deref _ptr: NonZero<*mut ArcInner>, } -unsafe impl Send for Weak { } -unsafe impl Sync for Weak { } +unsafe impl Send for Weak { } +unsafe impl Sync for Weak { } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Weak { +impl fmt::Debug for Weak { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "(Weak)") } } -struct ArcInner { +struct ArcInner { strong: atomic::AtomicUsize, weak: atomic::AtomicUsize, data: T, } -unsafe impl Send for ArcInner {} -unsafe impl Sync for ArcInner {} +unsafe impl Send for ArcInner {} +unsafe impl Sync for ArcInner {} impl Arc { /// Constructs a new `Arc`. @@ -182,7 +184,9 @@ impl Arc { }; Arc { _ptr: unsafe { NonZero::new(mem::transmute(x)) } } } +} +impl Arc { /// Downgrades the `Arc` to a `Weak` reference. /// /// # Examples @@ -204,7 +208,7 @@ impl Arc { } } -impl Arc { +impl Arc { #[inline] fn inner(&self) -> &ArcInner { // This unsafety is ok because while this arc is alive we're guaranteed @@ -222,11 +226,11 @@ impl Arc { // Destroy the data at this time, even though we may not free the box // allocation itself (there may still be weak pointers lying around). - drop(ptr::read(&self.inner().data)); + drop_in_place(&mut (*ptr).data); if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - deallocate(ptr as *mut u8, size_of::>(), min_align_of::>()) + deallocate(ptr as *mut u8, size_of_val(&*ptr), min_align_of_val(&*ptr)) } } } @@ -234,12 +238,12 @@ impl Arc { /// Get the number of weak references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn weak_count(this: &Arc) -> usize { this.inner().weak.load(SeqCst) - 1 } +pub fn weak_count(this: &Arc) -> usize { this.inner().weak.load(SeqCst) - 1 } /// Get the number of strong references to this value. #[inline] #[unstable(feature = "alloc")] -pub fn strong_count(this: &Arc) -> usize { this.inner().strong.load(SeqCst) } +pub fn strong_count(this: &Arc) -> usize { this.inner().strong.load(SeqCst) } /// Returns a mutable reference to the contained value if the `Arc` is unique. @@ -264,7 +268,7 @@ pub fn strong_count(this: &Arc) -> usize { this.inner().strong.load(SeqCst /// ``` #[inline] #[unstable(feature = "alloc")] -pub fn get_mut(this: &mut Arc) -> Option<&mut T> { +pub fn get_mut(this: &mut Arc) -> Option<&mut T> { if strong_count(this) == 1 && weak_count(this) == 0 { // This unsafety is ok because we're guaranteed that the pointer // returned is the *only* pointer that will ever be returned to T. Our @@ -279,7 +283,7 @@ pub fn get_mut(this: &mut Arc) -> Option<&mut T> { } #[stable(feature = "rust1", since = "1.0.0")] -impl Clone for Arc { +impl Clone for Arc { /// Makes a clone of the `Arc`. /// /// This increases the strong reference count. @@ -313,7 +317,7 @@ impl Clone for Arc { } #[stable(feature = "rust1", since = "1.0.0")] -impl Deref for Arc { +impl Deref for Arc { type Target = T; #[inline] @@ -356,7 +360,7 @@ impl Arc { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Arc { +impl Drop for Arc { /// Drops the `Arc`. /// /// This will decrement the strong reference count. If the strong reference @@ -390,7 +394,7 @@ impl Drop for Arc { // it's run more than once) let ptr = *self._ptr; // if ptr.is_null() { return } - if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return } + if ptr as usize == 0 || ptr as usize == mem::POST_DROP_USIZE { return } // Because `fetch_sub` is already atomic, we do not need to synchronize // with other threads unless we are going to delete the object. This @@ -424,7 +428,7 @@ impl Drop for Arc { #[unstable(feature = "alloc", reason = "Weak pointers may not belong in this module.")] -impl Weak { +impl Weak { /// Upgrades a weak reference to a strong reference. /// /// Upgrades the `Weak` reference to an `Arc`, if possible. @@ -465,7 +469,7 @@ impl Weak { #[unstable(feature = "alloc", reason = "Weak pointers may not belong in this module.")] -impl Clone for Weak { +impl Clone for Weak { /// Makes a clone of the `Weak`. /// /// This increases the weak reference count. @@ -489,7 +493,7 @@ impl Clone for Weak { } #[stable(feature = "rust1", since = "1.0.0")] -impl Drop for Weak { +impl Drop for Weak { /// Drops the `Weak`. /// /// This will decrement the weak reference count. @@ -520,21 +524,22 @@ impl Drop for Weak { let ptr = *self._ptr; // see comments above for why this check is here - if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return } + if ptr as usize == 0 || ptr as usize == mem::POST_DROP_USIZE { return } // If we find out that we were the last weak pointer, then its time to // deallocate the data entirely. See the discussion in Arc::drop() about // the memory orderings if self.inner().weak.fetch_sub(1, Release) == 1 { atomic::fence(Acquire); - unsafe { deallocate(ptr as *mut u8, size_of::>(), - min_align_of::>()) } + unsafe { deallocate(ptr as *mut u8, + size_of_val(&*ptr), + min_align_of_val(&*ptr)) } } } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for Arc { +impl PartialEq for Arc { /// Equality for two `Arc`s. /// /// Two `Arc`s are equal if their inner value are equal. @@ -566,7 +571,7 @@ impl PartialEq for Arc { fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl PartialOrd for Arc { +impl PartialOrd for Arc { /// Partial comparison for two `Arc`s. /// /// The two are compared by calling `partial_cmp()` on their inner values. @@ -645,21 +650,21 @@ impl PartialOrd for Arc { fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Ord for Arc { +impl Ord for Arc { fn cmp(&self, other: &Arc) -> Ordering { (**self).cmp(&**other) } } #[stable(feature = "rust1", since = "1.0.0")] -impl Eq for Arc {} +impl Eq for Arc {} #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Display for Arc { +impl fmt::Display for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&**self, f) } } #[stable(feature = "rust1", since = "1.0.0")] -impl fmt::Debug for Arc { +impl fmt::Debug for Arc { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Debug::fmt(&**self, f) } @@ -679,7 +684,7 @@ impl Default for Arc { } #[stable(feature = "rust1", since = "1.0.0")] -impl Hash for Arc { +impl Hash for Arc { fn hash(&self, state: &mut H) { (**self).hash(state) } @@ -906,4 +911,13 @@ mod tests { // Make sure deriving works with Arc #[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Debug, Default)] struct Foo { inner: Arc } + + #[test] + fn test_unsized() { + let x: Arc<[i32]> = Arc::new([1, 2, 3]); + assert_eq!(format!("{:?}", x), "[1, 2, 3]"); + let y = x.clone().downgrade(); + drop(x); + assert!(y.upgrade().is_none()); + } } diff --git a/src/liballoc/arc_stage0.rs b/src/liballoc/arc_stage0.rs new file mode 100644 index 0000000000000..290b0566fd1b5 --- /dev/null +++ b/src/liballoc/arc_stage0.rs @@ -0,0 +1,686 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![stable(feature = "rust1", since = "1.0.0")] + +//! Threadsafe reference-counted boxes (the `Arc` type). +//! +//! The `Arc` type provides shared ownership of an immutable value. +//! Destruction is deterministic, and will occur as soon as the last owner is +//! gone. It is marked as `Send` because it uses atomic reference counting. +//! +//! If you do not need thread-safety, and just need shared ownership, consider +//! the [`Rc` type](../rc/struct.Rc.html). It is the same as `Arc`, but +//! does not use atomics, making it both thread-unsafe as well as significantly +//! faster when updating the reference count. +//! +//! The `downgrade` method can be used to create a non-owning `Weak` pointer +//! to the box. A `Weak` pointer can be upgraded to an `Arc` pointer, but +//! will return `None` if the value has already been dropped. +//! +//! For example, a tree with parent pointers can be represented by putting the +//! nodes behind strong `Arc` pointers, and then storing the parent pointers +//! as `Weak` pointers. +//! +//! # Examples +//! +//! Sharing some immutable data between threads: +//! +//! ```no_run +//! use std::sync::Arc; +//! use std::thread; +//! +//! let five = Arc::new(5); +//! +//! for _ in 0..10 { +//! let five = five.clone(); +//! +//! thread::spawn(move || { +//! println!("{:?}", five); +//! }); +//! } +//! ``` +//! +//! Sharing mutable data safely between threads with a `Mutex`: +//! +//! ```no_run +//! use std::sync::{Arc, Mutex}; +//! use std::thread; +//! +//! let five = Arc::new(Mutex::new(5)); +//! +//! for _ in 0..10 { +//! let five = five.clone(); +//! +//! thread::spawn(move || { +//! let mut number = five.lock().unwrap(); +//! +//! *number += 1; +//! +//! println!("{}", *number); // prints 6 +//! }); +//! } +//! ``` + +use boxed::Box; + +use core::prelude::*; + +use core::atomic; +use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst}; +use core::fmt; +use core::cmp::Ordering; +use core::mem::{min_align_of, size_of}; +use core::mem; +use core::nonzero::NonZero; +use core::ops::Deref; +use core::ptr; +use core::hash::{Hash, Hasher}; +use heap::deallocate; + +/// An atomically reference counted wrapper for shared state. +/// +/// # Examples +/// +/// In this example, a large vector of floats is shared between several threads. +/// With simple pipes, without `Arc`, a copy would have to be made for each +/// thread. +/// +/// When you clone an `Arc`, it will create another pointer to the data and +/// increase the reference counter. +/// +/// ``` +/// # #![feature(alloc, core)] +/// use std::sync::Arc; +/// use std::thread; +/// +/// fn main() { +/// let numbers: Vec<_> = (0..100u32).collect(); +/// let shared_numbers = Arc::new(numbers); +/// +/// for _ in 0..10 { +/// let child_numbers = shared_numbers.clone(); +/// +/// thread::spawn(move || { +/// let local_numbers = &child_numbers[..]; +/// +/// // Work with the local numbers +/// }); +/// } +/// } +/// ``` +#[unsafe_no_drop_flag] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Arc { + // FIXME #12808: strange name to try to avoid interfering with + // field accesses of the contained type via Deref + _ptr: NonZero<*mut ArcInner>, +} + +unsafe impl Send for Arc { } +unsafe impl Sync for Arc { } + + +/// A weak pointer to an `Arc`. +/// +/// Weak pointers will not keep the data inside of the `Arc` alive, and can be +/// used to break cycles between `Arc` pointers. +#[unsafe_no_drop_flag] +#[unstable(feature = "alloc", + reason = "Weak pointers may not belong in this module.")] +pub struct Weak { + // FIXME #12808: strange name to try to avoid interfering with + // field accesses of the contained type via Deref + _ptr: NonZero<*mut ArcInner>, +} + +unsafe impl Send for Weak { } +unsafe impl Sync for Weak { } + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Weak { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "(Weak)") + } +} + +struct ArcInner { + strong: atomic::AtomicUsize, + weak: atomic::AtomicUsize, + data: T, +} + +unsafe impl Send for ArcInner {} +unsafe impl Sync for ArcInner {} + +impl Arc { + /// Constructs a new `Arc`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn new(data: T) -> Arc { + // Start the weak pointer count as 1 which is the weak pointer that's + // held by all the strong pointers (kinda), see std/rc.rs for more info + let x: Box<_> = box ArcInner { + strong: atomic::AtomicUsize::new(1), + weak: atomic::AtomicUsize::new(1), + data: data, + }; + Arc { _ptr: unsafe { NonZero::new(mem::transmute(x)) } } + } + + /// Downgrades the `Arc` to a `Weak` reference. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// let weak_five = five.downgrade(); + /// ``` + #[unstable(feature = "alloc", + reason = "Weak pointers may not belong in this module.")] + pub fn downgrade(&self) -> Weak { + // See the clone() impl for why this is relaxed + self.inner().weak.fetch_add(1, Relaxed); + Weak { _ptr: self._ptr } + } +} + +impl Arc { + #[inline] + fn inner(&self) -> &ArcInner { + // 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 } + } + + // Non-inlined part of `drop`. + #[inline(never)] + unsafe fn drop_slow(&mut self) { + let ptr = *self._ptr; + + // Destroy the data at this time, even though we may not free the box + // allocation itself (there may still be weak pointers lying around). + drop(ptr::read(&self.inner().data)); + + if self.inner().weak.fetch_sub(1, Release) == 1 { + atomic::fence(Acquire); + deallocate(ptr as *mut u8, size_of::>(), min_align_of::>()) + } + } +} + +/// Get the number of weak references to this value. +#[inline] +#[unstable(feature = "alloc")] +pub fn weak_count(this: &Arc) -> usize { this.inner().weak.load(SeqCst) - 1 } + +/// Get the number of strong references to this value. +#[inline] +#[unstable(feature = "alloc")] +pub fn strong_count(this: &Arc) -> usize { this.inner().strong.load(SeqCst) } + + +/// Returns a mutable reference to the contained value if the `Arc` is unique. +/// +/// Returns `None` if the `Arc` is not unique. +/// +/// # Examples +/// +/// ``` +/// # #![feature(alloc)] +/// extern crate alloc; +/// # fn main() { +/// use alloc::arc::{Arc, get_mut}; +/// +/// let mut x = Arc::new(3); +/// *get_mut(&mut x).unwrap() = 4; +/// assert_eq!(*x, 4); +/// +/// let _y = x.clone(); +/// assert!(get_mut(&mut x).is_none()); +/// # } +/// ``` +#[inline] +#[unstable(feature = "alloc")] +pub fn get_mut(this: &mut Arc) -> Option<&mut T> { + if strong_count(this) == 1 && weak_count(this) == 0 { + // This unsafety is ok because we're guaranteed that the pointer + // returned is the *only* pointer that will ever be returned to T. Our + // reference count is guaranteed to be 1 at this point, and we required + // the Arc itself to be `mut`, so we're returning the only possible + // reference to the inner data. + let inner = unsafe { &mut **this._ptr }; + Some(&mut inner.data) + } else { + None + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Clone for Arc { + /// Makes a clone of the `Arc`. + /// + /// This increases the strong reference count. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five.clone(); + /// ``` + #[inline] + fn clone(&self) -> Arc { + // 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. + // + // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + self.inner().strong.fetch_add(1, Relaxed); + Arc { _ptr: self._ptr } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Deref for Arc { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.inner().data + } +} + +impl Arc { + /// Make a mutable reference from the given `Arc`. + /// + /// This is also referred to as a copy-on-write operation because the inner + /// data is cloned if the reference count is greater than one. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// let mut five = Arc::new(5); + /// + /// let mut_five = five.make_unique(); + /// ``` + #[inline] + #[unstable(feature = "alloc")] + pub fn make_unique(&mut self) -> &mut T { + // Note that we hold a strong reference, which also counts as a weak + // reference, so we only clone if there is an additional reference of + // either kind. + if self.inner().strong.load(SeqCst) != 1 || + self.inner().weak.load(SeqCst) != 1 { + *self = Arc::new((**self).clone()) + } + // As with `get_mut()`, the unsafety is ok because our reference was + // either unique to begin with, or became one upon cloning the contents. + let inner = unsafe { &mut **self._ptr }; + &mut inner.data + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Drop for Arc { + /// Drops the `Arc`. + /// + /// This will decrement the strong reference count. If the strong reference + /// count becomes zero and the only other references are `Weak` ones, + /// `drop`s the inner value. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// { + /// let five = Arc::new(5); + /// + /// // stuff + /// + /// drop(five); // explicit drop + /// } + /// { + /// let five = Arc::new(5); + /// + /// // stuff + /// + /// } // implicit drop + /// ``` + #[inline] + fn drop(&mut self) { + // This structure has #[unsafe_no_drop_flag], so this drop glue may run + // more than once (but it is guaranteed to be zeroed after the first if + // it's run more than once) + let ptr = *self._ptr; + // if ptr.is_null() { return } + if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return } + + // Because `fetch_sub` is already atomic, we do not need to synchronize + // with other threads unless we are going to delete the object. This + // same logic applies to the below `fetch_sub` to the `weak` count. + if self.inner().strong.fetch_sub(1, Release) != 1 { return } + + // This fence is needed to prevent reordering of use of the data and + // deletion of the data. Because it is marked `Release`, the decreasing + // of the reference count synchronizes with this `Acquire` fence. This + // means that use of the data happens before decreasing the reference + // count, which happens before this fence, which happens before the + // deletion of the data. + // + // As explained in the [Boost documentation][1], + // + // > It is important to enforce any possible access to the object in one + // > thread (through an existing reference) to *happen before* deleting + // > the object in a different thread. This is achieved by a "release" + // > operation after dropping a reference (any access to the object + // > through this reference must obviously happened before), and an + // > "acquire" operation before deleting the object. + // + // [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html) + atomic::fence(Acquire); + + unsafe { + self.drop_slow() + } + } +} + +#[unstable(feature = "alloc", + reason = "Weak pointers may not belong in this module.")] +impl Weak { + /// Upgrades a weak reference to a strong reference. + /// + /// Upgrades the `Weak` reference to an `Arc`, if possible. + /// + /// Returns `None` if there were no strong references and the data was + /// destroyed. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// let weak_five = five.downgrade(); + /// + /// let strong_five: Option> = weak_five.upgrade(); + /// ``` + pub fn upgrade(&self) -> Option> { + // We use a CAS loop to increment the strong count instead of a + // fetch_add because once the count hits 0 it must never be above 0. + let inner = self.inner(); + loop { + let n = inner.strong.load(SeqCst); + if n == 0 { return None } + let old = inner.strong.compare_and_swap(n, n + 1, SeqCst); + if old == n { return Some(Arc { _ptr: self._ptr }) } + } + } + + #[inline] + fn inner(&self) -> &ArcInner { + // See comments above for why this is "safe" + unsafe { &**self._ptr } + } +} + +#[unstable(feature = "alloc", + reason = "Weak pointers may not belong in this module.")] +impl Clone for Weak { + /// Makes a clone of the `Weak`. + /// + /// This increases the weak reference count. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// let weak_five = Arc::new(5).downgrade(); + /// + /// weak_five.clone(); + /// ``` + #[inline] + fn clone(&self) -> Weak { + // See comments in Arc::clone() for why this is relaxed + self.inner().weak.fetch_add(1, Relaxed); + Weak { _ptr: self._ptr } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Drop for Weak { + /// Drops the `Weak`. + /// + /// This will decrement the weak reference count. + /// + /// # Examples + /// + /// ``` + /// # #![feature(alloc)] + /// use std::sync::Arc; + /// + /// { + /// let five = Arc::new(5); + /// let weak_five = five.downgrade(); + /// + /// // stuff + /// + /// drop(weak_five); // explicit drop + /// } + /// { + /// let five = Arc::new(5); + /// let weak_five = five.downgrade(); + /// + /// // stuff + /// + /// } // implicit drop + /// ``` + fn drop(&mut self) { + let ptr = *self._ptr; + + // see comments above for why this check is here + if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { return } + + // If we find out that we were the last weak pointer, then its time to + // deallocate the data entirely. See the discussion in Arc::drop() about + // the memory orderings + if self.inner().weak.fetch_sub(1, Release) == 1 { + atomic::fence(Acquire); + unsafe { deallocate(ptr as *mut u8, size_of::>(), + min_align_of::>()) } + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialEq for Arc { + /// Equality for two `Arc`s. + /// + /// Two `Arc`s are equal if their inner value are equal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five == Arc::new(5); + /// ``` + fn eq(&self, other: &Arc) -> bool { *(*self) == *(*other) } + + /// Inequality for two `Arc`s. + /// + /// Two `Arc`s are unequal if their inner value are unequal. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five != Arc::new(5); + /// ``` + fn ne(&self, other: &Arc) -> bool { *(*self) != *(*other) } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl PartialOrd for Arc { + /// Partial comparison for two `Arc`s. + /// + /// The two are compared by calling `partial_cmp()` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five.partial_cmp(&Arc::new(5)); + /// ``` + fn partial_cmp(&self, other: &Arc) -> Option { + (**self).partial_cmp(&**other) + } + + /// Less-than comparison for two `Arc`s. + /// + /// The two are compared by calling `<` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five < Arc::new(5); + /// ``` + fn lt(&self, other: &Arc) -> bool { *(*self) < *(*other) } + + /// 'Less-than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `<=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five <= Arc::new(5); + /// ``` + fn le(&self, other: &Arc) -> bool { *(*self) <= *(*other) } + + /// Greater-than comparison for two `Arc`s. + /// + /// The two are compared by calling `>` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five > Arc::new(5); + /// ``` + fn gt(&self, other: &Arc) -> bool { *(*self) > *(*other) } + + /// 'Greater-than or equal to' comparison for two `Arc`s. + /// + /// The two are compared by calling `>=` on their inner values. + /// + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// + /// let five = Arc::new(5); + /// + /// five >= Arc::new(5); + /// ``` + fn ge(&self, other: &Arc) -> bool { *(*self) >= *(*other) } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Ord for Arc { + fn cmp(&self, other: &Arc) -> Ordering { (**self).cmp(&**other) } +} +#[stable(feature = "rust1", since = "1.0.0")] +impl Eq for Arc {} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Display for Arc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Display::fmt(&**self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Debug for Arc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&**self, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl fmt::Pointer for Arc { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&*self._ptr, f) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Default for Arc { + #[stable(feature = "rust1", since = "1.0.0")] + fn default() -> Arc { Arc::new(Default::default()) } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Hash for Arc { + fn hash(&self, state: &mut H) { + (**self).hash(state) + } +} diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 473429b813c50..45dcea909f44a 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -64,7 +64,7 @@ #![staged_api] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![doc(test(no_crate_inject))] @@ -112,7 +112,14 @@ pub mod boxed; mod boxed { pub use std::boxed::{Box, HEAP}; } #[cfg(test)] mod boxed_test; +#[cfg(not(stage0))] pub mod arc; +#[cfg(stage0)] +mod arc_stage0; +#[cfg(stage0)] +pub mod arc { + pub use arc_stage0::*; +} pub mod rc; /// Common out-of-memory routine diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index adfcca14d8d5a..5817cee24dc41 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -27,7 +27,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(alloc)] diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index bca0e1427e442..4f3c3b0826342 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -19,6 +19,8 @@ pub use self::TraversalItem::*; use core::prelude::*; use core::cmp::Ordering::{Greater, Less, Equal}; +#[cfg(not(stage0))] +use core::intrinsics::arith_offset; use core::iter::Zip; use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; @@ -205,6 +207,7 @@ impl RawItems { RawItems::from_parts(slice.as_ptr(), slice.len()) } + #[cfg(stage0)] unsafe fn from_parts(ptr: *const T, len: usize) -> RawItems { if mem::size_of::() == 0 { RawItems { @@ -219,6 +222,22 @@ impl RawItems { } } + #[cfg(not(stage0))] + unsafe fn from_parts(ptr: *const T, len: usize) -> RawItems { + if mem::size_of::() == 0 { + RawItems { + head: ptr, + tail: arith_offset(ptr as *const i8, len as isize) as *const T, + } + } else { + RawItems { + head: ptr, + tail: ptr.offset(len as isize), + } + } + } + + #[cfg(stage0)] unsafe fn push(&mut self, val: T) { ptr::write(self.tail as *mut T, val); @@ -228,11 +247,23 @@ impl RawItems { self.tail = self.tail.offset(1); } } + + #[cfg(not(stage0))] + unsafe fn push(&mut self, val: T) { + ptr::write(self.tail as *mut T, val); + + if mem::size_of::() == 0 { + self.tail = arith_offset(self.tail as *const i8, 1) as *const T; + } else { + self.tail = self.tail.offset(1); + } + } } impl Iterator for RawItems { type Item = T; + #[cfg(stage0)] fn next(&mut self) -> Option { if self.head == self.tail { None @@ -250,9 +281,29 @@ impl Iterator for RawItems { } } } + + #[cfg(not(stage0))] + fn next(&mut self) -> Option { + if self.head == self.tail { + None + } else { + unsafe { + let ret = Some(ptr::read(self.head)); + + if mem::size_of::() == 0 { + self.head = arith_offset(self.head as *const i8, 1) as *const T; + } else { + self.head = self.head.offset(1); + } + + ret + } + } + } } impl DoubleEndedIterator for RawItems { + #[cfg(stage0)] fn next_back(&mut self) -> Option { if self.head == self.tail { None @@ -268,6 +319,23 @@ impl DoubleEndedIterator for RawItems { } } } + + #[cfg(not(stage0))] + fn next_back(&mut self) -> Option { + if self.head == self.tail { + None + } else { + unsafe { + if mem::size_of::() == 0 { + self.tail = arith_offset(self.tail as *const i8, -1) as *const T; + } else { + self.tail = self.tail.offset(-1); + } + + Some(ptr::read(self.tail)) + } + } + } } impl Drop for RawItems { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index ecbe9369e781f..cfdb9053da183 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -19,7 +19,7 @@ #![staged_api] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![doc(test(no_crate_inject))] diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 28e476742911b..1f2443d977180 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -433,7 +433,7 @@ impl String { /// /// ``` /// let mut s = String::new(); - /// s.reserve(10); + /// s.reserve_exact(10); /// assert!(s.capacity() >= 10); /// ``` #[inline] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e35d81d3996b3..d3315758df04b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -66,6 +66,8 @@ use core::cmp::Ordering; use core::fmt; use core::hash::{self, Hash}; use core::intrinsics::assume; +#[cfg(not(stage0))] +use core::intrinsics::arith_offset; use core::iter::{repeat, FromIterator}; use core::marker::PhantomData; use core::mem; @@ -1527,6 +1529,7 @@ impl IntoIterator for Vec { /// } /// ``` #[inline] + #[cfg(stage0)] fn into_iter(self) -> IntoIter { unsafe { let ptr = *self.ptr; @@ -1542,6 +1545,24 @@ impl IntoIterator for Vec { IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end } } } + + #[inline] + #[cfg(not(stage0))] + fn into_iter(self) -> IntoIter { + unsafe { + let ptr = *self.ptr; + assume(!ptr.is_null()); + let cap = self.cap; + let begin = ptr as *const T; + let end = if mem::size_of::() == 0 { + arith_offset(ptr as *const i8, self.len() as isize) as *const T + } else { + ptr.offset(self.len() as isize) as *const T + }; + mem::forget(self); + IntoIter { allocation: ptr, cap: cap, ptr: begin, end: end } + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -1746,6 +1767,7 @@ impl Iterator for IntoIter { type Item = T; #[inline] + #[cfg(stage0)] fn next(&mut self) -> Option { unsafe { if self.ptr == self.end { @@ -1769,6 +1791,31 @@ impl Iterator for IntoIter { } } + #[inline] + #[cfg(not(stage0))] + fn next(&mut self) -> Option { + unsafe { + if self.ptr == self.end { + None + } else { + if mem::size_of::() == 0 { + // purposefully don't use 'ptr.offset' because for + // vectors with 0-size elements this would return the + // same pointer. + self.ptr = arith_offset(self.ptr as *const i8, 1) as *const T; + + // Use a non-null pointer value + Some(ptr::read(EMPTY as *mut T)) + } else { + let old = self.ptr; + self.ptr = self.ptr.offset(1); + + Some(ptr::read(old)) + } + } + } + } + #[inline] fn size_hint(&self) -> (usize, Option) { let diff = (self.end as usize) - (self.ptr as usize); @@ -1786,6 +1833,7 @@ impl Iterator for IntoIter { #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { #[inline] + #[cfg(stage0)] fn next_back(&mut self) -> Option { unsafe { if self.end == self.ptr { @@ -1805,6 +1853,28 @@ impl DoubleEndedIterator for IntoIter { } } } + + #[inline] + #[cfg(not(stage0))] + fn next_back(&mut self) -> Option { + unsafe { + if self.end == self.ptr { + None + } else { + if mem::size_of::() == 0 { + // See above for why 'ptr.offset' isn't used + self.end = arith_offset(self.end as *const i8, -1) as *const T; + + // Use a non-null pointer value + Some(ptr::read(EMPTY as *mut T)) + } else { + self.end = self.end.offset(-1); + + Some(ptr::read(mem::transmute(self.end))) + } + } + } + } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index d94b8884112d6..fa432e311eb74 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -283,6 +283,20 @@ extern "rust-intrinsic" { /// returned value will result in undefined behavior. pub fn offset(dst: *const T, offset: isize) -> *const T; + /// Calculates the offset from a pointer, potentially wrapping. + /// + /// This is implemented as an intrinsic to avoid converting to and from an + /// integer, since the conversion inhibits certain optimizations. + /// + /// # Safety + /// + /// Unlike the `offset` intrinsic, this intrinsic does not restrict the + /// resulting pointer to point into or one byte past the end of an allocated + /// object, and it wraps with two's complement arithmetic. The resulting + /// value is not necessarily valid to be used to actually access memory. + #[cfg(not(stage0))] + pub fn arith_offset(dst: *const T, offset: isize) -> *const T; + /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may *not* overlap. /// diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index dd06c3d0987d9..0794fb0c45dee 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -53,7 +53,7 @@ #![staged_api] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![doc(test(no_crate_inject))] diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 546e0bc806e12..cbac70921b7ee 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -124,6 +124,43 @@ pub trait SliceExt { fn clone_from_slice(&mut self, &[Self::Item]) -> usize where Self::Item: Clone; } +// Use macros to be generic over const/mut +#[cfg(stage0)] +macro_rules! slice_offset { + ($ptr:expr, $by:expr) => {{ + let ptr = $ptr; + if size_from_ptr(ptr) == 0 { + transmute((ptr as isize).wrapping_add($by)) + } else { + ptr.offset($by) + } + }}; +} + +#[cfg(not(stage0))] +macro_rules! slice_offset { + ($ptr:expr, $by:expr) => {{ + let ptr = $ptr; + if size_from_ptr(ptr) == 0 { + ::intrinsics::arith_offset(ptr as *mut i8, $by) as *mut _ + } else { + ptr.offset($by) + } + }}; +} + +macro_rules! slice_ref { + ($ptr:expr) => {{ + let ptr = $ptr; + if size_from_ptr(ptr) == 0 { + // Use a non-null pointer value + &mut *(1 as *mut _) + } else { + transmute(ptr) + } + }}; +} + #[unstable(feature = "core")] impl SliceExt for [T] { type Item = T; @@ -136,16 +173,18 @@ impl SliceExt for [T] { #[inline] fn iter<'a>(&'a self) -> Iter<'a, T> { unsafe { - let p = self.as_ptr(); - assume(!p.is_null()); - if mem::size_of::() == 0 { - Iter {ptr: p, - end: ((p as usize).wrapping_add(self.len())) as *const T, - _marker: marker::PhantomData} + let p = if mem::size_of::() == 0 { + 1 as *const _ } else { - Iter {ptr: p, - end: p.offset(self.len() as isize), - _marker: marker::PhantomData} + let p = self.as_ptr(); + assume(!p.is_null()); + p + }; + + Iter { + ptr: p, + end: slice_offset!(p, self.len() as isize), + _marker: marker::PhantomData } } } @@ -273,16 +312,18 @@ impl SliceExt for [T] { #[inline] fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { unsafe { - let p = self.as_mut_ptr(); - assume(!p.is_null()); - if mem::size_of::() == 0 { - IterMut {ptr: p, - end: ((p as usize).wrapping_add(self.len())) as *mut T, - _marker: marker::PhantomData} + let p = if mem::size_of::() == 0 { + 1 as *mut _ } else { - IterMut {ptr: p, - end: p.offset(self.len() as isize), - _marker: marker::PhantomData} + let p = self.as_mut_ptr(); + assume(!p.is_null()); + p + }; + + IterMut { + ptr: p, + end: slice_offset!(p, self.len() as isize), + _marker: marker::PhantomData } } } @@ -630,31 +671,6 @@ fn size_from_ptr(_: *const T) -> usize { mem::size_of::() } - -// Use macros to be generic over const/mut -macro_rules! slice_offset { - ($ptr:expr, $by:expr) => {{ - let ptr = $ptr; - if size_from_ptr(ptr) == 0 { - transmute((ptr as isize).wrapping_add($by)) - } else { - ptr.offset($by) - } - }}; -} - -macro_rules! slice_ref { - ($ptr:expr) => {{ - let ptr = $ptr; - if size_from_ptr(ptr) == 0 { - // Use a non-null pointer value - &mut *(1 as *mut _) - } else { - transmute(ptr) - } - }}; -} - // The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { (struct $name:ident -> $ptr:ty, $elem:ty) => { @@ -781,7 +797,7 @@ impl<'a, T> Iter<'a, T> { match self.as_slice().get(n) { Some(elem_ref) => unsafe { self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1)); - Some(slice_ref!(elem_ref)) + Some(elem_ref) }, None => { self.ptr = self.end; @@ -849,7 +865,7 @@ impl<'a, T> IterMut<'a, T> { match make_mut_slice!(self.ptr, self.end).get_mut(n) { Some(elem_ref) => unsafe { self.ptr = slice_offset!(self.ptr, (n as isize).wrapping_add(1)); - Some(slice_ref!(elem_ref)) + Some(elem_ref) }, None => { self.ptr = self.end; diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 1e0e2018050ba..606352ea14b22 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(libc)] diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index fa2ae79688d72..c2b28bd134d47 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 5782c57834eed..48649a3143464 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -85,7 +85,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 95b78e1cbfd03..35b5064bcbdfb 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -279,7 +279,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(collections)] #![feature(into_cow)] diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 69ab34fee5a1f..6e6d16f4e0fc2 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -18,7 +18,7 @@ #![cfg_attr(not(feature = "cargo-build"), staged_api)] #![cfg_attr(not(feature = "cargo-build"), no_std)] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![cfg_attr(test, feature(test))] diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index 4280a88f724a2..f2b4d15d42fa7 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -164,7 +164,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![deny(missing_docs)] diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 1359894b4dd72..7ade4ef1c4628 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -21,7 +21,7 @@ #![crate_name = "rand"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![no_std] diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs index b7938397038b4..23ce42626d948 100644 --- a/src/librbml/lib.rs +++ b/src/librbml/lib.rs @@ -119,7 +119,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 12d6fcd0303ec..2936b6b1c2b4f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(associated_consts)] diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 4bfc4c5b850fd..328972c54e377 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1866,7 +1866,7 @@ impl FakeExtCtxt for parse::ParseSess { #[cfg(test)] fn mk_ctxt() -> parse::ParseSess { - parse::new_parse_sess() + parse::ParseSess::new() } #[cfg(test)] diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index b999929c4af9e..48fe574e71f48 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -852,7 +852,7 @@ pub fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { parse::parse_meta_from_source_str("cfgspec".to_string(), s.to_string(), Vec::new(), - &parse::new_parse_sess()) + &parse::ParseSess::new()) }).collect::() } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 7a8ce1bf48e47..87634886009ef 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -64,7 +64,9 @@ pub struct Session { /// operations such as auto-dereference and monomorphization. pub recursion_limit: Cell, - pub can_print_warnings: bool + pub can_print_warnings: bool, + + next_node_id: Cell } impl Session { @@ -213,16 +215,23 @@ impl Session { lints.insert(id, vec!((lint_id, sp, msg))); } pub fn next_node_id(&self) -> ast::NodeId { - self.parse_sess.next_node_id() + self.reserve_node_ids(1) } pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { - self.parse_sess.reserve_node_ids(count) + let id = self.next_node_id.get(); + + match id.checked_add(count) { + Some(next) => self.next_node_id.set(next), + None => self.bug("Input too large, ran out of node ids!") + } + + id } pub fn diagnostic<'a>(&'a self) -> &'a diagnostic::SpanHandler { &self.parse_sess.span_diagnostic } pub fn codemap<'a>(&'a self) -> &'a codemap::CodeMap { - &self.parse_sess.span_diagnostic.cm + self.parse_sess.codemap() } // This exists to help with refactoring to eliminate impossible // cases later on @@ -359,9 +368,9 @@ pub fn build_session(sopts: config::Options, let codemap = codemap::CodeMap::new(); let diagnostic_handler = - diagnostic::default_handler(sopts.color, Some(registry), can_print_warnings); + diagnostic::Handler::new(sopts.color, Some(registry), can_print_warnings); let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); + diagnostic::SpanHandler::new(diagnostic_handler, codemap); build_session_(sopts, local_crate_source_file, span_diagnostic_handler) } @@ -378,7 +387,7 @@ pub fn build_session_(sopts: config::Options, } }; let target_cfg = config::build_target_config(&sopts, &span_diagnostic); - let p_s = parse::new_parse_sess_special_handler(span_diagnostic); + let p_s = parse::ParseSess::with_span_handler(span_diagnostic); let default_sysroot = match sopts.maybe_sysroot { Some(_) => None, None => Some(filesearch::get_or_default_sysroot()) @@ -421,7 +430,8 @@ pub fn build_session_(sopts: config::Options, delayed_span_bug: RefCell::new(None), features: RefCell::new(feature_gate::Features::new()), recursion_limit: Cell::new(64), - can_print_warnings: can_print_warnings + can_print_warnings: can_print_warnings, + next_node_id: Cell::new(1) }; sess diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs index 3e55f7f8045b5..7d46cc84fd685 100644 --- a/src/librustc_back/lib.rs +++ b/src/librustc_back/lib.rs @@ -29,7 +29,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(box_syntax)] diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index c5f1882fa1dd7..811d59d67485a 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -218,7 +218,7 @@ impl Target { // this is 1. ugly, 2. error prone. - let handler = diagnostic::default_handler(diagnostic::Auto, None, true); + let handler = diagnostic::Handler::new(diagnostic::Auto, None, true); let get_req_field = |name: &str| { match obj.find(name) diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index 50dc08e299a82..e96605fda333c 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -16,7 +16,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index a618f4b6ef675..5d3af83c898d8 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(box_syntax)] diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a8cf753317996..b53f2b1dcfa65 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -105,9 +105,9 @@ fn test_env(source_string: &str, let codemap = CodeMap::new(); let diagnostic_handler = - diagnostic::mk_handler(true, emitter); + diagnostic::Handler::with_emitter(true, emitter); let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); + diagnostic::SpanHandler::new(diagnostic_handler, codemap); let sess = session::build_session_(options, None, span_diagnostic_handler); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index df834c36e5b22..1343453d103ad 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -27,7 +27,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(box_patterns)] diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index 2a2aa2bf4cf93..4ba4399ae2d03 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(associated_consts)] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9a8bbc5ea0bc0..36d175fb59b62 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -16,7 +16,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 38ab0a8c5ed0d..1f8d23fd4dc0d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -16,7 +16,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(alloc)] @@ -2361,8 +2361,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "type name" }; - let msg = format!("use of undeclared {} `{}`", kind, - path_names_to_string(path, 0)); + let self_type_name = special_idents::type_self.name; + let is_invalid_self_type_name = + path.segments.len() > 0 && + maybe_qself.is_none() && + path.segments[0].identifier.name == self_type_name; + let msg = if is_invalid_self_type_name { + "use of `Self` outside of an impl or trait".to_string() + } else { + format!("use of undeclared {} `{}`", + kind, path_names_to_string(path, 0)) + }; + self.resolve_error(ty.span, &msg[..]); } } diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index a10ff71a8f689..a9e9e3f4048ac 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -21,7 +21,7 @@ use util::common::time; use util::common::path2cstr; use syntax::codemap; use syntax::diagnostic; -use syntax::diagnostic::{Emitter, Handler, Level, mk_handler}; +use syntax::diagnostic::{Emitter, Handler, Level}; use std::ffi::{CStr, CString}; use std::fs; @@ -928,7 +928,7 @@ fn run_work_multithreaded(sess: &Session, futures.push(rx); thread::Builder::new().name(format!("codegen-{}", i)).spawn(move || { - let diag_handler = mk_handler(true, box diag_emitter); + let diag_handler = Handler::with_emitter(true, box diag_emitter); // Must construct cgcx inside the proc because it has non-Send // fields. diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 3e2db80a9c556..e28681f1d6a60 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(alloc)] diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 951d30c4fb8db..4608918ec59bd 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -418,6 +418,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, let offset = llargs[1]; InBoundsGEP(bcx, ptr, &[offset]) } + (_, "arith_offset") => { + let ptr = llargs[0]; + let offset = llargs[1]; + GEP(bcx, ptr, &[offset]) + } (_, "copy_nonoverlapping") => { copy_intrinsic(bcx, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3cdbaec15284b..f13305bba343e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5009,7 +5009,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) { "type_name" => (1, Vec::new(), ty::mk_str_slice(tcx, tcx.mk_region(ty::ReStatic), ast::MutImmutable)), "type_id" => (1, Vec::new(), ccx.tcx.types.u64), - "offset" => { + "offset" | "arith_offset" => { (1, vec!( ty::mk_ptr(tcx, ty::mt { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index e50693ea804b6..baecaa2e221b9 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -70,7 +70,7 @@ This API is completely unstable and subject to change. #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![allow(non_camel_case_types)] diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs index edfa8db311f35..2f72b940e3283 100644 --- a/src/librustc_unicode/lib.rs +++ b/src/librustc_unicode/lib.rs @@ -29,7 +29,7 @@ #![staged_api] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![feature(no_std)] diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1b74123c4adcd..f7757b9fee753 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -110,9 +110,9 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, }; let codemap = codemap::CodeMap::new(); - let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None, true); + let diagnostic_handler = diagnostic::Handler::new(diagnostic::Auto, None, true); let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); + diagnostic::SpanHandler::new(diagnostic_handler, codemap); let sess = session::build_session_(sessopts, cpath, span_diagnostic_handler); diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index d19ccabed478e..e375ec3afc254 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -24,10 +24,8 @@ use syntax::parse; /// Highlights some source code, returning the HTML output. pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String { debug!("highlighting: ================\n{}\n==============", src); - let sess = parse::new_parse_sess(); - let fm = parse::string_to_filemap(&sess, - src.to_string(), - "".to_string()); + let sess = parse::ParseSess::new(); + let fm = sess.codemap().new_filemap("".to_string(), src.to_string()); let mut out = Vec::new(); doit(&sess, @@ -62,7 +60,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, loop { let next = lexer.next_token(); - let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap(); + let snip = |sp| sess.codemap().span_to_snippet(sp).unwrap(); if next.tok == token::Eof { break } @@ -178,7 +176,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, // as mentioned above, use the original source code instead of // stringifying this token - let snip = sess.span_diagnostic.cm.span_to_snippet(next.sp).unwrap(); + let snip = sess.codemap().span_to_snippet(next.sp).unwrap(); if klass == "" { try!(write!(out, "{}", Escape(&snip))); } else { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 9c393d6f89737..38cc120698431 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -16,7 +16,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f8c2626d09e31..8e2a3e6fcc3a1 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -65,9 +65,9 @@ pub fn run(input: &str, }; let codemap = CodeMap::new(); - let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None, true); + let diagnostic_handler = diagnostic::Handler::new(diagnostic::Auto, None, true); let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); + diagnostic::SpanHandler::new(diagnostic_handler, codemap); let sess = session::build_session_(sessopts, Some(input_path.clone()), @@ -184,7 +184,7 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, // it with a sink that is also passed to rustc itself. When this function // returns the output of the sink is copied onto the output of our own thread. // - // The basic idea is to not use a default_handler() for rustc, and then also + // The basic idea is to not use a default Handler for rustc, and then also // not print things by default to the actual stderr. struct Sink(Arc>>); impl Write for Sink { @@ -206,9 +206,9 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths, // Compile the code let codemap = CodeMap::new(); - let diagnostic_handler = diagnostic::mk_handler(true, box emitter); + let diagnostic_handler = diagnostic::Handler::with_emitter(true, box emitter); let span_diagnostic_handler = - diagnostic::mk_span_handler(diagnostic_handler, codemap); + diagnostic::SpanHandler::new(diagnostic_handler, codemap); let sess = session::build_session_(sessopts, None, diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 7f3633eb5bdda..31790ce6290fe 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -23,7 +23,7 @@ Core encoding and decoding interfaces. #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 48f65a5abfd45..a5fbc4374e0b9 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -539,7 +539,7 @@ impl HashMap { /// Creates an empty hashmap which will use the given hasher to hash keys. /// - /// The creates map has the default initial capacity. + /// The created map has the default initial capacity. /// /// # Examples /// diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 04513e9d048be..b83a8efe1d083 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -53,8 +53,7 @@ use vec::Vec; /// fn my_printer(s: *const libc::c_char); /// } /// -/// let to_print = &b"Hello, world!"[..]; -/// let c_to_print = CString::new(to_print).unwrap(); +/// let c_to_print = CString::new("Hello, world!").unwrap(); /// unsafe { /// my_printer(c_to_print.as_ptr()); /// } diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index fc5405ea7f69e..481d9e69abd53 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1099,20 +1099,19 @@ pub fn remove_dir_all>(path: P) -> io::Result<()> { /// # Examples /// /// ``` -/// # #![feature(path_ext)] /// use std::io; -/// use std::fs::{self, PathExt, DirEntry}; +/// use std::fs::{self, DirEntry}; /// use std::path::Path; /// /// // one possible implementation of fs::walk_dir only visiting files -/// fn visit_dirs(dir: &Path, cb: &mut FnMut(DirEntry)) -> io::Result<()> { -/// if dir.is_dir() { +/// fn visit_dirs(dir: &Path, cb: &Fn(&DirEntry)) -> io::Result<()> { +/// if try!(fs::metadata(dir)).is_dir() { /// for entry in try!(fs::read_dir(dir)) { /// let entry = try!(entry); -/// if entry.path().is_dir() { +/// if try!(fs::metadata(entry.path())).is_dir() { /// try!(visit_dirs(&entry.path(), cb)); /// } else { -/// cb(entry); +/// cb(&entry); /// } /// } /// } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 048af8eae1de2..1c6a02f1dcf6c 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -97,7 +97,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![doc(test(no_crate_inject, attr(deny(warnings))))] diff --git a/src/libstd/path.rs b/src/libstd/path.rs index 934b3156357d6..6732af556e0f1 100644 --- a/src/libstd/path.rs +++ b/src/libstd/path.rs @@ -1485,7 +1485,7 @@ impl Path { iter_after(self.components().rev(), child.as_ref().components().rev()).is_some() } - /// Extracts the stem (non-extension) portion of `self.file()`. + /// Extracts the stem (non-extension) portion of `self.file_name()`. /// /// The stem is: /// @@ -1508,7 +1508,7 @@ impl Path { self.file_name().map(split_file_at_dot).and_then(|(before, after)| before.or(after)) } - /// Extracts the extension of `self.file()`, if possible. + /// Extracts the extension of `self.file_name()`, if possible. /// /// The extension is: /// diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index c692babfacc44..b2a366ec5beb6 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -21,9 +21,11 @@ pub use self::MacroFormat::*; use std::cell::RefCell; use std::ops::{Add, Sub}; +use std::path::Path; use std::rc::Rc; -use std::fmt; +use std::{fmt, fs}; +use std::io::{self, Read}; use serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -527,6 +529,29 @@ impl FileMap { } } +/// An abstraction over the fs operations used by the Parser. +pub trait FileLoader { + /// Query the existence of a file. + fn file_exists(&self, path: &Path) -> bool; + + /// Read the contents of an UTF-8 file into memory. + fn read_file(&self, path: &Path) -> io::Result; +} + +/// A FileLoader that uses std::fs to load real files. +pub struct RealFileLoader; + +impl FileLoader for RealFileLoader { + fn file_exists(&self, path: &Path) -> bool { + fs::metadata(path).is_ok() + } + + fn read_file(&self, path: &Path) -> io::Result { + let mut src = String::new(); + try!(try!(fs::File::open(path)).read_to_string(&mut src)); + Ok(src) + } +} // _____________________________________________________________________________ // CodeMap @@ -534,7 +559,8 @@ impl FileMap { pub struct CodeMap { pub files: RefCell>>, - expansions: RefCell> + expansions: RefCell>, + file_loader: Box } impl CodeMap { @@ -542,9 +568,27 @@ impl CodeMap { CodeMap { files: RefCell::new(Vec::new()), expansions: RefCell::new(Vec::new()), + file_loader: Box::new(RealFileLoader) + } + } + + pub fn with_file_loader(file_loader: Box) -> CodeMap { + CodeMap { + files: RefCell::new(Vec::new()), + expansions: RefCell::new(Vec::new()), + file_loader: file_loader } } + pub fn file_exists(&self, path: &Path) -> bool { + self.file_loader.file_exists(path) + } + + pub fn load_file(&self, path: &Path) -> io::Result> { + let src = try!(self.file_loader.read_file(path)); + Ok(self.new_filemap(path.to_str().unwrap().to_string(), src)) + } + pub fn new_filemap(&self, filename: FileName, mut src: String) -> Rc { let mut files = self.files.borrow_mut(); let start_pos = match files.last() { diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 0097bab2fea4d..718bc1773fe59 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -122,6 +122,12 @@ pub struct SpanHandler { } impl SpanHandler { + pub fn new(handler: Handler, cm: codemap::CodeMap) -> SpanHandler { + SpanHandler { + handler: handler, + cm: cm, + } + } pub fn span_fatal(&self, sp: Span, msg: &str) -> FatalError { self.handler.emit(Some((&self.cm, sp)), msg, Fatal); return FatalError; @@ -187,6 +193,19 @@ pub struct Handler { } impl Handler { + pub fn new(color_config: ColorConfig, + registry: Option, + can_emit_warnings: bool) -> Handler { + let emitter = Box::new(EmitterWriter::stderr(color_config, registry)); + Handler::with_emitter(can_emit_warnings, emitter) + } + pub fn with_emitter(can_emit_warnings: bool, e: Box) -> Handler { + Handler { + err_count: Cell::new(0), + emit: RefCell::new(e), + can_emit_warnings: can_emit_warnings + } + } pub fn fatal(&self, msg: &str) -> ! { self.emit.borrow_mut().emit(None, msg, None, Fatal); panic!(FatalError); @@ -254,27 +273,6 @@ impl Handler { } } -pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler { - SpanHandler { - handler: handler, - cm: cm, - } -} - -pub fn default_handler(color_config: ColorConfig, - registry: Option, - can_emit_warnings: bool) -> Handler { - mk_handler(can_emit_warnings, Box::new(EmitterWriter::stderr(color_config, registry))) -} - -pub fn mk_handler(can_emit_warnings: bool, e: Box) -> Handler { - Handler { - err_count: Cell::new(0), - emit: RefCell::new(e), - can_emit_warnings: can_emit_warnings - } -} - #[derive(Copy, PartialEq, Clone, Debug)] pub enum Level { Bug, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 2ecefef51045e..2d3c2e8223aed 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -648,7 +648,7 @@ impl<'a> ExtCtxt<'a> { parse::tts_to_parser(self.parse_sess, tts.to_vec(), self.cfg()) } - pub fn codemap(&self) -> &'a CodeMap { &self.parse_sess.span_diagnostic.cm } + pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() } pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } pub fn cfg(&self) -> ast::CrateConfig { self.cfg.clone() } pub fn call_site(&self) -> Span { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index fae0b56ce3d0b..484684a87f4cd 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1684,7 +1684,7 @@ mod tests { #[test] fn macros_cant_escape_fns_test () { let src = "fn bogus() {macro_rules! z (() => (3+4));}\ fn inty() -> i32 { z!() }".to_string(); - let sess = parse::new_parse_sess(); + let sess = parse::ParseSess::new(); let crate_ast = parse::parse_crate_from_source_str( "".to_string(), src, @@ -1698,7 +1698,7 @@ mod tests { #[test] fn macros_cant_escape_mods_test () { let src = "mod foo {macro_rules! z (() => (3+4));}\ fn inty() -> i32 { z!() }".to_string(); - let sess = parse::new_parse_sess(); + let sess = parse::ParseSess::new(); let crate_ast = parse::parse_crate_from_source_str( "".to_string(), src, @@ -1710,7 +1710,7 @@ mod tests { #[test] fn macros_can_escape_flattened_mods_test () { let src = "#[macro_use] mod foo {macro_rules! z (() => (3+4));}\ fn inty() -> i32 { z!() }".to_string(); - let sess = parse::new_parse_sess(); + let sess = parse::ParseSess::new(); let crate_ast = parse::parse_crate_from_source_str( "".to_string(), src, @@ -1719,7 +1719,7 @@ mod tests { } fn expand_crate_str(crate_str: String) -> ast::Crate { - let ps = parse::new_parse_sess(); + let ps = parse::ParseSess::new(); let crate_ast = panictry!(string_to_parser(&ps, crate_str).parse_crate_mod()); // the cfg argument actually does matter, here... expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast) diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 330fe86deeb37..20f8c9707bfdd 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -22,7 +22,7 @@ #![crate_type = "dylib"] #![crate_type = "rlib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(associated_consts)] diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b70594a96a028..32b15066b5528 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -1412,8 +1412,8 @@ mod tests { fn mk_sh() -> diagnostic::SpanHandler { // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. let emitter = diagnostic::EmitterWriter::new(Box::new(io::sink()), None); - let handler = diagnostic::mk_handler(true, Box::new(emitter)); - diagnostic::mk_span_handler(handler, CodeMap::new()) + let handler = diagnostic::Handler::with_emitter(true, Box::new(emitter)); + diagnostic::SpanHandler::new(handler, CodeMap::new()) } // open a string reader for the given string diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 8c9ce5f78d482..68574560533fe 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -12,14 +12,13 @@ use ast; use codemap::{Span, CodeMap, FileMap}; -use diagnostic::{SpanHandler, mk_span_handler, default_handler, Auto, FatalError}; +use diagnostic::{SpanHandler, Handler, Auto, FatalError}; use parse::attr::ParserAttr; use parse::parser::Parser; use ptr::P; use str::char_at; -use std::cell::{Cell, RefCell}; -use std::fs::File; +use std::cell::RefCell; use std::io::Read; use std::iter; use std::path::{Path, PathBuf}; @@ -44,38 +43,23 @@ pub struct ParseSess { pub span_diagnostic: SpanHandler, // better be the same as the one in the reader! /// Used to determine and report recursive mod inclusions included_mod_stack: RefCell>, - pub node_id: Cell, -} - -pub fn new_parse_sess() -> ParseSess { - ParseSess { - span_diagnostic: mk_span_handler(default_handler(Auto, None, true), CodeMap::new()), - included_mod_stack: RefCell::new(Vec::new()), - node_id: Cell::new(1), - } -} - -pub fn new_parse_sess_special_handler(sh: SpanHandler) -> ParseSess { - ParseSess { - span_diagnostic: sh, - included_mod_stack: RefCell::new(Vec::new()), - node_id: Cell::new(1), - } } impl ParseSess { - pub fn next_node_id(&self) -> ast::NodeId { - self.reserve_node_ids(1) + pub fn new() -> ParseSess { + let handler = SpanHandler::new(Handler::new(Auto, None, true), CodeMap::new()); + ParseSess::with_span_handler(handler) } - pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { - let v = self.node_id.get(); - match v.checked_add(count) { - Some(next) => { self.node_id.set(next); } - None => panic!("Input too large, ran out of node ids!") + pub fn with_span_handler(sh: SpanHandler) -> ParseSess { + ParseSess { + span_diagnostic: sh, + included_mod_stack: RefCell::new(vec![]) } + } - v + pub fn codemap(&self) -> &CodeMap { + &self.span_diagnostic.cm } } @@ -189,7 +173,7 @@ pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String) -> Parser<'a> { - filemap_to_parser(sess, string_to_filemap(sess, source, name), cfg) + filemap_to_parser(sess, sess.codemap().new_filemap(name, source), cfg) } /// Create a new parser, handling errors as appropriate @@ -235,41 +219,20 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, /// Given a session and a path and an optional span (for error reporting), /// add the path to the session's codemap and return the new filemap. -pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) - -> Rc { - let err = |msg: &str| { - match spanopt { - Some(sp) => panic!(sess.span_diagnostic.span_fatal(sp, msg)), - None => sess.span_diagnostic.handler().fatal(msg), - } - }; - let mut bytes = Vec::new(); - match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) { - Ok(..) => {} +fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option) + -> Rc { + match sess.codemap().load_file(path) { + Ok(filemap) => filemap, Err(e) => { - err(&format!("couldn't read {:?}: {}", path.display(), e)); - unreachable!(); - } - }; - match str::from_utf8(&bytes[..]).ok() { - Some(s) => { - string_to_filemap(sess, s.to_string(), - path.to_str().unwrap().to_string()) - } - None => { - err(&format!("{:?} is not UTF-8 encoded", path.display())); - unreachable!(); + let msg = format!("couldn't read {:?}: {}", path.display(), e); + match spanopt { + Some(sp) => panic!(sess.span_diagnostic.span_fatal(sp, &msg)), + None => sess.span_diagnostic.handler().fatal(&msg) + } } } } -/// Given a session and a string, add the string to -/// the session's codemap and return the new filemap -pub fn string_to_filemap(sess: &ParseSess, source: String, path: String) - -> Rc { - sess.span_diagnostic.cm.new_filemap(path, source) -} - /// Given a filemap, produce a sequence of token-trees pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc) -> Vec { @@ -905,7 +868,7 @@ mod tests { } #[test] fn parse_ident_pat () { - let sess = new_parse_sess(); + let sess = ParseSess::new(); let mut parser = string_to_parser(&sess, "b".to_string()); assert!(panictry!(parser.parse_pat_nopanic()) == P(ast::Pat{ @@ -1086,7 +1049,7 @@ mod tests { } #[test] fn crlf_doc_comments() { - let sess = new_parse_sess(); + let sess = ParseSess::new(); let name = "".to_string(); let source = "/// doc comment\r\nfn foo() {}".to_string(); @@ -1109,7 +1072,7 @@ mod tests { #[test] fn ttdelim_span() { - let sess = parse::new_parse_sess(); + let sess = ParseSess::new(); let expr = parse::parse_expr_from_source_str("foo".to_string(), "foo!( fn main() { body } )".to_string(), vec![], &sess); @@ -1123,7 +1086,7 @@ mod tests { let span = tts.iter().rev().next().unwrap().get_span(); - match sess.span_diagnostic.cm.span_to_snippet(span) { + match sess.codemap().span_to_snippet(span) { Ok(s) => assert_eq!(&s[..], "{ body }"), Err(_) => panic!("could not get snippet"), } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b3b20f2d0ae6f..2b6f91bbc993a 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -79,7 +79,6 @@ use parse::PResult; use diagnostic::FatalError; use std::collections::HashSet; -use std::fs; use std::io::prelude::*; use std::mem; use std::path::{Path, PathBuf}; @@ -4840,8 +4839,7 @@ impl<'a> Parser<'a> { outer_attrs: &[ast::Attribute], id_sp: Span) -> PResult<(ast::Item_, Vec )> { - let mut prefix = PathBuf::from(&self.sess.span_diagnostic.cm - .span_to_filename(self.span)); + let mut prefix = PathBuf::from(&self.sess.codemap().span_to_filename(self.span)); prefix.pop(); let mut dir_path = prefix; for part in &self.mod_path_stack { @@ -4857,8 +4855,8 @@ impl<'a> Parser<'a> { let secondary_path_str = format!("{}/mod.rs", mod_name); let default_path = dir_path.join(&default_path_str[..]); let secondary_path = dir_path.join(&secondary_path_str[..]); - let default_exists = fs::metadata(&default_path).is_ok(); - let secondary_exists = fs::metadata(&secondary_path).is_ok(); + let default_exists = self.sess.codemap().file_exists(&default_path); + let secondary_exists = self.sess.codemap().file_exists(&secondary_path); if !self.owns_directory { self.span_err(id_sp, diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index a3cfb647853d2..458e3f7f0bd9b 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -301,7 +301,7 @@ fn ignored_span(cx: &TestCtxt, sp: Span) -> Span { allow_internal_unstable: true, } }; - let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info); + let expn_id = cx.sess.codemap().record_expansion(info); let mut sp = sp; sp.expn_id = expn_id; return sp; diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 929f2a6abd6b8..6e6e2d181b9ef 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -9,8 +9,7 @@ // except according to those terms. use ast; -use parse::new_parse_sess; -use parse::{ParseSess,string_to_filemap,filemap_to_tts}; +use parse::{ParseSess,filemap_to_tts}; use parse::new_parser_from_source_str; use parse::parser::Parser; use parse::token; @@ -19,9 +18,8 @@ use str::char_at; /// Map a string to tts, using a made-up filename: pub fn string_to_tts(source_str: String) -> Vec { - let ps = new_parse_sess(); - filemap_to_tts(&ps, - string_to_filemap(&ps, source_str, "bogofile".to_string())) + let ps = ParseSess::new(); + filemap_to_tts(&ps, ps.codemap().new_filemap("bogofile".to_string(), source_str)) } /// Map string to parser (via tts) @@ -35,7 +33,7 @@ pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> fn with_error_checking_parse(s: String, f: F) -> T where F: FnOnce(&mut Parser) -> T, { - let ps = new_parse_sess(); + let ps = ParseSess::new(); let mut p = string_to_parser(&ps, s); let x = f(&mut p); p.abort_if_errors(); @@ -75,7 +73,7 @@ pub fn string_to_stmt(source_str : String) -> P { pub fn string_to_pat(source_str: String) -> P { // Binding `sess` and `parser` works around dropck-injected // region-inference issues; see #25212, #22323, #22321. - let sess = new_parse_sess(); + let sess = ParseSess::new(); let mut parser = string_to_parser(&sess, source_str); parser.parse_pat() } diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index 74ec3406f73bc..ec1426e6e48ce 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -50,7 +50,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![deny(missing_docs)] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index b16154861530d..575f29b3bc97f 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -31,7 +31,7 @@ #![crate_type = "rlib"] #![crate_type = "dylib"] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "http://www.rust-lang.org/favicon.ico", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] #![feature(asm)] diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs index cf68efe5855b7..c83a154056ba2 100644 --- a/src/test/compile-fail-fulldeps/qquote.rs +++ b/src/test/compile-fail-fulldeps/qquote.rs @@ -20,7 +20,7 @@ use syntax::parse; use syntax::print::pprust; fn main() { - let ps = syntax::parse::new_parse_sess(); + let ps = syntax::parse::ParseSess::new(); let mut cx = syntax::ext::base::ExtCtxt::new( &ps, vec![], syntax::ext::expand::ExpansionConfig::default("qquote".to_string())); diff --git a/src/test/compile-fail/gated-associated_consts.rs b/src/test/compile-fail/gated-associated_consts.rs index 21672b18bde44..cfa75ff9763e9 100644 --- a/src/test/compile-fail/gated-associated_consts.rs +++ b/src/test/compile-fail/gated-associated_consts.rs @@ -11,7 +11,6 @@ trait MyTrait { const C: bool; //~^ associated constants are experimental - //~| add #![feature(associated_consts)] to the crate attributes to enable } struct Foo; @@ -19,5 +18,4 @@ struct Foo; impl Foo { const C: bool = true; //~^ associated constants are experimental - //~| add #![feature(associated_consts)] to the crate attributes to enable } diff --git a/src/test/compile-fail/issue-12796.rs b/src/test/compile-fail/issue-12796.rs index ce3c8c52b0e47..2249741cdaac5 100644 --- a/src/test/compile-fail/issue-12796.rs +++ b/src/test/compile-fail/issue-12796.rs @@ -12,7 +12,7 @@ trait Trait { fn outer(self) { fn inner(_: Self) { //~^ ERROR can't use type parameters from outer function - //~^^ ERROR use of undeclared type name `Self` + //~^^ ERROR use of `Self` outside of an impl or trait } } } diff --git a/src/test/compile-fail/issue-24968.rs b/src/test/compile-fail/issue-24968.rs new file mode 100644 index 0000000000000..f51b77b0ee539 --- /dev/null +++ b/src/test/compile-fail/issue-24968.rs @@ -0,0 +1,15 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(_: Self) { + //~^ ERROR use of `Self` outside of an impl or trait +} + +fn main() {} diff --git a/src/test/compile-fail/not-utf8.rs b/src/test/compile-fail/not-utf8.rs index 1b323edd589e1..5331062d9b68d 100644 --- a/src/test/compile-fail/not-utf8.rs +++ b/src/test/compile-fail/not-utf8.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: is not UTF-8 +// error-pattern: did not contain valid UTF-8 fn foo() { include!("not-utf8.bin") diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs index 6ae22392b939e..4251579bbdcd1 100644 --- a/src/test/run-fail-fulldeps/qquote.rs +++ b/src/test/run-fail-fulldeps/qquote.rs @@ -22,7 +22,7 @@ use syntax::parse; use syntax::print::pprust; fn main() { - let ps = syntax::parse::new_parse_sess(); + let ps = syntax::parse::ParseSess::new(); let mut cx = syntax::ext::base::ExtCtxt::new( &ps, vec![], syntax::ext::expand::ExpansionConfig::default("qquote".to_string())); diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index ceface384847f..6670f200ba71e 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -18,7 +18,7 @@ use syntax::codemap::DUMMY_SP; use syntax::print::pprust::*; fn main() { - let ps = syntax::parse::new_parse_sess(); + let ps = syntax::parse::ParseSess::new(); let mut cx = syntax::ext::base::ExtCtxt::new( &ps, vec![], syntax::ext::expand::ExpansionConfig::default("qquote".to_string())); diff --git a/src/test/run-pass/issue18173.rs b/src/test/run-pass/issue18173.rs new file mode 100644 index 0000000000000..f4266fada32fc --- /dev/null +++ b/src/test/run-pass/issue18173.rs @@ -0,0 +1,21 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +trait Foo { + type T; +} + +// should be able to use a trait with an associated type without specifying it as an argument +trait Bar { + fn bar(foo: &F); +} + +pub fn main() { +}