Skip to content

Commit b6af518

Browse files
committed
---
yaml --- r: 89962 b: refs/heads/master c: a1afe9c h: refs/heads/master v: v3
1 parent edecc7a commit b6af518

File tree

5 files changed

+97
-59
lines changed

5 files changed

+97
-59
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 6143400aaac2239feb979deebe9777f6edccce1a
2+
refs/heads/master: a1afe9cc0ad410af599ff580d41ce9c9e158136f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d3e57dca68fde4effdda3e4ae2887aa535fcd6
55
refs/heads/try: b160761e35efcd1207112b3b782c06633cf441a8

trunk/doc/tutorial.md

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,9 @@ calling the destructor, and the owner determines whether the object is mutable.
890890

891891
Ownership is recursive, so mutability is inherited recursively and a destructor
892892
destroys the contained tree of owned objects. Variables are top-level owners
893-
and destroy the contained object when they go out of scope.
893+
and destroy the contained object when they go out of scope. A box managed by
894+
the garbage collector starts a new ownership tree, and the destructor is called
895+
when it is collected.
894896

895897
~~~~
896898
// the struct owns the objects contained in the `x` and `y` fields
@@ -1007,6 +1009,51 @@ let mut s = r; // box becomes mutable
10071009
let t = s; // box becomes immutable
10081010
~~~~
10091011

1012+
# Managed boxes
1013+
1014+
A managed box (`@`) is a heap allocation with the lifetime managed by a
1015+
task-local garbage collector. It will be destroyed at some point after there
1016+
are no references left to the box, no later than the end of the task. Managed
1017+
boxes lack an owner, so they start a new ownership tree and don't inherit
1018+
mutability. They do own the contained object, and mutability is defined by the
1019+
type of the managed box (`@` or `@mut`). An object containing a managed box is
1020+
not `Owned`, and can't be sent between tasks.
1021+
1022+
~~~~
1023+
let a = @5; // immutable
1024+
1025+
let mut b = @5; // mutable variable, immutable box
1026+
b = @10;
1027+
1028+
let c = @mut 5; // immutable variable, mutable box
1029+
*c = 10;
1030+
1031+
let mut d = @mut 5; // mutable variable, mutable box
1032+
*d += 5;
1033+
d = @mut 15;
1034+
~~~~
1035+
1036+
A mutable variable and an immutable variable can refer to the same box, given
1037+
that their types are compatible. Mutability of a box is a property of its type,
1038+
however, so for example a mutable handle to an immutable box cannot be
1039+
assigned a reference to a mutable box.
1040+
1041+
~~~~
1042+
let a = @1; // immutable box
1043+
let b = @mut 2; // mutable box
1044+
1045+
let mut c : @int; // declare a variable with type managed immutable int
1046+
let mut d : @mut int; // and one of type managed mutable int
1047+
1048+
c = a; // box type is the same, okay
1049+
d = b; // box type is the same, okay
1050+
~~~~
1051+
1052+
~~~~ {.xfail-test}
1053+
// but b cannot be assigned to c, or a to d
1054+
c = b; // error
1055+
~~~~
1056+
10101057
# Borrowed pointers
10111058

10121059
Rust's borrowed pointers are a general purpose reference type. In contrast with
@@ -1300,52 +1347,6 @@ defined in [`std::vec`] and [`std::str`].
13001347
[`std::vec`]: std/vec/index.html
13011348
[`std::str`]: std/str/index.html
13021349
1303-
# Ownership escape hatches
1304-
1305-
Ownership can cleanly describe tree-like data structures, and borrowed pointers provide non-owning
1306-
references. However, more flexibility is often desired and Rust provides ways to escape from strict
1307-
single parent ownership.
1308-
1309-
The standard library provides the `std::rc::Rc` pointer type to express *shared ownership* over a
1310-
reference counted box. As soon as all of the `Rc` pointers go out of scope, the box and the
1311-
contained value are destroyed.
1312-
1313-
~~~
1314-
use std::rc::Rc;
1315-
1316-
// A fixed-size array allocated in a reference-counted box
1317-
let x = Rc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1318-
let y = x.clone(); // a new owner
1319-
let z = x; // this moves `x` into `z`, rather than creating a new owner
1320-
1321-
assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1322-
1323-
let mut a = Rc::new([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]); // the variable is mutable, but not the box
1324-
a = z;
1325-
~~~
1326-
1327-
A garbage collected pointer is provided via `std::gc::Gc`, with a task-local garbage collector
1328-
having ownership of the box. It allows the creation of cycles, and the individual `Gc` pointers do
1329-
not have a destructor.
1330-
1331-
~~~
1332-
use std::gc::Gc;
1333-
1334-
// A fixed-size array allocated in a garbage-collected box
1335-
let x = Gc::new([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1336-
let y = x; // does not perform a move, unlike with `Rc`
1337-
let z = x;
1338-
1339-
assert_eq!(*z.borrow(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
1340-
~~~
1341-
1342-
With shared ownership, mutability cannot be inherited so the boxes are always immutable. However,
1343-
it's possible to use *dynamic* mutability via types like `std::cell::Cell` where freezing is handled
1344-
via dynamic checks and can fail at runtime.
1345-
1346-
The `Rc` and `Gc` types are not sendable, so they cannot be used to share memory between tasks. Safe
1347-
immutable and mutable shared memory is provided by the `extra::arc` module.
1348-
13491350
# Closures
13501351
13511352
Named functions, like those we've seen so far, may not refer to local

trunk/src/librustc/middle/lint.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub enum lint {
7575
type_limits,
7676
type_overflow,
7777
unused_unsafe,
78+
unsafe_block,
7879

7980
managed_heap_memory,
8081
owned_heap_memory,
@@ -236,6 +237,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
236237
default: warn
237238
}),
238239

240+
("unsafe_block",
241+
LintSpec {
242+
lint: unsafe_block,
243+
desc: "usage of an `unsafe` block",
244+
default: allow
245+
}),
246+
239247
("unused_variable",
240248
LintSpec {
241249
lint: unused_variable,
@@ -870,8 +878,7 @@ fn check_pat_non_uppercase_statics(cx: &Context, p: &ast::Pat) {
870878

871879
fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
872880
match e.node {
873-
// Don't warn about generated blocks, that'll just pollute the
874-
// output.
881+
// Don't warn about generated blocks, that'll just pollute the output.
875882
ast::ExprBlock(ref blk) => {
876883
if blk.rules == ast::UnsafeBlock(ast::UserProvided) &&
877884
!cx.tcx.used_unsafe.contains(&blk.id) {
@@ -883,6 +890,16 @@ fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
883890
}
884891
}
885892

893+
fn check_unsafe_block(cx: &Context, e: &ast::Expr) {
894+
match e.node {
895+
// Don't warn about generated blocks, that'll just pollute the output.
896+
ast::ExprBlock(ref blk) if blk.rules == ast::UnsafeBlock(ast::UserProvided) => {
897+
cx.span_lint(unsafe_block, blk.span, "usage of an `unsafe` block");
898+
}
899+
_ => ()
900+
}
901+
}
902+
886903
fn check_unused_mut_pat(cx: &Context, p: @ast::Pat) {
887904
match p.node {
888905
ast::PatIdent(ast::BindByValue(ast::MutMutable),
@@ -1126,6 +1143,7 @@ impl<'self> Visitor<()> for Context<'self> {
11261143
check_while_true_expr(self, e);
11271144
check_stability(self, e);
11281145
check_unused_unsafe(self, e);
1146+
check_unsafe_block(self, e);
11291147
check_unnecessary_allocation(self, e);
11301148
check_heap_expr(self, e);
11311149

trunk/src/librustdoc/html/render.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -466,15 +466,14 @@ impl DocFolder for Cache {
466466
// Register any generics to their corresponding string. This is used
467467
// when pretty-printing types
468468
match item.inner {
469-
clean::StructItem(ref s) => self.generics(&s.generics),
470-
clean::EnumItem(ref e) => self.generics(&e.generics),
471-
clean::FunctionItem(ref f) => self.generics(&f.generics),
472-
clean::TypedefItem(ref t) => self.generics(&t.generics),
473-
clean::TraitItem(ref t) => self.generics(&t.generics),
474-
clean::ImplItem(ref i) => self.generics(&i.generics),
475-
clean::TyMethodItem(ref i) => self.generics(&i.generics),
476-
clean::MethodItem(ref i) => self.generics(&i.generics),
477-
clean::ForeignFunctionItem(ref f) => self.generics(&f.generics),
469+
clean::StructItem(ref s) => self.generics(&s.generics),
470+
clean::EnumItem(ref e) => self.generics(&e.generics),
471+
clean::FunctionItem(ref f) => self.generics(&f.generics),
472+
clean::TypedefItem(ref t) => self.generics(&t.generics),
473+
clean::TraitItem(ref t) => self.generics(&t.generics),
474+
clean::ImplItem(ref i) => self.generics(&i.generics),
475+
clean::TyMethodItem(ref i) => self.generics(&i.generics),
476+
clean::MethodItem(ref i) => self.generics(&i.generics),
478477
_ => {}
479478
}
480479

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2013 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+
#[allow(unused_unsafe)];
12+
#[deny(unsafe_block)];
13+
14+
unsafe fn allowed() {}
15+
16+
#[allow(unsafe_block)] fn also_allowed() { unsafe {} }
17+
18+
fn main() {
19+
unsafe {} //~ ERROR: usage of an `unsafe` block
20+
}

0 commit comments

Comments
 (0)