Auto merge of #87569 - JohnTitor:rollup-7ydfetw, r=JohnTitor

Rollup of 10 pull requests

Successful merges:

 - #81050 (Stabilize core::task::ready!)
 - #81363 (Remove P: Unpin bound on impl Future for Pin)
 - #86839 (Add doc aliases to fs.rs)
 - #87435 (fix example code for E0617)
 - #87451 (Add support for tuple struct field documentation)
 - #87491 (Integrate context into the memorial to Anna)
 - #87521 (Add long explanation for E0498)
 - #87527 (Don't run MIR unsafeck at all when using `-Zthir-unsafeck`)
 - #87550 (Add `CI_ONLY_WHEN_CHANNEL` and run `x86_64-gnu-stable` only on nightly)
 - #87565 (Use backticks when referring to `core::future::Ready` in panic message)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-07-28 22:06:51 +00:00
commit 4533be947b
24 changed files with 202 additions and 69 deletions

View File

@ -263,6 +263,7 @@ jobs:
env:
IMAGE: x86_64-gnu
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
CI_ONLY_WHEN_CHANNEL: nightly
os: ubuntu-latest-xl
- name: x86_64-gnu-aux
os: ubuntu-latest-xl

View File

@ -248,6 +248,7 @@ E0493: include_str!("./error_codes/E0493.md"),
E0495: include_str!("./error_codes/E0495.md"),
E0496: include_str!("./error_codes/E0496.md"),
E0497: include_str!("./error_codes/E0497.md"),
E0498: include_str!("./error_codes/E0498.md"),
E0499: include_str!("./error_codes/E0499.md"),
E0500: include_str!("./error_codes/E0500.md"),
E0501: include_str!("./error_codes/E0501.md"),
@ -604,7 +605,6 @@ E0783: include_str!("./error_codes/E0783.md"),
// E0488, // lifetime of variable does not enclose its declaration
// E0489, // type/lifetime parameter not in scope here
E0490, // a value of type `..` is borrowed for too long
E0498, // malformed plugin attribute
E0514, // metadata version mismatch
E0519, // local crate and dependency have same (crate-name, disambiguator)
// two dependencies have same (crate-name, disambiguator) but different SVH

View File

@ -0,0 +1,22 @@
The `plugin` attribute was malformed.
Erroneous code example:
```compile_fail,E0498
#![feature(plugin)]
#![plugin(foo(args))] // error: invalid argument
#![plugin(bar="test")] // error: invalid argument
```
The `#[plugin]` attribute should take a single argument: the name of the plugin.
For example, for the plugin `foo`:
```ignore (requires external plugin crate)
#![feature(plugin)]
#![plugin(foo)] // ok!
```
See the [`plugin` feature] section of the Unstable book for more details.
[`plugin` feature]: https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html

View File

@ -3,12 +3,13 @@ Attempted to pass an invalid type of variable into a variadic function.
Erroneous code example:
```compile_fail,E0617
# use std::os::raw::{c_char, c_int};
extern "C" {
fn printf(c: *const i8, ...);
fn printf(format: *const c_char, ...) -> c_int;
}
unsafe {
printf(::std::ptr::null(), 0f32);
printf("%f\n\0".as_ptr() as _, 0f32);
// error: cannot pass an `f32` to variadic function, cast to `c_double`
}
```
@ -21,10 +22,12 @@ to import from `std::os::raw`).
In this case, `c_double` has the same size as `f64` so we can use it directly:
```no_run
# use std::os::raw::{c_char, c_int};
# extern "C" {
# fn printf(c: *const i8, ...);
# fn printf(format: *const c_char, ...) -> c_int;
# }
unsafe {
printf(::std::ptr::null(), 0f64); // ok!
printf("%f\n\0".as_ptr() as _, 0f64); // ok!
}
```

View File

@ -259,10 +259,12 @@ fn mir_const<'tcx>(
}
// Unsafety check uses the raw mir, so make sure it is run.
if let Some(param_did) = def.const_param_did {
tcx.ensure().unsafety_check_result_for_const_arg((def.did, param_did));
} else {
tcx.ensure().unsafety_check_result(def.did);
if !tcx.sess.opts.debugging_opts.thir_unsafeck {
if let Some(param_did) = def.const_param_did {
tcx.ensure().unsafety_check_result_for_const_arg((def.did, param_did));
} else {
tcx.ensure().unsafety_check_result(def.did);
}
}
let mut body = tcx.mir_built(def).steal();

View File

@ -111,11 +111,11 @@ impl<F: ?Sized + Future + Unpin> Future for &mut F {
#[stable(feature = "futures_api", since = "1.36.0")]
impl<P> Future for Pin<P>
where
P: Unpin + ops::DerefMut<Target: Future>,
P: ops::DerefMut<Target: Future>,
{
type Output = <<P as ops::Deref>::Target as Future>::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
Pin::get_mut(self).as_mut().poll(cx)
<P::Target as Future>::poll(self.as_deref_mut(), cx)
}
}

View File

@ -20,7 +20,7 @@ impl<T> Future for Ready<T> {
#[inline]
fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
Poll::Ready(self.0.take().expect("Ready polled after completion"))
Poll::Ready(self.0.take().expect("`Ready` polled after completion"))
}
}

View File

@ -128,6 +128,7 @@
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(auto_traits)]
#![feature(pin_deref_mut)]
#![feature(prelude_import)]
#![feature(ptr_metadata)]
#![feature(repr_simd, platform_intrinsics)]

View File

@ -802,6 +802,44 @@ impl<T: ?Sized> Pin<&'static T> {
}
}
impl<'a, P: DerefMut> Pin<&'a mut Pin<P>> {
/// Gets a pinned mutable reference from this nested pinned pointer.
///
/// This is a generic method to go from `Pin<&mut Pin<Pointer<T>>>` to `Pin<&mut T>`. It is
/// safe because the existence of a `Pin<Pointer<T>>` ensures that the pointee, `T`, cannot
/// move in the future, and this method does not enable the pointee to move. "Malicious"
/// implementations of `P::DerefMut` are likewise ruled out by the contract of
/// `Pin::new_unchecked`.
#[unstable(feature = "pin_deref_mut", issue = "86918")]
#[inline(always)]
pub fn as_deref_mut(self) -> Pin<&'a mut P::Target> {
// SAFETY: What we're asserting here is that going from
//
// Pin<&mut Pin<P>>
//
// to
//
// Pin<&mut P::Target>
//
// is safe.
//
// We need to ensure that two things hold for that to be the case:
//
// 1) Once we give out a `Pin<&mut P::Target>`, an `&mut P::Target` will not be given out.
// 2) By giving out a `Pin<&mut P::Target>`, we do not risk of violating `Pin<&mut Pin<P>>`
//
// The existence of `Pin<P>` is sufficient to guarantee #1: since we already have a
// `Pin<P>`, it must already uphold the pinning guarantees, which must mean that
// `Pin<&mut P::Target>` does as well, since `Pin::as_mut` is safe. We do not have to rely
// on the fact that P is _also_ pinned.
//
// For #2, we need to ensure that code given a `Pin<&mut P::Target>` cannot cause the
// `Pin<P>` to move? That is not possible, since `Pin<&mut P::Target>` no longer retains
// any access to the `P` itself, much less the `Pin<P>`.
unsafe { self.get_unchecked_mut() }.as_mut()
}
}
impl<T: ?Sized> Pin<&'static mut T> {
/// Get a pinned mutable reference from a static mutable reference.
///

View File

@ -11,5 +11,5 @@ mod wake;
pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker};
mod ready;
#[unstable(feature = "ready_macro", issue = "70922")]
#[stable(feature = "ready_macro", since = "1.56.0")]
pub use ready::ready;

View File

@ -8,8 +8,6 @@
/// # Examples
///
/// ```
/// #![feature(ready_macro)]
///
/// use std::task::{ready, Context, Poll};
/// use std::future::{self, Future};
/// use std::pin::Pin;
@ -29,8 +27,6 @@
/// The `ready!` call expands to:
///
/// ```
/// # #![feature(ready_macro)]
/// #
/// # use std::task::{Context, Poll};
/// # use std::future::{self, Future};
/// # use std::pin::Pin;
@ -49,7 +45,7 @@
/// # Poll::Ready(())
/// # }
/// ```
#[unstable(feature = "ready_macro", issue = "70922")]
#[stable(feature = "ready_macro", since = "1.56.0")]
#[rustc_macro_transparency = "semitransparent"]
pub macro ready($e:expr) {
match $e {

View File

@ -1912,6 +1912,7 @@ pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
/// Ok(())
/// }
/// ```
#[doc(alias = "mkdir")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
DirBuilder::new().create(path.as_ref())
@ -1991,6 +1992,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// Ok(())
/// }
/// ```
#[doc(alias = "rmdir")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs_imp::rmdir(path.as_ref())

View File

@ -304,7 +304,6 @@
#![feature(pin_static_ref)]
#![feature(prelude_import)]
#![feature(ptr_internals)]
#![feature(ready_macro)]
#![feature(rustc_attrs)]
#![feature(rustc_private)]
#![feature(shrink_to)]

View File

@ -416,6 +416,10 @@ jobs:
env:
IMAGE: x86_64-gnu
RUST_CI_OVERRIDE_RELEASE_CHANNEL: stable
# Only run this job on the nightly channel. Running this on beta
# could cause failures when `dev: 1` in `stage0.txt`, and running
# this on stable is useless.
CI_ONLY_WHEN_CHANNEL: nightly
<<: *job-linux-xl
- name: x86_64-gnu-aux

View File

@ -8,31 +8,43 @@ IFS=$'\n\t'
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
if [[ -z "${CI_ONLY_WHEN_SUBMODULES_CHANGED+x}" ]]; then
echo "Executing the job since there is no skip rule in effect"
exit 0
if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
git fetch "https://github.com/$GITHUB_REPOSITORY" "$GITHUB_BASE_REF"
BASE_COMMIT="$(git merge-base FETCH_HEAD HEAD)"
echo "Searching for toolstate changes between $BASE_COMMIT and $(git rev-parse HEAD)"
if git diff "$BASE_COMMIT" | grep --quiet "^index .* 160000"; then
# Submodules pseudo-files inside git have the 160000 permissions, so when
# those files are present in the diff a submodule was updated.
echo "Submodules were updated"
elif ! git diff --quiet "$BASE_COMMIT" -- src/tools/clippy src/tools/rustfmt; then
# There is not an easy blanket search for subtrees. For now, manually list
# the subtrees.
echo "Clippy or rustfmt subtrees were updated"
elif ! (git diff --quiet "$BASE_COMMIT" -- \
src/test/rustdoc-gui \
src/librustdoc \
src/tools/rustdoc-gui); then
# There was a change in either rustdoc or in its GUI tests.
echo "Rustdoc was updated"
else
echo "Not executing this job since no submodules nor subtrees were updated"
ciCommandSetEnv SKIP_JOB 1
exit 0
fi
fi
git fetch "https://github.com/$GITHUB_REPOSITORY" "$GITHUB_BASE_REF"
BASE_COMMIT="$(git merge-base FETCH_HEAD HEAD)"
echo "Searching for toolstate changes between $BASE_COMMIT and $(git rev-parse HEAD)"
if git diff "$BASE_COMMIT" | grep --quiet "^index .* 160000"; then
# Submodules pseudo-files inside git have the 160000 permissions, so when
# those files are present in the diff a submodule was updated.
echo "Executing the job since submodules are updated"
elif ! git diff --quiet "$BASE_COMMIT" -- src/tools/clippy src/tools/rustfmt; then
# There is not an easy blanket search for subtrees. For now, manually list
# the subtrees.
echo "Executing the job since clippy or rustfmt subtree was updated"
elif ! (git diff --quiet "$BASE_COMMIT" -- \
src/test/rustdoc-gui \
src/librustdoc \
src/tools/rustdoc-gui); then
# There was a change in either rustdoc or in its GUI tests.
echo "Executing the job since rustdoc was updated"
else
echo "Not executing this job since no submodules nor subtrees were updated"
ciCommandSetEnv SKIP_JOB 1
if [[ -n "${CI_ONLY_WHEN_CHANNEL-}" ]]; then
if [[ "${CI_ONLY_WHEN_CHANNEL}" = "$(cat src/ci/channel)" ]]; then
echo "The channel is the expected one"
else
echo "Not executing this job as the channel is not the expected one"
ciCommandSetEnv SKIP_JOB 1
exit 0
fi
fi
echo "Executing the job since there is no skip rule preventing the execution"
exit 0

View File

@ -1730,9 +1730,13 @@ impl Clean<Variant> for hir::VariantData<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
match self {
hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)),
hir::VariantData::Tuple(..) => {
Variant::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
}
// Important note here: `Variant::Tuple` is used on tuple structs which are not in an
// enum (so where converting from `ty::VariantDef`). In case we are in an enum, the kind
// is provided by the `Variant` wrapper directly, and since we need the fields' name
// (even for a tuple struct variant!), it's simpler to just store it as a
// `Variant::Struct` instead of a `Variant::Tuple` (otherwise it would force us to make
// a lot of changes when rendering them to generate the name as well).
hir::VariantData::Tuple(..) => Variant::Struct(self.clean(cx)),
hir::VariantData::Unit(..) => Variant::CLike,
}
}

View File

@ -2007,6 +2007,9 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
}
sidebar.push_str("</div>");
} else if let CtorKind::Fn = s.struct_type {
sidebar
.push_str("<h3 class=\"sidebar-title\"><a href=\"#fields\">Tuple Fields</a></h3>");
}
}

View File

@ -1037,8 +1037,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
write!(
w,
"<h3>Fields of <b>{name}</b></h3><div>",
name = variant.name.as_ref().unwrap()
"<h3>{extra}Fields of <b>{name}</b></h3><div>",
extra = if s.struct_type == CtorKind::Fn { "Tuple " } else { "" },
name = variant.name.as_ref().unwrap(),
);
for field in &s.fields {
use crate::clean::StructFieldItem;
@ -1176,21 +1177,21 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
_ => None,
})
.peekable();
if let CtorKind::Fictive = s.struct_type {
if let CtorKind::Fictive | CtorKind::Fn = s.struct_type {
if fields.peek().is_some() {
write!(
w,
"<h2 id=\"fields\" class=\"fields small-section-header\">\
Fields{}<a href=\"#fields\" class=\"anchor\"></a></h2>",
{}{}<a href=\"#fields\" class=\"anchor\"></a>\
</h2>",
if let CtorKind::Fictive = s.struct_type { "Fields" } else { "Tuple Fields" },
document_non_exhaustive_header(it)
);
document_non_exhaustive(w, it);
for (field, ty) in fields {
let id = cx.derive_id(format!(
"{}.{}",
ItemType::StructField,
field.name.as_ref().unwrap()
));
for (index, (field, ty)) in fields.enumerate() {
let field_name =
field.name.map_or_else(|| index.to_string(), |sym| (*sym.as_str()).to_string());
let id = cx.derive_id(format!("{}.{}", ItemType::StructField, field_name));
write!(
w,
"<span id=\"{id}\" class=\"{item_type} small-section-header\">\
@ -1199,7 +1200,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
</span>",
item_type = ItemType::StructField,
id = id,
name = field.name.as_ref().unwrap(),
name = field_name,
ty = ty.print(cx)
);
document(w, cx, field, Some(it));
@ -1507,7 +1508,10 @@ fn render_struct(
if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx, 0, false),)
}
w.write_str(";");
// We only want a ";" when we are displaying a tuple struct, not a variant tuple struct.
if structhead {
w.write_str(";");
}
}
CtorKind::Const => {
// Needed for PhantomData.

View File

@ -1,7 +1,7 @@
+-------------------------------------+------------+------------+------------+------------+
| File | Documented | Percentage | Examples | Percentage |
+-------------------------------------+------------+------------+------------+------------+
| ...est/rustdoc-ui/coverage/enums.rs | 6 | 75.0% | 0 | 0.0% |
| ...est/rustdoc-ui/coverage/enums.rs | 6 | 66.7% | 0 | 0.0% |
+-------------------------------------+------------+------------+------------+------------+
| Total | 6 | 75.0% | 0 | 0.0% |
| Total | 6 | 66.7% | 0 | 0.0% |
+-------------------------------------+------------+------------+------------+------------+

View File

@ -81,8 +81,8 @@ pub enum EnumStructVariant {
}
// @has 'toggle_item_contents/enum.LargeEnum.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
// @count - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 1
// @has - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants'
pub enum LargeEnum {
A, B, C, D, E, F(u8), G, H, I, J, K, L, M
}

View File

@ -0,0 +1,36 @@
#![crate_name = "foo"]
// @has foo/struct.Foo.html
// @has - '//h2[@id="fields"]' 'Tuple Fields'
// @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields'
// @has - '//*[@id="structfield.0"]' '0: u32'
// @has - '//*[@id="main"]/div[@class="docblock"]' 'hello'
// @!has - '//*[@id="structfield.1"]'
// @has - '//*[@id="structfield.2"]' '2: char'
// @has - '//*[@id="structfield.3"]' '3: i8'
// @has - '//*[@id="main"]/div[@class="docblock"]' 'not hello'
pub struct Foo(
/// hello
pub u32,
char,
pub char,
/// not hello
pub i8,
);
// @has foo/enum.Bar.html
// @has - '//pre[@class="rust enum"]' 'BarVariant(String),'
// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$'
// @has - '//*[@id="variant.BarVariant.field.0"]' '0: String'
// @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs'
// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$'
pub enum Bar {
BarVariant(
/// Hello docs
String
),
FooVariant {
/// hello
x: u32,
},
}

View File

@ -14,3 +14,4 @@ LL | #![plugin(empty_plugin(args))]
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0498`.

View File

@ -20,13 +20,17 @@
// in permitting generic arguments to be provided without the consent of the
// Great Turbofish. Should you be so naïve as to try to revolt against its
// mighty clutches, here shall its wrath be indomitably displayed. This
// program must pass for all eternity, fundamentally at odds with an impetuous
// rebellion against the Turbofish.
// program must pass for all eternity: forever watched by the guardian angel
// which gave this beast its name, and stands fundamentally at odds with the
// impetuous rebellion against the Turbofish.
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.
// to all those who come after: for they too must overcome the impassible
// hurdle of defeating the great beast, championed by a resolute winged
// guardian.
//
// RIP Anna Harren, Guardian Angel of the Hallowed Turbofish. <3
// Here stands the Bastion of the Turbofish, a memorial to Anna Harren,
// Guardian Angel of these Hallowed Grounds. <3
// See https://github.com/rust-lang/rust/pull/53562
// and https://github.com/rust-lang/rfcs/pull/2527
@ -34,6 +38,6 @@
// for context.
fn main() {
let (oh, woe, is, me) = ("the", "Turbofish", "remains", "undefeated");
let _: (bool, bool) = (oh<woe, is>(me));
let (the, guardian, stands, resolute) = ("the", "Turbofish", "remains", "undefeated");
let _: (bool, bool) = (the<guardian, stands>(resolute));
}

View File

@ -14,3 +14,4 @@ LL | #![plugin(foo="bleh")]
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0498`.