Skip to content

Rollup of 15 pull requests #33629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 31 commits into from
Closed
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
66404f3
Simplify text
dns2utf8 May 10, 2016
85e0242
Add error description for E0455
cristianoliveira May 4, 2016
7a9f4c2
Add E0500 error explanation
GuillaumeGomez May 10, 2016
5cbfa12
Fix typo in std::sync::Once documentation
Amanieu May 11, 2016
bf09a9e
Add detailed error explanation for E0505
billyevans May 6, 2016
6458b04
Cleanup formatting and wording for `std::env::temp_dir` docs.
frewsxcv May 12, 2016
a7902b1
Tighten span for E0063
sanxiyn May 12, 2016
843b174
typeck: if a private field exists, also check for a public method
birkenfeld May 2, 2016
df4fe5f
update "reason" for fnbox feature gate
durka May 12, 2016
b9fce76
fix tidy
durka May 12, 2016
91e43ac
Use the correct word in the explanation
dns2utf8 May 12, 2016
d4bff0c
doc: Fix comment in std::string::String example code
haikoschol May 12, 2016
1e901de
Add error explanations for E0374, E0375, E0376 on issue #33383
dfockler May 4, 2016
a181d2f
doc: line these comments up
tshepang May 12, 2016
10c984a
doc: use less awkward and less confusing language
tshepang May 12, 2016
226cb9c
doc: to_string not needed since we gots coercion
tshepang May 12, 2016
8176a7c
Rollup merge of #33342 - birkenfeld:issue-26472, r=jseyfried
sanxiyn May 14, 2016
9c50746
Rollup merge of #33393 - cristianoliveira:docs-error-explanation, r=s…
sanxiyn May 14, 2016
8c656ec
Rollup merge of #33415 - dfockler:master, r=steveklabnik
sanxiyn May 14, 2016
13d0d6a
Rollup merge of #33475 - billyevans:master, r=guillaumegomez
sanxiyn May 14, 2016
f28138d
Rollup merge of #33517 - sanxiyn:tight-span, r=nagisa
sanxiyn May 14, 2016
7de362a
Rollup merge of #33533 - GuillaumeGomez:add_E0500, r=steveklabnik
sanxiyn May 14, 2016
a4a7462
Rollup merge of #33534 - dns2utf8:atomic_docs, r=GuillaumeGomez
sanxiyn May 14, 2016
ec48f47
Rollup merge of #33565 - Amanieu:once_doc, r=GuillaumeGomez
sanxiyn May 14, 2016
a8a67ad
Rollup merge of #33580 - frewsxcv:temp-dir, r=alexcrichton
sanxiyn May 14, 2016
2f3f79b
Rollup merge of #33590 - durka:patch-22, r=aturon
sanxiyn May 14, 2016
fb59641
Rollup merge of #33591 - dns2utf8:systemtime_wording, r=GuillaumeGomez
sanxiyn May 14, 2016
5686aa6
Rollup merge of #33598 - haikoschol:master, r=alexcrichton
sanxiyn May 14, 2016
344b02b
Rollup merge of #33603 - tshepang:no-need, r=apasel422
sanxiyn May 14, 2016
4433903
Rollup merge of #33604 - tshepang:line-em-up, r=GuillaumeGomez
sanxiyn May 14, 2016
7ba8ec7
Rollup merge of #33605 - tshepang:less-awkward, r=steveklabnik
sanxiyn May 14, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/liballoc/boxed.rs
Original file line number Diff line number Diff line change
@@ -525,14 +525,16 @@ impl<I: ExactSizeIterator + ?Sized> ExactSizeIterator for Box<I> {}
/// }
/// ```
#[rustc_paren_sugar]
#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
pub trait FnBox<A> {
type Output;

fn call_box(self: Box<Self>, args: A) -> Self::Output;
}

#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
impl<A, F> FnBox<A> for F where F: FnOnce<A>
{
type Output = F::Output;
@@ -542,7 +544,8 @@ impl<A, F> FnBox<A> for F where F: FnOnce<A>
}
}

#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
type Output = R;

@@ -551,7 +554,8 @@ impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + 'a> {
}
}

#[unstable(feature = "fnbox", reason = "Newly introduced", issue = "28796")]
#[unstable(feature = "fnbox",
reason = "will be deprecated if and when Box<FnOnce> becomes usable", issue = "28796")]
impl<'a, A, R> FnOnce<A> for Box<FnBox<A, Output = R> + Send + 'a> {
type Output = R;

10 changes: 5 additions & 5 deletions src/libcollections/fmt.rs
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@
//!
//! ```
//! format!("{argument}", argument = "test"); // => "test"
//! format!("{name} {}", 1, name = 2); // => "2 1"
//! format!("{name} {}", 1, name = 2); // => "2 1"
//! format!("{a} {c} {b}", a="a", b='b', c=3); // => "a 3 b"
//! ```
//!
@@ -104,8 +104,8 @@
//! octal.
//!
//! There are various parameters which do require a particular type, however.
//! Namely, the `{:.*}` syntax, which sets the number of numbers after the
//! decimal in floating-point types:
//! An example is the `{:.*}` syntax, which sets the number of decimal places
//! in floating-point types:
//!
//! ```
//! let formatted_number = format!("{:.*}", 2, 1.234567);
@@ -527,15 +527,15 @@ use string;
/// use std::fmt;
///
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
/// assert_eq!(s, "Hello, world!".to_string());
/// assert_eq!(s, "Hello, world!");
/// ```
///
/// Please note that using [`format!`][format!] might be preferrable.
/// Example:
///
/// ```
/// let s = format!("Hello, {}!", "world");
/// assert_eq!(s, "Hello, world!".to_string());
/// assert_eq!(s, "Hello, world!");
/// ```
///
/// [format!]: ../macro.format!.html
2 changes: 1 addition & 1 deletion src/libcollections/string.rs
Original file line number Diff line number Diff line change
@@ -184,7 +184,7 @@ use boxed::Box;
/// let len = story.len();
/// let capacity = story.capacity();
///
/// // story has thirteen bytes
/// // story has nineteen bytes
/// assert_eq!(19, len);
///
/// // Now that we have our parts, we throw the story away.
4 changes: 2 additions & 2 deletions src/libcore/sync/atomic.rs
Original file line number Diff line number Diff line change
@@ -142,13 +142,13 @@ pub enum Ordering {
#[stable(feature = "rust1", since = "1.0.0")]
Relaxed,
/// When coupled with a store, all previous writes become visible
/// to another thread that performs a load with `Acquire` ordering
/// to the other threads that perform a load with `Acquire` ordering
/// on the same value.
#[stable(feature = "rust1", since = "1.0.0")]
Release,
/// When coupled with a load, all subsequent loads will see data
/// written before a store with `Release` ordering on the same value
/// in another thread.
/// in other threads.
#[stable(feature = "rust1", since = "1.0.0")]
Acquire,
/// When coupled with a load, uses `Acquire` ordering, and with a store
128 changes: 126 additions & 2 deletions src/librustc_borrowck/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -378,6 +378,53 @@ let c = &i; // still ok!
```
"##,

E0500: r##"
A borrowed variable was used in another closure. Example of erroneous code:

```compile_fail
fn you_know_nothing(jon_snow: &mut i32) {
let nights_watch = || {
*jon_snow = 2;
};
let starks = || {
*jon_snow = 3; // error: closure requires unique access to `jon_snow`
// but it is already borrowed
};
}

In here, `jon_snow` is already borrowed by the `nights_watch` closure, so it
cannot be borrowed by the `starks` closure at the same time. To fix this issue,
you can put the closure in its own scope:

```
fn you_know_nothing(jon_snow: &mut i32) {
{
let nights_watch = || {
*jon_snow = 2;
};
} // At this point, `jon_snow` is free.
let starks = || {
*jon_snow = 3;
};
}
```

Or, if the type implements the `Clone` trait, you can clone it between
closures:

```
fn you_know_nothing(jon_snow: &mut i32) {
let mut jon_copy = jon_snow.clone();
let nights_watch = || {
jon_copy = 2;
};
let starks = || {
*jon_snow = 3;
};
}
```
"##,

E0501: r##"
This error indicates that a mutable variable is being used while it is still
captured by a closure. Because the closure has borrowed the variable, it is not
@@ -642,6 +689,85 @@ fn print_fancy_ref(fancy_ref: &FancyNum){
```
"##,

E0505: r##"
A value was moved out while it was still borrowed.
Erroneous code example:

```compile_fail
struct Value {}

fn eat(val: Value) {}

fn main() {
let x = Value{};
{
let _ref_to_val: &Value = &x;
eat(x);
}
}
```

Here, the function `eat` takes the ownership of `x`. However,
`x` cannot be moved because it was borrowed to `_ref_to_val`.
To fix that you can do few different things:

* Try to avoid moving the variable.
* Release borrow before move.
* Implement the `Copy` trait on the type.

Examples:

```
struct Value {}

fn eat(val: &Value) {}

fn main() {
let x = Value{};
{
let _ref_to_val: &Value = &x;
eat(&x); // pass by reference, if it's possible
}
}
```

Or:

```
struct Value {}

fn eat(val: Value) {}

fn main() {
let x = Value{};
{
let _ref_to_val: &Value = &x;
}
eat(x); // release borrow and then move it.
}
```

Or:

```
#[derive(Clone, Copy)] // implement Copy trait
struct Value {}

fn eat(val: Value) {}

fn main() {
let x = Value{};
{
let _ref_to_val: &Value = &x;
eat(x); // it will be copied here.
}
}
```

You can find more information about borrowing in the rust-book:
http://doc.rust-lang.org/stable/book/references-and-borrowing.html
"##,

E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example:

@@ -857,10 +983,8 @@ fn main() {
register_diagnostics! {
E0385, // {} in an aliasable location
E0388, // {} in a static location
E0500, // closure requires unique access to `..` but .. is already borrowed
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
E0503, // cannot use `..` because it was mutably borrowed
E0505, // cannot move out of `..` because it is borrowed
E0508, // cannot move out of type `..`, a non-copy fixed-size array
E0524, // two closures require unique access to `..` at the same time
}
22 changes: 21 additions & 1 deletion src/librustc_metadata/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -26,6 +26,27 @@ name. Example:
```
"##,

E0455: r##"
Linking with `kind=framework` is only supported when targeting OS X,
as frameworks are specific to that operating system.

Erroneous code example:

```compile_fail"
#[link(name = "FooCoreServices", kind = "framework")] extern {}
// OS used to compile is Linux for example
```

To solve this error you can use conditional compilation:

```
#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))]
extern {}
```

See more: https://doc.rust-lang.org/book/conditional-compilation.html
"##,

E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:

@@ -73,7 +94,6 @@ well, and you link to them the same way.
}

register_diagnostics! {
E0455, // native frameworks are only available on OSX targets
E0456, // plugin `..` is not available for triple `..`
E0457, // plugin `..` only found in rlib format, but must be available...
E0514, // metadata version mismatch
5 changes: 3 additions & 2 deletions src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
@@ -84,7 +84,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
span: Span,
method_name: ast::Name,
self_ty: ty::Ty<'tcx>,
call_expr_id: ast::NodeId)
call_expr_id: ast::NodeId,
allow_private: bool)
-> bool
{
let mode = probe::Mode::MethodCall;
@@ -93,7 +94,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Err(NoMatch(..)) => false,
Err(Ambiguity(..)) => true,
Err(ClosureAmbiguity(..)) => true,
Err(PrivateMatch(..)) => true,
Err(PrivateMatch(..)) => allow_private,
}
}

14 changes: 10 additions & 4 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -3052,12 +3052,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {

if let Some((did, field_ty)) = private_candidate {
let struct_path = self.tcx().item_path_str(did);
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
self.tcx().sess.span_err(expr.span, &msg);
self.write_ty(expr.id, field_ty);
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
let mut err = self.tcx().sess.struct_span_err(expr.span, &msg);
// Also check if an accessible method exists, which is often what is meant.
if self.method_exists(field.span, field.node, expr_t, expr.id, false) {
err.note(&format!("a method `{}` also exists, perhaps you wish to call it",
field.node));
}
err.emit();
} else if field.node == keywords::Invalid.name() {
self.write_error(expr.id);
} else if self.method_exists(field.span, field.node, expr_t, expr.id) {
} else if self.method_exists(field.span, field.node, expr_t, expr.id, true) {
self.type_error_struct(field.span, |actual| {
format!("attempted to take value of method `{}` on type \
`{}`", field.node, actual)
@@ -3306,7 +3312,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let expr_ty = self.instantiate_type(def.def_id(), path);
self.write_ty(expr.id, expr_ty);

self.check_expr_struct_fields(expr_ty, expr.span, variant, fields,
self.check_expr_struct_fields(expr_ty, path.span, variant, fields,
base_expr.is_none());
if let &Some(ref base_expr) = base_expr {
self.check_expr_has_type(base_expr, expr_ty);
165 changes: 158 additions & 7 deletions src/librustc_typeck/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -3284,6 +3284,164 @@ impl Baz for Bar { } // Note: This is OK
```
"##,

E0374: r##"
A struct without a field containing an unsized type cannot implement
`CoerceUnsized`. An
[unsized type](https://doc.rust-lang.org/book/unsized-types.html)
is any type that the compiler doesn't know the length or alignment of at
compile time. Any struct containing an unsized type is also unsized.
Example of erroneous code:
```compile_fail
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
struct Foo<T: ?Sized> {
a: i32,
}
// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
where T: CoerceUnsized<U> {}
```
`CoerceUnsized` is used to coerce one struct containing an unsized type
into another struct containing a different unsized type. If the struct
doesn't have any fields of unsized types then you don't need explicit
coercion to get the types you want. To fix this you can either
not try to implement `CoerceUnsized` or you can add a field that is
unsized to the struct.
Example:
```
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
// We don't need to impl `CoerceUnsized` here.
struct Foo {
a: i32,
}
// We add the unsized type field to the struct.
struct Bar<T: ?Sized> {
a: i32,
b: T,
}
// The struct has an unsized field so we can implement
// `CoerceUnsized` for it.
impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
where T: CoerceUnsized<U> {}
```
Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
and `Arc` to be able to mark that they can coerce unsized types that they
are pointing at.
"##,

E0375: r##"
A struct with more than one field containing an unsized type cannot implement
`CoerceUnsized`. This only occurs when you are trying to coerce one of the
types in your struct to another type in the struct. In this case we try to
impl `CoerceUnsized` from `T` to `U` which are both types that the struct
takes. An [unsized type](https://doc.rust-lang.org/book/unsized-types.html)
is any type that the compiler doesn't know the length or alignment of at
compile time. Any struct containing an unsized type is also unsized.
Example of erroneous code:
```compile_fail
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
struct Foo<T: ?Sized, U: ?Sized> {
a: i32,
b: T,
c: U,
}
// error: Struct `Foo` has more than one unsized field.
impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
```
`CoerceUnsized` only allows for coercion from a structure with a single
unsized type field to another struct with a single unsized type field.
In fact Rust only allows for a struct to have one unsized type in a struct
and that unsized type must be the last field in the struct. So having two
unsized types in a single struct is not allowed by the compiler. To fix this
use only one field containing an unsized type in the struct and then use
multiple structs to manage each unsized type field you need.
Example:
```
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
struct Foo<T: ?Sized> {
a: i32,
b: T,
}
impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
where T: CoerceUnsized<U> {}
fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
}
```
"##,

E0376: r##"
The type you are trying to impl `CoerceUnsized` for is not a struct.
`CoerceUnsized` can only be implemented for a struct. Unsized types are
already able to be coerced without an implementation of `CoerceUnsized`
whereas a struct containing an unsized type needs to know the unsized type
field it's containing is able to be coerced. An
[unsized type](https://doc.rust-lang.org/book/unsized-types.html)
is any type that the compiler doesn't know the length or alignment of at
compile time. Any struct containing an unsized type is also unsized.
Example of erroneous code:
```compile_fail
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
struct Foo<T: ?Sized> {
a: T,
}
// error: The type `U` is not a struct
impl<T, U> CoerceUnsized<U> for Foo<T> {}
```
The `CoerceUnsized` trait takes a struct type. Make sure the type you are
providing to `CoerceUnsized` is a struct with only the last field containing an
unsized type.
Example:
```
#![feature(coerce_unsized)]
use std::ops::CoerceUnsized;
struct Foo<T> {
a: T,
}
// The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
```
Note that in Rust, structs can only contain an unsized type if the field
containing the unsized type is the last and only unsized type field in the
struct.
"##,

E0379: r##"
Trait methods cannot be declared `const` by design. For more information, see
[RFC 911].
@@ -3777,13 +3935,6 @@ register_diagnostics! {
E0320, // recursive overflow during dropck
E0328, // cannot implement Unsize explicitly
// E0372, // coherence not object safe
E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, none found
E0375, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, but multiple
// fields need coercions
E0376, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
E0399, // trait items need to be implemented because the associated
20 changes: 10 additions & 10 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
@@ -452,16 +452,16 @@ pub fn home_dir() -> Option<PathBuf> {

/// Returns the path of a temporary directory.
///
/// On Unix, returns the value of the 'TMPDIR' environment variable if it is
/// set, otherwise for non-Android it returns '/tmp'. If Android, since there
/// is no global temporary folder (it is usually allocated per-app), we return
/// '/data/local/tmp'.
///
/// On Windows, returns the value of, in order, the 'TMP', 'TEMP',
/// 'USERPROFILE' environment variable if any are set and not the empty
/// string. Otherwise, tmpdir returns the path of the Windows directory. This
/// behavior is identical to that of [GetTempPath][msdn], which this function
/// uses internally.
/// On Unix, returns the value of the `TMPDIR` environment variable if it is
/// set, otherwise for non-Android it returns `/tmp`. If Android, since there
/// is no global temporary folder (it is usually allocated per-app), it returns
/// `/data/local/tmp`.
///
/// On Windows, returns the value of, in order, the `TMP`, `TEMP`,
/// `USERPROFILE` environment variable if any are set and not the empty
/// string. Otherwise, `temp_dir` returns the path of the Windows directory.
/// This behavior is identical to that of [`GetTempPath`][msdn], which this
/// function uses internally.
///
/// [msdn]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992(v=vs.85).aspx
///
1 change: 0 additions & 1 deletion src/libstd/sync/once.rs
Original file line number Diff line number Diff line change
@@ -218,7 +218,6 @@ impl Once {
/// The closure `f` is yielded a structure which can be used to query the
/// state of this `Once` (whether initialization has previously panicked or
/// not).
/// poisoned or not.
#[unstable(feature = "once_poison", issue = "31688")]
pub fn call_once_force<F>(&'static self, f: F) where F: FnOnce(&OnceState) {
// same as above, just with a different parameter to `call_inner`.
2 changes: 1 addition & 1 deletion src/libstd/time/mod.rs
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ pub struct Instant(time::Instant);
/// Distinct from the `Instant` type, this time measurement **is not
/// monotonic**. This means that you can save a file to the file system, then
/// save another file to the file system, **and the second file has a
/// `SystemTime` measurement earlier than the second**. In other words, an
/// `SystemTime` measurement earlier than the first**. In other words, an
/// operation that happens after another operation in real time may have an
/// earlier `SystemTime`!
///
24 changes: 24 additions & 0 deletions src/test/compile-fail/issue-26472.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod sub {
pub struct S { len: usize }
impl S {
pub fn new() -> S { S { len: 0 } }
pub fn len(&self) -> usize { self.len }
}
}

fn main() {
let s = sub::S::new();
let v = s.len;
//~^ ERROR field `len` of struct `sub::S` is private
//~| NOTE a method `len` also exists, perhaps you wish to call it
}