From 82ccdab96cd8c146d9958c1050a2d2669dd367e8 Mon Sep 17 00:00:00 2001 From: Alexis Bourget Date: Wed, 29 Jul 2020 21:58:09 +0200 Subject: [PATCH 01/12] Disallow missing unsafe blocks in unsafe fn in panicking.rs This adds SAFETY comments where necessary, explaining the preconditions and how they are respected. --- library/std/src/panicking.rs | 50 +++++++++++++++++++++++++++++---- library/std/src/thread/local.rs | 6 +++- 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 9542e7209b4..f92c1dd76a1 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -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: F) -> Result> 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::, data_ptr, do_catch::) == 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::, data_ptr, do_catch::) == 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: F) -> Result> // non-cold function, though, as of the writing of this comment). #[cold] unsafe fn cleanup(payload: *mut u8) -> Box { - 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` + // 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 R, R>(data: *mut u8) { + // SAFETY: this is the responsibilty of the caller, see above. unsafe { let data = data as *mut Data; let data = &mut (*data); @@ -352,8 +377,21 @@ pub unsafe fn r#try R>(f: F) -> Result> // 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` + // 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 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; let data = &mut (*data); diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index ecd6fbc6b93..66508f06b28 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -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 { From e7e41a846578de9c1dc1ccf8ac4bbb0a3a5dea60 Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Sat, 8 Aug 2020 18:06:04 +0800 Subject: [PATCH 02/12] Add additonal case for Path starts with Show what happens if there is an extra extension --- library/std/src/path.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 392c815ef28..e8aa9e27c0f 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2087,9 +2087,12 @@ 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(es) is 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>(&self, base: P) -> bool { From 4dbe0ac9287d723ae9d39e3c2b90930813eed4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 8 Aug 2020 20:53:40 -0700 Subject: [PATCH 03/12] Detect likely `for foo of bar` JS syntax Fix #75311. --- src/librustc_parse/parser/expr.rs | 19 +++++++++++++------ src/librustc_span/symbol.rs | 1 + src/test/ui/issues/issue-40782.fixed | 2 ++ src/test/ui/issues/issue-40782.rs | 2 ++ src/test/ui/issues/issue-40782.stderr | 8 +++++++- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 3aec300d86d..55a134ae091 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -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, ) diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 98776a04782..ad8b6f3e3b8 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -736,6 +736,7 @@ symbols! { not, note, object_safe_for_dispatch, + of, offset, omit_gdb_pretty_printer_section, on, diff --git a/src/test/ui/issues/issue-40782.fixed b/src/test/ui/issues/issue-40782.fixed index d61c248c6ec..305a9c3292a 100644 --- a/src/test/ui/issues/issue-40782.fixed +++ b/src/test/ui/issues/issue-40782.fixed @@ -3,4 +3,6 @@ fn main() { for _i in 0..2 { //~ ERROR missing `in` } + for _i in 0..2 { //~ ERROR missing `in` + } } diff --git a/src/test/ui/issues/issue-40782.rs b/src/test/ui/issues/issue-40782.rs index 3688c69fbc6..43460ec1535 100644 --- a/src/test/ui/issues/issue-40782.rs +++ b/src/test/ui/issues/issue-40782.rs @@ -3,4 +3,6 @@ fn main() { for _i 0..2 { //~ ERROR missing `in` } + for _i of 0..2 { //~ ERROR missing `in` + } } diff --git a/src/test/ui/issues/issue-40782.stderr b/src/test/ui/issues/issue-40782.stderr index 9d7776f32b3..81f419bf687 100644 --- a/src/test/ui/issues/issue-40782.stderr +++ b/src/test/ui/issues/issue-40782.stderr @@ -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 From cc54a1f9306c4453edbb3f914c0d010d3c2a21fe Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 9 Aug 2020 13:13:56 +0200 Subject: [PATCH 04/12] Clean up E0749 explanation --- src/librustc_error_codes/error_codes/E0749.md | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0749.md b/src/librustc_error_codes/error_codes/E0749.md index 9eb8ee4e3fd..7a1a745b53c 100644 --- a/src/librustc_error_codes/error_codes/E0749.md +++ b/src/librustc_error_codes/error_codes/E0749.md @@ -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. From 4e78760137c8d6c314c4ecafd7e8240a89737b6e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 9 Aug 2020 13:15:33 +0200 Subject: [PATCH 05/12] Remove E0749 from untested error codes --- src/tools/tidy/src/error_codes_check.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/tidy/src/error_codes_check.rs b/src/tools/tidy/src/error_codes_check.rs index 9c36d853ef7..2fa0f12d7e8 100644 --- a/src/tools/tidy/src/error_codes_check.rs +++ b/src/tools/tidy/src/error_codes_check.rs @@ -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, From b11e2f23411ec9aea4aa261c644f2c9e0df9457a Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 9 Aug 2020 00:02:08 -0400 Subject: [PATCH 06/12] Give precedence to primitives over modules This has less surprising behavior when there is a module with the same name as a primitive in scope. --- src/librustdoc/passes/collect_intra_doc_links.rs | 8 +++++--- src/test/rustdoc/intra-link-prim-precedence.rs | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f84486347af..062bd61a7d0 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -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)); diff --git a/src/test/rustdoc/intra-link-prim-precedence.rs b/src/test/rustdoc/intra-link-prim-precedence.rs index 5f10c1ec4a7..15ea1232fd6 100644 --- a/src/test/rustdoc/intra-link-prim-precedence.rs +++ b/src/test/rustdoc/intra-link-prim-precedence.rs @@ -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; From 4b549fa043486b10673d69ba547522238bb2f25f Mon Sep 17 00:00:00 2001 From: Ivan Tham Date: Mon, 10 Aug 2020 00:43:45 +0800 Subject: [PATCH 07/12] show multiple slashes starts_with Path example Co-authored-by: Joshua Nelson --- library/std/src/path.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index e8aa9e27c0f..e543006e394 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2087,7 +2087,8 @@ impl Path { /// assert!(path.starts_with("/etc")); /// assert!(path.starts_with("/etc/")); /// assert!(path.starts_with("/etc/passwd")); - /// assert!(path.starts_with("/etc/passwd/")); // extra slash(es) is okay + /// 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")); From f3cc957f2e470b30b23ca874d8f0bfc6a7164d7b Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 9 Aug 2020 12:09:05 -0700 Subject: [PATCH 08/12] Rename "Important traits" to "Notable traits" * Rename it in the UI * Rename the CSS classes --- src/librustdoc/html/render/mod.rs | 4 +-- src/librustdoc/html/static/main.js | 4 +-- src/librustdoc/html/static/rustdoc.css | 28 ++++++++++----------- src/librustdoc/html/static/themes/ayu.css | 2 +- src/librustdoc/html/static/themes/dark.css | 2 +- src/librustdoc/html/static/themes/light.css | 2 +- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 5fb2d9f6f91..4cbc56333b1 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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!( - "

Important traits for {}

\ + "

Notable traits for {}

\ ", impl_.for_.print() )); @@ -3485,7 +3485,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> String { if !out.is_empty() { out.insert_str( 0, - "
" + "
" ); out.push_str("
"); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 082f9cca064..19284018a30 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -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"); }; }); diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index d0312d77a7c..db0e4f4d31d 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -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; diff --git a/src/librustdoc/html/static/themes/ayu.css b/src/librustdoc/html/static/themes/ayu.css index f4710f6ae87..60f0d25b219 100644 --- a/src/librustdoc/html/static/themes/ayu.css +++ b/src/librustdoc/html/static/themes/ayu.css @@ -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; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index b3b586ba362..34c6cbbf4fa 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -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; } diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index b0c5715604b..137aad4ed43 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -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; } From e9e319c460468123200b90ab46871cf8288edfec Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Sun, 9 Aug 2020 21:20:57 +0200 Subject: [PATCH 09/12] Use intra-doc links --- library/core/src/time.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index acaedbd135e..4d15a8d51af 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -33,9 +33,7 @@ const MICROS_PER_SEC: u64 = 1_000_000; /// `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,7 +419,7 @@ impl Duration { /// Checked `Duration` addition. Computes `self + other`, returning [`None`] /// if overflow occurred. /// - /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`None`]: crate::option::Option::None /// /// # Examples /// @@ -457,7 +455,7 @@ 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 + /// [`None`]: crate::option::Option::None /// /// # Examples /// @@ -494,7 +492,7 @@ impl Duration { /// Checked `Duration` multiplication. Computes `self * other`, returning /// [`None`] if overflow occurred. /// - /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`None`]: crate::option::Option::None /// /// # Examples /// @@ -526,7 +524,7 @@ impl Duration { /// Checked `Duration` division. Computes `self / other`, returning [`None`] /// if `other == 0`. /// - /// [`None`]: ../../std/option/enum.Option.html#variant.None + /// [`None`]: crate::option::Option::None /// /// # Examples /// From ce244210b16871e716539b1eb4de0f8390e4b732 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Sun, 9 Aug 2020 23:12:30 +0200 Subject: [PATCH 10/12] Remove liNone as it is in the prelude --- library/core/src/time.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 4d15a8d51af..cdbad0332ce 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -419,8 +419,6 @@ impl Duration { /// Checked `Duration` addition. Computes `self + other`, returning [`None`] /// if overflow occurred. /// - /// [`None`]: crate::option::Option::None - /// /// # Examples /// /// Basic usage: @@ -455,8 +453,6 @@ impl Duration { /// Checked `Duration` subtraction. Computes `self - other`, returning [`None`] /// if the result would be negative or if overflow occurred. /// - /// [`None`]: crate::option::Option::None - /// /// # Examples /// /// Basic usage: @@ -492,8 +488,6 @@ impl Duration { /// Checked `Duration` multiplication. Computes `self * other`, returning /// [`None`] if overflow occurred. /// - /// [`None`]: crate::option::Option::None - /// /// # Examples /// /// Basic usage: @@ -524,8 +518,6 @@ impl Duration { /// Checked `Duration` division. Computes `self / other`, returning [`None`] /// if `other == 0`. /// - /// [`None`]: crate::option::Option::None - /// /// # Examples /// /// Basic usage: From 9e71c13f28b8ca817f6629b1722ddbefd8c63076 Mon Sep 17 00:00:00 2001 From: Denis Vasilik Date: Sun, 9 Aug 2020 23:26:42 +0200 Subject: [PATCH 11/12] Add link for Duration Co-authored-by: Joshua Nelson --- library/core/src/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/time.rs b/library/core/src/time.rs index cdbad0332ce..5741f8a53b5 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -30,8 +30,8 @@ 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`. /// /// [`ops`]: crate::ops /// From bdf426afe757ed2160c9d8ead9081a07751b9efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 9 Aug 2020 15:12:59 -0700 Subject: [PATCH 12/12] Do not ICE when lowering invalid extern fn with bodies Fix #75283. --- src/librustc_ast_lowering/lib.rs | 4 +++- src/test/ui/issues/issue-75283.rs | 6 ++++++ src/test/ui/issues/issue-75283.stderr | 18 ++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-75283.rs create mode 100644 src/test/ui/issues/issue-75283.stderr diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 9df7ad2a9ac..f2a59cccf9d 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -574,7 +574,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(); diff --git a/src/test/ui/issues/issue-75283.rs b/src/test/ui/issues/issue-75283.rs new file mode 100644 index 00000000000..d556132e47f --- /dev/null +++ b/src/test/ui/issues/issue-75283.rs @@ -0,0 +1,6 @@ +extern "C" { + fn lol() { //~ ERROR incorrect function inside `extern` block + println!(""); + } +} +fn main() {} diff --git a/src/test/ui/issues/issue-75283.stderr b/src/test/ui/issues/issue-75283.stderr new file mode 100644 index 00000000000..da3800affc0 --- /dev/null +++ b/src/test/ui/issues/issue-75283.stderr @@ -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 +