Auto merge of #25888 - steveklabnik:rollup, r=steveklabnik

- Successful merges: #25788, #25861, #25864, #25865, #25866, #25873, #25876, #25883, #25886
- Failed merges:
This commit is contained in:
bors 2015-05-29 21:00:26 +00:00
commit b77d60adb0
15 changed files with 191 additions and 37 deletions

View File

@ -20,6 +20,7 @@ for any operation that is clearly associated with a particular
type.
Methods have numerous advantages over functions:
* They do not need to be imported or qualified to be used: all you
need is a value of the appropriate type.
* Their invocation performs autoborrowing (including mutable borrows).

View File

@ -159,7 +159,7 @@ fn foo(a: u8) { ... }
Note that
[`ascii::Ascii`](http://static.rust-lang.org/doc/master/std/ascii/struct.Ascii.html)
is a _wrapper_ around `u8` that guarantees the highest bit is zero; see
[newtype patterns]() for more details on creating typesafe wrappers.
[newtype patterns](../types/newtype.md) for more details on creating typesafe wrappers.
Static enforcement usually comes at little run-time cost: it pushes the
costs to the boundaries (e.g. when a `u8` is first converted into an

View File

@ -34,7 +34,7 @@ Prefer
```rust
let foo = match bar {
Baz => 0,
Baz => 0,
Quux => 1
};
```
@ -44,7 +44,7 @@ over
```rust
let foo;
match bar {
Baz => {
Baz => {
foo = 0;
}
Quux => {
@ -61,8 +61,8 @@ conditional expression.
Prefer
```rust
s.iter().map(|x| x * 2)
.collect::<Vec<_>>()
let v = s.iter().map(|x| x * 2)
.collect::<Vec<_>>();
```
over

View File

@ -16,7 +16,7 @@ If `T` is such a data structure, consider introducing a `T` _builder_:
value. When possible, choose a better name: e.g. `Command` is the builder for
`Process`.
2. The builder constructor should take as parameters only the data _required_ to
to make a `T`.
make a `T`.
3. The builder should offer a suite of convenient methods for configuration,
including setting up compound inputs (like slices) incrementally.
These methods should return `self` to allow chaining.

View File

@ -15,7 +15,7 @@ language would.
[rust]: http://rust-lang.org
“The Rust Programming Language” is split into seven sections. This introduction
“The Rust Programming Language” is split into eight sections. This introduction
is the first. After this:
* [Getting started][gs] - Set up your computer for Rust development.

View File

@ -19,7 +19,7 @@ In the example above `x` and `y` have arity 2. `z` has arity 3.
When a compiler is compiling your program, it does a number of different
things. One of the things that it does is turn the text of your program into an
abstract syntax tree, orAST. This tree is a representation of the
abstract syntax tree, or AST. This tree is a representation of the
structure of your program. For example, `2 + 3` can be turned into a tree:
```text

View File

@ -134,8 +134,29 @@ x: &'a i32,
# }
```
uses it. So why do we need a lifetime here? We need to ensure that any
reference to the contained `i32` does not outlive the containing `Foo`.
uses it. So why do we need a lifetime here? We need to ensure that any reference
to a `Foo` cannot outlive the reference to an `i32` it contains.
If you have multiple references, you can use the same lifetime multiple times:
```rust
fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str {
# x
# }
```
This says that `x` and `y` both are alive for the same scope, and that the
return value is also alive for that scope. If you wanted `x` and `y` to have
different lifetimes, you can use multiple lifetime parameters:
```rust
fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
# x
# }
```
In this example, `x` and `y` have different valid scopes, but the return value
has the same lifetime as `x`.
## Thinking in scopes

View File

@ -4,7 +4,7 @@ Functions are great, but if you want to call a bunch of them on some data, it
can be awkward. Consider this code:
```rust,ignore
baz(bar(foo)));
baz(bar(foo));
```
We would read this left-to right, and so we see baz bar foo. But this isnt the

View File

@ -285,7 +285,7 @@ fn bar<T, K>(x: T, y: K) where T: Clone, K: Clone + Debug {
fn main() {
foo("Hello", "world");
bar("Hello", "workd");
bar("Hello", "world");
}
```

View File

@ -52,20 +52,61 @@ pub use intrinsics::transmute;
/// * `mpsc::{Sender, Receiver}` cycles (they use `Arc` internally)
/// * Panicking destructors are likely to leak local resources
///
/// # When To Use
///
/// There's only a few reasons to use this function. They mainly come
/// up in unsafe code or FFI code.
///
/// * You have an uninitialized value, perhaps for performance reasons, and
/// need to prevent the destructor from running on it.
/// * You have two copies of a value (like `std::mem::swap`), but need the
/// destructor to only run once to prevent a double free.
/// * Transferring resources across FFI boundries.
///
/// # Example
///
/// Leak some heap memory by never deallocating it.
///
/// ```rust
/// use std::mem;
///
/// let heap_memory = Box::new(3);
/// mem::forget(heap_memory);
/// ```
///
/// Leak an I/O object, never closing the file.
///
/// ```rust,no_run
/// use std::mem;
/// use std::fs::File;
///
/// // Leak some heap memory by never deallocating it
/// let heap_memory = Box::new(3);
/// mem::forget(heap_memory);
///
/// // Leak an I/O object, never closing the file
/// let file = File::open("foo.txt").unwrap();
/// mem::forget(file);
/// ```
///
/// The swap function uses forget to good effect.
///
/// ```rust
/// use std::mem;
/// use std::ptr;
///
/// fn swap<T>(x: &mut T, y: &mut T) {
/// unsafe {
/// // Give ourselves some scratch space to work with
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping(&*x, &mut t, 1);
/// ptr::copy_nonoverlapping(&*y, x, 1);
/// ptr::copy_nonoverlapping(&t, y, 1);
///
/// // y and t now point to the same thing, but we need to completely
/// // forget `t` because we do not want to run the destructor for `T`
/// // on its value, which is still owned somewhere outside this function.
/// mem::forget(t);
/// }
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn forget<T>(t: T) {
unsafe { intrinsics::forget(t) }
@ -267,8 +308,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
ptr::copy_nonoverlapping(&*y, x, 1);
ptr::copy_nonoverlapping(&t, y, 1);
// y and t now point to the same thing, but we need to completely forget `t`
// because it's no longer relevant.
// y and t now point to the same thing, but we need to completely
// forget `t` because we do not want to run the destructor for `T`
// on its value, which is still owned somewhere outside this function.
forget(t);
}
}

View File

@ -196,9 +196,13 @@ const Y: i32 = A;
"##,
E0015: r##"
The only function calls allowed in static or constant expressions are enum
variant constructors or struct constructors (for unit or tuple structs). This
is because Rust currently does not support compile-time function execution.
The only functions that can be called in static or constant expressions are
`const` functions. Rust currently does not support more general compile-time
function execution.
See [RFC 911] for more details on the design of `const fn`s.
[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
"##,
E0018: r##"
@ -842,6 +846,53 @@ struct Foo<T: 'static> {
foo: &'static T
}
```
"##,
E0378: r##"
Method calls that aren't calls to inherent `const` methods are disallowed
in statics, constants, and constant functions.
For example:
```
const BAZ: i32 = Foo(25).bar(); // error, `bar` isn't `const`
struct Foo(i32);
impl Foo {
const fn foo(&self) -> i32 {
self.bar() // error, `bar` isn't `const`
}
fn bar(&self) -> i32 { self.0 }
}
```
For more information about `const fn`'s, see [RFC 911].
[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
"##,
E0394: r##"
From [RFC 246]:
> It is illegal for a static to reference another static by value. It is
> required that all references be borrowed.
[RFC 246]: https://github.com/rust-lang/rfcs/pull/246
"##,
E0397: r##"
It is not allowed for a mutable static to allocate or have destructors. For
example:
```
// error: mutable statics are not allowed to have boxes
static mut FOO: Option<Box<usize>> = None;
// error: mutable statics are not allowed to have destructors
static mut BAR: Option<Vec<i32>> = None;
```
"##
}
@ -891,9 +942,6 @@ register_diagnostics! {
E0315, // cannot invoke closure outside of its lifetime
E0316, // nested quantification of lifetimes
E0370, // discriminant overflow
E0378, // method calls limited to constant inherent methods
E0394, // cannot refer to other statics by value, use the address-of
// operator or a constant instead
E0395, // pointer comparison in const-expr
E0396 // pointer dereference in const-expr
}

View File

@ -273,13 +273,13 @@ impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
let suffix = if tcontents.has_dtor() {
"destructors"
} else if tcontents.owns_owned() {
"owned pointers"
"boxes"
} else {
return
};
self.tcx.sess.span_err(e.span, &format!("mutable statics are not allowed \
to have {}", suffix));
span_err!(self.tcx.sess, e.span, E0397,
"mutable statics are not allowed to have {}", suffix);
}
fn check_static_type(&self, e: &ast::Expr) {

View File

@ -170,6 +170,31 @@ Reference:
http://doc.rust-lang.org/reference.html#trait-objects
"##,
E0040: r##"
It is not allowed to manually call destructors in Rust. It is also not
necessary to do this since `drop` is called automatically whenever a value goes
out of scope.
Here's an example of this error:
```
struct Foo {
x: i32,
}
impl Drop for Foo {
fn drop(&mut self) {
println!("kaboom");
}
}
fn main() {
let mut x = Foo { x: -7 };
x.drop(); // error: explicit use of destructor method
}
```
"##,
E0046: r##"
When trying to make some type implement a trait `Foo`, you must, at minimum,
provide implementations for all of `Foo`'s required methods (meaning the
@ -241,7 +266,7 @@ impl Foo for Bar {
fn foo(x: i16) { }
// error, values differ in mutability
fn foo(&mut self) { }
fn bar(&mut self) { }
}
```
"##,
@ -542,6 +567,21 @@ enum Empty {}
```
"##,
E0087: r##"
Too many type parameters were supplied for a function. For example:
```
fn foo<T>() {}
fn main() {
foo::<f64, bool>(); // error, expected 1 parameter, found 2 parameters
}
```
The number of supplied parameters much exactly match the number of defined type
parameters.
"##,
E0089: r##"
Not enough type parameters were supplied for a function. For example:
@ -1098,6 +1138,13 @@ Trait2 { ... }`) does not work if the trait is not object-safe. Please see the
[RFC 255]: https://github.com/rust-lang/rfcs/pull/255
"##,
E0379: r##"
Trait methods cannot be declared `const` by design. For more information, see
[RFC 911].
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
"##,
E0380: r##"
Default impls are only allowed for traits with no methods or associated items.
For more information see the [opt-in builtin traits RFC](https://github.com/rust
@ -1113,7 +1160,6 @@ register_diagnostics! {
E0034, // multiple applicable methods in scope
E0035, // does not take type parameters
E0036, // incorrect number of type parameters given for this method
E0040, // explicit use of destructor method
E0044, // foreign items may not have type parameters
E0045, // variadic function must have C calling convention
E0057, // method has an incompatible type for trait
@ -1128,7 +1174,6 @@ register_diagnostics! {
E0077,
E0085,
E0086,
E0087,
E0088,
E0090,
E0091,
@ -1235,7 +1280,6 @@ register_diagnostics! {
// between structures
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
E0379, // trait fns cannot be const
E0390, // only a single inherent implementation marked with
// `#[lang = \"{}\"]` is allowed for the `{}` primitive
E0391, // unsupported cyclic reference between types/traits detected

View File

@ -12,6 +12,6 @@
static mut a: Box<isize> = box 3;
//~^ ERROR allocations are not allowed in statics
//~^^ ERROR mutable statics are not allowed to have owned pointers
//~^^ ERROR mutable statics are not allowed to have boxes
fn main() {}

View File

@ -17,14 +17,12 @@
use std::slice;
pub type IoResult<T> = Result<T, ()>;
trait MyWriter {
fn my_write(&mut self, buf: &[u8]) -> IoResult<()>;
fn my_write(&mut self, buf: &[u8]) -> Result<(), ()>;
}
impl<'a> MyWriter for &'a mut [u8] {
fn my_write(&mut self, buf: &[u8]) -> IoResult<()> {
fn my_write(&mut self, buf: &[u8]) -> Result<(), ()> {
slice::bytes::copy_memory(buf, *self);
let write_len = buf.len();