Auto merge of - Manishearth:rollup, r=Manishearth

- Successful merges: , , , , , , , 
- Failed merges:
This commit is contained in:
bors 2016-02-03 00:58:37 +00:00
commit a9922419cf
10 changed files with 210 additions and 18 deletions
src
doc/book
etc
libcore
librustc_typeck
librustdoc/html
libstd
libsyntax
test/run-pass

@ -276,7 +276,7 @@ its called on, and if it isnt a successful one, [`panic!`][panic]s with a
message you passed it. A `panic!` like this will cause our program to crash,
displaying the message.
[expect]: ../std/option/enum.Option.html#method.expect
[expect]: ../std/result/enum.Result.html#method.expect
[panic]: error-handling.html
If we leave off calling this method, our program will compile, but

@ -173,7 +173,39 @@ let (x, _, z) = coordinate();
Here, we bind the first and last element of the tuple to `x` and `z`, but
ignore the middle element.
Similarly, you can use `..` in a pattern to disregard multiple values.
Its worth noting that using `_` never binds the value in the first place,
which means a value may not move:
```rust
let tuple: (u32, String) = (5, String::from("five"));
// Here, tuple is moved, because the String moved:
let (x, _s) = tuple;
// The next line would give "error: use of partially moved value: `tuple`"
// println!("Tuple is: {:?}", tuple);
// However,
let tuple = (5, String::from("five"));
// Here, tuple is _not_ moved, as the String was never moved, and u32 is Copy:
let (x, _) = tuple;
// That means this works:
println!("Tuple is: {:?}", tuple);
```
This also means that any temporary variables will be dropped at the end of the
statement:
```rust
// Here, the String created will be dropped immediately, as its not bound:
let _ = String::from(" hello ").trim();
```
You can also use `..` in a pattern to disregard multiple values:
```rust
enum OptionalTuple {

@ -114,7 +114,7 @@ if len(errcode_not_found) > 0:
if errcode in errcode_checked:
continue
all_errors.append(errcode)
print("error: unused error code: " + errcode)
print("error: unused error code: {0} ({1}:{2})".format(*errcode_map[errcode][0]))
errors = True

@ -1050,6 +1050,30 @@ pub trait Iterator {
/// // got a false, take_while() isn't used any more
/// assert_eq!(iter.next(), None);
/// ```
///
/// Because `take_while()` needs to look at the value in order to see if it
/// should be included or not, consuming iterators will see that it is
/// removed:
///
/// ```
/// let a = [1, 2, 3, 4];
/// let mut iter = a.into_iter();
///
/// let result: Vec<i32> = iter.by_ref()
/// .take_while(|n| **n != 3)
/// .cloned()
/// .collect();
///
/// assert_eq!(result, &[1, 2]);
///
/// let result: Vec<i32> = iter.cloned().collect();
///
/// assert_eq!(result, &[4]);
/// ```
///
/// The `3` is no longer there, because it was consumed in order to see if
/// the iteration should stop, but wasn't placed back into the iterator or
/// some similar thing.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
@ -3258,6 +3282,49 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
///
/// [`map()`]: trait.Iterator.html#method.map
/// [`Iterator`]: trait.Iterator.html
///
/// # Notes about side effects
///
/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that
/// you can also [`map()`] backwards:
///
/// ```rust
/// let v: Vec<i32> = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect();
///
/// assert_eq!(v, [4, 3, 2]);
/// ```
///
/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
///
/// But if your closure has state, iterating backwards may act in a way you do
/// not expect. Let's go through an example. First, in the forward direction:
///
/// ```rust
/// let mut c = 0;
///
/// for pair in vec!['a', 'b', 'c'].into_iter()
/// .map(|letter| { c += 1; (letter, c) }) {
/// println!("{:?}", pair);
/// }
/// ```
///
/// This will print "('a', 1), ('b', 2), ('c', 3)".
///
/// Now consider this twist where we add a call to `rev`. This version will
/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
/// but the values of the counter still go in order. This is because `map()` is
/// still being called lazilly on each item, but we are popping items off the
/// back of the vector now, instead of shifting them from the front.
///
/// ```rust
/// let mut c = 0;
///
/// for pair in vec!['a', 'b', 'c'].into_iter()
/// .map(|letter| { c += 1; (letter, c) })
/// .rev() {
/// println!("{:?}", pair);
/// }
/// ```
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]

@ -209,9 +209,12 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
return;
}
_ => {
span_err!(self.tcx.sess, item.span, E0118,
"no base type found for inherent implementation; \
implement a trait or new type instead");
struct_span_err!(self.tcx.sess, item.span, E0118,
"no base type found for inherent implementation")
.span_help(item.span,
"either implement a trait on it or create a newtype to wrap it \
instead")
.emit();
return;
}
}

@ -1489,22 +1489,46 @@ For information on the design of the orphan rules, see [RFC 1023].
"##,
E0118: r##"
Rust can't find a base type for an implementation you are providing, or the type
cannot have an implementation. For example, only a named type or a trait can
have an implementation:
You're trying to write an inherent implementation for something which isn't a
struct nor an enum. Erroneous code example:
```
type NineString = [char, ..9] // This isn't a named type (struct, enum or trait)
impl NineString {
// Some code here
impl (u8, u8) { // error: no base type found for inherent implementation
fn get_state(&self) -> String {
// ...
}
}
```
In the other, simpler case, Rust just can't find the type you are providing an
impelementation for:
To fix this error, please implement a trait on the type or wrap it in a struct.
Example:
```
impl SomeTypeThatDoesntExist { }
// we create a trait here
trait LiveLongAndProsper {
fn get_state(&self) -> String;
}
// and now you can implement it on (u8, u8)
impl LiveLongAndProsper for (u8, u8) {
fn get_state(&self) -> String {
"He's dead, Jim!".to_owned()
}
}
```
Alternatively, you can create a newtype. A newtype is a wrapping tuple-struct.
For example, `NewType` is a newtype over `Foo` in `struct NewType(Foo)`.
Example:
```
struct TypeWrapper((u8, u8));
impl TypeWrapper {
fn get_state(&self) -> String {
"Fascinating!".to_owned()
}
}
```
"##,

@ -54,10 +54,12 @@ use externalfiles::ExternalHtml;
use serialize::json::{self, ToJson};
use syntax::{abi, ast};
use syntax::feature_gate::UnstableFeatures;
use rustc::middle::cstore::LOCAL_CRATE;
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::middle::privacy::AccessLevels;
use rustc::middle::stability;
use rustc::session::config::get_unstable_features_setting;
use rustc_front::hir;
use clean::{self, SelfTy};
@ -1897,10 +1899,14 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
f: &clean::Function) -> fmt::Result {
let vis_constness = match get_unstable_features_setting() {
UnstableFeatures::Allow => f.constness,
_ => hir::Constness::NotConst
};
try!(write!(w, "<pre class='rust fn'>{vis}{constness}{unsafety}{abi}fn \
{name}{generics}{decl}{where_clause}</pre>",
vis = VisSpace(it.visibility),
constness = ConstnessSpace(f.constness),
constness = ConstnessSpace(vis_constness),
unsafety = UnsafetySpace(f.unsafety),
abi = AbiSpace(f.abi),
name = it.name.as_ref().unwrap(),
@ -2122,9 +2128,13 @@ fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
}
};
let vis_constness = match get_unstable_features_setting() {
UnstableFeatures::Allow => constness,
_ => hir::Constness::NotConst
};
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
{generics}{decl}{where_clause}",
ConstnessSpace(constness),
ConstnessSpace(vis_constness),
UnsafetySpace(unsafety),
match abi {
Abi::Rust => String::new(),

@ -365,6 +365,9 @@ pub mod builtin {
/// stringification of all the tokens passed to the macro. No restrictions
/// are placed on the syntax of the macro invocation itself.
///
/// Note that the expanded results of the input tokens may change in the
/// future. You should be careful if you rely on the output.
///
/// # Examples
///
/// ```

@ -1174,6 +1174,20 @@ impl TokenTree {
}
(&TokenTree::Token(sp, token::DocComment(name)), _) => {
let stripped = strip_doc_comment_decoration(&name.as_str());
// Searches for the occurrences of `"#*` and returns the minimum number of `#`s
// required to wrap the text.
let num_of_hashes = stripped.chars().scan(0, |cnt, x| {
*cnt = if x == '"' {
1
} else if *cnt != 0 && x == '#' {
*cnt + 1
} else {
0
};
Some(*cnt)
}).max().unwrap_or(0);
TokenTree::Delimited(sp, Rc::new(Delimited {
delim: token::Bracket,
open_span: sp,
@ -1181,7 +1195,7 @@ impl TokenTree {
token::Plain)),
TokenTree::Token(sp, token::Eq),
TokenTree::Token(sp, token::Literal(
token::StrRaw(token::intern(&stripped), 0), None))],
token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
close_span: sp,
}))
}

@ -0,0 +1,39 @@
// 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.
// The number of `#`s used to wrap the documentation comment should differ regarding the content.
//
// Related issue: #27489
macro_rules! homura {
($x:expr, #[$y:meta]) => (assert_eq!($x, stringify!($y)))
}
fn main() {
homura! {
r#"doc = r" Madoka""#,
/// Madoka
};
homura! {
r##"doc = r#" One quote mark: ["]"#"##,
/// One quote mark: ["]
};
homura! {
r##"doc = r#" Two quote marks: [""]"#"##,
/// Two quote marks: [""]
};
homura! {
r#####"doc = r####" Raw string ending sequences: ["###]"####"#####,
/// Raw string ending sequences: ["###]
};
}