diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/doc/index.md | 49 | ||||
| -rw-r--r-- | src/doc/nomicon/other-reprs.md | 3 | ||||
| -rw-r--r-- | src/doc/trpl/references-and-borrowing.md | 7 | ||||
| -rwxr-xr-x[-rw-r--r--] | src/etc/add-authors.sh | 4 | ||||
| -rw-r--r-- | src/liballoc/arc.rs | 16 | ||||
| -rw-r--r-- | src/liballoc/boxed.rs | 8 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 16 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 10 | ||||
| -rw-r--r-- | src/librustc_resolve/diagnostics.rs | 9 | ||||
| -rw-r--r-- | src/libstd/sync/mutex.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 25 | ||||
| -rw-r--r-- | src/test/run-pass/env-funky-keys.rs | 45 | ||||
| -rw-r--r-- | src/test/run-pass/env-vars.rs | 5 |
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); } } |
