Skip to content

Commit 055517e

Browse files
committed
---
yaml --- r: 234750 b: refs/heads/tmp c: fb690c7 h: refs/heads/master v: v3
1 parent ddee3bd commit 055517e

File tree

7 files changed

+57
-43
lines changed

7 files changed

+57
-43
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ refs/tags/0.11.0: e1247cb1d0d681be034adb4b558b5a0c0d5720f9
2525
refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
2626
refs/heads/beta: d2e13e822a73e0ea46ae9e21afdd3155fc997f6d
2727
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
28-
refs/heads/tmp: 6fa0ff25bdc5aa5aae00dbe7c1cafc927b6806b6
28+
refs/heads/tmp: fb690c7af6949cf55766a0075a16c381a1f1de12
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: ab792abf1fcc28afbd315426213f6428da25c085
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828

branches/tmp/mk/dist.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ $(PKG_TAR): $(PKG_FILES)
7777
-C $(S) \
7878
--exclude-vcs \
7979
--exclude=*~ \
80+
--exclude=*.pyc \
8081
--exclude=*/llvm/test/*/*.ll \
8182
--exclude=*/llvm/test/*/*.td \
8283
--exclude=*/llvm/test/*/*.s \

branches/tmp/src/doc/trpl/concurrency.md

Lines changed: 28 additions & 31 deletions
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

branches/tmp/src/librustc/diagnostics.rs

Lines changed: 10 additions & 2 deletions
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

branches/tmp/src/librustc/lint/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,6 @@ pub trait LateLintPass: LintPass {
161161
fn check_lifetime_ref(&mut self, _: &LateContext, _: &hir::Lifetime) { }
162162
fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
163163
fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
164-
// Note that you shouldn't implement both check_mac and check_ast_mac,
165-
// because then your lint will be called twice. Prefer check_ast_mac.
166-
fn check_mac(&mut self, _: &LateContext, _: &ast::Mac) { }
167164
fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
168165
fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }
169166

@@ -209,7 +206,6 @@ pub trait EarlyLintPass: LintPass {
209206
fn check_lifetime_ref(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
210207
fn check_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
211208
fn check_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
212-
fn check_mac(&mut self, _: &EarlyContext, _: &ast::Mac) { }
213209
fn check_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
214210
fn check_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
215211

branches/tmp/src/librustc/middle/check_const.rs

Lines changed: 16 additions & 4 deletions
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
}

branches/tmp/src/test/borrowck-loan-of-static-data-issue-27616.rs renamed to branches/tmp/src/test/compile-fail/borrowck-loan-of-static-data-issue-27616.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn evil(mut s: &'static mut String)
2323
let alias: &'static mut String = s;
2424
let inner: &str = &alias;
2525
// free value
26-
*s = String::new(); //~ ERROR cannot assign
26+
*s = String::new(); //~ ERROR use of moved value
2727
let _spray = "0wned".to_owned();
2828
// ... and then use it
2929
println!("{}", inner);

0 commit comments

Comments
 (0)