Skip to content

Rollup of 7 pull requests #36300

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 21 commits into from
Closed
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3401f4e
Add E0466 error explanation
GuillaumeGomez Aug 29, 2016
b9eaeb1
Add E0467 error explanation
GuillaumeGomez Aug 29, 2016
e32dad3
Add E0468 error explanation
GuillaumeGomez Aug 29, 2016
980402c
Add E0469 error explanation
GuillaumeGomez Aug 29, 2016
5629f7e
Add E0470 error explanation
GuillaumeGomez Aug 29, 2016
7c53eb9
Add librustc metadata error codes to global check
GuillaumeGomez Aug 29, 2016
8d3fd03
Clean up thread-local storage docs
apasel422 Sep 4, 2016
1aa777b
Updated E0559 to new format
Cobrand Sep 4, 2016
e4784fc
Remove mention of `unsafe_no_drop_flag` from Reference and Nomicon
apasel422 Sep 5, 2016
d53ea97
E0516 Update error format #36108
gavinb Aug 30, 2016
8bcd6a3
E0517 Update error format #36109
gavinb Aug 30, 2016
cd56d47
E0518 Update error format #36111
gavinb Aug 30, 2016
e8c5dc4
Updated E0527 to new error format
Cobrand Aug 29, 2016
dc0e9c0
Add missing urls
GuillaumeGomez Sep 6, 2016
d3b305e
Rollup merge of #36102 - GuillaumeGomez:rustc_metadata_diagnostics, r…
Sep 6, 2016
a4a9f04
Rollup merge of #36121 - Cobrand:master, r=jonathandturner
Sep 6, 2016
f03886e
Rollup merge of #36128 - gavinb:error_msgs_p2, r=jonathandturner
Sep 6, 2016
0ffa53f
Rollup merge of #36263 - apasel422:scoped, r=steveklabnik
Sep 6, 2016
d21e489
Rollup merge of #36267 - Cobrand:E0559, r=jonathandturner
Sep 6, 2016
f654719
Rollup merge of #36273 - apasel422:unsafe_no_drop_flag, r=steveklabnik
Sep 6, 2016
c059459
Rollup merge of #36298 - GuillaumeGomez:hashmap_doc, r=steveklabnik
Sep 6, 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
4 changes: 0 additions & 4 deletions src/doc/nomicon/safe-unsafe-meaning.md
Original file line number Diff line number Diff line change
@@ -26,10 +26,6 @@ can therefore be trusted. You can use `unsafe` on a trait implementation
to declare that the implementation of that trait has adhered to whatever
contracts the trait's documentation requires.

There is also the `#[unsafe_no_drop_flag]` attribute, which exists for
historic reasons and is being phased out. See the section on [drop flags]
for details.

The standard library has a number of unsafe functions, including:

* `slice::get_unchecked`, which performs unchecked indexing, allowing
10 changes: 0 additions & 10 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
@@ -2059,10 +2059,6 @@ macro scope.
outside of its dynamic extent), and thus this attribute has the word
"unsafe" in its name. To use this, the
`unsafe_destructor_blind_to_params` feature gate must be enabled.
- `unsafe_no_drop_flag` - on structs, remove the flag that prevents
destructors from being run twice. Destructors might be run multiple times on
the same object with this attribute. To use this, the `unsafe_no_drop_flag` feature
gate must be enabled.
- `doc` - Doc comments such as `/// foo` are equivalent to `#[doc = "foo"]`.
- `rustc_on_unimplemented` - Write a custom note to be shown along with the error
when the trait is found to be unimplemented on a type.
@@ -2458,12 +2454,6 @@ The currently implemented features of the reference compiler are:
* `unboxed_closures` - Rust's new closure design, which is currently a work in
progress feature with many known bugs.

* `unsafe_no_drop_flag` - Allows use of the `#[unsafe_no_drop_flag]` attribute,
which removes hidden flag added to a type that
implements the `Drop` trait. The design for the
`Drop` flag is subject to change, and this feature
may be removed in the future.

* `unmarked_api` - Allows use of items within a `#![staged_api]` crate
which have not been marked with a stability marker.
Such items should not be allowed by the compiler to exist,
24 changes: 16 additions & 8 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
@@ -42,7 +42,9 @@ struct CheckAttrVisitor<'a> {
impl<'a> CheckAttrVisitor<'a> {
fn check_inline(&self, attr: &ast::Attribute, target: Target) {
if target != Target::Fn {
span_err!(self.sess, attr.span, E0518, "attribute should be applied to function");
struct_span_err!(self.sess, attr.span, E0518, "attribute should be applied to function")
.span_label(attr.span, &format!("requires a function"))
.emit();
}
}

@@ -56,18 +58,20 @@ impl<'a> CheckAttrVisitor<'a> {

let mut conflicting_reprs = 0;
for word in words {

let name = match word.name() {
Some(word) => word,
None => continue,
};

let message = match &*name {
let (message, label) = match &*name {
"C" => {
conflicting_reprs += 1;
if target != Target::Struct &&
target != Target::Union &&
target != Target::Enum {
"attribute should be applied to struct, enum or union"
("attribute should be applied to struct, enum or union",
"a struct, enum or union")
} else {
continue
}
@@ -77,15 +81,17 @@ impl<'a> CheckAttrVisitor<'a> {
// can be used to modify another repr hint
if target != Target::Struct &&
target != Target::Union {
"attribute should be applied to struct or union"
("attribute should be applied to struct or union",
"a struct or union")
} else {
continue
}
}
"simd" => {
conflicting_reprs += 1;
if target != Target::Struct {
"attribute should be applied to struct"
("attribute should be applied to struct",
"a struct")
} else {
continue
}
@@ -95,15 +101,17 @@ impl<'a> CheckAttrVisitor<'a> {
"isize" | "usize" => {
conflicting_reprs += 1;
if target != Target::Enum {
"attribute should be applied to enum"
("attribute should be applied to enum",
"an enum")
} else {
continue
}
}
_ => continue,
};

span_err!(self.sess, attr.span, E0517, "{}", message);
struct_span_err!(self.sess, attr.span, E0517, "{}", message)
.span_label(attr.span, &format!("requires {}", label))
.emit();
}
if conflicting_reprs > 1 {
span_warn!(self.sess, attr.span, E0566,
1 change: 1 addition & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
@@ -1139,6 +1139,7 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
all_errors.extend_from_slice(&rustc_privacy::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_trans::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_const_eval::DIAGNOSTICS);
all_errors.extend_from_slice(&rustc_metadata::DIAGNOSTICS);

Registry::new(&all_errors)
}
188 changes: 181 additions & 7 deletions src/librustc_metadata/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@ A link name was given with an empty name. Erroneous code example:
The rust compiler cannot link to an external library if you don't give it its
name. Example:

```
```ignore
#[link(name = "some_lib")] extern {} // ok!
```
"##,
@@ -72,7 +72,7 @@ A link was used without a name parameter. Erroneous code example:
Please add the name parameter to allow the rust compiler to find the library
you want. Example:

```
```ignore
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
```
"##,
@@ -91,6 +91,185 @@ You need to link your code to the relevant crate in order to be able to use it
well, and you link to them the same way.
"##,

E0466: r##"
Macro import declarations were malformed.

Erroneous code examples:

```compile_fail,E0466
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
extern crate some_crate;

#[macro_use(i_want = "some_macros")] // error: invalid import declaration
extern crate another_crate;
```

This is a syntax error at the level of attribute declarations. The proper
syntax for macro imports is the following:

```ignore
// In some_crate:
#[macro_export]
macro_rules! get_tacos {
...
}

#[macro_export]
macro_rules! get_pimientos {
...
}

// In your crate:
#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
extern crate some_crate; // `get_pimientos` macros from some_crate
```

If you would like to import all exported macros, write `macro_use` with no
arguments.
"##,

E0467: r##"
Macro reexport declarations were empty or malformed.

Erroneous code examples:

```compile_fail,E0467
#[macro_reexport] // error: no macros listed for export
extern crate macros_for_good;

#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
extern crate other_macros_for_good;
```

This is a syntax error at the level of attribute declarations.

Currently, `macro_reexport` requires at least one macro name to be listed.
Unlike `macro_use`, listing no names does not reexport all macros from the
given crate.

Decide which macros you would like to export and list them properly.

These are proper reexport declarations:

```ignore
#[macro_reexport(some_macro, another_macro)]
extern crate macros_for_good;
```
"##,

E0468: r##"
A non-root module attempts to import macros from another crate.

Example of erroneous code:

```compile_fail,E0468
mod foo {
#[macro_use(helpful_macro)] // error: must be at crate root to import
extern crate some_crate; // macros from another crate
helpful_macro!(...)
}
```

Only `extern crate` imports at the crate root level are allowed to import
macros.

Either move the macro import to crate root or do without the foreign macros.
This will work:

```ignore
#[macro_use(helpful_macro)]
extern crate some_crate;

mod foo {
helpful_macro!(...)
}
```
"##,

E0469: r##"
A macro listed for import was not found.

Erroneous code example:

```compile_fail,E0469
#[macro_use(drink, be_merry)] // error: imported macro not found
extern crate collections;

fn main() {
// ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for import, and that the crate
in question exports them.

A working version would be:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
...
}

#[macro_export]
macro_rules! drink {
...
}

// In your crate:
#[macro_use(eat, drink)]
extern crate some_crate; //ok!
```
"##,

E0470: r##"
A macro listed for reexport was not found.

Erroneous code example:

```compile_fail,E0470
#[macro_reexport(drink, be_merry)]
extern crate collections;

fn main() {
// ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for reexport, and that the crate
in question exports them.

A working version:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
...
}

#[macro_export]
macro_rules! drink {
...
}

// In your_crate:
#[macro_reexport(eat, drink)]
extern crate some_crate;
```
"##,

}

register_diagnostics! {
@@ -102,11 +281,6 @@ register_diagnostics! {
E0462, // found staticlib `..` instead of rlib or dylib
E0464, // multiple matching crates for `..`
E0465, // multiple .. candidates for `..` found
E0466, // bad macro import
E0467, // bad macro reexport
E0468, // an `extern crate` loading macros must be at the crate root
E0469, // imported macro not found
E0470, // reexported macro not found
E0519, // local crate and dependency have same (crate-name, disambiguator)
E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
}
2 changes: 2 additions & 0 deletions src/librustc_metadata/lib.rs
Original file line number Diff line number Diff line change
@@ -68,3 +68,5 @@ pub mod index;
pub mod loader;
pub mod macro_import;
pub mod tls_context;

__build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
7 changes: 5 additions & 2 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
@@ -1769,8 +1769,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
}
}
hir::TyTypeof(ref _e) => {
span_err!(tcx.sess, ast_ty.span, E0516,
"`typeof` is a reserved keyword but unimplemented");
struct_span_err!(tcx.sess, ast_ty.span, E0516,
"`typeof` is a reserved keyword but unimplemented")
.span_label(ast_ty.span, &format!("reserved keyword"))
.emit();

tcx.types.err
}
hir::TyInfer => {
9 changes: 6 additions & 3 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
@@ -233,9 +233,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let min_len = before.len() + after.len();
if slice.is_none() {
if min_len != size {
span_err!(tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size);
struct_span_err!(
tcx.sess, pat.span, E0527,
"pattern requires {} elements but array has {}",
min_len, size)
.span_label(pat.span, &format!("expected {} elements",size))
.emit();
}
(inner_ty, tcx.types.err)
} else if let Some(rest) = size.checked_sub(min_len) {
28 changes: 16 additions & 12 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -118,7 +118,6 @@ use syntax::parse::token::{self, InternedString, keywords};
use syntax::ptr::P;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{self, Span};
use errors::DiagnosticBuilder;

use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::{self, PatKind};
@@ -2959,7 +2958,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}, expr_t);
match expr_t.sty {
ty::TyStruct(def, _) | ty::TyUnion(def, _) => {
Self::suggest_field_names(&mut err, def.struct_variant(), field, vec![]);
if let Some(suggested_field_name) =
Self::suggest_field_name(def.struct_variant(), field, vec![]) {
err.span_help(field.span,
&format!("did you mean `{}`?", suggested_field_name));
};
}
ty::TyRawPtr(..) => {
err.note(&format!("`{0}` is a native pointer; perhaps you need to deref with \
@@ -2972,11 +2975,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
}

// displays hints about the closest matches in field names
fn suggest_field_names(err: &mut DiagnosticBuilder,
variant: ty::VariantDef<'tcx>,
field: &Spanned<ast::Name>,
skip : Vec<InternedString>) {
// Return an hint about the closest match in field names
fn suggest_field_name(variant: ty::VariantDef<'tcx>,
field: &Spanned<ast::Name>,
skip : Vec<InternedString>)
-> Option<InternedString> {
let name = field.node.as_str();
let names = variant.fields.iter().filter_map(|field| {
// ignore already set fields and private fields from non-local crates
@@ -2989,10 +2992,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
});

// only find fits with at least one matching letter
if let Some(name) = find_best_match_for_name(names, &name, Some(name.len())) {
err.span_help(field.span,
&format!("did you mean `{}`?", name));
}
find_best_match_for_name(names, &name, Some(name.len()))
}

// Check tuple index expressions
@@ -3086,7 +3086,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty);
// prevent all specified fields from being suggested
let skip_fields = skip_fields.iter().map(|ref x| x.name.node.as_str());
Self::suggest_field_names(&mut err, variant, &field.name, skip_fields.collect());
if let Some(field_name) = Self::suggest_field_name(variant,
&field.name,
skip_fields.collect()) {
err.span_label(field.name.span,&format!("did you mean `{}`?",field_name));
};
err.emit();
}

60 changes: 42 additions & 18 deletions src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
@@ -206,7 +206,7 @@ fn test_resize_policy() {
/// require this behavior you can create your own hashing function using
/// [BuildHasherDefault](../hash/struct.BuildHasherDefault.html).
///
/// It is required that the keys implement the `Eq` and `Hash` traits, although
/// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although
/// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`.
/// If you implement these yourself, it is important that the following
/// property holds:
@@ -218,9 +218,9 @@ fn test_resize_policy() {
/// In other words, if two keys are equal, their hashes must be equal.
///
/// It is a logic error for a key to be modified in such a way that the key's
/// hash, as determined by the `Hash` trait, or its equality, as determined by
/// the `Eq` trait, changes while it is in the map. This is normally only
/// possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
/// the [`Eq`] trait, changes while it is in the map. This is normally only
/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
///
/// Relevant papers/articles:
///
@@ -298,8 +298,14 @@ fn test_resize_policy() {
/// *stat += random_stat_buff();
/// ```
///
/// The easiest way to use `HashMap` with a custom type as key is to derive `Eq` and `Hash`.
/// We must also derive `PartialEq`.
/// The easiest way to use `HashMap` with a custom type as key is to derive [`Eq`] and [`Hash`].
/// We must also derive [`PartialEq`].
///
/// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html
/// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html
/// [`RefCell`]: ../../std/cell/struct.RefCell.html
/// [`Cell`]: ../../std/cell/struct.Cell.html
///
/// ```
/// use std::collections::HashMap;
@@ -525,7 +531,7 @@ impl<K, V, S> HashMap<K, V, S>
}

impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
/// Creates an empty HashMap.
/// Creates an empty `HashMap`.
///
/// # Examples
///
@@ -539,7 +545,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
Default::default()
}

/// Creates an empty hash map with the given initial capacity.
/// Creates an empty `HashMap` with the given initial capacity.
///
/// # Examples
///
@@ -557,7 +563,7 @@ impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
impl<K, V, S> HashMap<K, V, S>
where K: Eq + Hash, S: BuildHasher
{
/// Creates an empty hashmap which will use the given hash builder to hash
/// Creates an empty `HashMap` which will use the given hash builder to hash
/// keys.
///
/// The created map has the default initial capacity.
@@ -587,7 +593,7 @@ impl<K, V, S> HashMap<K, V, S>
}
}

/// Creates an empty HashMap with space for at least `capacity`
/// Creates an empty `HashMap` with space for at least `capacity`
/// elements, using `hasher` to hash the keys.
///
/// Warning: `hasher` is normally randomly generated, and
@@ -677,7 +683,7 @@ impl<K, V, S> HashMap<K, V, S>
/// Resizes the internal vectors to a new capacity. It's your responsibility to:
/// 1) Make sure the new capacity is enough for all the elements, accounting
/// for the load factor.
/// 2) Ensure new_capacity is a power of two or zero.
/// 2) Ensure `new_capacity` is a power of two or zero.
fn resize(&mut self, new_capacity: usize) {
assert!(self.table.size() <= new_capacity);
assert!(new_capacity.is_power_of_two() || new_capacity == 0);
@@ -1040,9 +1046,12 @@ impl<K, V, S> HashMap<K, V, S>
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html
///
/// # Examples
///
/// ```
@@ -1063,9 +1072,12 @@ impl<K, V, S> HashMap<K, V, S>
/// Returns true if the map contains a value for the specified key.
///
/// The key may be any borrowed form of the map's key type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html
///
/// # Examples
///
/// ```
@@ -1086,9 +1098,12 @@ impl<K, V, S> HashMap<K, V, S>
/// Returns a mutable reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html
///
/// # Examples
///
/// ```
@@ -1143,9 +1158,12 @@ impl<K, V, S> HashMap<K, V, S>
/// was previously in the map.
///
/// The key may be any borrowed form of the map's key type, but
/// `Hash` and `Eq` on the borrowed form *must* match those for
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// [`Eq`]: ../../std/cmp/trait.Eq.html
/// [`Hash`]: ../../std/hash/trait.Hash.html
///
/// # Examples
///
/// ```
@@ -1904,12 +1922,15 @@ impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap<K, V, S>
}
}

/// `RandomState` is the default state for `HashMap` types.
/// `RandomState` is the default state for [`HashMap`] types.
///
/// A particular instance `RandomState` will create the same instances of
/// `Hasher`, but the hashers created by two different `RandomState`
/// [`Hasher`], but the hashers created by two different `RandomState`
/// instances are unlikely to produce the same result for the same values.
///
/// [`HashMap`]: struct.HashMap.html
/// [`Hasher`]: ../../hash/trait.Hasher.html
///
/// # Examples
///
/// ```
@@ -1980,10 +2001,13 @@ impl BuildHasher for RandomState {
}
}

/// The default `Hasher` used by `RandomState`.
/// The default [`Hasher`] used by [`RandomState`].
///
/// The internal algorithm is not specified, and so it and its hashes should
/// not be relied upon over releases.
///
/// [`RandomState`]: struct.RandomState.html
/// [`Hasher`]: ../../hash/trait.Hasher.html
#[unstable(feature = "hashmap_default_hasher", issue = "0")]
pub struct DefaultHasher(SipHasher13);

35 changes: 15 additions & 20 deletions src/libstd/thread/mod.rs
Original file line number Diff line number Diff line change
@@ -135,29 +135,24 @@
//!
//! ## Thread-local storage
//!
//! This module also provides an implementation of thread local storage for Rust
//! programs. Thread local storage is a method of storing data into a global
//! variable which each thread in the program will have its own copy of.
//! This module also provides an implementation of thread-local storage for Rust
//! programs. Thread-local storage is a method of storing data into a global
//! variable that each thread in the program will have its own copy of.
//! Threads do not share this data, so accesses do not need to be synchronized.
//!
//! At a high level, this module provides two variants of storage:
//!
//! * Owned thread-local storage. This is a type of thread local key which
//! owns the value that it contains, and will destroy the value when the
//! thread exits. This variant is created with the `thread_local!` macro and
//! can contain any value which is `'static` (no borrowed pointers).
//!
//! * Scoped thread-local storage. This type of key is used to store a reference
//! to a value into local storage temporarily for the scope of a function
//! call. There are no restrictions on what types of values can be placed
//! into this key.
//!
//! Both forms of thread local storage provide an accessor function, `with`,
//! which will yield a shared reference to the value to the specified
//! closure. Thread-local keys only allow shared access to values as there is no
//! way to guarantee uniqueness if a mutable borrow was allowed. Most values
//! A thread-local key owns the value it contains and will destroy the value when the
//! thread exits. It is created with the [`thread_local!`] macro and can contain any
//! value that is `'static` (no borrowed pointers). It provides an accessor function,
//! [`with`], that yields a shared reference to the value to the specified
//! closure. Thread-local keys allow only shared access to values, as there would be no
//! way to guarantee uniqueness if mutable borrows were allowed. Most values
//! will want to make use of some form of **interior mutability** through the
//! `Cell` or `RefCell` types.
//! [`Cell`] or [`RefCell`] types.
//!
//! [`Cell`]: ../cell/struct.Cell.html
//! [`RefCell`]: ../cell/struct.RefCell.html
//! [`thread_local!`]: ../macro.thread_local!.html
//! [`with`]: struct.LocalKey.html#method.with
#![stable(feature = "rust1", since = "1.0.0")]

1 change: 1 addition & 0 deletions src/test/compile-fail/E0516.rs
Original file line number Diff line number Diff line change
@@ -10,4 +10,5 @@

fn main() {
let x: typeof(92) = 92; //~ ERROR E0516
//~| reserved keyword
}
4 changes: 4 additions & 0 deletions src/test/compile-fail/E0517.rs
Original file line number Diff line number Diff line change
@@ -9,15 +9,19 @@
// except according to those terms.

#[repr(C)] //~ ERROR E0517
//~| requires a struct, enum or union
type Foo = u8;

#[repr(packed)] //~ ERROR E0517
//~| requires a struct
enum Foo2 {Bar, Baz}

#[repr(u8)] //~ ERROR E0517
//~| requires an enum
struct Foo3 {bar: bool, baz: bool}

#[repr(C)] //~ ERROR E0517
//~| requires a struct, enum or union
impl Foo3 {
}

2 changes: 2 additions & 0 deletions src/test/compile-fail/E0518.rs
Original file line number Diff line number Diff line change
@@ -9,9 +9,11 @@
// except according to those terms.

#[inline(always)] //~ ERROR E0518
//~| requires a function
struct Foo;

#[inline(never)] //~ ERROR E0518
//~| requires a function
impl Foo {
}

4 changes: 3 additions & 1 deletion src/test/compile-fail/E0527.rs
Original file line number Diff line number Diff line change
@@ -13,7 +13,9 @@
fn main() {
let r = &[1, 2, 3, 4];
match r {
&[a, b] => { //~ ERROR E0527
&[a, b] => {
//~^ ERROR E0527
//~| NOTE expected 4 elements
println!("a={}, b={}", a, b);
}
}
4 changes: 3 additions & 1 deletion src/test/compile-fail/E0559.rs
Original file line number Diff line number Diff line change
@@ -13,5 +13,7 @@ enum Field {
}

fn main() {
let s = Field::Fool { joke: 0 }; //~ ERROR E0559
let s = Field::Fool { joke: 0 };
//~^ ERROR E0559
//~| NOTE did you mean `x`?
}
5 changes: 3 additions & 2 deletions src/test/compile-fail/struct-fields-hints-no-dupe.rs
Original file line number Diff line number Diff line change
@@ -17,8 +17,9 @@ struct A {
fn main() {
let a = A {
foo : 5,
bar : 42,//~ ERROR struct `A` has no field named `bar`
//~^ HELP did you mean `barr`?
bar : 42,
//~^ ERROR struct `A` has no field named `bar`
//~| NOTE did you mean `barr`?
car : 9,
};
}
5 changes: 3 additions & 2 deletions src/test/compile-fail/struct-fields-hints.rs
Original file line number Diff line number Diff line change
@@ -17,7 +17,8 @@ struct A {
fn main() {
let a = A {
foo : 5,
bar : 42,//~ ERROR struct `A` has no field named `bar`
//~^ HELP did you mean `car`?
bar : 42,
//~^ ERROR struct `A` has no field named `bar`
//~| NOTE did you mean `car`?
};
}
20 changes: 12 additions & 8 deletions src/test/compile-fail/suggest-private-fields.rs
Original file line number Diff line number Diff line change
@@ -22,16 +22,20 @@ struct A {
fn main () {
// external crate struct
let k = B {
aa: 20, //~ ERROR struct `xc::B` has no field named `aa`
//~^ HELP did you mean `a`?
bb: 20, //~ ERROR struct `xc::B` has no field named `bb`
//~^ HELP did you mean `a`?
aa: 20,
//~^ ERROR struct `xc::B` has no field named `aa`
//~| NOTE did you mean `a`?
bb: 20,
//~^ ERROR struct `xc::B` has no field named `bb`
//~| NOTE did you mean `a`?
};
// local crate struct
let l = A {
aa: 20, //~ ERROR struct `A` has no field named `aa`
//~^ HELP did you mean `a`?
bb: 20, //~ ERROR struct `A` has no field named `bb`
//~^ HELP did you mean `b`?
aa: 20,
//~^ ERROR struct `A` has no field named `aa`
//~| NOTE did you mean `a`?
bb: 20,
//~^ ERROR struct `A` has no field named `bb`
//~| NOTE did you mean `b`?
};
}
5 changes: 3 additions & 2 deletions src/test/compile-fail/union/union-suggest-field.rs
Original file line number Diff line number Diff line change
@@ -19,8 +19,9 @@ impl U {
}

fn main() {
let u = U { principle: 0 }; //~ ERROR union `U` has no field named `principle`
//~^ HELP did you mean `principal`?
let u = U { principle: 0 };
//~^ ERROR union `U` has no field named `principle`
//~| NOTE did you mean `principal`?
let w = u.principial; //~ ERROR attempted access of field `principial` on type `U`
//~^ HELP did you mean `principal`?