Auto merge of #75351 - JohnTitor:rollup-q9udsyx, r=JohnTitor

Rollup of 8 pull requests

Successful merges:

 - #74200 (Std panicking unsafe block in unsafe fn)
 - #75286 (Add additional case for Path starts with)
 - #75318 (Resolve `char` as a primitive even if there is a module in scope)
 - #75320 (Detect likely `for foo of bar` JS syntax)
 - #75328 (Cleanup E0749)
 - #75344 (Rename "Important traits" to "Notable traits")
 - #75348 (Move to intra-doc links in library/core/src/time.rs)
 - #75350 (Do not ICE when lowering invalid extern fn with bodies)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-08-10 00:09:45 +00:00
commit cee62c17aa
22 changed files with 162 additions and 60 deletions

View File

@ -30,12 +30,10 @@ const MICROS_PER_SEC: u64 = 1_000_000;
/// nanosecond-level precision, APIs binding a system timeout will typically round up
/// the number of nanoseconds.
///
/// `Duration`s implement many common traits, including [`Add`], [`Sub`], and other
/// [`ops`] traits. It implements `Default` by returning a zero-length `Duration`.
/// [`Duration`]s implement many common traits, including [`Add`], [`Sub`], and other
/// [`ops`] traits. It implements [`Default`] by returning a zero-length `Duration`.
///
/// [`Add`]: ../../std/ops/trait.Add.html
/// [`Sub`]: ../../std/ops/trait.Sub.html
/// [`ops`]: ../../std/ops/index.html
/// [`ops`]: crate::ops
///
/// # Examples
///
@ -293,7 +291,7 @@ impl Duration {
/// + duration.subsec_nanos() as f64 * 1e-9);
/// ```
///
/// [`subsec_nanos`]: #method.subsec_nanos
/// [`subsec_nanos`]: Duration::subsec_nanos
#[stable(feature = "duration", since = "1.3.0")]
#[rustc_const_stable(feature = "duration", since = "1.32.0")]
#[inline]
@ -421,8 +419,6 @@ impl Duration {
/// Checked `Duration` addition. Computes `self + other`, returning [`None`]
/// if overflow occurred.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:
@ -457,8 +453,6 @@ impl Duration {
/// Checked `Duration` subtraction. Computes `self - other`, returning [`None`]
/// if the result would be negative or if overflow occurred.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:
@ -494,8 +488,6 @@ impl Duration {
/// Checked `Duration` multiplication. Computes `self * other`, returning
/// [`None`] if overflow occurred.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:
@ -526,8 +518,6 @@ impl Duration {
/// Checked `Duration` division. Computes `self / other`, returning [`None`]
/// if `other == 0`.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
///
/// # Examples
///
/// Basic usage:

View File

@ -7,6 +7,8 @@
//! * Executing a panic up to doing the actual implementation
//! * Shims around "try"
#![deny(unsafe_op_in_unsafe_fn)]
use core::panic::{BoxMeUp, Location, PanicInfo};
use crate::any::Any;
@ -322,11 +324,22 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
let mut data = Data { f: ManuallyDrop::new(f) };
let data_ptr = &mut data as *mut _ as *mut u8;
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
Ok(ManuallyDrop::into_inner(data.r))
} else {
Err(ManuallyDrop::into_inner(data.p))
};
// SAFETY:
//
// Access to the union's fields: this is `std` and we know that the `r#try`
// intrinsic fills in the `r` or `p` union field based on its return value.
//
// The call to `intrinsics::r#try` is made safe by:
// - `do_call`, the first argument, can be called with the initial `data_ptr`.
// - `do_catch`, the second argument, can be called with the `data_ptr` as well.
// See their safety preconditions for more informations
unsafe {
return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
Ok(ManuallyDrop::into_inner(data.r))
} else {
Err(ManuallyDrop::into_inner(data.p))
};
}
// We consider unwinding to be rare, so mark this function as cold. However,
// do not mark it no-inline -- that decision is best to leave to the
@ -334,13 +347,25 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
// non-cold function, though, as of the writing of this comment).
#[cold]
unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send + 'static> {
let obj = Box::from_raw(__rust_panic_cleanup(payload));
// SAFETY: The whole unsafe block hinges on a correct implementation of
// the panic handler `__rust_panic_cleanup`. As such we can only
// assume it returns the correct thing for `Box::from_raw` to work
// without undefined behavior.
let obj = unsafe { Box::from_raw(__rust_panic_cleanup(payload)) };
panic_count::decrease();
obj
}
// SAFETY:
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
// Its must contains a valid `f` (type: F) value that can be use to fill
// `data.r`.
//
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
// expects normal function pointers.
#[inline]
fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
// SAFETY: this is the responsibilty of the caller, see above.
unsafe {
let data = data as *mut Data<F, R>;
let data = &mut (*data);
@ -352,8 +377,21 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
// We *do* want this part of the catch to be inlined: this allows the
// compiler to properly track accesses to the Data union and optimize it
// away most of the time.
//
// SAFETY:
// data must be non-NUL, correctly aligned, and a pointer to a `Data<F, R>`
// Since this uses `cleanup` it also hinges on a correct implementation of
// `__rustc_panic_cleanup`.
//
// This function cannot be marked as `unsafe` because `intrinsics::r#try`
// expects normal function pointers.
#[inline]
fn do_catch<F: FnOnce() -> R, R>(data: *mut u8, payload: *mut u8) {
// SAFETY: this is the responsibilty of the caller, see above.
//
// When `__rustc_panic_cleaner` is correctly implemented we can rely
// on `obj` being the correct thing to pass to `data.p` (after wrapping
// in `ManuallyDrop`).
unsafe {
let data = data as *mut Data<F, R>;
let data = &mut (*data);

View File

@ -2031,9 +2031,13 @@ impl Path {
/// assert!(path.starts_with("/etc"));
/// assert!(path.starts_with("/etc/"));
/// assert!(path.starts_with("/etc/passwd"));
/// assert!(path.starts_with("/etc/passwd/"));
/// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
/// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
///
/// assert!(!path.starts_with("/e"));
/// assert!(!path.starts_with("/etc/passwd.txt"));
///
/// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {

View File

@ -172,7 +172,11 @@ macro_rules! __thread_local_inner {
static __KEY: $crate::thread::__OsLocalKeyInner<$t> =
$crate::thread::__OsLocalKeyInner::new();
__KEY.get(__init)
// FIXME: remove the #[allow(...)] marker when macros don't
// raise warning for missing/extraneous unsafe blocks anymore.
// See https://github.com/rust-lang/rust/issues/74838.
#[allow(unused_unsafe)]
unsafe { __KEY.get(__init) }
}
unsafe {

View File

@ -573,7 +573,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.resolver
.trait_map()
.iter()
.map(|(&k, v)| (self.node_id_to_hir_id[k].unwrap(), v.clone()))
.filter_map(|(&k, v)| {
self.node_id_to_hir_id.get(k).and_then(|id| id.as_ref()).map(|id| (*id, v.clone()))
})
.collect();
let mut def_id_to_hir_id = IndexVec::default();

View File

@ -1,4 +1,19 @@
Negative impls are not allowed to have any items. Negative impls
declare that a trait is **not** implemented (and never will be) and
hence there is no need to specify the values for trait methods or
other items.
An item was added on a negative impl.
Erroneous code example:
```compile_fail,E0749
# #![feature(negative_impls)]
trait MyTrait {
type Foo;
}
impl !MyTrait for u32 {
type Foo = i32; // error!
}
# fn main() {}
```
Negative impls are not allowed to have any items. Negative impls declare that a
trait is **not** implemented (and never will be) and hence there is no need to
specify the values for trait methods or other items.

View File

@ -1733,13 +1733,20 @@ impl<'a> Parser<'a> {
Ok(self.mk_expr(lo.to(self.prev_token.span), kind, attrs))
}
fn error_missing_in_for_loop(&self) {
let in_span = self.prev_token.span.between(self.token.span);
self.struct_span_err(in_span, "missing `in` in `for` loop")
fn error_missing_in_for_loop(&mut self) {
let (span, msg, sugg) = if self.token.is_ident_named(sym::of) {
// Possibly using JS syntax (#75311).
let span = self.token.span;
self.bump();
(span, "try using `in` here instead", "in")
} else {
(self.prev_token.span.between(self.token.span), "try adding `in` here", " in ")
};
self.struct_span_err(span, "missing `in` in `for` loop")
.span_suggestion_short(
in_span,
"try adding `in` here",
" in ".into(),
span,
msg,
sugg.into(),
// Has been misleading, at least in the past (closed Issue #48492).
Applicability::MaybeIncorrect,
)

View File

@ -737,6 +737,7 @@ symbols! {
not,
note,
object_safe_for_dispatch,
of,
offset,
omit_gdb_pretty_printer_section,
on,

View File

@ -3450,7 +3450,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
if impl_.trait_.def_id().map_or(false, |d| c.traits[&d].is_spotlight) {
if out.is_empty() {
out.push_str(&format!(
"<h3 class=\"important\">Important traits for {}</h3>\
"<h3 class=\"notable\">Notable traits for {}</h3>\
<code class=\"content\">",
impl_.for_.print()
));
@ -3485,7 +3485,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String {
if !out.is_empty() {
out.insert_str(
0,
"<span class=\"important-traits\"><span class=\"important-traits-tooltip\">ⓘ<div class='important-traits-tooltiptext'><span class=\"docblock\">"
"<span class=\"notable-traits\"><span class=\"notable-traits-tooltip\">ⓘ<div class='notable-traits-tooltiptext'><span class=\"docblock\">"
);
out.push_str("</code></span></div></span></span>");

View File

@ -2636,9 +2636,9 @@ function defocusSearchBar() {
});
}());
onEachLazy(document.getElementsByClassName("important-traits"), function(e) {
onEachLazy(document.getElementsByClassName("notable-traits"), function(e) {
e.onclick = function() {
this.getElementsByClassName('important-traits-tooltiptext')[0]
this.getElementsByClassName('notable-traits-tooltiptext')[0]
.classList.toggle("force-tooltip");
};
});

View File

@ -91,7 +91,7 @@ h2 {
h3 {
font-size: 1.3em;
}
h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.important),
h1, h2, h3:not(.impl):not(.method):not(.type):not(.tymethod):not(.notable),
h4:not(.method):not(.type):not(.tymethod):not(.associatedconstant) {
font-weight: 500;
margin: 20px 0 15px 0;
@ -528,7 +528,7 @@ h4 > code, h3 > code, .invisible > code {
font-size: 0.8em;
}
.content .methods > div:not(.important-traits) {
.content .methods > div:not(.notable-traits) {
margin-left: 40px;
margin-bottom: 15px;
}
@ -1099,17 +1099,17 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
font-size: 20px;
}
.important-traits-tooltip {
.notable-traits-tooltip {
display: inline-block;
cursor: pointer;
}
.important-traits:hover .important-traits-tooltiptext,
.important-traits .important-traits-tooltiptext.force-tooltip {
.notable-traits:hover .notable-traits-tooltiptext,
.notable-traits .notable-traits-tooltiptext.force-tooltip {
display: inline-block;
}
.important-traits .important-traits-tooltiptext {
.notable-traits .notable-traits-tooltiptext {
display: none;
padding: 5px 3px 3px 3px;
border-radius: 6px;
@ -1121,18 +1121,18 @@ h3 > .collapse-toggle, h4 > .collapse-toggle {
border: 1px solid;
}
.important-traits-tooltip::after {
.notable-traits-tooltip::after {
/* The margin on the tooltip does not capture hover events,
this extends the area of hover enough so that mouse hover is not
lost when moving the mouse to the tooltip */
content: "\00a0\00a0\00a0";
}
.important-traits .important, .important-traits .docblock {
.notable-traits .notable, .notable-traits .docblock {
margin: 0;
}
.important-traits .docblock code.content{
.notable-traits .docblock code.content{
margin: 0;
padding: 0;
font-size: 20px;
@ -1183,13 +1183,13 @@ pre.rust {
font-size: 16px;
}
.important-traits {
.notable-traits {
cursor: pointer;
z-index: 2;
margin-left: 5px;
}
h4 > .important-traits {
h4 > .notable-traits {
position: absolute;
left: -44px;
top: 2px;
@ -1431,7 +1431,7 @@ h4 > .important-traits {
z-index: 1;
}
h4 > .important-traits {
h4 > .notable-traits {
position: absolute;
left: -22px;
top: 24px;
@ -1522,7 +1522,7 @@ h4 > .important-traits {
margin-top: 0;
}
.important-traits .important-traits-tooltiptext {
.notable-traits .notable-traits-tooltiptext {
left: 0;
top: 100%;
}
@ -1544,7 +1544,7 @@ h4 > .important-traits {
}
}
h3.important {
h3.notable {
margin: 0;
margin-bottom: 13px;
font-size: 19px;

View File

@ -389,7 +389,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
border-color: transparent #314559 transparent transparent;
}
.important-traits-tooltiptext {
.notable-traits-tooltiptext {
background-color: #314559;
border-color: #5c6773;
}

View File

@ -339,7 +339,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
border-color: transparent black transparent transparent;
}
.important-traits-tooltiptext {
.notable-traits-tooltiptext {
background-color: #111;
border-color: #777;
}

View File

@ -333,7 +333,7 @@ pre.ignore:hover, .information:hover + pre.ignore {
border-color: transparent black transparent transparent;
}
.important-traits-tooltiptext {
.notable-traits-tooltiptext {
background-color: #eee;
border-color: #999;
}

View File

@ -217,9 +217,11 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
return Ok((res, Some(path_str.to_owned())));
}
Res::Def(DefKind::Mod, _) => {
// This resolved to a module, but if we were passed `type@`,
// we want primitive types to take precedence instead.
if disambiguator == Some(Disambiguator::Namespace(Namespace::TypeNS)) {
// This resolved to a module, but we want primitive types to take precedence instead.
if matches!(
disambiguator,
None | Some(Disambiguator::Namespace(Namespace::TypeNS))
) {
if let Some(prim) = is_primitive(path_str, ns) {
if extra_fragment.is_some() {
return Err(ErrorKind::AnchorFailure(AnchorFailure::Primitive));

View File

@ -8,5 +8,10 @@ pub mod char {}
pub struct MyString;
/// See also [char]
// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'intra_link_prim_precedence/char/index.html'
// @has intra_link_prim_precedence/struct.MyString2.html '//a/@href' 'https://doc.rust-lang.org/nightly/std/primitive.char.html'
pub struct MyString2;
/// See also [crate::char] and [mod@char]
// @has intra_link_prim_precedence/struct.MyString3.html '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'crate::char'
// @has - '//*[@href="../intra_link_prim_precedence/char/index.html"]' 'mod@char'
pub struct MyString3;

View File

@ -3,4 +3,6 @@
fn main() {
for _i in 0..2 { //~ ERROR missing `in`
}
for _i in 0..2 { //~ ERROR missing `in`
}
}

View File

@ -3,4 +3,6 @@
fn main() {
for _i 0..2 { //~ ERROR missing `in`
}
for _i of 0..2 { //~ ERROR missing `in`
}
}

View File

@ -4,5 +4,11 @@ error: missing `in` in `for` loop
LL | for _i 0..2 {
| ^ help: try adding `in` here
error: aborting due to previous error
error: missing `in` in `for` loop
--> $DIR/issue-40782.rs:6:12
|
LL | for _i of 0..2 {
| ^^ help: try using `in` here instead
error: aborting due to 2 previous errors

View File

@ -0,0 +1,6 @@
extern "C" {
fn lol() { //~ ERROR incorrect function inside `extern` block
println!("");
}
}
fn main() {}

View File

@ -0,0 +1,18 @@
error: incorrect function inside `extern` block
--> $DIR/issue-75283.rs:2:8
|
LL | extern "C" {
| ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
LL | fn lol() {
| ________^^^___-
| | |
| | cannot have a body
LL | | println!("");
LL | | }
| |_____- help: remove the invalid body: `;`
|
= help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
error: aborting due to previous error

View File

@ -16,7 +16,7 @@ const EXEMPTED_FROM_TEST: &[&str] = &[
];
// Some error codes don't have any tests apparently...
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729", "E0749"];
const IGNORE_EXPLANATION_CHECK: &[&str] = &["E0570", "E0601", "E0602", "E0639", "E0729"];
fn check_error_code_explanation(
f: &str,