From cf30ac847decca2caaaaf8a2591552bce380c14d Mon Sep 17 00:00:00 2001 From: DeveloperC Date: Fri, 8 Oct 2021 22:02:31 +0100 Subject: [PATCH 1/8] refactor: VecDeques Iter fields to private Made the fields of VecDeque's Iter private by creating a Iter::new(...) function to create a new instance of Iter and migrating usage to use Iter::new(...). --- .../alloc/src/collections/vec_deque/iter.rs | 12 ++++++++--- .../alloc/src/collections/vec_deque/mod.rs | 21 +++++++------------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index e8290809276f..5139db7f451a 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -13,9 +13,15 @@ use super::{count, wrap_index, RingSlices}; /// [`iter`]: super::VecDeque::iter #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { - pub(crate) ring: &'a [MaybeUninit], - pub(crate) tail: usize, - pub(crate) head: usize, + ring: &'a [MaybeUninit], + tail: usize, + head: usize, +} + +impl<'a, T> Iter<'a, T> { + pub(super) fn new(ring: &'a [MaybeUninit], tail: usize, head: usize) -> Self { + Iter { ring, tail, head } + } } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 63280e56332c..e1e0276fc8d8 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1009,7 +1009,7 @@ impl VecDeque { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<'_, T> { - Iter { tail: self.tail, head: self.head, ring: unsafe { self.buffer_as_slice() } } + Iter::new(unsafe { self.buffer_as_slice() }, self.tail, self.head) } /// Returns a front-to-back iterator that returns mutable references. @@ -1188,12 +1188,8 @@ impl VecDeque { R: RangeBounds, { let (tail, head) = self.range_tail_head(range); - Iter { - tail, - head, - // The shared reference we have in &self is maintained in the '_ of Iter. - ring: unsafe { self.buffer_as_slice() }, - } + // The shared reference we have in &self is maintained in the '_ of Iter. + Iter::new(unsafe { self.buffer_as_slice() }, tail, head) } /// Creates an iterator that covers the specified mutable range in the deque. @@ -1309,16 +1305,15 @@ impl VecDeque { self.head = drain_tail; let deque = NonNull::from(&mut *self); - let iter = Iter { - tail: drain_tail, - head: drain_head, + unsafe { // Crucially, we only create shared references from `self` here and read from // it. We do not write to `self` nor reborrow to a mutable reference. // Hence the raw pointer we created above, for `deque`, remains valid. - ring: unsafe { self.buffer_as_slice() }, - }; + let ring = self.buffer_as_slice(); + let iter = Iter::new(ring, drain_tail, drain_head); - unsafe { Drain::new(drain_head, head, iter, deque) } + Drain::new(drain_head, head, iter, deque) + } } /// Clears the deque, removing all values. From d7a2d9ae0e7e4b3c5811bdfd4809cfc772062140 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 25 May 2022 14:29:46 +0200 Subject: [PATCH 2/8] Miri call ABI check: ensure type size+align stay the same --- compiler/rustc_const_eval/src/interpret/terminator.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index a5c7d4c8e20d..10da2f803afe 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -185,7 +185,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // No question return true; } - // Compare layout + if caller_abi.layout.size != callee_abi.layout.size + || caller_abi.layout.align.abi != callee_abi.layout.align.abi + { + // This cannot go well... + // FIXME: What about unsized types? + return false; + } + // The rest *should* be okay, but we are extra conservative. match (caller_abi.layout.abi, callee_abi.layout.abi) { // Different valid ranges are okay (once we enforce validity, // that will take care to make it UB to leave the range, just From 126ef8ee318d5562c92b351868f77b1b9db0b830 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 26 May 2022 10:21:20 -0700 Subject: [PATCH 3/8] don't do Sized/other fn signature checks on RPIT's real type --- compiler/rustc_typeck/src/check/check.rs | 13 ++++++------- src/test/ui/impl-trait/rpit-not-sized.rs | 6 ++++++ src/test/ui/impl-trait/rpit-not-sized.stderr | 12 ++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/impl-trait/rpit-not-sized.rs create mode 100644 src/test/ui/impl-trait/rpit-not-sized.stderr diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 3e76738cc5d9..da51633df991 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -103,12 +103,6 @@ pub(super) fn check_fn<'a, 'tcx>( DUMMY_SP, param_env, )); - // HACK(oli-obk): we rewrite the declared return type, too, so that we don't end up inferring all - // unconstrained RPIT to have `()` as their hidden type. This would happen because further down we - // compare the ret_coercion with declared_ret_ty, and anything uninferred would be inferred to the - // opaque type itself. That again would cause writeback to assume we have a recursive call site - // and do the sadly stabilized fallback to `()`. - let declared_ret_ty = ret_ty; fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty))); fcx.ret_type_span = Some(decl.output.span()); @@ -252,7 +246,12 @@ pub(super) fn check_fn<'a, 'tcx>( fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); debug!("actual_return_ty replaced with {:?}", actual_return_ty); } - fcx.demand_suptype(span, declared_ret_ty, actual_return_ty); + + // HACK(oli-obk, compiler-errors): We should be comparing this against + // `declared_ret_ty`, but then anything uninferred would be inferred to + // the opaque type itself. That again would cause writeback to assume + // we have a recursive call site and do the sadly stabilized fallback to `()`. + fcx.demand_suptype(span, ret_ty, actual_return_ty); // Check that a function marked as `#[panic_handler]` has signature `fn(&PanicInfo) -> !` if let Some(panic_impl_did) = tcx.lang_items().panic_impl() diff --git a/src/test/ui/impl-trait/rpit-not-sized.rs b/src/test/ui/impl-trait/rpit-not-sized.rs new file mode 100644 index 000000000000..bd25940780a1 --- /dev/null +++ b/src/test/ui/impl-trait/rpit-not-sized.rs @@ -0,0 +1,6 @@ +fn foo() -> impl ?Sized { + //~^ ERROR the size for values of type `impl ?Sized` cannot be known at compilation time + () +} + +fn main() {} diff --git a/src/test/ui/impl-trait/rpit-not-sized.stderr b/src/test/ui/impl-trait/rpit-not-sized.stderr new file mode 100644 index 000000000000..608c94fc0723 --- /dev/null +++ b/src/test/ui/impl-trait/rpit-not-sized.stderr @@ -0,0 +1,12 @@ +error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time + --> $DIR/rpit-not-sized.rs:1:13 + | +LL | fn foo() -> impl ?Sized { + | ^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `impl ?Sized` + = note: the return type of a function must have a statically known size + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 0be2ca96fa7d723db870fb2f96df0f07d32c0774 Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Mon, 30 May 2022 15:56:43 +0800 Subject: [PATCH 4/8] Optimize the diagnostic generation for `extern unsafe` --- compiler/rustc_parse/src/parser/item.rs | 41 +++++++------------ src/test/ui/parser/issues/issue-19398.stderr | 7 +--- src/test/ui/parser/unsafe-foreign-mod-2.rs | 8 ++++ .../ui/parser/unsafe-foreign-mod-2.stderr | 28 +++++++++++++ 4 files changed, 52 insertions(+), 32 deletions(-) create mode 100644 src/test/ui/parser/unsafe-foreign-mod-2.rs create mode 100644 src/test/ui/parser/unsafe-foreign-mod-2.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 0f940cffcc46..5c9943b270fd 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -997,35 +997,24 @@ impl<'a> Parser<'a> { fn parse_item_foreign_mod( &mut self, attrs: &mut Vec, - unsafety: Unsafe, + mut unsafety: Unsafe, ) -> PResult<'a, ItemInfo> { - let sp_start = self.prev_token.span; let abi = self.parse_abi(); // ABI? - match self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No)) { - Ok(items) => { - let module = ast::ForeignMod { unsafety, abi, items }; - Ok((Ident::empty(), ItemKind::ForeignMod(module))) - } - Err(mut err) => { - let current_qual_sp = self.prev_token.span; - let current_qual_sp = current_qual_sp.to(sp_start); - if let Ok(current_qual) = self.span_to_snippet(current_qual_sp) { - // FIXME(davidtwco): avoid depending on the error message text - if err.message[0].0.expect_str() == "expected `{`, found keyword `unsafe`" { - let invalid_qual_sp = self.token.uninterpolated_span(); - let invalid_qual = self.span_to_snippet(invalid_qual_sp).unwrap(); - - err.span_suggestion( - current_qual_sp.to(invalid_qual_sp), - &format!("`{}` must come before `{}`", invalid_qual, current_qual), - format!("{} {}", invalid_qual, current_qual), - Applicability::MachineApplicable, - ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`"); - } - } - Err(err) - } + if unsafety == Unsafe::No + && self.token.is_keyword(kw::Unsafe) + && self.look_ahead(1, |t| t.kind == token::OpenDelim(Delimiter::Brace)) + { + let mut err = self.expect(&token::OpenDelim(Delimiter::Brace)).unwrap_err(); + err.emit(); + unsafety = Unsafe::Yes(self.token.span); + self.eat_keyword(kw::Unsafe); } + let module = ast::ForeignMod { + unsafety, + abi, + items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?, + }; + Ok((Ident::empty(), ItemKind::ForeignMod(module))) } /// Parses a foreign item (one in an `extern { ... }` block). diff --git a/src/test/ui/parser/issues/issue-19398.stderr b/src/test/ui/parser/issues/issue-19398.stderr index bbd85374b4bc..1da00960adfe 100644 --- a/src/test/ui/parser/issues/issue-19398.stderr +++ b/src/test/ui/parser/issues/issue-19398.stderr @@ -4,15 +4,10 @@ error: expected `{`, found keyword `unsafe` LL | trait T { | - while parsing this item list starting here LL | extern "Rust" unsafe fn foo(); - | --------------^^^^^^ - | | | - | | expected `{` - | help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"` + | ^^^^^^ expected `{` LL | LL | } | - the item list ends here - | - = note: keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern` error: aborting due to previous error diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.rs b/src/test/ui/parser/unsafe-foreign-mod-2.rs new file mode 100644 index 000000000000..77856fb67340 --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod-2.rs @@ -0,0 +1,8 @@ +extern "C" unsafe { + //~^ ERROR expected `{`, found keyword `unsafe` + //~| ERROR extern block cannot be declared unsafe + unsafe fn foo(); + //~^ ERROR functions in `extern` blocks cannot have qualifiers +} + +fn main() {} diff --git a/src/test/ui/parser/unsafe-foreign-mod-2.stderr b/src/test/ui/parser/unsafe-foreign-mod-2.stderr new file mode 100644 index 000000000000..7cc2de141ae1 --- /dev/null +++ b/src/test/ui/parser/unsafe-foreign-mod-2.stderr @@ -0,0 +1,28 @@ +error: expected `{`, found keyword `unsafe` + --> $DIR/unsafe-foreign-mod-2.rs:1:12 + | +LL | extern "C" unsafe { + | ^^^^^^ expected `{` + +error: extern block cannot be declared unsafe + --> $DIR/unsafe-foreign-mod-2.rs:1:12 + | +LL | extern "C" unsafe { + | ^^^^^^ + +error: functions in `extern` blocks cannot have qualifiers + --> $DIR/unsafe-foreign-mod-2.rs:4:15 + | +LL | extern "C" unsafe { + | ----------------- in this `extern` block +... +LL | unsafe fn foo(); + | ^^^ + | +help: remove the qualifiers + | +LL | fn foo(); + | ~~ + +error: aborting due to 3 previous errors + From f3eae89b33fbd729fb6c401b42daa672bdd1751c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 May 2022 16:53:24 +0200 Subject: [PATCH 5/8] Fix invalid line number computation when clicking on something else than a line number --- src/librustdoc/html/static/js/source-script.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index aaac878d3a37..58c036e0b3ca 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -205,6 +205,10 @@ const handleSourceHighlight = (function() { return ev => { let cur_line_id = parseInt(ev.target.id, 10); + // It can happen when clicking not on a line number span. + if (isNaN(cur_line_id)) { + return; + } ev.preventDefault(); if (ev.shiftKey && prev_line_id) { From 16d5cdc570b45a17a9c85953244ef6058929f608 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 May 2022 17:07:21 +0200 Subject: [PATCH 6/8] Improve source-code-page.goml GUI test code --- src/test/rustdoc-gui/source-code-page.goml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index ad7080c39b84..f31acc80f7e5 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -2,9 +2,9 @@ goto: file://|DOC_PATH|/src/test_docs/lib.rs.html // Check that we can click on the line number. click: ".line-numbers > span:nth-child(4)" // This is the span for line 4. -// Unfortunately, "#4" isn't a valid query selector, so we have to go around that limitation -// by instead getting the nth span. -assert-attribute: (".line-numbers > span:nth-child(4)", {"class": "line-highlighted"}) +// Ensure that the page URL was updated. +assert-document-property: ({"URL": "#4"}, ENDS_WITH) +assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) // We now check that the good spans are highlighted goto: file://|DOC_PATH|/src/test_docs/lib.rs.html#4-6 assert-attribute-false: (".line-numbers > span:nth-child(3)", {"class": "line-highlighted"}) From d286df1402f0e3a96e9ec11748e80c8be4bca92f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 30 May 2022 17:14:46 +0200 Subject: [PATCH 7/8] Add line number click GUI test --- src/test/rustdoc-gui/source-code-page.goml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test/rustdoc-gui/source-code-page.goml b/src/test/rustdoc-gui/source-code-page.goml index f31acc80f7e5..509739c9f295 100644 --- a/src/test/rustdoc-gui/source-code-page.goml +++ b/src/test/rustdoc-gui/source-code-page.goml @@ -3,7 +3,7 @@ goto: file://|DOC_PATH|/src/test_docs/lib.rs.html // Check that we can click on the line number. click: ".line-numbers > span:nth-child(4)" // This is the span for line 4. // Ensure that the page URL was updated. -assert-document-property: ({"URL": "#4"}, ENDS_WITH) +assert-document-property: ({"URL": "lib.rs.html#4"}, ENDS_WITH) assert-attribute: ("//*[@id='4']", {"class": "line-highlighted"}) // We now check that the good spans are highlighted goto: file://|DOC_PATH|/src/test_docs/lib.rs.html#4-6 @@ -17,3 +17,13 @@ compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) // Assert that the line numbers text is aligned to the right. assert-css: (".line-numbers", {"text-align": "right"}) + +// Now let's check that clicking on something else than the line number doesn't +// do anything (and certainly not add a `#NaN` to the URL!). +show-text: true +goto: file://|DOC_PATH|/src/test_docs/lib.rs.html +// We use this assert-position to know where we will click. +assert-position: ("//*[@id='1']", {"x": 104, "y": 103}) +// We click on the left of the "1" span but still in the "line-number" `
`.
+click: (103, 103)
+assert-document-property: ({"URL": "/lib.rs.html"}, ENDS_WITH)

From 56662bcdff2123702c131b4b1a9dc574dea3e402 Mon Sep 17 00:00:00 2001
From: Tobias Stoeckmann 
Date: Mon, 30 May 2022 21:21:32 +0200
Subject: [PATCH 8/8] Fix typos in comment

---
 compiler/rustc_data_structures/src/stable_hasher.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index c8bb4fc5e6af..a915a4daa954 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -632,10 +632,10 @@ fn stable_hash_reduce(
     }
 }
 
-/// Controls what data we do or not not hash.
+/// Controls what data we do or do not hash.
 /// Whenever a `HashStable` implementation caches its
 /// result, it needs to include `HashingControls` as part
-/// of the key, to ensure that is does not produce an incorrect
+/// of the key, to ensure that it does not produce an incorrect
 /// result (for example, using a `Fingerprint` produced while
 /// hashing `Span`s when a `Fingerprint` without `Span`s is
 /// being requested)