From 7624d33fccea45c8deabfcbd1aa702103ac63294 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Jul 2023 14:15:13 +0200 Subject: [PATCH 01/16] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 17b1d2b1120b9..c0c2abfb5ec82 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -743333f3dd90721461c09387ec73d09c080d5f5f +136dab66142115d9de16b4cfe2d8395d71a8ab6d From 58433bfb95b6df7f9518fe0b09c678792304c062 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Jul 2023 14:21:39 +0200 Subject: [PATCH 02/16] fmt --- src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs | 2 +- src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs | 2 +- src/tools/miri/src/lib.rs | 9 +++++---- src/tools/miri/src/machine.rs | 5 ++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index e22b352e7400d..15a7d72edf120 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -996,7 +996,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Protect a place so that it cannot be used any more for the duration of the current function /// call. - /// + /// /// This is used to ensure soundness of in-place function argument/return passing. fn sb_protect_place(&mut self, place: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 274a4a0aaba1d..2afd45829bd89 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -497,7 +497,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Protect a place so that it cannot be used any more for the duration of the current function /// call. - /// + /// /// This is used to ensure soundness of in-place function argument/return passing. fn tb_protect_place(&mut self, place: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 4a093d7bcc6b7..5327c2f24e06d 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -43,19 +43,20 @@ // Needed for rustdoc from bootstrap (with `-Znormalize-docs`). #![recursion_limit = "256"] +extern crate either; // the one from rustc + extern crate rustc_apfloat; extern crate rustc_ast; -extern crate rustc_errors; -#[macro_use] -extern crate rustc_middle; extern crate rustc_const_eval; extern crate rustc_data_structures; +extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_index; +#[macro_use] +extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; -extern crate either; // the one from rustc // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta // files. diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 5510e3f94b75a..f3ac8ebc9cad7 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -1097,9 +1097,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ptr: Pointer, ) -> InterpResult<'tcx> { match ptr.provenance { - Provenance::Concrete { alloc_id, tag } => { - intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag) - } + Provenance::Concrete { alloc_id, tag } => + intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag), Provenance::Wildcard => { // No need to do anything for wildcard pointers as // their provenances have already been previously exposed. From d1e1f76afe15b50a474091dafa0c41f0813b6b2d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 12 Jul 2023 22:28:33 +0200 Subject: [PATCH 03/16] fix tag GC deleting protected tags --- src/tools/miri/src/borrow_tracker/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index a2cf7c80950f6..fcfa8f6457008 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -74,7 +74,7 @@ pub struct FrameState { impl VisitTags for FrameState { fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) { - // `protected_tags` are fine to GC. + // `protected_tags` are already recorded by `GlobalStateInner`. } } @@ -108,9 +108,12 @@ pub struct GlobalStateInner { } impl VisitTags for GlobalStateInner { - fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) { - // The only candidate is base_ptr_tags, and that does not need visiting since we don't ever - // GC the bottommost tag. + fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) { + for &tag in self.protected_tags.keys() { + visit(tag); + } + // The only other candidate is base_ptr_tags, and that does not need visiting since we don't ever + // GC the bottommost/root tag. } } From 477ef41309237a4b2c87104c8c7b667e6e513faa Mon Sep 17 00:00:00 2001 From: The Miri Conjob Bot Date: Thu, 13 Jul 2023 06:33:31 +0000 Subject: [PATCH 04/16] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index c0c2abfb5ec82..3bef3be2a53d6 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -136dab66142115d9de16b4cfe2d8395d71a8ab6d +33a2c2487ac5d9927830ea4c1844335c6b9f77db From c0a105be7ce5833a7d4e744e3dd4b45a1af40796 Mon Sep 17 00:00:00 2001 From: Pedro Lobo Date: Thu, 13 Jul 2023 18:10:52 +0100 Subject: [PATCH 05/16] Rename VecDeque's rotate_left and rotate_right parameters --- .../alloc/src/collections/vec_deque/mod.rs | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 896da37f94c02..5965ec2affac6 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2283,21 +2283,21 @@ impl VecDeque { unsafe { slice::from_raw_parts_mut(ptr.add(self.head), self.len) } } - /// Rotates the double-ended queue `mid` places to the left. + /// Rotates the double-ended queue `n` places to the left. /// /// Equivalently, - /// - Rotates item `mid` into the first position. - /// - Pops the first `mid` items and pushes them to the end. - /// - Rotates `len() - mid` places to the right. + /// - Rotates item `n` into the first position. + /// - Pops the first `n` items and pushes them to the end. + /// - Rotates `len() - n` places to the right. /// /// # Panics /// - /// If `mid` is greater than `len()`. Note that `mid == len()` + /// If `n` is greater than `len()`. Note that `n == len()` /// does _not_ panic and is a no-op rotation. /// /// # Complexity /// - /// Takes `*O*(min(mid, len() - mid))` time and no extra space. + /// Takes `*O*(min(n, len() - n))` time and no extra space. /// /// # Examples /// @@ -2316,31 +2316,31 @@ impl VecDeque { /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` #[stable(feature = "vecdeque_rotate", since = "1.36.0")] - pub fn rotate_left(&mut self, mid: usize) { - assert!(mid <= self.len()); - let k = self.len - mid; - if mid <= k { - unsafe { self.rotate_left_inner(mid) } + pub fn rotate_left(&mut self, n: usize) { + assert!(n <= self.len()); + let k = self.len - n; + if n <= k { + unsafe { self.rotate_left_inner(n) } } else { unsafe { self.rotate_right_inner(k) } } } - /// Rotates the double-ended queue `k` places to the right. + /// Rotates the double-ended queue `n` places to the right. /// /// Equivalently, - /// - Rotates the first item into position `k`. - /// - Pops the last `k` items and pushes them to the front. - /// - Rotates `len() - k` places to the left. + /// - Rotates the first item into position `n`. + /// - Pops the last `n` items and pushes them to the front. + /// - Rotates `len() - n` places to the left. /// /// # Panics /// - /// If `k` is greater than `len()`. Note that `k == len()` + /// If `n` is greater than `len()`. Note that `n == len()` /// does _not_ panic and is a no-op rotation. /// /// # Complexity /// - /// Takes `*O*(min(k, len() - k))` time and no extra space. + /// Takes `*O*(min(n, len() - n))` time and no extra space. /// /// # Examples /// @@ -2359,13 +2359,13 @@ impl VecDeque { /// assert_eq!(buf, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); /// ``` #[stable(feature = "vecdeque_rotate", since = "1.36.0")] - pub fn rotate_right(&mut self, k: usize) { - assert!(k <= self.len()); - let mid = self.len - k; - if k <= mid { - unsafe { self.rotate_right_inner(k) } + pub fn rotate_right(&mut self, n: usize) { + assert!(n <= self.len()); + let k = self.len - n; + if n <= k { + unsafe { self.rotate_right_inner(n) } } else { - unsafe { self.rotate_left_inner(mid) } + unsafe { self.rotate_left_inner(k) } } } From 30a029e51bd89788539afc0525b8651676fdaa78 Mon Sep 17 00:00:00 2001 From: Pedro Lobo Date: Thu, 13 Jul 2023 18:39:09 +0100 Subject: [PATCH 06/16] Fix VecDeque's rotate_left and rotate_right panic tests --- library/alloc/src/collections/vec_deque/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 205a8ff3c19a8..b7fdebfa60b2a 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -351,14 +351,14 @@ fn test_rotate_left_right() { } #[test] -#[should_panic = "assertion failed: mid <= self.len()"] +#[should_panic = "assertion failed: n <= self.len()"] fn test_rotate_left_panic() { let mut tester: VecDeque<_> = (1..=10).collect(); tester.rotate_left(tester.len() + 1); } #[test] -#[should_panic = "assertion failed: k <= self.len()"] +#[should_panic = "assertion failed: n <= self.len()"] fn test_rotate_right_panic() { let mut tester: VecDeque<_> = (1..=10).collect(); tester.rotate_right(tester.len() + 1); From 3ddf6f7c1793ddcd1159c3f21f627b6a7f86518d Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 11 Jul 2023 22:22:22 +0800 Subject: [PATCH 07/16] use maybe_body_owned_by for closure --- .../src/diagnostics/conflict_errors.rs | 19 +--- .../src/diagnostics/mutability_errors.rs | 101 +++++++----------- .../copy-suggestion-region-vid.stderr | 5 + tests/ui/borrowck/issue-85765-closure.rs | 31 ++++++ tests/ui/borrowck/issue-85765-closure.stderr | 48 +++++++++ tests/ui/btreemap/btreemap-index-mut-2.rs | 8 ++ tests/ui/btreemap/btreemap-index-mut-2.stderr | 19 ++++ tests/ui/liveness/liveness-move-call-arg-2.rs | 12 +++ .../liveness/liveness-move-call-arg-2.stderr | 26 +++++ .../suggest-mut-method-for-loop-closure.rs | 19 ++++ ...suggest-mut-method-for-loop-closure.stderr | 15 +++ 11 files changed, 229 insertions(+), 74 deletions(-) create mode 100644 tests/ui/borrowck/issue-85765-closure.rs create mode 100644 tests/ui/borrowck/issue-85765-closure.stderr create mode 100644 tests/ui/btreemap/btreemap-index-mut-2.rs create mode 100644 tests/ui/btreemap/btreemap-index-mut-2.stderr create mode 100644 tests/ui/liveness/liveness-move-call-arg-2.rs create mode 100644 tests/ui/liveness/liveness-move-call-arg-2.stderr create mode 100644 tests/ui/suggestions/suggest-mut-method-for-loop-closure.rs create mode 100644 tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 6e7b0c2e11f45..bc6ae2bdabf02 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -363,21 +363,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } let hir = self.infcx.tcx.hir(); - if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(_, _, body_id), - .. - })) = hir.find(self.mir_hir_id()) - && let Some(hir::Node::Expr(expr)) = hir.find(body_id.hir_id) - { + if let Some(body_id) = hir.maybe_body_owned_by(self.mir_def_id()) { + let expr = hir.body(body_id).value; let place = &self.move_data.move_paths[mpi].place; - let span = place.as_local() - .map(|local| self.body.local_decls[local].source_info.span); - let mut finder = ExpressionFinder { - expr_span: move_span, - expr: None, - pat: None, - parent_pat: None, - }; + let span = place.as_local().map(|local| self.body.local_decls[local].source_info.span); + let mut finder = + ExpressionFinder { expr_span: move_span, expr: None, pat: None, parent_pat: None }; finder.visit_expr(expr); if let Some(span) = span && let Some(expr) = finder.expr { for (_, expr) in hir.parent_iter(expr.hir_id) { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a0a145ef70a46..3c32121a51a60 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -2,7 +2,6 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed use rustc_hir as hir; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; -use rustc_middle::hir::map::Map; use rustc_middle::mir::{Mutability, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{ @@ -646,14 +645,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); - let hir_id = hir_map.local_def_id_to_hir_id(def_id.as_local().unwrap()); - let node = hir_map.find(hir_id); - let Some(hir::Node::Item(item)) = node else { - return; - }; - let hir::ItemKind::Fn(.., body_id) = item.kind else { - return; - }; + let Some(local_def_id) = def_id.as_local() else { return }; + let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) else { return }; let body = self.infcx.tcx.hir().body(body_id); let mut v = V { assign_span: span, err, ty, suggested: false }; @@ -790,23 +783,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // In the future, attempt in all path but initially for RHS of for_loop fn suggest_similar_mut_method_for_for_loop(&self, err: &mut Diagnostic) { use hir::{ - BodyId, Expr, + Expr, ExprKind::{Block, Call, DropTemps, Match, MethodCall}, - HirId, ImplItem, ImplItemKind, Item, ItemKind, }; - fn maybe_body_id_of_fn(hir_map: Map<'_>, id: HirId) -> Option { - match hir_map.find(id) { - Some(Node::Item(Item { kind: ItemKind::Fn(_, _, body_id), .. })) - | Some(Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(_, body_id), .. })) => { - Some(*body_id) - } - _ => None, - } - } let hir_map = self.infcx.tcx.hir(); - let mir_body_hir_id = self.mir_hir_id(); - if let Some(fn_body_id) = maybe_body_id_of_fn(hir_map, mir_body_hir_id) { + if let Some(body_id) = hir_map.maybe_body_owned_by(self.mir_def_id()) { if let Block( hir::Block { expr: @@ -840,7 +822,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .. }, _, - ) = hir_map.body(fn_body_id).value.kind + ) = hir_map.body(body_id).value.kind { let opt_suggestions = self .infcx @@ -1102,46 +1084,45 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let hir_map = self.infcx.tcx.hir(); let def_id = self.body.source.def_id(); - let hir_id = hir_map.local_def_id_to_hir_id(def_id.expect_local()); - let node = hir_map.find(hir_id); - let hir_id = if let Some(hir::Node::Item(item)) = node - && let hir::ItemKind::Fn(.., body_id) = item.kind - { - let body = hir_map.body(body_id); - let mut v = BindingFinder { - span: err_label_span, - hir_id: None, + let hir_id = if let Some(local_def_id) = def_id.as_local() && + let Some(body_id) = hir_map.maybe_body_owned_by(local_def_id) + { + let body = hir_map.body(body_id); + let mut v = BindingFinder { + span: err_label_span, + hir_id: None, + }; + v.visit_body(body); + v.hir_id + } else { + None }; - v.visit_body(body); - v.hir_id - } else { - None - }; + if let Some(hir_id) = hir_id && let Some(hir::Node::Local(local)) = hir_map.find(hir_id) - { - let (changing, span, sugg) = match local.ty { - Some(ty) => ("changing", ty.span, message), - None => ( - "specifying", - local.pat.span.shrink_to_hi(), - format!(": {message}"), - ), - }; - err.span_suggestion_verbose( - span, - format!("consider {changing} this binding's type"), - sugg, - Applicability::HasPlaceholders, - ); - } else { - err.span_label( - err_label_span, - format!( - "consider changing this binding's type to be: `{message}`" - ), - ); - } + { + let (changing, span, sugg) = match local.ty { + Some(ty) => ("changing", ty.span, message), + None => ( + "specifying", + local.pat.span.shrink_to_hi(), + format!(": {message}"), + ), + }; + err.span_suggestion_verbose( + span, + format!("consider {changing} this binding's type"), + sugg, + Applicability::HasPlaceholders, + ); + } else { + err.span_label( + err_label_span, + format!( + "consider changing this binding's type to be: `{message}`" + ), + ); + } } None => {} } diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.stderr b/tests/ui/borrowck/copy-suggestion-region-vid.stderr index 40b8ab182f3b3..8492778089c01 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.stderr +++ b/tests/ui/borrowck/copy-suggestion-region-vid.stderr @@ -8,6 +8,11 @@ LL | HelperStruct { helpers, is_empty: helpers[0].is_empty() } | ------- ^^^^^^^^^^ value borrowed here after move | | | value moved here + | +help: consider cloning the value if the performance cost is acceptable + | +LL | HelperStruct { helpers.clone(), is_empty: helpers[0].is_empty() } + | ++++++++ error: aborting due to previous error diff --git a/tests/ui/borrowck/issue-85765-closure.rs b/tests/ui/borrowck/issue-85765-closure.rs new file mode 100644 index 0000000000000..f2d1dd0fbc3fb --- /dev/null +++ b/tests/ui/borrowck/issue-85765-closure.rs @@ -0,0 +1,31 @@ +fn main() { + let _ = || { + let mut test = Vec::new(); + let rofl: &Vec> = &mut test; + //~^ HELP consider changing this binding's type + rofl.push(Vec::new()); + //~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference + //~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + + let mut mutvar = 42; + let r = &mutvar; + //~^ HELP consider changing this to be a mutable reference + *r = 0; + //~^ ERROR cannot assign to `*r`, which is behind a `&` reference + //~| NOTE `r` is a `&` reference, so the data it refers to cannot be written + + #[rustfmt::skip] + let x: &usize = &mut{0}; + //~^ HELP consider changing this binding's type + *x = 1; + //~^ ERROR cannot assign to `*x`, which is behind a `&` reference + //~| NOTE `x` is a `&` reference, so the data it refers to cannot be written + + #[rustfmt::skip] + let y: &usize = &mut(0); + //~^ HELP consider changing this binding's type + *y = 1; + //~^ ERROR cannot assign to `*y`, which is behind a `&` reference + //~| NOTE `y` is a `&` reference, so the data it refers to cannot be written + }; +} diff --git a/tests/ui/borrowck/issue-85765-closure.stderr b/tests/ui/borrowck/issue-85765-closure.stderr new file mode 100644 index 0000000000000..936ddd67bcd81 --- /dev/null +++ b/tests/ui/borrowck/issue-85765-closure.stderr @@ -0,0 +1,48 @@ +error[E0596]: cannot borrow `*rofl` as mutable, as it is behind a `&` reference + --> $DIR/issue-85765-closure.rs:6:9 + | +LL | rofl.push(Vec::new()); + | ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable + | +help: consider changing this binding's type + | +LL | let rofl: &mut Vec> = &mut test; + | ~~~~~~~~~~~~~~~~~~ + +error[E0594]: cannot assign to `*r`, which is behind a `&` reference + --> $DIR/issue-85765-closure.rs:13:9 + | +LL | *r = 0; + | ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written + | +help: consider changing this to be a mutable reference + | +LL | let r = &mut mutvar; + | +++ + +error[E0594]: cannot assign to `*x`, which is behind a `&` reference + --> $DIR/issue-85765-closure.rs:20:9 + | +LL | *x = 1; + | ^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written + | +help: consider changing this binding's type + | +LL | let x: &mut usize = &mut{0}; + | ~~~~~~~~~~ + +error[E0594]: cannot assign to `*y`, which is behind a `&` reference + --> $DIR/issue-85765-closure.rs:27:9 + | +LL | *y = 1; + | ^^^^^^ `y` is a `&` reference, so the data it refers to cannot be written + | +help: consider changing this binding's type + | +LL | let y: &mut usize = &mut(0); + | ~~~~~~~~~~ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0594, E0596. +For more information about an error, try `rustc --explain E0594`. diff --git a/tests/ui/btreemap/btreemap-index-mut-2.rs b/tests/ui/btreemap/btreemap-index-mut-2.rs new file mode 100644 index 0000000000000..fe676210a1b81 --- /dev/null +++ b/tests/ui/btreemap/btreemap-index-mut-2.rs @@ -0,0 +1,8 @@ +use std::collections::BTreeMap; + +fn main() { + let _ = || { + let mut map = BTreeMap::::new(); + map[&0] = 1; //~ ERROR cannot assign + }; +} diff --git a/tests/ui/btreemap/btreemap-index-mut-2.stderr b/tests/ui/btreemap/btreemap-index-mut-2.stderr new file mode 100644 index 0000000000000..c8d4fd59550f0 --- /dev/null +++ b/tests/ui/btreemap/btreemap-index-mut-2.stderr @@ -0,0 +1,19 @@ +error[E0594]: cannot assign to data in an index of `BTreeMap` + --> $DIR/btreemap-index-mut-2.rs:6:9 + | +LL | map[&0] = 1; + | ^^^^^^^^^^^ cannot assign + | + = help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `BTreeMap` +help: to modify a `BTreeMap`, use `.get_mut()`, `.insert()` or the entry API + | +LL | map.insert(&0, 1); + | ~~~~~~~~ ~ + +LL | map.get_mut(&0).map(|val| { *val = 1; }); + | ~~~~~~~~~ ~~~~~~~~~~~~~~~~~~ ++++ +LL | let val = map.entry(&0).or_insert(1); + | +++++++++ ~~~~~~~ ~~~~~~~~~~~~ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. diff --git a/tests/ui/liveness/liveness-move-call-arg-2.rs b/tests/ui/liveness/liveness-move-call-arg-2.rs new file mode 100644 index 0000000000000..b93535c89b19e --- /dev/null +++ b/tests/ui/liveness/liveness-move-call-arg-2.rs @@ -0,0 +1,12 @@ +fn take(_x: Box) {} + + +fn main() { + let _ = || { + let x: Box = Box::new(25); + + loop { + take(x); //~ ERROR use of moved value: `x` + } + }; +} diff --git a/tests/ui/liveness/liveness-move-call-arg-2.stderr b/tests/ui/liveness/liveness-move-call-arg-2.stderr new file mode 100644 index 0000000000000..479a086a80c32 --- /dev/null +++ b/tests/ui/liveness/liveness-move-call-arg-2.stderr @@ -0,0 +1,26 @@ +error[E0382]: use of moved value: `x` + --> $DIR/liveness-move-call-arg-2.rs:9:18 + | +LL | let x: Box = Box::new(25); + | - move occurs because `x` has type `Box`, which does not implement the `Copy` trait +LL | +LL | loop { + | ---- inside of this loop +LL | take(x); + | ^ value moved here, in previous iteration of loop + | +note: consider changing this parameter type in function `take` to borrow instead if owning the value isn't necessary + --> $DIR/liveness-move-call-arg-2.rs:1:13 + | +LL | fn take(_x: Box) {} + | ---- ^^^^^^^^^^ this parameter takes ownership of the value + | | + | in this function +help: consider cloning the value if the performance cost is acceptable + | +LL | take(x.clone()); + | ++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-closure.rs b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.rs new file mode 100644 index 0000000000000..e4721ba019337 --- /dev/null +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.rs @@ -0,0 +1,19 @@ +use std::collections::HashMap; +struct X(usize); +struct Y { + v: u32, +} + +fn main() { + let _ = || { + let mut buzz = HashMap::new(); + buzz.insert("a", Y { v: 0 }); + + for mut t in buzz.values() { + //~^ HELP + //~| SUGGESTION values_mut() + t.v += 1; + //~^ ERROR cannot assign + } + }; +} diff --git a/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr new file mode 100644 index 0000000000000..8a2df8d7cc1ad --- /dev/null +++ b/tests/ui/suggestions/suggest-mut-method-for-loop-closure.stderr @@ -0,0 +1,15 @@ +error[E0594]: cannot assign to `t.v`, which is behind a `&` reference + --> $DIR/suggest-mut-method-for-loop-closure.rs:15:13 + | +LL | for mut t in buzz.values() { + | ------------- + | | | + | | help: use mutable method: `values_mut()` + | this iterator yields `&` references +... +LL | t.v += 1; + | ^^^^^^^^ `t` is a `&` reference, so the data it refers to cannot be written + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0594`. From bdd04a62f9fd142a8ad362b8589a3512e8c357d7 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 13 Jul 2023 18:55:45 +0800 Subject: [PATCH 08/16] fix the issue of shorthand in suggest_cloning --- .../src/diagnostics/conflict_errors.rs | 18 ++++++-- compiler/rustc_hir_typeck/src/demand.rs | 41 ++----------------- .../src/fn_ctxt/suggestions.rs | 6 +-- compiler/rustc_middle/src/hir/map/mod.rs | 27 ++++++++++++ .../ui/borrowck/copy-suggestion-region-vid.rs | 1 + .../copy-suggestion-region-vid.stderr | 6 +-- 6 files changed, 53 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index bc6ae2bdabf02..86f2481834291 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -452,7 +452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } = move_spans { // We already suggest cloning for these cases in `explain_captures`. } else { - self.suggest_cloning(err, ty, move_span); + self.suggest_cloning(err, ty, expr, move_span); } } } @@ -727,9 +727,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { true } - fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { + fn suggest_cloning( + &self, + err: &mut Diagnostic, + ty: Ty<'tcx>, + expr: &hir::Expr<'_>, + span: Span, + ) { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` + let suggestion = + if let Some(symbol) = tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { + format!(": {}.clone()", symbol) + } else { + ".clone()".to_owned() + }; if let Some(clone_trait_def) = tcx.lang_items().clone_trait() && self.infcx .type_implements_trait( @@ -742,7 +754,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_suggestion_verbose( span.shrink_to_hi(), "consider cloning the value if the performance cost is acceptable", - ".clone()", + suggestion, Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 80db01e08dbc7..6b8deab9fd255 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeFoldable}; -use rustc_span::symbol::{sym, Symbol}; +use rustc_span::symbol::sym; use rustc_span::{BytePos, Span, DUMMY_SP}; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::ObligationCause; @@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .collect(); let suggestions_for = |variant: &_, ctor_kind, field_name| { - let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { + let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -1240,39 +1240,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(crate) fn maybe_get_struct_pattern_shorthand_field( - &self, - expr: &hir::Expr<'_>, - ) -> Option { - let hir = self.tcx.hir(); - let local = match expr { - hir::Expr { - kind: - hir::ExprKind::Path(hir::QPath::Resolved( - None, - hir::Path { - res: hir::def::Res::Local(_), - segments: [hir::PathSegment { ident, .. }], - .. - }, - )), - .. - } => Some(ident), - _ => None, - }?; - - match hir.find_parent(expr.hir_id)? { - Node::ExprField(field) => { - if field.ident.name == local.name && field.is_shorthand { - return Some(local.name); - } - } - _ => {} - } - - None - } - /// If the given `HirId` corresponds to a block with a trailing expression, return that expression pub(crate) fn maybe_get_block_expr( &self, @@ -1467,7 +1434,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } - let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { + let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!("{ident}: "), None => String::new(), }; @@ -1661,7 +1628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }; - let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { + let prefix = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!("{ident}: "), None => String::new(), }; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 5d80137f212d1..350b023b79480 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { vec![(expr.span.shrink_to_hi(), format!(".{}()", conversion_method.name))] }; let struct_pat_shorthand_field = - self.maybe_get_struct_pattern_shorthand_field(expr); + self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr); if let Some(name) = struct_pat_shorthand_field { sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name))); } @@ -1069,7 +1069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .must_apply_modulo_regions() { - let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) { + let suggestion = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!(": {}.clone()", ident), None => ".clone()".to_string() }; @@ -1247,7 +1247,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) { + let suggestion = match self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!(": {}.is_some()", ident), None => ".is_some()".to_string(), }; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 6bb8e632dbedb..1fd68dc5cb28e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1103,6 +1103,33 @@ impl<'hir> Map<'hir> { _ => None, } } + + pub fn maybe_get_struct_pattern_shorthand_field(&self, expr: &Expr<'_>) -> Option { + let local = match expr { + Expr { + kind: + ExprKind::Path(QPath::Resolved( + None, + Path { + res: def::Res::Local(_), segments: [PathSegment { ident, .. }], .. + }, + )), + .. + } => Some(ident), + _ => None, + }?; + + match self.find_parent(expr.hir_id)? { + Node::ExprField(field) => { + if field.ident.name == local.name && field.is_shorthand { + return Some(local.name); + } + } + _ => {} + } + + None + } } impl<'hir> intravisit::Map<'hir> for Map<'hir> { diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.rs b/tests/ui/borrowck/copy-suggestion-region-vid.rs index dff95283459b6..3c5b887ce17bd 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.rs +++ b/tests/ui/borrowck/copy-suggestion-region-vid.rs @@ -1,3 +1,4 @@ +//@run-rustfix pub struct DataStruct(); pub struct HelperStruct<'n> { diff --git a/tests/ui/borrowck/copy-suggestion-region-vid.stderr b/tests/ui/borrowck/copy-suggestion-region-vid.stderr index 8492778089c01..b344aa6640517 100644 --- a/tests/ui/borrowck/copy-suggestion-region-vid.stderr +++ b/tests/ui/borrowck/copy-suggestion-region-vid.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `helpers` - --> $DIR/copy-suggestion-region-vid.rs:12:43 + --> $DIR/copy-suggestion-region-vid.rs:13:43 | LL | let helpers = [vec![], vec![]]; | ------- move occurs because `helpers` has type `[Vec<&i64>; 2]`, which does not implement the `Copy` trait @@ -11,8 +11,8 @@ LL | HelperStruct { helpers, is_empty: helpers[0].is_empty() } | help: consider cloning the value if the performance cost is acceptable | -LL | HelperStruct { helpers.clone(), is_empty: helpers[0].is_empty() } - | ++++++++ +LL | HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() } + | +++++++++++++++++ error: aborting due to previous error From 04dbc7da40b7445ba10917eb10b700a23bde8d2b Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 14 Jul 2023 06:54:40 +0000 Subject: [PATCH 09/16] rustdoc-json: Add test for private supertrait. --- tests/rustdoc-json/traits/private_supertrait.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/rustdoc-json/traits/private_supertrait.rs diff --git a/tests/rustdoc-json/traits/private_supertrait.rs b/tests/rustdoc-json/traits/private_supertrait.rs new file mode 100644 index 0000000000000..49238e5e88be4 --- /dev/null +++ b/tests/rustdoc-json/traits/private_supertrait.rs @@ -0,0 +1,15 @@ +// ignore-tidy-linelength + +#![feature(no_core)] +#![no_core] + + +// @!has "$.index[*][?(@.name == 'sealed')]" +mod sealed { + // @set sealed_id = "$.index[*][?(@.name=='Sealed')].id" + pub trait Sealed {} +} + +// @count "$.index[*][?(@.name=='Trait')].inner.trait.bounds[*]" 1 +// @is "$.index[*][?(@.name=='Trait')].inner.trait.bounds[0].trait_bound.trait.id" $sealed_id +pub trait Trait: sealed::Sealed {} From c0156d11201258c349b80f8317ffe3de18a4f7e3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 14 Jul 2023 10:32:27 +0200 Subject: [PATCH 10/16] also apply to nested modules of `solve` --- triagebot.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index da9d167bd3e36..1a435ff074ee7 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -264,7 +264,7 @@ exclude_labels = [ [autolabel."WG-trait-system-refactor"] trigger_files = [ "compiler/rustc_trait_selection/src/solve", - "compiler/rustc_middle/src/traits/solve.rs" + "compiler/rustc_middle/src/traits/solve" ] [notify-zulip."I-prioritize"] From 40cef615c02efcab2e42e771b55fb386b3f53383 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 14 Jul 2023 12:12:27 +0200 Subject: [PATCH 11/16] work around custom_mir span --- .../function_calls/arg_inplace_observe_after.rs | 6 +++--- .../function_calls/arg_inplace_observe_after.stderr | 13 +++---------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs index 8eda913feb4ba..093b55759fdec 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs @@ -5,9 +5,9 @@ pub struct S(i32); #[custom_mir(dialect = "runtime", phase = "optimized")] fn main() { - // FIXME: the span is not great (probably caused by custom MIR) - mir! { //~ERROR: uninitialized + mir! { let unit: (); + let _observe: i32; { let non_copy = S(42); // This could change `non_copy` in-place @@ -15,7 +15,7 @@ fn main() { } after_call = { // So now we must not be allowed to observe non-copy again. - let _observe = non_copy.0; + _observe = non_copy.0; //~ERROR: uninitialized Return() } diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr index 3ff7976c70bd1..5d9a3af0c8aa0 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr @@ -1,20 +1,13 @@ error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/arg_inplace_observe_after.rs:LL:CC | -LL | / mir! { -LL | | let unit: (); -LL | | { -LL | | let non_copy = S(42); -... | -LL | | -LL | | } - | |_____^ using uninitialized data, but this operation requires initialized memory +LL | _observe = non_copy.0; + | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/intrinsics/mir.rs:LL:CC - = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: inside `main` at $DIR/arg_inplace_observe_after.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace From 6ddf9128b2b55f9def80af57f7353d2521527c6a Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 14 Jul 2023 12:10:29 +0000 Subject: [PATCH 12/16] llvm-wrapper: update for LLVM API change No functional changes intended. Adds an include for llvm::SmallString. Previously, this must have been implicitly provided by some of the existing headers. With recent LLVM changes, not anymore: https://buildkite.com/llvm-project/rust-llvm-integrate-prototype/builds/20776#01895448-44a4-4a1e-8407-9d41d0186132/209-690 --- compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index 0493d6b05d030..bf00d11edf6d8 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -7,6 +7,7 @@ // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp +#include "llvm/ADT/SmallString.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Object/ObjectFile.h" From 668f2d7dbfb3dafa91ae2817b6447291e7f369d3 Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Fri, 14 Jul 2023 13:11:31 +0000 Subject: [PATCH 13/16] tests: adapt for removal of -opaque-pointers in LLVM 17 The commit https://github.com/llvm/llvm-project/commit/53717cabf837a589dd54a47dd8b4b3b9677f0b85 removed the flag from LLVM. --- tests/ui/dyn-star/llvm-old-style-ptrs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ui/dyn-star/llvm-old-style-ptrs.rs b/tests/ui/dyn-star/llvm-old-style-ptrs.rs index d35519632becf..4c042a539798b 100644 --- a/tests/ui/dyn-star/llvm-old-style-ptrs.rs +++ b/tests/ui/dyn-star/llvm-old-style-ptrs.rs @@ -3,6 +3,8 @@ // (opaque-pointers flag is called force-opaque-pointers in LLVM 13...) // min-llvm-version: 14.0 +// (the ability to disable opaque pointers has been removed in LLVM 17) +// ignore-llvm-version: 17 - 99 // This test can be removed once non-opaque pointers are gone from LLVM, maybe. From b88bcda35a8cdb380b17d278feac1033ad99fb52 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Jul 2023 15:53:45 +0200 Subject: [PATCH 14/16] remove compile-flags that are no longer needed --- .../miri/tests/fail/dangling_pointers/dangling_zst_deref.rs | 3 +-- src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs | 4 ++-- .../fail/dangling_pointers/maybe_null_pointer_deref_zst.rs | 3 --- .../fail/dangling_pointers/maybe_null_pointer_write_zst.rs | 3 --- .../tests/fail/dangling_pointers/null_pointer_deref_zst.rs | 3 --- .../tests/fail/dangling_pointers/null_pointer_write_zst.rs | 3 --- .../miri/tests/fail/dangling_pointers/stack_temporary.rs | 4 ++-- .../tests/fail/dangling_pointers/storage_dead_dangling.rs | 4 ++-- src/tools/miri/tests/fail/data_race/read_write_race_stack.rs | 5 +---- src/tools/miri/tests/fail/erroneous_const.rs | 2 -- .../miri/tests/fail/unaligned_pointers/dyn_alignment.rs | 2 +- .../miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs | 3 +-- src/tools/miri/tests/fail/validity/nonzero.rs | 2 -- src/tools/miri/tests/fail/zst2.rs | 3 --- src/tools/miri/tests/fail/zst3.rs | 3 --- 15 files changed, 10 insertions(+), 37 deletions(-) diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs index 534d7d5f42f32..e749eb896e241 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs @@ -1,6 +1,5 @@ // Make sure we find these even with many checks disabled. -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation fn main() { let p = { diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs index 54f353ebebeb1..87ca8a6077cad 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs @@ -1,5 +1,5 @@ -// should find the bug even without these, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 +// should find the bug even without these +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows struct SliceWithHead(u8, [u8]); diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs index a48a3189db2e3..73d0b12068013 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // This pointer *could* be NULL so we cannot load from it, not even at ZST let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *const (); diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs index 449c65d218a02..5537207ae424f 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // This pointer *could* be NULL so we cannot load from it, not even at ZST. // Not using the () type here, as writes of that type do not even have MIR generated. diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs index d6a607c61cbeb..4cb805db09526 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - #[allow(deref_nullptr)] fn main() { let x: () = unsafe { *std::ptr::null() }; //~ ERROR: dereferencing pointer failed: null pointer is a dangling pointer diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs index 21344208130ea..ec34c631a4667 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - #[allow(deref_nullptr)] fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs index 1373773f68d59..c193d5fe0b31e 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs @@ -1,5 +1,5 @@ -// This should fail even without validation, but some MIR opts mask the error -//@compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 +// This should fail even without validation +//@compile-flags: -Zmiri-disable-validation unsafe fn make_ref<'a>(x: *mut i32) -> &'a mut i32 { &mut *x diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs index 366930a831c88..f9983f48c6174 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs @@ -1,5 +1,5 @@ -// This should fail even without validation, but some MIR opts mask the error -//@compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 -Zmiri-permissive-provenance +// This should fail even without validation +//@compile-flags: -Zmiri-disable-validation -Zmiri-permissive-provenance static mut LEAK: usize = 0; diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs index 40224ced12d08..c3e5c401d879a 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs @@ -1,7 +1,4 @@ -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows - -// Note: mir-opt-level set to 0 to prevent the read of stack_var in thread 1 -// from being optimized away and preventing the detection of the data-race. +//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows use std::ptr::null_mut; use std::sync::atomic::{AtomicPtr, Ordering}; diff --git a/src/tools/miri/tests/fail/erroneous_const.rs b/src/tools/miri/tests/fail/erroneous_const.rs index d37837c71931e..65f7aafc3cc85 100644 --- a/src/tools/miri/tests/fail/erroneous_const.rs +++ b/src/tools/miri/tests/fail/erroneous_const.rs @@ -1,7 +1,5 @@ //! Make sure we detect erroneous constants post-monomorphization even when they are unused. //! (https://github.com/rust-lang/miri/issues/1382) -// Inlining changes the error location -//@compile-flags: -Zmir-opt-level=0 #![feature(never_type)] struct PrintName(T); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs index 555aa57de3018..b5a9b2bf18ee3 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs @@ -1,5 +1,5 @@ // should find the bug even without, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no //@normalize-stderr-test: "but found [0-9]+" -> "but found $$ALIGN" #[repr(align(256))] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs index 04dbe3fd8d497..289536287a90e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs @@ -1,6 +1,5 @@ // This should fail even without validation -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Cdebug-assertions=no fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/validity/nonzero.rs b/src/tools/miri/tests/fail/validity/nonzero.rs index 384c94a556998..7cba90bc15d13 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.rs +++ b/src/tools/miri/tests/fail/validity/nonzero.rs @@ -1,5 +1,3 @@ -// gets masked by optimizations -//@compile-flags: -Zmir-opt-level=0 #![feature(rustc_attrs)] #![allow(unused_attributes)] diff --git a/src/tools/miri/tests/fail/zst2.rs b/src/tools/miri/tests/fail/zst2.rs index 82470866f179f..1d3e8ea9d007e 100644 --- a/src/tools/miri/tests/fail/zst2.rs +++ b/src/tools/miri/tests/fail/zst2.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. // Also not assigning directly as that's array initialization, not assignment. diff --git a/src/tools/miri/tests/fail/zst3.rs b/src/tools/miri/tests/fail/zst3.rs index a511f38998feb..454bef25f2234 100644 --- a/src/tools/miri/tests/fail/zst3.rs +++ b/src/tools/miri/tests/fail/zst3.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. // Also not assigning directly as that's array initialization, not assignment. From 18305eae8e48cdb437224702b7e753d3efefff23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 14 Jul 2023 16:07:24 +0200 Subject: [PATCH 15/16] Print artifact sizes in `opt-dist` --- src/tools/opt-dist/src/main.rs | 8 ++++++-- src/tools/opt-dist/src/utils/io.rs | 16 +++++++++++++++- src/tools/opt-dist/src/utils/mod.rs | 26 ++++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 39fa7e1fb2afd..5e82430416b6b 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -7,7 +7,9 @@ use crate::tests::run_tests; use crate::timer::Timer; use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles}; use crate::utils::io::reset_directory; -use crate::utils::{clear_llvm_files, format_env_variables, print_free_disk_space}; +use crate::utils::{ + clear_llvm_files, format_env_variables, print_binary_sizes, print_free_disk_space, +}; mod environment; mod exec; @@ -170,6 +172,8 @@ fn main() -> anyhow::Result<()> { log::info!("Timer results\n{}", timer.format_stats()); print_free_disk_space()?; + result.context("Optimized build pipeline has failed")?; + print_binary_sizes(env.as_ref())?; - result.context("Optimized build pipeline has failed") + Ok(()) } diff --git a/src/tools/opt-dist/src/utils/io.rs b/src/tools/opt-dist/src/utils/io.rs index 43546e5fcfa67..aab078067afca 100644 --- a/src/tools/opt-dist/src/utils/io.rs +++ b/src/tools/opt-dist/src/utils/io.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use camino::Utf8Path; +use camino::{Utf8Path, Utf8PathBuf}; use fs_extra::dir::CopyOptions; use std::fs::File; @@ -46,3 +46,17 @@ pub fn unpack_archive(path: &Utf8Path, dest_dir: &Utf8Path) -> anyhow::Result<() archive.unpack(dest_dir.as_std_path())?; Ok(()) } + +/// Returns paths in the given `dir` (non-recursively), optionally with the given `suffix`. +/// The `suffix` should contain the leading dot. +pub fn get_files_from_dir( + dir: &Utf8Path, + suffix: Option<&str>, +) -> anyhow::Result> { + let path = format!("{dir}/*{}", suffix.unwrap_or("")); + + Ok(glob::glob(&path)? + .into_iter() + .map(|p| p.map(|p| Utf8PathBuf::from_path_buf(p).unwrap())) + .collect::, _>>()?) +} diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs index 9305d4989aa76..65e0e8cc4ef4a 100644 --- a/src/tools/opt-dist/src/utils/mod.rs +++ b/src/tools/opt-dist/src/utils/mod.rs @@ -1,8 +1,8 @@ pub mod io; use crate::environment::Environment; -use crate::utils::io::delete_directory; -use humansize::BINARY; +use crate::utils::io::{delete_directory, get_files_from_dir}; +use humansize::{format_size, BINARY}; use sysinfo::{DiskExt, RefreshKind, System, SystemExt}; pub fn format_env_variables() -> String { @@ -25,6 +25,28 @@ pub fn print_free_disk_space() -> anyhow::Result<()> { Ok(()) } +pub fn print_binary_sizes(env: &dyn Environment) -> anyhow::Result<()> { + use std::fmt::Write; + + let root = env.build_artifacts().join("stage2"); + + let mut files = get_files_from_dir(&root.join("bin"), None)?; + files.extend(get_files_from_dir(&root.join("lib"), Some(".so"))?); + files.sort_unstable(); + + let mut output = String::new(); + for file in files { + let size = std::fs::metadata(file.as_std_path())?.len(); + let size_formatted = format_size(size, BINARY); + let name = format!("{}:", file.file_name().unwrap()); + writeln!(output, "{name:<50}{size_formatted:>10}")?; + } + + log::info!("Rustc artifact size\n{output}"); + + Ok(()) +} + pub fn clear_llvm_files(env: &dyn Environment) -> anyhow::Result<()> { // Bootstrap currently doesn't support rebuilding LLVM when PGO options // change (or any other llvm-related options); so just clear out the relevant From 14672eba8bec4eeec03d24d5985a4c8c172a01da Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 14 Jul 2023 15:18:19 +0000 Subject: [PATCH 16/16] Make it clearer that we're just checking for an RPITIT --- compiler/rustc_hir_analysis/src/astconv/errors.rs | 4 ++-- compiler/rustc_hir_analysis/src/astconv/object_safety.rs | 2 +- compiler/rustc_hir_analysis/src/check/compare_impl_item.rs | 4 ++-- compiler/rustc_hir_analysis/src/check/mod.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/ty/assoc.rs | 4 ++++ compiler/rustc_passes/src/dead.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- compiler/rustc_trait_selection/src/traits/object_safety.rs | 2 +- 9 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index ddf99853b2e52..deed811a4bb7c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -123,7 +123,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let all_candidate_names: Vec<_> = all_candidates() .flat_map(|r| self.tcx().associated_items(r.def_id()).in_definition_order()) .filter_map(|item| { - if item.opt_rpitit_info.is_none() && item.kind == ty::AssocKind::Type { + if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type { Some(item.name) } else { None @@ -164,7 +164,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.tcx().associated_items(*trait_def_id).in_definition_order() }) .filter_map(|item| { - if item.opt_rpitit_info.is_none() && item.kind == ty::AssocKind::Type { + if !item.is_impl_trait_in_trait() && item.kind == ty::AssocKind::Type { Some(item.name) } else { None diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 9227ee9345142..b49cadd3221a4 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -173,7 +173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.associated_items(pred.def_id()) .in_definition_order() .filter(|item| item.kind == ty::AssocKind::Type) - .filter(|item| item.opt_rpitit_info.is_none()) + .filter(|item| !item.is_impl_trait_in_trait()) .map(|item| item.def_id), ); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 22e576e345e1f..620174b7753ff 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1319,7 +1319,7 @@ fn compare_number_of_generics<'tcx>( // has mismatched type or const generic arguments, then the method that it's // inheriting the generics from will also have mismatched arguments, and // we'll report an error for that instead. Delay a bug for safety, though. - if trait_.opt_rpitit_info.is_some() { + if trait_.is_impl_trait_in_trait() { return Err(tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "errors comparing numbers of generics of trait/impl functions were not emitted", @@ -2111,7 +2111,7 @@ pub(super) fn check_type_bounds<'tcx>( // A synthetic impl Trait for RPITIT desugaring has no HIR, which we currently use to get the // span for an impl's associated type. Instead, for these, use the def_span for the synthesized // associated type. - let impl_ty_span = if impl_ty.opt_rpitit_info.is_some() { + let impl_ty_span = if impl_ty.is_impl_trait_in_trait() { tcx.def_span(impl_ty_def_id) } else { match tcx.hir().get_by_def_id(impl_ty_def_id) { diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index ce2da7cb1a325..60d5e1bdfabe2 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -188,7 +188,7 @@ fn missing_items_err( full_impl_span: Span, ) { let missing_items = - missing_items.iter().filter(|trait_item| trait_item.opt_rpitit_info.is_none()); + missing_items.iter().filter(|trait_item| !trait_item.is_impl_trait_in_trait()); let missing_items_msg = missing_items .clone() diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index fc1062a48b45c..93586e78a398f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1136,7 +1136,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) -> // the default projection predicates in default trait methods // with RPITITs. ty::AssocItemContainer::TraitContainer => { - assoc_item.defaultness(tcx).has_value() || assoc_item.opt_rpitit_info.is_some() + assoc_item.defaultness(tcx).has_value() || assoc_item.is_impl_trait_in_trait() } } } diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index cce609c261e8d..fdc38078104cb 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -92,6 +92,10 @@ impl AssocItem { } } } + + pub fn is_impl_trait_in_trait(&self) -> bool { + self.opt_rpitit_info.is_some() + } } #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)] diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d5ac1cd9ce335..cc883932ae981 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -276,7 +276,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } // Avoid accessing the HIR for the synthesized associated type generated for RPITITs. - if self.tcx.opt_rpitit_info(id.to_def_id()).is_some() { + if self.tcx.is_impl_trait_in_trait(id.to_def_id()) { self.live_symbols.insert(id); continue; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 1a9e21c2bea13..040bd4a67e288 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -435,7 +435,7 @@ fn suggest_restriction<'tcx>( ) { if hir_generics.where_clause_span.from_expansion() || hir_generics.where_clause_span.desugaring_kind().is_some() - || projection.is_some_and(|projection| tcx.opt_rpitit_info(projection.def_id).is_some()) + || projection.is_some_and(|projection| tcx.is_impl_trait_in_trait(projection.def_id)) { return; } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index c31944c162e6c..00646c0e1c397 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -393,7 +393,7 @@ fn object_safety_violation_for_assoc_item( ty::AssocKind::Type => { if !tcx.features().generic_associated_types_extended && !tcx.generics_of(item.def_id).params.is_empty() - && item.opt_rpitit_info.is_none() + && !item.is_impl_trait_in_trait() { Some(ObjectSafetyViolation::GAT(item.name, item.ident(tcx).span)) } else {