Auto merge of #53400 - GuillaumeGomez:rollup, r=GuillaumeGomez

Rollup of 8 pull requests

Successful merges:

 - #52453 (improve diagnostics for tests with custom return values)
 - #53271 (use ? to simplify `TransitiveRelation.maybe_map`)
 - #53279 (Extend documentation of `rustc_on_unimplemented`)
 - #53342 (fix error for unsized packed struct field)
 - #53344 (Add doc examples for std::alloc::{alloc,alloc_zeroed}.)
 - #53368 (Ignore test that fails on stage1)
 - #53388 (Fix links' color)
 - #53396 (Fix since of Iterator::flatten to be a proper semver)

Failed merges:

r? @ghost
This commit is contained in:
bors 2018-08-15 19:39:54 +00:00
commit d767ee1161
17 changed files with 206 additions and 58 deletions

View File

@ -1226,6 +1226,11 @@ name = "mac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "macro-utils"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "maplit"
version = "1.0.1"
@ -1303,10 +1308,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "minifier"
version = "0.0.14"
version = "0.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2451,7 +2456,7 @@ dependencies = [
name = "rustdoc"
version = "0.0.0"
dependencies = [
"minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
"minifier 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)",
"pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -3218,6 +3223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19af41f0565d7c19b2058153ad0b42d4d5ce89ec4dbf06ed6741114a8b63e7cd"
"checksum lzma-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d1eaa027402541975218bb0eec67d6b0412f6233af96e0d096d31dbdfd22e614"
"checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
"checksum macro-utils 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2c4deaccc2ead6a28c16c0ba82f07d52b6475397415ce40876e559b0b0ea510"
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
"checksum markup5ever 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfedc97d5a503e96816d10fedcd5b42f760b2e525ce2f7ec71f6a41780548475"
"checksum matches 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "835511bab37c34c47da5cb44844bea2cfde0236db0b506f90ea4224482c9774a"
@ -3225,7 +3231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
"checksum minifier 0.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "78cb57f9a385530d60f2d67f6e108050b478b7a0ffd0bb9c350803e1356535dd"
"checksum minifier 0.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9908ed7c62f990c21ab41fdca53a864a3ada0da69d8729c4de727b397e27bc11"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
"checksum new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0cdc457076c78ab54d5e0d6fa7c47981757f1e34dc39ff92787f217dede586c4"

View File

@ -8,7 +8,9 @@ The tracking issue for this feature is: [#29628]
The `on_unimplemented` feature provides the `#[rustc_on_unimplemented]`
attribute, which allows trait definitions to add specialized notes to error
messages when an implementation was expected but not found.
messages when an implementation was expected but not found. You can refer
to the trait's generic arguments by name and to the resolved type using
`Self`.
For example:
@ -41,7 +43,98 @@ error[E0277]: the trait bound `&[{integer}]: MyIterator<char>` is not satisfied
|
= help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
= note: required by `iterate_chars`
error: aborting due to previous error
```
`on_unimplemented` also supports advanced filtering for better targeting
of messages, as well as modifying specific parts of the error message. You
target the text of:
- the main error message (`message`)
- the label (`label`)
- an extra note (`note`)
For example, the following attribute
```rust,compile_fail
#[rustc_on_unimplemented(
message="message",
label="label",
note="note"
)]
trait MyIterator<A> {
fn next(&mut self) -> A;
}
```
Would generate the following output:
```text
error[E0277]: message
--> <anon>:14:5
|
14 | iterate_chars(&[1, 2, 3][..]);
| ^^^^^^^^^^^^^ label
|
= note: note
= help: the trait `MyIterator<char>` is not implemented for `&[{integer}]`
= note: required by `iterate_chars`
```
To allow more targeted error messages, it is possible to filter the
application of these fields based on a variety of attributes when using
`on`:
- `crate_local`: whether the code causing the trait bound to not be
fulfilled is part of the user's crate. This is used to avoid suggesting
code changes that would require modifying a dependency.
- Any of the generic arguments that can be substituted in the text can be
referred by name as well for filtering, like `Rhs="i32"`, except for
`Self`.
- `_Self`: to filter only on a particular calculated trait resolution, like
`Self="std::iter::Iterator<char>"`. This is needed because `Self` is a
keyword which cannot appear in attributes.
- `direct`: user-specified rather than derived obligation.
- `from_method`: usable both as boolean (whether the flag is present, like
`crate_local`) or matching against a particular method. Currently used
for `try`.
- `from_desugaring`: usable both as boolean (whether the flag is present)
or matching against a particular desugaring.
For example, the `Iterator` trait can be annotated in the following way:
```rust,compile_fail
#[rustc_on_unimplemented(
on(
_Self="&str",
note="call `.chars()` or `.as_bytes()` on `{Self}"
),
message="`{Self}` is not an iterator",
label="`{Self}` is not an iterator",
note="maybe try calling `.iter()` or a similar method"
)]
pub trait Iterator {}
```
Which would produce the following outputs:
```text
error[E0277]: `Foo` is not an iterator
--> src/main.rs:4:16
|
4 | for foo in Foo {}
| ^^^ `Foo` is not an iterator
|
= note: maybe try calling `.iter()` or a similar method
= help: the trait `std::iter::Iterator` is not implemented for `Foo`
= note: required by `std::iter::IntoIterator::into_iter`
error[E0277]: `&str` is not an iterator
--> src/main.rs:5:16
|
5 | for foo in "" {}
| ^^ `&str` is not an iterator
|
= note: call `.chars()` or `.bytes() on `&str`
= help: the trait `std::iter::Iterator` is not implemented for `&str`
= note: required by `std::iter::IntoIterator::into_iter`
```

View File

@ -56,6 +56,22 @@ pub struct Global;
/// # Safety
///
/// See [`GlobalAlloc::alloc`].
///
/// # Examples
///
/// ```
/// use std::alloc::{alloc, dealloc, Layout};
///
/// unsafe {
/// let layout = Layout::new::<u16>();
/// let ptr = alloc(layout);
///
/// *(ptr as *mut u16) = 42;
/// assert_eq!(*(ptr as *mut u16), 42);
///
/// dealloc(ptr, layout);
/// }
/// ```
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn alloc(layout: Layout) -> *mut u8 {
@ -110,6 +126,21 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
/// # Safety
///
/// See [`GlobalAlloc::alloc_zeroed`].
///
/// # Examples
///
/// ```
/// use std::alloc::{alloc_zeroed, dealloc, Layout};
///
/// unsafe {
/// let layout = Layout::new::<u16>();
/// let ptr = alloc_zeroed(layout);
///
/// assert_eq!(*(ptr as *mut u16), 0);
///
/// dealloc(ptr, layout);
/// }
/// ```
#[stable(feature = "global_alloc", since = "1.28.0")]
#[inline]
pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {

View File

@ -1110,7 +1110,7 @@ pub trait Iterator {
///
/// [`flat_map()`]: #method.flat_map
#[inline]
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
fn flatten(self) -> Flatten<Self>
where Self: Sized, Self::Item: IntoIterator {
Flatten { inner: flatten_compat(self) }

View File

@ -2577,13 +2577,13 @@ impl<I, U, F> FusedIterator for FlatMap<I, U, F>
/// [`flatten`]: trait.Iterator.html#method.flatten
/// [`Iterator`]: trait.Iterator.html
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
pub struct Flatten<I: Iterator>
where I::Item: IntoIterator {
inner: FlattenCompat<I, <I::Item as IntoIterator>::IntoIter>,
}
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> fmt::Debug for Flatten<I>
where I: Iterator + fmt::Debug, U: Iterator + fmt::Debug,
I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
@ -2593,7 +2593,7 @@ impl<I, U> fmt::Debug for Flatten<I>
}
}
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Clone for Flatten<I>
where I: Iterator + Clone, U: Iterator + Clone,
I::Item: IntoIterator<IntoIter = U, Item = U::Item>,
@ -2601,7 +2601,7 @@ impl<I, U> Clone for Flatten<I>
fn clone(&self) -> Self { Flatten { inner: self.inner.clone() } }
}
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> Iterator for Flatten<I>
where I: Iterator, U: Iterator,
I::Item: IntoIterator<IntoIter = U, Item = U::Item>
@ -2629,7 +2629,7 @@ impl<I, U> Iterator for Flatten<I>
}
}
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> DoubleEndedIterator for Flatten<I>
where I: DoubleEndedIterator, U: DoubleEndedIterator,
I::Item: IntoIterator<IntoIter = U, Item = U::Item>
@ -2652,7 +2652,7 @@ impl<I, U> DoubleEndedIterator for Flatten<I>
}
}
#[stable(feature = "iterator_flatten", since = "1.29")]
#[stable(feature = "iterator_flatten", since = "1.29.0")]
impl<I, U> FusedIterator for Flatten<I>
where I: FusedIterator, U: Iterator,
I::Item: IntoIterator<IntoIter = U, Item = U::Item> {}

View File

@ -1472,11 +1472,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ObligationCauseCode::StructInitializerSized => {
err.note("structs must have a statically known size to be initialized");
}
ObligationCauseCode::FieldSized(ref item) => {
ObligationCauseCode::FieldSized { adt_kind: ref item, last } => {
match *item {
AdtKind::Struct => {
err.note("only the last field of a struct may have a dynamically \
sized type");
if last {
err.note("the last field of a packed struct may only have a \
dynamically sized type if it does not need drop to be run");
} else {
err.note("only the last field of a struct may have a dynamically \
sized type");
}
}
AdtKind::Union => {
err.note("no field of a union may have a dynamically sized type");

View File

@ -192,8 +192,8 @@ pub enum ObligationCauseCode<'tcx> {
/// [T,..n] --> T must be Copy
RepeatVec,
/// Types of fields (other than the last) in a struct must be sized.
FieldSized(AdtKind),
/// Types of fields (other than the last, except for packed structs) in a struct must be sized.
FieldSized { adt_kind: AdtKind, last: bool },
/// Constant expressions must be sized.
ConstSized,

View File

@ -206,7 +206,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
super::SizedReturnType => Some(super::SizedReturnType),
super::SizedYieldType => Some(super::SizedYieldType),
super::RepeatVec => Some(super::RepeatVec),
super::FieldSized(item) => Some(super::FieldSized(item)),
super::FieldSized { adt_kind, last } => Some(super::FieldSized { adt_kind, last }),
super::ConstSized => Some(super::ConstSized),
super::SharedStatic => Some(super::SharedStatic),
super::BuiltinDerivedObligation(ref cause) => {

View File

@ -97,12 +97,7 @@ impl<T: Clone + Debug + Eq + Hash> TransitiveRelation<T> {
{
let mut result = TransitiveRelation::new();
for edge in &self.edges {
f(&self.elements[edge.source.0]).and_then(|source| {
f(&self.elements[edge.target.0]).and_then(|target| {
result.add(source, target);
Some(())
})
})?;
result.add(f(&self.elements[edge.source.0])?, f(&self.elements[edge.target.0])?);
}
Some(result)
}

View File

@ -258,25 +258,35 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty.needs_drop(fcx_tcx, fcx_tcx.param_env(def_id))
}
};
let unsized_len = if
let all_sized =
all_sized ||
variant.fields.is_empty() ||
needs_drop_copy()
{
needs_drop_copy();
let unsized_len = if all_sized {
0
} else {
1
};
for field in &variant.fields[..variant.fields.len() - unsized_len] {
for (idx, field) in variant.fields[..variant.fields.len() - unsized_len]
.iter()
.enumerate()
{
let last = idx == variant.fields.len() - 1;
fcx.register_bound(
field.ty,
fcx.tcx.require_lang_item(lang_items::SizedTraitLangItem),
traits::ObligationCause::new(field.span,
fcx.body_id,
traits::FieldSized(match item.node.adt_kind() {
Some(i) => i,
None => bug!(),
})));
traits::ObligationCause::new(
field.span,
fcx.body_id,
traits::FieldSized {
adt_kind: match item.node.adt_kind() {
Some(i) => i,
None => bug!(),
},
last
}
)
);
}
// All field types must be well-formed.

View File

@ -9,5 +9,5 @@ path = "lib.rs"
[dependencies]
pulldown-cmark = { version = "0.1.2", default-features = false }
minifier = "0.0.14"
minifier = "0.0.19"
tempfile = "3"

View File

@ -165,8 +165,8 @@ a {
color: #ddd;
}
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), .docblock-short
a:not(.srclink):not(.test-arrow), .stability a {
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
.docblock-short a:not(.srclink):not(.test-arrow), .stability a {
color: #D2991D;
}

View File

@ -165,8 +165,8 @@ a {
color: #000;
}
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow), .docblock-short
a:not(.srclink):not(.test-arrow), .stability a {
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
.docblock-short a:not(.srclink):not(.test-arrow), .stability a {
color: #3873AD;
}

View File

@ -324,7 +324,14 @@ pub fn test_main_static(tests: &[TestDescAndFn]) {
/// test is considered a failure. By default, invokes `report()`
/// and checks for a `0` result.
pub fn assert_test_result<T: Termination>(result: T) {
assert_eq!(result.report(), 0);
let code = result.report();
assert_eq!(
code,
0,
"the test returned a termination value with a non-zero status code ({}) \
which indicates a failure",
code
);
}
#[derive(Copy, Clone, Debug)]

View File

@ -7,7 +7,7 @@ LL | data: T, //~ ERROR the size for values of type
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= help: consider adding a `where T: std::marker::Sized` bound
= note: only the last field of a struct may have a dynamically sized type
= note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run
error: aborting due to previous error

View File

@ -10,6 +10,7 @@
// normalize-stderr-test: "The system cannot find the file specified\." -> "No such file or directory"
// ignore-tidy-linelength
// ignore-stage1
// test that errors in a (selection) of macros don't kill compilation
// immediately, so that we get more errors listed at a time.

View File

@ -1,47 +1,47 @@
error[E0665]: `Default` cannot be derived for enums, only structs
--> $DIR/macros-nonfatal-errors.rs:20:10
--> $DIR/macros-nonfatal-errors.rs:21:10
|
LL | #[derive(Default)] //~ ERROR
| ^^^^^^^
error: inline assembly must be a string literal
--> $DIR/macros-nonfatal-errors.rs:24:10
--> $DIR/macros-nonfatal-errors.rs:25:10
|
LL | asm!(invalid); //~ ERROR
| ^^^^^^^
error: concat_idents! requires ident args.
--> $DIR/macros-nonfatal-errors.rs:26:5
--> $DIR/macros-nonfatal-errors.rs:27:5
|
LL | concat_idents!("not", "idents"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:28:17
--> $DIR/macros-nonfatal-errors.rs:29:17
|
LL | option_env!(invalid); //~ ERROR
| ^^^^^^^
error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:29:10
--> $DIR/macros-nonfatal-errors.rs:30:10
|
LL | env!(invalid); //~ ERROR
| ^^^^^^^
error: expected string literal
--> $DIR/macros-nonfatal-errors.rs:30:10
--> $DIR/macros-nonfatal-errors.rs:31:10
|
LL | env!(foo, abr, baz); //~ ERROR
| ^^^
error: environment variable `RUST_HOPEFULLY_THIS_DOESNT_EXIST` not defined
--> $DIR/macros-nonfatal-errors.rs:31:5
--> $DIR/macros-nonfatal-errors.rs:32:5
|
LL | env!("RUST_HOPEFULLY_THIS_DOESNT_EXIST"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0658]: non-ident macro paths are experimental (see issue #35896)
--> $DIR/macros-nonfatal-errors.rs:33:5
--> $DIR/macros-nonfatal-errors.rs:34:5
|
LL | foo::blah!(); //~ ERROR
| ^^^^^^^^^
@ -49,7 +49,7 @@ LL | foo::blah!(); //~ ERROR
= help: add #![feature(use_extern_macros)] to the crate attributes to enable
error: format argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:35:13
--> $DIR/macros-nonfatal-errors.rs:36:13
|
LL | format!(invalid); //~ ERROR
| ^^^^^^^
@ -59,37 +59,37 @@ LL | format!("{}", invalid); //~ ERROR
| ^^^^^
error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:37:14
--> $DIR/macros-nonfatal-errors.rs:38:14
|
LL | include!(invalid); //~ ERROR
| ^^^^^^^
error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:39:18
--> $DIR/macros-nonfatal-errors.rs:40:18
|
LL | include_str!(invalid); //~ ERROR
| ^^^^^^^
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: No such file or directory (os error 2)
--> $DIR/macros-nonfatal-errors.rs:40:5
--> $DIR/macros-nonfatal-errors.rs:41:5
|
LL | include_str!("i'd be quite surprised if a file with this name existed"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: argument must be a string literal
--> $DIR/macros-nonfatal-errors.rs:41:20
--> $DIR/macros-nonfatal-errors.rs:42:20
|
LL | include_bytes!(invalid); //~ ERROR
| ^^^^^^^
error: couldn't read $DIR/i'd be quite surprised if a file with this name existed: No such file or directory (os error 2)
--> $DIR/macros-nonfatal-errors.rs:42:5
--> $DIR/macros-nonfatal-errors.rs:43:5
|
LL | include_bytes!("i'd be quite surprised if a file with this name existed"); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: trace_macros! accepts only `true` or `false`
--> $DIR/macros-nonfatal-errors.rs:44:5
--> $DIR/macros-nonfatal-errors.rs:45:5
|
LL | trace_macros!(invalid); //~ ERROR
| ^^^^^^^^^^^^^^^^^^^^^^^