Skip to content

Commit 25aaeb4

Browse files
committed
Auto merge of #28529 - Manishearth:rollup, r=Manishearth
- Successful merges: #28463, #28507, #28522, #28525, #28526 - Failed merges:
2 parents fd38a75 + d7ec69a commit 25aaeb4

File tree

102 files changed

+215
-67
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+215
-67
lines changed

src/doc/trpl/choosing-your-guarantees.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ there's a lot of concurrent access happening.
321321

322322
# Composition
323323

324-
A common gripe when reading Rust code is with types like `Rc<RefCell<Vec<T>>>` (or even more more
324+
A common gripe when reading Rust code is with types like `Rc<RefCell<Vec<T>>>` (or even more
325325
complicated compositions of such types). It's not always clear what the composition does, or why the
326326
author chose one like this (and when one should be using such a composition in one's own code)
327327

src/doc/trpl/concurrency.md

+28-31
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ to help us make sense of code that can possibly be concurrent.
2626
### `Send`
2727

2828
The first trait we're going to talk about is
29-
[`Send`](../std/marker/trait.Send.html). When a type `T` implements `Send`, it indicates
30-
to the compiler that something of this type is able to have ownership transferred
29+
[`Send`](../std/marker/trait.Send.html). When a type `T` implements `Send`, it
30+
indicates that something of this type is able to have ownership transferred
3131
safely between threads.
3232

3333
This is important to enforce certain restrictions. For example, if we have a
@@ -42,13 +42,19 @@ us enforce that it can't leave the current thread.
4242
### `Sync`
4343

4444
The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
45-
When a type `T` implements `Sync`, it indicates to the compiler that something
45+
When a type `T` implements `Sync`, it indicates that something
4646
of this type has no possibility of introducing memory unsafety when used from
47-
multiple threads concurrently.
48-
49-
For example, sharing immutable data with an atomic reference count is
50-
threadsafe. Rust provides a type like this, `Arc<T>`, and it implements `Sync`,
51-
so it is safe to share between threads.
47+
multiple threads concurrently through shared references. This implies that
48+
types which don't have [interior mutability](mutability.html) are inherently
49+
`Sync`, which includes simple primitive types (like `u8`) and aggregate types
50+
containing them.
51+
52+
For sharing references across threads, Rust provides a wrapper type called
53+
`Arc<T>`. `Arc<T>` implements `Send` and `Sync` if and only if `T` implements
54+
both `Send` and `Sync`. For example, an object of type `Arc<RefCell<U>>` cannot
55+
be transferred across threads because
56+
[`RefCell`](choosing-your-guarantees.html#refcell%3Ct%3E) does not implement
57+
`Sync`, consequently `Arc<RefCell<U>>` would not implement `Send`.
5258

5359
These two traits allow you to use the type system to make strong guarantees
5460
about the properties of your code under concurrency. Before we demonstrate
@@ -70,7 +76,7 @@ fn main() {
7076
}
7177
```
7278

73-
The `thread::spawn()` method accepts a closure, which is executed in a
79+
The `thread::spawn()` method accepts a [closure](closures.html), which is executed in a
7480
new thread. It returns a handle to the thread, that can be used to
7581
wait for the child thread to finish and extract its result:
7682

@@ -215,29 +221,18 @@ fn main() {
215221
}
216222
```
217223

224+
Note that the value of `i` is bound (copied) to the closure and not shared
225+
among the threads.
218226

219-
If we'd tried to use `Mutex<T>` without wrapping it in an `Arc<T>` we would have
220-
seen another error like:
221-
222-
```text
223-
error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
224-
thread::spawn(move || {
225-
^~~~~~~~~~~~~
226-
note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
227-
thread::spawn(move || {
228-
^~~~~~~~~~~~~
229-
```
230-
231-
You see, [`Mutex`](../std/sync/struct.Mutex.html) has a
232-
[`lock`](../std/sync/struct.Mutex.html#method.lock)
233-
method which has this signature:
227+
Also note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of
228+
[`Mutex`](../std/sync/struct.Mutex.html) has this signature:
234229

235230
```ignore
236231
fn lock(&self) -> LockResult<MutexGuard<T>>
237232
```
238233

239-
and because `Send` is not implemented for `MutexGuard<T>`, we couldn't have
240-
transferred the guard across thread boundaries on it's own.
234+
and because `Send` is not implemented for `MutexGuard<T>`, the guard cannot
235+
cross thread boundaries, ensuring thread-locality of lock acquire and release.
241236

242237
Let's examine the body of the thread more closely:
243238

@@ -317,22 +312,24 @@ use std::sync::mpsc;
317312
fn main() {
318313
let (tx, rx) = mpsc::channel();
319314

320-
for _ in 0..10 {
315+
for i in 0..10 {
321316
let tx = tx.clone();
322317

323318
thread::spawn(move || {
324-
let answer = 42;
319+
let answer = i * i;
325320

326321
tx.send(answer);
327322
});
328323
}
329324

330-
rx.recv().ok().expect("Could not receive answer");
325+
for _ in 0..10 {
326+
println!("{}", rx.recv().unwrap());
327+
}
331328
}
332329
```
333330

334-
A `u32` is `Send` because we can make a copy. So we create a thread, ask it to calculate
335-
the answer, and then it `send()`s us the answer over the channel.
331+
Here we create 10 threads, asking each to calculate the square of a number (`i`
332+
at the time of `spawn()`), and then `send()` back the answer over the channel.
336333

337334

338335
## Panics

src/librustc/diagnostics.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,18 @@ const FOO: i32 = { 0 }; // but brackets are useless here
298298
```
299299
"##,
300300

301+
// FIXME(#24111) Change the language here when const fn stabilizes
301302
E0015: r##"
302303
The only functions that can be called in static or constant expressions are
303-
`const` functions. Rust currently does not support more general compile-time
304-
function execution.
304+
`const` functions, and struct/enum constructors. `const` functions are only
305+
available on a nightly compiler. Rust currently does not support more general
306+
compile-time function execution.
307+
308+
```
309+
const FOO: Option<u8> = Some(1); // enum constructor
310+
struct Bar {x: u8}
311+
const BAR: Bar = Bar {x: 1}; // struct constructor
312+
```
305313
306314
See [RFC 911] for more details on the design of `const fn`s.
307315

src/librustc/middle/check_const.rs

+16-4
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use util::nodemap::NodeMap;
3939
use rustc_front::hir;
4040
use syntax::ast;
4141
use syntax::codemap::Span;
42+
use syntax::feature_gate::UnstableFeatures;
4243
use rustc_front::visit::{self, FnKind, Visitor};
4344

4445
use std::collections::hash_map::Entry;
@@ -709,10 +710,21 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
709710
if !is_const {
710711
v.add_qualif(ConstQualif::NOT_CONST);
711712
if v.mode != Mode::Var {
712-
span_err!(v.tcx.sess, e.span, E0015,
713-
"function calls in {}s are limited to \
714-
constant functions, \
715-
struct and enum constructors", v.msg());
713+
// FIXME(#24111) Remove this check when const fn stabilizes
714+
if let UnstableFeatures::Disallow = v.tcx.sess.opts.unstable_features {
715+
span_err!(v.tcx.sess, e.span, E0015,
716+
"function calls in {}s are limited to \
717+
struct and enum constructors", v.msg());
718+
v.tcx.sess.span_note(e.span,
719+
"a limited form of compile-time function \
720+
evaluation is available on a nightly \
721+
compiler via `const fn`");
722+
} else {
723+
span_err!(v.tcx.sess, e.span, E0015,
724+
"function calls in {}s are limited to \
725+
constant functions, \
726+
struct and enum constructors", v.msg());
727+
}
716728
}
717729
}
718730
}

src/libsyntax/ext/expand.rs

+25-24
Original file line numberDiff line numberDiff line change
@@ -684,15 +684,15 @@ fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool
684684
// logic as for expression-position macro invocations.
685685
pub fn expand_item_mac(it: P<ast::Item>,
686686
fld: &mut MacroExpander) -> SmallVector<P<ast::Item>> {
687-
let (extname, path_span, tts) = match it.node {
687+
let (extname, path_span, tts, span, attrs, ident) = it.and_then(|it| { match it.node {
688688
ItemMac(codemap::Spanned {
689-
node: MacInvocTT(ref pth, ref tts, _),
689+
node: MacInvocTT(pth, tts, _),
690690
..
691691
}) => {
692-
(pth.segments[0].identifier.name, pth.span, (*tts).clone())
692+
(pth.segments[0].identifier.name, pth.span, tts, it.span, it.attrs, it.ident)
693693
}
694694
_ => fld.cx.span_bug(it.span, "invalid item macro invocation")
695-
};
695+
}});
696696

697697
let fm = fresh_mark();
698698
let items = {
@@ -706,56 +706,56 @@ pub fn expand_item_mac(it: P<ast::Item>,
706706
}
707707

708708
Some(rc) => match *rc {
709-
NormalTT(ref expander, span, allow_internal_unstable) => {
710-
if it.ident.name != parse::token::special_idents::invalid.name {
709+
NormalTT(ref expander, tt_span, allow_internal_unstable) => {
710+
if ident.name != parse::token::special_idents::invalid.name {
711711
fld.cx
712712
.span_err(path_span,
713713
&format!("macro {}! expects no ident argument, given '{}'",
714714
extname,
715-
it.ident));
715+
ident));
716716
return SmallVector::zero();
717717
}
718718
fld.cx.bt_push(ExpnInfo {
719-
call_site: it.span,
719+
call_site: span,
720720
callee: NameAndSpan {
721721
format: MacroBang(extname),
722-
span: span,
722+
span: tt_span,
723723
allow_internal_unstable: allow_internal_unstable,
724724
}
725725
});
726726
// mark before expansion:
727727
let marked_before = mark_tts(&tts[..], fm);
728-
expander.expand(fld.cx, it.span, &marked_before[..])
728+
expander.expand(fld.cx, span, &marked_before[..])
729729
}
730-
IdentTT(ref expander, span, allow_internal_unstable) => {
731-
if it.ident.name == parse::token::special_idents::invalid.name {
730+
IdentTT(ref expander, tt_span, allow_internal_unstable) => {
731+
if ident.name == parse::token::special_idents::invalid.name {
732732
fld.cx.span_err(path_span,
733733
&format!("macro {}! expects an ident argument",
734734
extname));
735735
return SmallVector::zero();
736736
}
737737
fld.cx.bt_push(ExpnInfo {
738-
call_site: it.span,
738+
call_site: span,
739739
callee: NameAndSpan {
740740
format: MacroBang(extname),
741-
span: span,
741+
span: tt_span,
742742
allow_internal_unstable: allow_internal_unstable,
743743
}
744744
});
745745
// mark before expansion:
746746
let marked_tts = mark_tts(&tts[..], fm);
747-
expander.expand(fld.cx, it.span, it.ident, marked_tts)
747+
expander.expand(fld.cx, span, ident, marked_tts)
748748
}
749749
MacroRulesTT => {
750-
if it.ident.name == parse::token::special_idents::invalid.name {
750+
if ident.name == parse::token::special_idents::invalid.name {
751751
fld.cx.span_err(path_span,
752752
&format!("macro_rules! expects an ident argument")
753753
);
754754
return SmallVector::zero();
755755
}
756756

757757
fld.cx.bt_push(ExpnInfo {
758-
call_site: it.span,
758+
call_site: span,
759759
callee: NameAndSpan {
760760
format: MacroBang(extname),
761761
span: None,
@@ -767,7 +767,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
767767
});
768768
// DON'T mark before expansion.
769769

770-
let allow_internal_unstable = attr::contains_name(&it.attrs,
770+
let allow_internal_unstable = attr::contains_name(&attrs,
771771
"allow_internal_unstable");
772772

773773
// ensure any #[allow_internal_unstable]s are
@@ -777,18 +777,19 @@ pub fn expand_item_mac(it: P<ast::Item>,
777777
feature_gate::emit_feature_err(
778778
&fld.cx.parse_sess.span_diagnostic,
779779
"allow_internal_unstable",
780-
it.span,
780+
span,
781781
feature_gate::GateIssue::Language,
782782
feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
783783
}
784784

785+
let export = attr::contains_name(&attrs, "macro_export");
785786
let def = ast::MacroDef {
786-
ident: it.ident,
787-
attrs: it.attrs.clone(),
787+
ident: ident,
788+
attrs: attrs,
788789
id: ast::DUMMY_NODE_ID,
789-
span: it.span,
790+
span: span,
790791
imported_from: None,
791-
export: attr::contains_name(&it.attrs, "macro_export"),
792+
export: export,
792793
use_locally: true,
793794
allow_internal_unstable: allow_internal_unstable,
794795
body: tts,
@@ -800,7 +801,7 @@ pub fn expand_item_mac(it: P<ast::Item>,
800801
return SmallVector::zero();
801802
}
802803
_ => {
803-
fld.cx.span_err(it.span,
804+
fld.cx.span_err(span,
804805
&format!("{}! is not legal in item position",
805806
extname));
806807
return SmallVector::zero();

src/libsyntax/feature_gate.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,12 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
197197

198198
// allow overloading augmented assignment operations like `a += b`
199199
("augmented_assignments", "1.5.0", None, Active),
200+
201+
// allow `#[no_debug]`
202+
("no_debug", "1.5.0", None, Active),
203+
204+
// allow `#[omit_gdb_pretty_printer_section]`
205+
("omit_gdb_pretty_printer_section", "1.5.0", None, Active),
200206
];
201207
// (changing above list without updating src/doc/reference.md makes @cmr sad)
202208

@@ -320,8 +326,13 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat
320326
("link_section", Whitelisted, Ungated),
321327
("no_builtins", Whitelisted, Ungated),
322328
("no_mangle", Whitelisted, Ungated),
323-
("no_debug", Whitelisted, Ungated),
324-
("omit_gdb_pretty_printer_section", Whitelisted, Ungated),
329+
("no_debug", Whitelisted, Gated("no_debug",
330+
"the `#[no_debug]` attribute \
331+
is an experimental feature")),
332+
("omit_gdb_pretty_printer_section", Whitelisted, Gated("omit_gdb_pretty_printer_section",
333+
"the `#[omit_gdb_pretty_printer_section]` \
334+
attribute is just used for the Rust test \
335+
suite")),
325336
("unsafe_no_drop_flag", Whitelisted, Gated("unsafe_no_drop_flag",
326337
"unsafe_no_drop_flag has unstable semantics \
327338
and may be removed in the future")),

src/test/auxiliary/cross_crate_spans.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![crate_type = "rlib"]
1212

1313
#![allow(unused_variables)]
14+
#![feature(omit_gdb_pretty_printer_section)]
1415
#![omit_gdb_pretty_printer_section]
1516

1617
// no-prefer-dynamic
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
#[no_debug] //~ ERROR the `#[no_debug]` attribute is
12+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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+
#[omit_gdb_pretty_printer_section] //~ ERROR the `#[omit_gdb_pretty_printer_section]` attribute is
12+
fn main() {}

src/test/debuginfo/associated-types.rs

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
#![allow(unused_variables)]
8282
#![allow(dead_code)]
83+
#![feature(omit_gdb_pretty_printer_section)]
8384
#![omit_gdb_pretty_printer_section]
8485

8586
trait TraitWithAssocType {

src/test/debuginfo/basic-types-globals-metadata.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
#![allow(unused_variables)]
4646
#![allow(dead_code)]
47+
#![feature(omit_gdb_pretty_printer_section)]
4748
#![omit_gdb_pretty_printer_section]
4849

4950
// N.B. These are `mut` only so they don't constant fold away.

src/test/debuginfo/basic-types-globals.rs

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
// gdb-command:continue
5050

5151
#![allow(unused_variables)]
52+
#![feature(omit_gdb_pretty_printer_section)]
5253
#![omit_gdb_pretty_printer_section]
5354

5455
// N.B. These are `mut` only so they don't constant fold away.

0 commit comments

Comments
 (0)