Skip to content

Commit a992241

Browse files
committed
Auto merge of #31370 - Manishearth:rollup, r=Manishearth
- Successful merges: #27499, #31220, #31329, #31332, #31347, #31351, #31352, #31366 - Failed merges:
2 parents dea183a + 1a21dab commit a992241

File tree

10 files changed

+210
-18
lines changed

10 files changed

+210
-18
lines changed

src/doc/book/guessing-game.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ it’s called on, and if it isn’t a successful one, [`panic!`][panic]s with a
276276
message you passed it. A `panic!` like this will cause our program to crash,
277277
displaying the message.
278278

279-
[expect]: ../std/option/enum.Option.html#method.expect
279+
[expect]: ../std/result/enum.Result.html#method.expect
280280
[panic]: error-handling.html
281281

282282
If we leave off calling this method, our program will compile, but

src/doc/book/patterns.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,39 @@ let (x, _, z) = coordinate();
173173
Here, we bind the first and last element of the tuple to `x` and `z`, but
174174
ignore the middle element.
175175

176-
Similarly, you can use `..` in a pattern to disregard multiple values.
176+
It’s worth noting that using `_` never binds the value in the first place,
177+
which means a value may not move:
178+
179+
```rust
180+
let tuple: (u32, String) = (5, String::from("five"));
181+
182+
// Here, tuple is moved, because the String moved:
183+
let (x, _s) = tuple;
184+
185+
// The next line would give "error: use of partially moved value: `tuple`"
186+
// println!("Tuple is: {:?}", tuple);
187+
188+
// However,
189+
190+
let tuple = (5, String::from("five"));
191+
192+
// Here, tuple is _not_ moved, as the String was never moved, and u32 is Copy:
193+
let (x, _) = tuple;
194+
195+
// That means this works:
196+
println!("Tuple is: {:?}", tuple);
197+
```
198+
199+
This also means that any temporary variables will be dropped at the end of the
200+
statement:
201+
202+
```rust
203+
// Here, the String created will be dropped immediately, as it’s not bound:
204+
205+
let _ = String::from(" hello ").trim();
206+
```
207+
208+
You can also use `..` in a pattern to disregard multiple values:
177209

178210
```rust
179211
enum OptionalTuple {

src/etc/errorck.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def check_unused_error_codes(error_codes, check_error_codes, filenames, dirnames
114114
if errcode in errcode_checked:
115115
continue
116116
all_errors.append(errcode)
117-
print("error: unused error code: " + errcode)
117+
print("error: unused error code: {0} ({1}:{2})".format(*errcode_map[errcode][0]))
118118
errors = True
119119

120120

src/libcore/iter.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,30 @@ pub trait Iterator {
10501050
/// // got a false, take_while() isn't used any more
10511051
/// assert_eq!(iter.next(), None);
10521052
/// ```
1053+
///
1054+
/// Because `take_while()` needs to look at the value in order to see if it
1055+
/// should be included or not, consuming iterators will see that it is
1056+
/// removed:
1057+
///
1058+
/// ```
1059+
/// let a = [1, 2, 3, 4];
1060+
/// let mut iter = a.into_iter();
1061+
///
1062+
/// let result: Vec<i32> = iter.by_ref()
1063+
/// .take_while(|n| **n != 3)
1064+
/// .cloned()
1065+
/// .collect();
1066+
///
1067+
/// assert_eq!(result, &[1, 2]);
1068+
///
1069+
/// let result: Vec<i32> = iter.cloned().collect();
1070+
///
1071+
/// assert_eq!(result, &[4]);
1072+
/// ```
1073+
///
1074+
/// The `3` is no longer there, because it was consumed in order to see if
1075+
/// the iteration should stop, but wasn't placed back into the iterator or
1076+
/// some similar thing.
10531077
#[inline]
10541078
#[stable(feature = "rust1", since = "1.0.0")]
10551079
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
@@ -3258,6 +3282,49 @@ impl<A, B> DoubleEndedIterator for Zip<A, B> where
32583282
///
32593283
/// [`map()`]: trait.Iterator.html#method.map
32603284
/// [`Iterator`]: trait.Iterator.html
3285+
///
3286+
/// # Notes about side effects
3287+
///
3288+
/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that
3289+
/// you can also [`map()`] backwards:
3290+
///
3291+
/// ```rust
3292+
/// let v: Vec<i32> = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect();
3293+
///
3294+
/// assert_eq!(v, [4, 3, 2]);
3295+
/// ```
3296+
///
3297+
/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html
3298+
///
3299+
/// But if your closure has state, iterating backwards may act in a way you do
3300+
/// not expect. Let's go through an example. First, in the forward direction:
3301+
///
3302+
/// ```rust
3303+
/// let mut c = 0;
3304+
///
3305+
/// for pair in vec!['a', 'b', 'c'].into_iter()
3306+
/// .map(|letter| { c += 1; (letter, c) }) {
3307+
/// println!("{:?}", pair);
3308+
/// }
3309+
/// ```
3310+
///
3311+
/// This will print "('a', 1), ('b', 2), ('c', 3)".
3312+
///
3313+
/// Now consider this twist where we add a call to `rev`. This version will
3314+
/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed,
3315+
/// but the values of the counter still go in order. This is because `map()` is
3316+
/// still being called lazilly on each item, but we are popping items off the
3317+
/// back of the vector now, instead of shifting them from the front.
3318+
///
3319+
/// ```rust
3320+
/// let mut c = 0;
3321+
///
3322+
/// for pair in vec!['a', 'b', 'c'].into_iter()
3323+
/// .map(|letter| { c += 1; (letter, c) })
3324+
/// .rev() {
3325+
/// println!("{:?}", pair);
3326+
/// }
3327+
/// ```
32613328
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
32623329
#[stable(feature = "rust1", since = "1.0.0")]
32633330
#[derive(Clone)]

src/librustc_typeck/coherence/orphan.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,9 +209,12 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
209209
return;
210210
}
211211
_ => {
212-
span_err!(self.tcx.sess, item.span, E0118,
213-
"no base type found for inherent implementation; \
214-
implement a trait or new type instead");
212+
struct_span_err!(self.tcx.sess, item.span, E0118,
213+
"no base type found for inherent implementation")
214+
.span_help(item.span,
215+
"either implement a trait on it or create a newtype to wrap it \
216+
instead")
217+
.emit();
215218
return;
216219
}
217220
}

src/librustc_typeck/diagnostics.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,22 +1489,46 @@ For information on the design of the orphan rules, see [RFC 1023].
14891489
"##,
14901490

14911491
E0118: r##"
1492-
Rust can't find a base type for an implementation you are providing, or the type
1493-
cannot have an implementation. For example, only a named type or a trait can
1494-
have an implementation:
1492+
You're trying to write an inherent implementation for something which isn't a
1493+
struct nor an enum. Erroneous code example:
14951494
14961495
```
1497-
type NineString = [char, ..9] // This isn't a named type (struct, enum or trait)
1498-
impl NineString {
1499-
// Some code here
1496+
impl (u8, u8) { // error: no base type found for inherent implementation
1497+
fn get_state(&self) -> String {
1498+
// ...
1499+
}
1500+
}
1501+
```
1502+
1503+
To fix this error, please implement a trait on the type or wrap it in a struct.
1504+
Example:
1505+
1506+
```
1507+
// we create a trait here
1508+
trait LiveLongAndProsper {
1509+
fn get_state(&self) -> String;
1510+
}
1511+
1512+
// and now you can implement it on (u8, u8)
1513+
impl LiveLongAndProsper for (u8, u8) {
1514+
fn get_state(&self) -> String {
1515+
"He's dead, Jim!".to_owned()
1516+
}
15001517
}
15011518
```
15021519
1503-
In the other, simpler case, Rust just can't find the type you are providing an
1504-
impelementation for:
1520+
Alternatively, you can create a newtype. A newtype is a wrapping tuple-struct.
1521+
For example, `NewType` is a newtype over `Foo` in `struct NewType(Foo)`.
1522+
Example:
15051523
15061524
```
1507-
impl SomeTypeThatDoesntExist { }
1525+
struct TypeWrapper((u8, u8));
1526+
1527+
impl TypeWrapper {
1528+
fn get_state(&self) -> String {
1529+
"Fascinating!".to_owned()
1530+
}
1531+
}
15081532
```
15091533
"##,
15101534

src/librustdoc/html/render.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ use externalfiles::ExternalHtml;
5454

5555
use serialize::json::{self, ToJson};
5656
use syntax::{abi, ast};
57+
use syntax::feature_gate::UnstableFeatures;
5758
use rustc::middle::cstore::LOCAL_CRATE;
5859
use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
5960
use rustc::middle::privacy::AccessLevels;
6061
use rustc::middle::stability;
62+
use rustc::session::config::get_unstable_features_setting;
6163
use rustc_front::hir;
6264

6365
use clean::{self, SelfTy};
@@ -1897,10 +1899,14 @@ fn item_static(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
18971899

18981900
fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
18991901
f: &clean::Function) -> fmt::Result {
1902+
let vis_constness = match get_unstable_features_setting() {
1903+
UnstableFeatures::Allow => f.constness,
1904+
_ => hir::Constness::NotConst
1905+
};
19001906
try!(write!(w, "<pre class='rust fn'>{vis}{constness}{unsafety}{abi}fn \
19011907
{name}{generics}{decl}{where_clause}</pre>",
19021908
vis = VisSpace(it.visibility),
1903-
constness = ConstnessSpace(f.constness),
1909+
constness = ConstnessSpace(vis_constness),
19041910
unsafety = UnsafetySpace(f.unsafety),
19051911
abi = AbiSpace(f.abi),
19061912
name = it.name.as_ref().unwrap(),
@@ -2122,9 +2128,13 @@ fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item,
21222128
href(did).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
21232129
}
21242130
};
2131+
let vis_constness = match get_unstable_features_setting() {
2132+
UnstableFeatures::Allow => constness,
2133+
_ => hir::Constness::NotConst
2134+
};
21252135
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
21262136
{generics}{decl}{where_clause}",
2127-
ConstnessSpace(constness),
2137+
ConstnessSpace(vis_constness),
21282138
UnsafetySpace(unsafety),
21292139
match abi {
21302140
Abi::Rust => String::new(),

src/libstd/macros.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,9 @@ pub mod builtin {
365365
/// stringification of all the tokens passed to the macro. No restrictions
366366
/// are placed on the syntax of the macro invocation itself.
367367
///
368+
/// Note that the expanded results of the input tokens may change in the
369+
/// future. You should be careful if you rely on the output.
370+
///
368371
/// # Examples
369372
///
370373
/// ```

src/libsyntax/ast.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1174,14 +1174,28 @@ impl TokenTree {
11741174
}
11751175
(&TokenTree::Token(sp, token::DocComment(name)), _) => {
11761176
let stripped = strip_doc_comment_decoration(&name.as_str());
1177+
1178+
// Searches for the occurrences of `"#*` and returns the minimum number of `#`s
1179+
// required to wrap the text.
1180+
let num_of_hashes = stripped.chars().scan(0, |cnt, x| {
1181+
*cnt = if x == '"' {
1182+
1
1183+
} else if *cnt != 0 && x == '#' {
1184+
*cnt + 1
1185+
} else {
1186+
0
1187+
};
1188+
Some(*cnt)
1189+
}).max().unwrap_or(0);
1190+
11771191
TokenTree::Delimited(sp, Rc::new(Delimited {
11781192
delim: token::Bracket,
11791193
open_span: sp,
11801194
tts: vec![TokenTree::Token(sp, token::Ident(token::str_to_ident("doc"),
11811195
token::Plain)),
11821196
TokenTree::Token(sp, token::Eq),
11831197
TokenTree::Token(sp, token::Literal(
1184-
token::StrRaw(token::intern(&stripped), 0), None))],
1198+
token::StrRaw(token::intern(&stripped), num_of_hashes), None))],
11851199
close_span: sp,
11861200
}))
11871201
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// The number of `#`s used to wrap the documentation comment should differ regarding the content.
12+
//
13+
// Related issue: #27489
14+
15+
macro_rules! homura {
16+
($x:expr, #[$y:meta]) => (assert_eq!($x, stringify!($y)))
17+
}
18+
19+
fn main() {
20+
homura! {
21+
r#"doc = r" Madoka""#,
22+
/// Madoka
23+
};
24+
25+
homura! {
26+
r##"doc = r#" One quote mark: ["]"#"##,
27+
/// One quote mark: ["]
28+
};
29+
30+
homura! {
31+
r##"doc = r#" Two quote marks: [""]"#"##,
32+
/// Two quote marks: [""]
33+
};
34+
35+
homura! {
36+
r#####"doc = r####" Raw string ending sequences: ["###]"####"#####,
37+
/// Raw string ending sequences: ["###]
38+
};
39+
}

0 commit comments

Comments
 (0)