about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/index.md49
-rw-r--r--src/doc/nomicon/other-reprs.md3
-rw-r--r--src/doc/trpl/references-and-borrowing.md7
-rwxr-xr-x[-rw-r--r--]src/etc/add-authors.sh4
-rw-r--r--src/liballoc/arc.rs16
-rw-r--r--src/liballoc/boxed.rs8
-rw-r--r--src/liballoc/rc.rs16
-rw-r--r--src/libcore/num/mod.rs10
-rw-r--r--src/librustc_resolve/diagnostics.rs9
-rw-r--r--src/libstd/sync/mutex.rs2
-rw-r--r--src/libstd/sys/unix/os.rs25
-rw-r--r--src/test/run-pass/env-funky-keys.rs45
-rw-r--r--src/test/run-pass/env-vars.rs5
13 files changed, 137 insertions, 62 deletions
diff --git a/src/doc/index.md b/src/doc/index.md
index 992b6eef5e8..5f2ef610729 100644
--- a/src/doc/index.md
+++ b/src/doc/index.md
@@ -14,9 +14,8 @@ concepts. Upon completing the book, you'll be an intermediate Rust
 developer, and will have a good grasp of the fundamental ideas behind
 Rust.
 
-[Rust By Example][rbe] was originally a community resource, but was then
-donated to the Rust project. As the name implies, it teaches you Rust through a
-series of small examples.
+[Rust By Example][rbe] teaches you Rust through a series of small
+examples.
 
 [rbe]: http://rustbyexample.com/
 
@@ -32,49 +31,21 @@ library](std/index.html). There's a list of crates on the left with more
 specific sections, or you can use the search bar at the top to search for
 something if you know its name.
 
+# The Rustonomicon
+
+[The Rustonomicon] is an entire book dedicated to explaining
+how to write `unsafe` Rust code. It is for advanced Rust programmers.
+
+[The Rustonomicon]: nomicon/index.html
+
 # Tools
 
-[Cargo](https://crates.io) is the Rust's package manager providing access to libraries
+[Cargo](http://doc.crates.io/index.html) is the Rust package manager providing access to libraries
 beyond the standard one, and its website contains lots of good documentation.
 
 [`rustdoc`](book/documentation.html) is the Rust's documentation generator, a tool converting
 annotated source code into HTML docs.
 
-A bunch of non-official tools are available, such as [Racer](https://github.com/phildawes/racer)
-(code completion engine), or [rustfmt](https://github.com/nrc/rustfmt) (source code formatter),
-or text editor plugins.
-
-# Community & Getting Help
-
-If you need help with something, or just want to talk about Rust with others,
-there are a few places you can do that:
-
-The Rust IRC channels on [irc.mozilla.org](irc://irc.mozilla.org/) are the
-fastest way to get help.
-[`#rust`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust) is
-the general discussion channel, and you'll find people willing to help you with
-any questions you may have.
-
-There are also three specialty channels:
-[`#rust-gamedev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-gamedev)
-and
-[`#rust-osdev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-osdev)
-are for game development and operating system development, respectively.
-There's also
-[`#rust-internals`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals), which is for discussion of the development of Rust itself.
-
-You can also get help on [Stack
-Overflow](https://stackoverflow.com/questions/tagged/rust). Searching for your
-problem might reveal someone who has asked it before!
-
-There is an active [subreddit](https://reddit.com/r/rust) with lots of
-discussion and news about Rust.
-
-There is also a [user forum](https://users.rust-lang.org), for all
-user-oriented discussion, and a [developer
-forum](https://internals.rust-lang.org/), where the development of Rust
-itself is discussed.
-
 # FAQs
 
 There are questions that are asked quite often, so we've made FAQs for them:
diff --git a/src/doc/nomicon/other-reprs.md b/src/doc/nomicon/other-reprs.md
index e361fbb7ae8..2639c1d4d6f 100644
--- a/src/doc/nomicon/other-reprs.md
+++ b/src/doc/nomicon/other-reprs.md
@@ -26,6 +26,9 @@ still consumes a byte of space.
 * DSTs, tuples, and tagged unions are not a concept in C and as such are never
 FFI safe.
 
+* Tuple structs are like structs with regards to `repr(C)`, as the only
+  difference from a struct is that the fields aren’t named.
+
 * **If the type would have any [drop flags], they will still be added**
 
 * This is equivalent to one of `repr(u*)` (see the next section) for enums. The
diff --git a/src/doc/trpl/references-and-borrowing.md b/src/doc/trpl/references-and-borrowing.md
index 944417d1096..d8758e0c695 100644
--- a/src/doc/trpl/references-and-borrowing.md
+++ b/src/doc/trpl/references-and-borrowing.md
@@ -171,9 +171,9 @@ to the definition of a data race:
 > operations are not synchronized.
 
 With references, you may have as many as you’d like, since none of them are
-writing. If you are writing, you need two or more pointers to the same memory,
-and you can only have one `&mut` at a time. This is how Rust prevents data
-races at compile time: we’ll get errors if we break the rules.
+writing. However, as we can only have one `&mut` at a time, it is impossible to
+have a data race. This is how Rust prevents data races at compile time: we’ll
+get errors if we break the rules.
 
 With this in mind, let’s consider our example again.
 
@@ -378,3 +378,4 @@ statement 1 at 3:14
 
 In the above example, `y` is declared before `x`, meaning that `y` lives longer
 than `x`, which is not allowed.
+
diff --git a/src/etc/add-authors.sh b/src/etc/add-authors.sh
index 3ae0ec73957..e45b803fa07 100644..100755
--- a/src/etc/add-authors.sh
+++ b/src/etc/add-authors.sh
@@ -30,8 +30,8 @@ range="$1"
 authors_file="./AUTHORS.txt"
 tmp_file="./AUTHORS.txt.tmp"
 old_authors="$(cat "$authors_file" | tail -n +2 | sed "/^$/d" | sort)"
-new_authors="$(git log "$range" --format="%aN <%aE>" | sort | uniq)"
+new_authors="$(git log "$range" --use-mailmap --format="%aN <%aE>" | sort | uniq)"
 
 printf "%s\n\n" "Rust was written by these fine people:" > "$tmp_file"
-printf "%s\n%s" "$old_authors" "$new_authors" | sort | uniq >> "$tmp_file"
+printf "%s\n%s" "$old_authors" "$new_authors" | sort -fs | uniq >> "$tmp_file"
 mv -f "$tmp_file" "$authors_file"
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 34c8b5d4139..8205e13205f 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -87,6 +87,7 @@ use core::ptr::{self, Shared};
 use core::marker::Unsize;
 use core::hash::{Hash, Hasher};
 use core::{usize, isize};
+use core::convert::From;
 use heap::deallocate;
 
 const MAX_REFCOUNT: usize = (isize::MAX) as usize;
@@ -896,6 +897,13 @@ impl<T: ?Sized + Hash> Hash for Arc<T> {
     }
 }
 
+#[stable(feature = "from_for_ptrs", since = "1.6.0")]
+impl<T> From<T> for Arc<T> {
+    fn from(t: T) -> Self {
+        Arc::new(t)
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use std::clone::Clone;
@@ -910,6 +918,7 @@ mod tests {
     use std::vec::Vec;
     use super::{Arc, Weak};
     use std::sync::Mutex;
+    use std::convert::From;
 
     struct Canary(*mut atomic::AtomicUsize);
 
@@ -1139,6 +1148,13 @@ mod tests {
         drop(x);
         assert!(y.upgrade().is_none());
     }
+
+    #[test]
+    fn test_from_owned() {
+        let foo = 123;
+        let foo_arc = Arc::from(foo);
+        assert!(123 == *foo_arc);
+    }
 }
 
 impl<T: ?Sized> borrow::Borrow<T> for Arc<T> {
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 2e4ac13b34d..b5c6cdff119 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -67,6 +67,7 @@ use core::ops::{CoerceUnsized, Deref, DerefMut};
 use core::ops::{Placer, Boxed, Place, InPlace, BoxPlace};
 use core::ptr::{self, Unique};
 use core::raw::TraitObject;
+use core::convert::From;
 
 /// A value that represents the heap. This is the default place that the `box`
 /// keyword allocates into when no place is supplied.
@@ -373,6 +374,13 @@ impl<T: ?Sized + Hash> Hash for Box<T> {
     }
 }
 
+#[stable(feature = "from_for_ptrs", since = "1.6.0")]
+impl<T> From<T> for Box<T> {
+    fn from(t: T) -> Self {
+        Box::new(t)
+    }
+}
+
 impl Box<Any> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index b94e74ada9c..88db3cfe4b6 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -169,6 +169,7 @@ use core::ops::Deref;
 #[cfg(not(stage0))]
 use core::ops::CoerceUnsized;
 use core::ptr::{self, Shared};
+use core::convert::From;
 
 use heap::deallocate;
 
@@ -701,6 +702,13 @@ impl<T> fmt::Pointer for Rc<T> {
     }
 }
 
+#[stable(feature = "from_for_ptrs", since = "1.6.0")]
+impl<T> From<T> for Rc<T> {
+    fn from(t: T) -> Self {
+        Rc::new(t)
+    }
+}
+
 /// A weak version of `Rc<T>`.
 ///
 /// Weak references do not count when determining if the inner value should be
@@ -906,6 +914,7 @@ mod tests {
     use std::result::Result::{Err, Ok};
     use std::mem::drop;
     use std::clone::Clone;
+    use std::convert::From;
 
     #[test]
     fn test_clone() {
@@ -1108,6 +1117,13 @@ mod tests {
         let foo: Rc<[i32]> = Rc::new([1, 2, 3]);
         assert_eq!(foo, foo.clone());
     }
+
+    #[test]
+    fn test_from_owned() {
+        let foo = 123;
+        let foo_rc = Rc::from(foo);
+        assert!(123 == *foo_rc);
+    }
 }
 
 impl<T: ?Sized> borrow::Borrow<T> for Rc<T> {
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 3afc89c9841..c0f65fea7db 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -124,15 +124,15 @@ macro_rules! int_impl {
         /// Returns the smallest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn min_value() -> Self {
+        pub const fn min_value() -> Self {
             (-1 as Self) << ($BITS - 1)
         }
 
         /// Returns the largest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn max_value() -> Self {
-            let min = Self::min_value(); !min
+        pub const fn max_value() -> Self {
+            !Self::min_value()
         }
 
         /// Converts a string slice in a given base to an integer.
@@ -891,12 +891,12 @@ macro_rules! uint_impl {
         /// Returns the smallest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn min_value() -> Self { 0 }
+        pub const fn min_value() -> Self { 0 }
 
         /// Returns the largest value that can be represented by this integer type.
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
-        pub fn max_value() -> Self { !0 }
+        pub const fn max_value() -> Self { !0 }
 
         /// Converts a string slice in a given base to an integer.
         ///
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index a6665a13786..f35b554d6cf 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -806,6 +806,15 @@ mod something {
     pub struct Foo;
 }
 ```
+
+Or, if you tried to use a module from an external crate, you may have missed
+the `extern crate` declaration:
+
+```
+extern crate homura; // Required to use the `homura` crate
+
+use homura::Madoka;
+```
 "##,
 
 E0433: r##"
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index c0cd6d127d2..48631bfc5f9 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -66,7 +66,7 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// for _ in 0..10 {
 ///     let (data, tx) = (data.clone(), tx.clone());
 ///     thread::spawn(move || {
-///         // The shared static can only be accessed once the lock is held.
+///         // The shared state can only be accessed once the lock is held.
 ///         // Our non-atomic increment is safe because we're the only thread
 ///         // which can access the shared state when the lock is held.
 ///         //
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 3c53db53f85..5bc5567df2f 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -386,24 +386,33 @@ pub fn env() -> Env {
     let _g = ENV_LOCK.lock();
     return unsafe {
         let mut environ = *environ();
-        if environ as usize == 0 {
+        if environ == ptr::null() {
             panic!("os::env() failure getting env string from OS: {}",
                    io::Error::last_os_error());
         }
         let mut result = Vec::new();
         while *environ != ptr::null() {
-            result.push(parse(CStr::from_ptr(*environ).to_bytes()));
+            if let Some(key_value) = parse(CStr::from_ptr(*environ).to_bytes()) {
+                result.push(key_value);
+            }
             environ = environ.offset(1);
         }
         Env { iter: result.into_iter(), _dont_send_or_sync_me: ptr::null_mut() }
     };
 
-    fn parse(input: &[u8]) -> (OsString, OsString) {
-        let mut it = input.splitn(2, |b| *b == b'=');
-        let key = it.next().unwrap().to_vec();
-        let default: &[u8] = &[];
-        let val = it.next().unwrap_or(default).to_vec();
-        (OsStringExt::from_vec(key), OsStringExt::from_vec(val))
+    fn parse(input: &[u8]) -> Option<(OsString, OsString)> {
+        // Strategy (copied from glibc): Variable name and value are separated
+        // by an ASCII equals sign '='. Since a variable name must not be
+        // empty, allow variable names starting with an equals sign. Skip all
+        // malformed lines.
+        if input.is_empty() {
+            return None;
+        }
+        let pos = input[1..].iter().position(|&b| b == b'=').map(|p| p + 1);
+        pos.map(|p| (
+            OsStringExt::from_vec(input[..p].to_vec()),
+            OsStringExt::from_vec(input[p+1..].to_vec()),
+        ))
     }
 }
 
diff --git a/src/test/run-pass/env-funky-keys.rs b/src/test/run-pass/env-funky-keys.rs
new file mode 100644
index 00000000000..3ee20980747
--- /dev/null
+++ b/src/test/run-pass/env-funky-keys.rs
@@ -0,0 +1,45 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Ignore this test on Android, because it segfaults there.
+
+// ignore-android
+// ignore-windows
+// no-prefer-dynamic
+
+#![feature(convert)]
+#![feature(libc)]
+
+extern crate libc;
+
+use libc::c_char;
+use libc::execve;
+use std::env;
+use std::ffi::OsStr;
+use std::ptr;
+
+fn main() {
+    if env::args_os().next().is_none() {
+        for (key, value) in env::vars_os() {
+            panic!("found env value {:?} {:?}", key, value);
+        }
+        return;
+    }
+
+    let current_exe = env::current_exe().unwrap().into_os_string().to_cstring().unwrap();
+    let new_env_var = OsStr::new("FOOBAR").to_cstring().unwrap();
+    let filename: *const c_char = current_exe.as_ptr();
+    let argv: &[*const c_char] = &[ptr::null()];
+    let envp: &[*const c_char] = &[new_env_var.as_ptr(), ptr::null()];
+    unsafe {
+        execve(filename, &argv[0], &envp[0]);
+    }
+    panic!("execve failed");
+}
diff --git a/src/test/run-pass/env-vars.rs b/src/test/run-pass/env-vars.rs
index d86f63c9cb9..933d9a728db 100644
--- a/src/test/run-pass/env-vars.rs
+++ b/src/test/run-pass/env-vars.rs
@@ -14,10 +14,7 @@ use std::env::*;
 fn main() {
     for (k, v) in vars_os() {
         let v2 = var_os(&k);
-        // MingW seems to set some funky environment variables like
-        // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
-        // from vars() but not visible from var().
-        assert!(v2.is_none() || v2.as_ref().map(|s| &**s) == Some(&*v),
+        assert!(v2.as_ref().map(|s| &**s) == Some(&*v),
                 "bad vars->var transition: {:?} {:?} {:?}", k, v, v2);
     }
 }