Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 85a5d3f

Browse files
committedSep 23, 2017
Auto merge of #44784 - frewsxcv:rollup, r=frewsxcv
Rollup of 14 pull requests - Successful merges: #44554, #44648, #44658, #44712, #44717, #44726, #44745, #44746, #44749, #44759, #44770, #44773, #44776, #44778 - Failed merges:
2 parents 9ad67e9 + 2aa42ef commit 85a5d3f

File tree

19 files changed

+309
-58
lines changed

19 files changed

+309
-58
lines changed
 

‎CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ For people new to Rust, and just starting to contribute, or even for
461461
more seasoned developers, some useful places to look for information
462462
are:
463463

464+
* [Rust Forge][rustforge] contains additional documentation, including write-ups of how to achieve common tasks
464465
* The [Rust Internals forum][rif], a place to ask questions and
465466
discuss Rust's internals
466467
* The [generated documentation for rust's compiler][gdfrustc]
@@ -476,6 +477,7 @@ are:
476477
[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
477478
[rif]: http://internals.rust-lang.org
478479
[rr]: https://doc.rust-lang.org/book/README.html
480+
[rustforge]: https://forge.rust-lang.org/
479481
[tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
480482
[ro]: http://www.rustaceans.org/
481483
[rctd]: ./src/test/COMPILER_TESTS.md

‎src/liballoc/arc.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,13 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
7272
/// first: after all, isn't the point of `Arc<T>` thread safety? The key is
7373
/// this: `Arc<T>` makes it thread safe to have multiple ownership of the same
7474
/// data, but it doesn't add thread safety to its data. Consider
75-
/// `Arc<RefCell<T>>`. `RefCell<T>` isn't [`Sync`], and if `Arc<T>` was always
76-
/// [`Send`], `Arc<RefCell<T>>` would be as well. But then we'd have a problem:
77-
/// `RefCell<T>` is not thread safe; it keeps track of the borrowing count using
75+
/// `Arc<`[`RefCell<T>`]`>`. [`RefCell<T>`] isn't [`Sync`], and if `Arc<T>` was always
76+
/// [`Send`], `Arc<`[`RefCell<T>`]`>` would be as well. But then we'd have a problem:
77+
/// [`RefCell<T>`] is not thread safe; it keeps track of the borrowing count using
7878
/// non-atomic operations.
7979
///
8080
/// In the end, this means that you may need to pair `Arc<T>` with some sort of
81-
/// `std::sync` type, usually `Mutex<T>`.
81+
/// [`std::sync`] type, usually [`Mutex<T>`][mutex].
8282
///
8383
/// ## Breaking cycles with `Weak`
8484
///
@@ -106,7 +106,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
106106
/// // a and b both point to the same memory location as foo.
107107
/// ```
108108
///
109-
/// The `Arc::clone(&from)` syntax is the most idiomatic because it conveys more explicitly
109+
/// The [`Arc::clone(&from)`] syntax is the most idiomatic because it conveys more explicitly
110110
/// the meaning of the code. In the example above, this syntax makes it easier to see that
111111
/// this code is creating a new reference rather than copying the whole content of foo.
112112
///
@@ -141,6 +141,9 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
141141
/// [upgrade]: struct.Weak.html#method.upgrade
142142
/// [`None`]: ../../std/option/enum.Option.html#variant.None
143143
/// [assoc]: ../../book/first-edition/method-syntax.html#associated-functions
144+
/// [`RefCell<T>`]: ../../std/cell/struct.RefCell.html
145+
/// [`std::sync`]: ../../std/sync/index.html
146+
/// [`Arc::clone(&from)`]: #method.clone
144147
///
145148
/// # Examples
146149
///

‎src/libcore/fmt/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1700,8 +1700,18 @@ impl<T: ?Sized + Debug> Debug for RefCell<T> {
17001700
.finish()
17011701
}
17021702
Err(_) => {
1703+
// The RefCell is mutably borrowed so we can't look at its value
1704+
// here. Show a placeholder instead.
1705+
struct BorrowedPlaceholder;
1706+
1707+
impl Debug for BorrowedPlaceholder {
1708+
fn fmt(&self, f: &mut Formatter) -> Result {
1709+
f.write_str("<borrowed>")
1710+
}
1711+
}
1712+
17031713
f.debug_struct("RefCell")
1704-
.field("value", &"<borrowed>")
1714+
.field("value", &BorrowedPlaceholder)
17051715
.finish()
17061716
}
17071717
}

‎src/libcore/mem.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,15 +177,59 @@ pub fn forget<T>(t: T) {
177177

178178
/// Returns the size of a type in bytes.
179179
///
180-
/// More specifically, this is the offset in bytes between successive
181-
/// items of the same type, including alignment padding.
180+
/// More specifically, this is the offset in bytes between successive elements
181+
/// in an array with that item type including alignment padding. Thus, for any
182+
/// type `T` and length `n`, `[T; n]` has a size of `n * size_of::<T>()`.
183+
///
184+
/// In general, the size of a type is not stable across compilations, but
185+
/// specific types such as primitives are.
186+
///
187+
/// The following table gives the size for primitives.
188+
///
189+
/// Type | size_of::\<Type>()
190+
/// ---- | ---------------
191+
/// () | 0
192+
/// u8 | 1
193+
/// u16 | 2
194+
/// u32 | 4
195+
/// u64 | 8
196+
/// i8 | 1
197+
/// i16 | 2
198+
/// i32 | 4
199+
/// i64 | 8
200+
/// f32 | 4
201+
/// f64 | 8
202+
/// char | 4
203+
///
204+
/// Furthermore, `usize` and `isize` have the same size.
205+
///
206+
/// The types `*const T`, `&T`, `Box<T>`, `Option<&T>`, and `Option<Box<T>>` all have
207+
/// the same size. If `T` is Sized, all of those types have the same size as `usize`.
208+
///
209+
/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
210+
/// have the same size. Likewise for `*const T` and `*mut T`.
182211
///
183212
/// # Examples
184213
///
185214
/// ```
186215
/// use std::mem;
187216
///
217+
/// // Some primitives
188218
/// assert_eq!(4, mem::size_of::<i32>());
219+
/// assert_eq!(8, mem::size_of::<f64>());
220+
/// assert_eq!(0, mem::size_of::<()>());
221+
///
222+
/// // Some arrays
223+
/// assert_eq!(8, mem::size_of::<[i32; 2]>());
224+
/// assert_eq!(12, mem::size_of::<[i32; 3]>());
225+
/// assert_eq!(0, mem::size_of::<[i32; 0]>());
226+
///
227+
///
228+
/// // Pointer size equality
229+
/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>());
230+
/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>());
231+
/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
232+
/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
189233
/// ```
190234
#[inline]
191235
#[stable(feature = "rust1", since = "1.0.0")]

‎src/libcore/str/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,9 +1399,6 @@ Section: Comparing strings
13991399
*/
14001400

14011401
/// Bytewise slice equality
1402-
/// NOTE: This function is (ab)used in rustc::middle::trans::_match
1403-
/// to compare &[u8] byte slices that are not necessarily valid UTF-8.
1404-
#[lang = "str_eq"]
14051402
#[inline]
14061403
fn eq_slice(a: &str, b: &str) -> bool {
14071404
a.as_bytes() == b.as_bytes()

‎src/librustc/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ incremental improves that may change.)
3737

3838
The dependency structure of these crates is roughly a diamond:
3939

40-
````
40+
```
4141
rustc_driver
4242
/ | \
4343
/ | \

‎src/librustc/hir/lowering.rs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
6565
use syntax::std_inject;
6666
use syntax::symbol::{Symbol, keywords};
6767
use syntax::tokenstream::{TokenStream, TokenTree, Delimited};
68-
use syntax::parse::token::{Token, DelimToken};
68+
use syntax::parse::token::Token;
6969
use syntax::util::small_vector::SmallVector;
7070
use syntax::visit::{self, Visitor};
7171
use syntax_pos::Span;
@@ -606,10 +606,12 @@ impl<'a> LoweringContext<'a> {
606606
}
607607

608608
fn lower_token_stream(&mut self, tokens: TokenStream) -> TokenStream {
609-
tokens.into_trees().map(|tree| self.lower_token_tree(tree)).collect()
609+
tokens.into_trees()
610+
.flat_map(|tree| self.lower_token_tree(tree).into_trees())
611+
.collect()
610612
}
611613

612-
fn lower_token_tree(&mut self, tree: TokenTree) -> TokenTree {
614+
fn lower_token_tree(&mut self, tree: TokenTree) -> TokenStream {
613615
match tree {
614616
TokenTree::Token(span, token) => {
615617
self.lower_token(token, span)
@@ -618,23 +620,19 @@ impl<'a> LoweringContext<'a> {
618620
TokenTree::Delimited(span, Delimited {
619621
delim: delimited.delim,
620622
tts: self.lower_token_stream(delimited.tts.into()).into(),
621-
})
623+
}).into()
622624
}
623625
}
624626
}
625627

626-
fn lower_token(&mut self, token: Token, span: Span) -> TokenTree {
628+
fn lower_token(&mut self, token: Token, span: Span) -> TokenStream {
627629
match token {
628630
Token::Interpolated(_) => {}
629-
other => return TokenTree::Token(span, other),
631+
other => return TokenTree::Token(span, other).into(),
630632
}
631633

632634
let tts = token.interpolated_to_tokenstream(&self.sess.parse_sess, span);
633-
let tts = self.lower_token_stream(tts);
634-
TokenTree::Delimited(span, Delimited {
635-
delim: DelimToken::NoDelim,
636-
tts: tts.into(),
637-
})
635+
self.lower_token_stream(tts)
638636
}
639637

640638
fn lower_arm(&mut self, arm: &Arm) -> hir::Arm {

‎src/librustc/middle/lang_items.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,8 +280,6 @@ language_item_table! {
280280
EqTraitLangItem, "eq", eq_trait;
281281
OrdTraitLangItem, "ord", ord_trait;
282282

283-
StrEqFnLangItem, "str_eq", str_eq_fn;
284-
285283
// A number of panic-related lang items. The `panic` item corresponds to
286284
// divide-by-zero and various panic cases with `match`. The
287285
// `panic_bounds_check` item is for indexing arrays.

‎src/librustc/session/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,8 @@ impl Session {
411411
}
412412
pub fn emit_end_regions(&self) -> bool {
413413
self.opts.debugging_opts.emit_end_regions ||
414-
(self.opts.debugging_opts.mir_emit_validate > 0)
414+
(self.opts.debugging_opts.mir_emit_validate > 0) ||
415+
self.opts.debugging_opts.borrowck_mir
415416
}
416417
pub fn lto(&self) -> bool {
417418
self.opts.cg.lto

‎src/librustc_mir/borrow_check.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
419419
self.each_borrow_involving_path(
420420
context, lvalue_span.0, flow_state, |this, _idx, borrow| {
421421
if !borrow.compatible_with(BorrowKind::Shared) {
422-
this.report_use_while_mutably_borrowed(context, lvalue_span);
422+
this.report_use_while_mutably_borrowed(context, lvalue_span, borrow);
423423
Control::Break
424424
} else {
425425
Control::Continue
@@ -914,11 +914,17 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
914914

915915
fn report_use_while_mutably_borrowed(&mut self,
916916
_context: Context,
917-
(lvalue, span): (&Lvalue, Span)) {
917+
(lvalue, span): (&Lvalue, Span),
918+
borrow : &BorrowData) {
919+
let described_lvalue = self.describe_lvalue(lvalue);
920+
let borrow_span = self.retrieve_borrow_span(borrow);
921+
918922
let mut err = self.tcx.cannot_use_when_mutably_borrowed(
919-
span, &self.describe_lvalue(lvalue), Origin::Mir);
920-
// FIXME 1: add span_label for "borrow of `()` occurs here"
921-
// FIXME 2: add span_label for "use of `{}` occurs here"
923+
span, &described_lvalue, Origin::Mir);
924+
925+
err.span_label(borrow_span, format!("borrow of `{}` occurs here", described_lvalue));
926+
err.span_label(span, format!("use of borrowed `{}`", described_lvalue));
927+
922928
err.emit();
923929
}
924930

@@ -998,7 +1004,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
9981004
ProjectionElem::Downcast(..) =>
9991005
("", format!(""), None), // (dont emit downcast info)
10001006
ProjectionElem::Field(field, _ty) =>
1001-
("", format!(".{}", field.index()), None),
1007+
("", format!(".{}", field.index()), None), // FIXME: report name of field
10021008
ProjectionElem::Index(index) =>
10031009
("", format!(""), Some(index)),
10041010
ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
@@ -1024,6 +1030,13 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
10241030
}
10251031
}
10261032
}
1033+
1034+
// Retrieve span of given borrow from the current MIR representation
1035+
fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span {
1036+
self.mir.basic_blocks()[borrow.location.block]
1037+
.statements[borrow.location.statement_index]
1038+
.source_info.span
1039+
}
10271040
}
10281041

10291042
impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx> {

‎src/librustdoc/html/render.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2621,7 +2621,8 @@ fn render_assoc_item(w: &mut fmt::Formatter,
26212621
href(did).map(|p| format!("{}#{}.{}", p.0, ty, name)).unwrap_or(anchor)
26222622
}
26232623
};
2624-
let mut head_len = format!("{}{}{:#}fn {}{:#}",
2624+
let mut head_len = format!("{}{}{}{:#}fn {}{:#}",
2625+
VisSpace(&meth.visibility),
26252626
ConstnessSpace(constness),
26262627
UnsafetySpace(unsafety),
26272628
AbiSpace(abi),
@@ -2633,8 +2634,9 @@ fn render_assoc_item(w: &mut fmt::Formatter,
26332634
} else {
26342635
(0, true)
26352636
};
2636-
write!(w, "{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
2637+
write!(w, "{}{}{}{}fn <a href='{href}' class='fnname'>{name}</a>\
26372638
{generics}{decl}{where_clause}",
2639+
VisSpace(&meth.visibility),
26382640
ConstnessSpace(constness),
26392641
UnsafetySpace(unsafety),
26402642
AbiSpace(abi),

‎src/libstd/fs.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,9 +1595,9 @@ pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
15951595
///
15961596
/// Notable exception is made for situations where any of the directories
15971597
/// specified in the `path` could not be created as it was being created concurrently.
1598-
/// Such cases are considered success. In other words: calling `create_dir_all`
1599-
/// concurrently from multiple threads or processes is guaranteed to not fail
1600-
/// due to race itself.
1598+
/// Such cases are considered to be successful. That is, calling `create_dir_all`
1599+
/// concurrently from multiple threads or processes is guaranteed not to fail
1600+
/// due to a race condition with itself.
16011601
///
16021602
/// # Examples
16031603
///

‎src/libstd/io/util.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ use mem;
4040
///
4141
/// io::copy(&mut reader, &mut writer)?;
4242
///
43-
/// assert_eq!(reader, &writer[..]);
43+
/// assert_eq!(&b"hello"[..], &writer[..]);
4444
/// # Ok(())
4545
/// # }
46+
/// # foo().unwrap();
4647
/// ```
4748
#[stable(feature = "rust1", since = "1.0.0")]
4849
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> io::Result<u64>

‎src/libstd/primitive_docs.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,10 @@ mod prim_u128 { }
710710
//
711711
/// The pointer-sized signed integer type.
712712
///
713+
/// The size of this primitive is how many bytes it takes to reference any
714+
/// location in memory. For example, on a 32 bit target, this is 4 bytes
715+
/// and on a 64 bit target, this is 8 bytes.
716+
///
713717
/// *[See also the `std::isize` module](isize/index.html).*
714718
///
715719
/// However, please note that examples are shared between primitive integer
@@ -722,6 +726,10 @@ mod prim_isize { }
722726
//
723727
/// The pointer-sized unsigned integer type.
724728
///
729+
/// The size of this primitive is how many bytes it takes to reference any
730+
/// location in memory. For example, on a 32 bit target, this is 4 bytes
731+
/// and on a 64 bit target, this is 8 bytes.
732+
///
725733
/// *[See also the `std::usize` module](usize/index.html).*
726734
///
727735
/// However, please note that examples are shared between primitive integer

‎src/libstd/sync/rwlock.rs

Lines changed: 120 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,24 @@ use sys_common::rwlock as sys;
2424
/// of the underlying data (exclusive access) and the read portion of this lock
2525
/// typically allows for read-only access (shared access).
2626
///
27+
/// In comparison, a [`Mutex`] does not distinguish between readers or writers
28+
/// that aquire the lock, therefore blocking any threads waiting for the lock to
29+
/// become available. An `RwLock` will allow any number of readers to aquire the
30+
/// lock as long as a writer is not holding the lock.
31+
///
2732
/// The priority policy of the lock is dependent on the underlying operating
2833
/// system's implementation, and this type does not guarantee that any
2934
/// particular policy will be used.
3035
///
3136
/// The type parameter `T` represents the data that this lock protects. It is
32-
/// required that `T` satisfies `Send` to be shared across threads and `Sync` to
33-
/// allow concurrent access through readers. The RAII guards returned from the
34-
/// locking methods implement `Deref` (and `DerefMut` for the `write` methods)
35-
/// to allow access to the contained of the lock.
37+
/// required that `T` satisfies [`Send`] to be shared across threads and
38+
/// [`Sync`] to allow concurrent access through readers. The RAII guards
39+
/// returned from the locking methods implement [`Deref`][] (and [`DerefMut`]
40+
/// for the `write` methods) to allow access to the contained of the lock.
3641
///
3742
/// # Poisoning
3843
///
39-
/// An `RwLock`, like `Mutex`, will become poisoned on a panic. Note, however,
44+
/// An `RwLock`, like [`Mutex`], will become poisoned on a panic. Note, however,
4045
/// that an `RwLock` may only be poisoned if a panic occurs while it is locked
4146
/// exclusively (write mode). If a panic occurs in any reader, then the lock
4247
/// will not be poisoned.
@@ -63,6 +68,12 @@ use sys_common::rwlock as sys;
6368
/// assert_eq!(*w, 6);
6469
/// } // write lock is dropped here
6570
/// ```
71+
///
72+
/// [`Deref`]: ../../std/ops/trait.Deref.html
73+
/// [`DerefMut`]: ../../std/ops/trait.DerefMut.html
74+
/// [`Send`]: ../../std/marker/trait.Send.html
75+
/// [`Sync`]: ../../std/marker/trait.Sync.html
76+
/// [`Mutex`]: struct.Mutex.html
6677
#[stable(feature = "rust1", since = "1.0.0")]
6778
pub struct RwLock<T: ?Sized> {
6879
inner: Box<sys::RWLock>,
@@ -154,6 +165,24 @@ impl<T: ?Sized> RwLock<T> {
154165
/// # Panics
155166
///
156167
/// This function might panic when called if the lock is already held by the current thread.
168+
///
169+
/// # Examples
170+
///
171+
/// ```
172+
/// use std::sync::{Arc, RwLock};
173+
/// use std::thread;
174+
///
175+
/// let lock = Arc::new(RwLock::new(1));
176+
/// let c_lock = lock.clone();
177+
///
178+
/// let n = lock.read().unwrap();
179+
/// assert_eq!(*n, 1);
180+
///
181+
/// thread::spawn(move || {
182+
/// let r = c_lock.read();
183+
/// assert!(r.is_ok());
184+
/// }).join().unwrap();
185+
/// ```
157186
#[inline]
158187
#[stable(feature = "rust1", since = "1.0.0")]
159188
pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
@@ -180,6 +209,19 @@ impl<T: ?Sized> RwLock<T> {
180209
/// is poisoned whenever a writer panics while holding an exclusive lock. An
181210
/// error will only be returned if the lock would have otherwise been
182211
/// acquired.
212+
///
213+
/// # Examples
214+
///
215+
/// ```
216+
/// use std::sync::RwLock;
217+
///
218+
/// let lock = RwLock::new(1);
219+
///
220+
/// match lock.try_read() {
221+
/// Ok(n) => assert_eq!(*n, 1),
222+
/// Err(_) => unreachable!(),
223+
/// };
224+
/// ```
183225
#[inline]
184226
#[stable(feature = "rust1", since = "1.0.0")]
185227
pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
@@ -210,6 +252,19 @@ impl<T: ?Sized> RwLock<T> {
210252
/// # Panics
211253
///
212254
/// This function might panic when called if the lock is already held by the current thread.
255+
///
256+
/// # Examples
257+
///
258+
/// ```
259+
/// use std::sync::RwLock;
260+
///
261+
/// let lock = RwLock::new(1);
262+
///
263+
/// let mut n = lock.write().unwrap();
264+
/// *n = 2;
265+
///
266+
/// assert!(lock.try_read().is_err());
267+
/// ```
213268
#[inline]
214269
#[stable(feature = "rust1", since = "1.0.0")]
215270
pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
@@ -236,6 +291,19 @@ impl<T: ?Sized> RwLock<T> {
236291
/// is poisoned whenever a writer panics while holding an exclusive lock. An
237292
/// error will only be returned if the lock would have otherwise been
238293
/// acquired.
294+
///
295+
/// # Examples
296+
///
297+
/// ```
298+
/// use std::sync::RwLock;
299+
///
300+
/// let lock = RwLock::new(1);
301+
///
302+
/// let n = lock.read().unwrap();
303+
/// assert_eq!(*n, 1);
304+
///
305+
/// assert!(lock.try_write().is_err());
306+
/// ```
239307
#[inline]
240308
#[stable(feature = "rust1", since = "1.0.0")]
241309
pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
@@ -253,6 +321,22 @@ impl<T: ?Sized> RwLock<T> {
253321
/// If another thread is active, the lock can still become poisoned at any
254322
/// time. You should not trust a `false` value for program correctness
255323
/// without additional synchronization.
324+
///
325+
/// # Examples
326+
///
327+
/// ```
328+
/// use std::sync::{Arc, RwLock};
329+
/// use std::thread;
330+
///
331+
/// let lock = Arc::new(RwLock::new(0));
332+
/// let c_lock = lock.clone();
333+
///
334+
/// let _ = thread::spawn(move || {
335+
/// let _lock = c_lock.write().unwrap();
336+
/// panic!(); // the lock gets poisoned
337+
/// }).join();
338+
/// assert_eq!(lock.is_poisoned(), true);
339+
/// ```
256340
#[inline]
257341
#[stable(feature = "sync_poison", since = "1.2.0")]
258342
pub fn is_poisoned(&self) -> bool {
@@ -267,6 +351,19 @@ impl<T: ?Sized> RwLock<T> {
267351
/// is poisoned whenever a writer panics while holding an exclusive lock. An
268352
/// error will only be returned if the lock would have otherwise been
269353
/// acquired.
354+
///
355+
/// # Examples
356+
///
357+
/// ```
358+
/// use std::sync::RwLock;
359+
///
360+
/// let lock = RwLock::new(String::new());
361+
/// {
362+
/// let mut s = lock.write().unwrap();
363+
/// *s = "modified".to_owned();
364+
/// }
365+
/// assert_eq!(lock.into_inner().unwrap(), "modified");
366+
/// ```
270367
#[stable(feature = "rwlock_into_inner", since = "1.6.0")]
271368
pub fn into_inner(self) -> LockResult<T> where T: Sized {
272369
// We know statically that there are no outstanding references to
@@ -282,7 +379,7 @@ impl<T: ?Sized> RwLock<T> {
282379
(ptr::read(inner), ptr::read(poison), ptr::read(data))
283380
};
284381
mem::forget(self);
285-
inner.destroy(); // Keep in sync with the `Drop` impl.
382+
inner.destroy(); // Keep in sync with the `Drop` impl.
286383
drop(inner);
287384

288385
poison::map_result(poison.borrow(), |_| data.into_inner())
@@ -300,6 +397,16 @@ impl<T: ?Sized> RwLock<T> {
300397
/// is poisoned whenever a writer panics while holding an exclusive lock. An
301398
/// error will only be returned if the lock would have otherwise been
302399
/// acquired.
400+
///
401+
/// # Examples
402+
///
403+
/// ```
404+
/// use std::sync::RwLock;
405+
///
406+
/// let mut lock = RwLock::new(0);
407+
/// *lock.get_mut().unwrap() = 10;
408+
/// assert_eq!(*lock.read().unwrap(), 10);
409+
/// ```
303410
#[stable(feature = "rwlock_get_mut", since = "1.6.0")]
304411
pub fn get_mut(&mut self) -> LockResult<&mut T> {
305412
// We know statically that there are no other references to `self`, so
@@ -486,7 +593,7 @@ mod tests {
486593
fn test_rw_arc_poison_wr() {
487594
let arc = Arc::new(RwLock::new(1));
488595
let arc2 = arc.clone();
489-
let _: Result<(), _> = thread::spawn(move|| {
596+
let _: Result<(), _> = thread::spawn(move || {
490597
let _lock = arc2.write().unwrap();
491598
panic!();
492599
}).join();
@@ -498,7 +605,7 @@ mod tests {
498605
let arc = Arc::new(RwLock::new(1));
499606
assert!(!arc.is_poisoned());
500607
let arc2 = arc.clone();
501-
let _: Result<(), _> = thread::spawn(move|| {
608+
let _: Result<(), _> = thread::spawn(move || {
502609
let _lock = arc2.write().unwrap();
503610
panic!();
504611
}).join();
@@ -510,7 +617,7 @@ mod tests {
510617
fn test_rw_arc_no_poison_rr() {
511618
let arc = Arc::new(RwLock::new(1));
512619
let arc2 = arc.clone();
513-
let _: Result<(), _> = thread::spawn(move|| {
620+
let _: Result<(), _> = thread::spawn(move || {
514621
let _lock = arc2.read().unwrap();
515622
panic!();
516623
}).join();
@@ -521,7 +628,7 @@ mod tests {
521628
fn test_rw_arc_no_poison_rw() {
522629
let arc = Arc::new(RwLock::new(1));
523630
let arc2 = arc.clone();
524-
let _: Result<(), _> = thread::spawn(move|| {
631+
let _: Result<(), _> = thread::spawn(move || {
525632
let _lock = arc2.read().unwrap();
526633
panic!()
527634
}).join();
@@ -535,7 +642,7 @@ mod tests {
535642
let arc2 = arc.clone();
536643
let (tx, rx) = channel();
537644

538-
thread::spawn(move|| {
645+
thread::spawn(move || {
539646
let mut lock = arc2.write().unwrap();
540647
for _ in 0..10 {
541648
let tmp = *lock;
@@ -550,7 +657,7 @@ mod tests {
550657
let mut children = Vec::new();
551658
for _ in 0..5 {
552659
let arc3 = arc.clone();
553-
children.push(thread::spawn(move|| {
660+
children.push(thread::spawn(move || {
554661
let lock = arc3.read().unwrap();
555662
assert!(*lock >= 0);
556663
}));
@@ -571,7 +678,7 @@ mod tests {
571678
fn test_rw_arc_access_in_unwind() {
572679
let arc = Arc::new(RwLock::new(1));
573680
let arc2 = arc.clone();
574-
let _ = thread::spawn(move|| -> () {
681+
let _ = thread::spawn(move || -> () {
575682
struct Unwinder {
576683
i: Arc<RwLock<isize>>,
577684
}

‎src/libsyntax/parse/parser.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,7 +2632,7 @@ impl<'a> Parser<'a> {
26322632
self.bump();
26332633
let e = self.parse_prefix_expr(None);
26342634
let (span, e) = self.interpolated_or_expr_span(e)?;
2635-
(span, self.mk_unary(UnOp::Not, e))
2635+
(lo.to(span), self.mk_unary(UnOp::Not, e))
26362636
}
26372637
// Suggest `!` for bitwise negation when encountering a `~`
26382638
token::Tilde => {
@@ -2645,26 +2645,26 @@ impl<'a> Parser<'a> {
26452645
err.span_label(span_of_tilde, "did you mean `!`?");
26462646
err.help("use `!` instead of `~` if you meant to perform bitwise negation");
26472647
err.emit();
2648-
(span, self.mk_unary(UnOp::Not, e))
2648+
(lo.to(span), self.mk_unary(UnOp::Not, e))
26492649
}
26502650
token::BinOp(token::Minus) => {
26512651
self.bump();
26522652
let e = self.parse_prefix_expr(None);
26532653
let (span, e) = self.interpolated_or_expr_span(e)?;
2654-
(span, self.mk_unary(UnOp::Neg, e))
2654+
(lo.to(span), self.mk_unary(UnOp::Neg, e))
26552655
}
26562656
token::BinOp(token::Star) => {
26572657
self.bump();
26582658
let e = self.parse_prefix_expr(None);
26592659
let (span, e) = self.interpolated_or_expr_span(e)?;
2660-
(span, self.mk_unary(UnOp::Deref, e))
2660+
(lo.to(span), self.mk_unary(UnOp::Deref, e))
26612661
}
26622662
token::BinOp(token::And) | token::AndAnd => {
26632663
self.expect_and()?;
26642664
let m = self.parse_mutability();
26652665
let e = self.parse_prefix_expr(None);
26662666
let (span, e) = self.interpolated_or_expr_span(e)?;
2667-
(span, ExprKind::AddrOf(m, e))
2667+
(lo.to(span), ExprKind::AddrOf(m, e))
26682668
}
26692669
token::Ident(..) if self.token.is_keyword(keywords::In) => {
26702670
self.bump();
@@ -2675,13 +2675,13 @@ impl<'a> Parser<'a> {
26752675
let blk = self.parse_block()?;
26762676
let span = blk.span;
26772677
let blk_expr = self.mk_expr(span, ExprKind::Block(blk), ThinVec::new());
2678-
(span, ExprKind::InPlace(place, blk_expr))
2678+
(lo.to(span), ExprKind::InPlace(place, blk_expr))
26792679
}
26802680
token::Ident(..) if self.token.is_keyword(keywords::Box) => {
26812681
self.bump();
26822682
let e = self.parse_prefix_expr(None);
26832683
let (span, e) = self.interpolated_or_expr_span(e)?;
2684-
(span, ExprKind::Box(e))
2684+
(lo.to(span), ExprKind::Box(e))
26852685
}
26862686
_ => return self.parse_dot_or_call_expr(Some(attrs))
26872687
};

‎src/test/run-pass/ifmt.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![allow(unused_features)]
1414
#![feature(box_syntax)]
1515

16+
use std::cell::RefCell;
1617
use std::fmt::{self, Write};
1718
use std::usize;
1819

@@ -240,6 +241,8 @@ pub fn main() {
240241
// test that trailing commas are acceptable
241242
format!("{}", "test",);
242243
format!("{foo}", foo="test",);
244+
245+
test_refcell();
243246
}
244247

245248
// Basic test to make sure that we can invoke the `write!` macro with an
@@ -319,3 +322,12 @@ fn test_once() {
319322
assert_eq!(format!("{0} {0} {0} {a} {a} {a}", foo(), a=foo()),
320323
"1 1 1 2 2 2".to_string());
321324
}
325+
326+
fn test_refcell() {
327+
let refcell = RefCell::new(5);
328+
assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }");
329+
let borrow = refcell.borrow_mut();
330+
assert_eq!(format!("{:?}", refcell), "RefCell { value: <borrowed> }");
331+
drop(borrow);
332+
assert_eq!(format!("{:?}", refcell), "RefCell { value: 5 }");
333+
}

‎src/test/run-pass/issue-44730.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2017 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+
//! dox
12+
13+
#![deny(missing_docs)]
14+
15+
macro_rules! doc {
16+
($e:expr) => (
17+
#[doc = $e]
18+
pub struct Foo;
19+
)
20+
}
21+
22+
doc!("a");
23+
24+
fn main() {}

‎src/test/rustdoc/pub-method.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2017 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+
// ignore-tidy-linelength
12+
// compile-flags: --no-defaults --passes collapse-docs --passes unindent-comments --passes strip-priv-imports
13+
14+
#![crate_name = "foo"]
15+
16+
// @has foo/fn.bar.html
17+
// @has - '//*[@class="rust fn"]' 'pub fn bar() -> '
18+
/// foo
19+
pub fn bar() -> usize {
20+
2
21+
}
22+
23+
// @has foo/struct.Foo.html
24+
// @has - '//*[@class="method"]' 'pub fn new()'
25+
// @has - '//*[@class="method"]' 'fn not_pub()'
26+
pub struct Foo(usize);
27+
28+
impl Foo {
29+
pub fn new() -> Foo { Foo(0) }
30+
fn not_pub() {}
31+
}

0 commit comments

Comments
 (0)
Please sign in to comment.