From 3a13a721418b53ee6ca4c24fdbd17cc136ebcebb Mon Sep 17 00:00:00 2001 From: threadexception Date: Wed, 17 Nov 2021 16:31:56 +0100 Subject: [PATCH 01/24] Improve `unsafe` diagnostic --- compiler/rustc_parse/src/parser/item.rs | 28 +++++++++++++++++--- src/test/ui/parser/issues/issue-19398.stderr | 7 ++++- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 24a8df49ac7ee..6e9eaf0c0f947 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -933,10 +933,32 @@ impl<'a> Parser<'a> { attrs: &mut Vec, unsafety: Unsafe, ) -> PResult<'a, ItemInfo> { + let sp_start = self.prev_token.span; let abi = self.parse_abi(); // ABI? - let items = self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?; - let module = ast::ForeignMod { unsafety, abi, items }; - Ok((Ident::empty(), ItemKind::ForeignMod(module))) + 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) { + if err.message() == "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 `default`, `pub`, `const`, `async`, `unsafe`, `extern`"); + } + } + Err(err) + } + } } /// 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 1da00960adfe4..f9c3ca763f26e 100644 --- a/src/test/ui/parser/issues/issue-19398.stderr +++ b/src/test/ui/parser/issues/issue-19398.stderr @@ -4,10 +4,15 @@ error: expected `{`, found keyword `unsafe` LL | trait T { | - while parsing this item list starting here LL | extern "Rust" unsafe fn foo(); - | ^^^^^^ expected `{` + | --------------^^^^^^ + | | | + | | expected `{` + | help: `unsafe` must come before `extern "Rust"`: `unsafe extern "Rust"` LL | LL | } | - the item list ends here + | + = note: keyword order for functions declaration is `default`, `pub`, `const`, `async`, `unsafe`, `extern` error: aborting due to previous error From 60f5cad6ebaa683ac58132b7bb64002a90deb343 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 18 Feb 2022 17:06:48 -0500 Subject: [PATCH 02/24] try to fix issue 57017, but not quite there yet Co-authored-by: Eric Holk --- .../src/check/generator_interior.rs | 14 +++++++++++-- .../check/generator_interior/drop_ranges.rs | 21 ++++++++++++++++--- .../drop_ranges/cfg_build.rs | 6 +++--- .../drop_ranges/record_consumed_borrow.rs | 17 ++++++++++++++- foo.rs | 21 +++++++++++++++++++ 5 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 foo.rs diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 9684237be8313..30469e2ec7bbd 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -13,7 +13,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdSet; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind}; -use rustc_middle::middle::region::{self, YieldData}; +use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -369,7 +369,17 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { self.expr_count += 1; - let scope = self.region_scope_tree.temporary_scope(expr.hir_id.local_id); + debug!("is_borrowed_temporary: {:?}", self.drop_ranges.is_borrowed_temporary(expr)); + + let scope = if self.drop_ranges.is_borrowed_temporary(expr) { + self.region_scope_tree.temporary_scope(expr.hir_id.local_id) + } else { + debug!("parent_node: {:?}", self.fcx.tcx.hir().find_parent_node(expr.hir_id)); + match self.fcx.tcx.hir().find_parent_node(expr.hir_id) { + Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }), + None => self.region_scope_tree.temporary_scope(expr.hir_id.local_id), + } + }; // If there are adjustments, then record the final type -- // this is the actual value that is being produced. diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs index 972dd622d6e98..4fa7ed82c6a84 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges.rs @@ -18,6 +18,7 @@ use crate::check::FnCtxt; use hir::def_id::DefId; use hir::{Body, HirId, HirIdMap, Node}; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_set::FxHashSet; use rustc_hir as hir; use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; @@ -41,7 +42,7 @@ pub fn compute_drop_ranges<'a, 'tcx>( let consumed_borrowed_places = find_consumed_and_borrowed(fcx, def_id, body); let num_exprs = fcx.tcx.region_scope_tree(def_id).body_expr_count(body.id()).unwrap_or(0); - let mut drop_ranges = build_control_flow_graph( + let (mut drop_ranges, borrowed_temporaries) = build_control_flow_graph( fcx.tcx.hir(), fcx.tcx, &fcx.typeck_results.borrow(), @@ -52,11 +53,20 @@ pub fn compute_drop_ranges<'a, 'tcx>( drop_ranges.propagate_to_fixpoint(); - DropRanges { tracked_value_map: drop_ranges.tracked_value_map, nodes: drop_ranges.nodes } + debug!("borrowed_temporaries = {borrowed_temporaries:?}"); + DropRanges { + tracked_value_map: drop_ranges.tracked_value_map, + nodes: drop_ranges.nodes, + borrowed_temporaries: Some(borrowed_temporaries), + } } else { // If drop range tracking is not enabled, skip all the analysis and produce an // empty set of DropRanges. - DropRanges { tracked_value_map: FxHashMap::default(), nodes: IndexVec::new() } + DropRanges { + tracked_value_map: FxHashMap::default(), + nodes: IndexVec::new(), + borrowed_temporaries: None, + } } } @@ -161,6 +171,7 @@ impl TryFrom<&PlaceWithHirId<'_>> for TrackedValue { pub struct DropRanges { tracked_value_map: FxHashMap, nodes: IndexVec, + borrowed_temporaries: Option>, } impl DropRanges { @@ -174,6 +185,10 @@ impl DropRanges { }) } + pub fn is_borrowed_temporary(&self, expr: &hir::Expr<'_>) -> bool { + if let Some(b) = &self.borrowed_temporaries { b.contains(&expr.hir_id) } else { true } + } + /// Returns a reference to the NodeInfo for a node, panicking if it does not exist fn expect_node(&self, id: PostOrderId) -> &NodeInfo { &self.nodes[id] diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs index cfed784ea728b..f4dd4cc010d3c 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_build.rs @@ -6,7 +6,7 @@ use hir::{ intravisit::{self, Visitor}, Body, Expr, ExprKind, Guard, HirId, LoopIdError, }; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::{fx::FxHashMap, stable_set::FxHashSet}; use rustc_hir as hir; use rustc_index::vec::IndexVec; use rustc_middle::{ @@ -27,14 +27,14 @@ pub(super) fn build_control_flow_graph<'tcx>( consumed_borrowed_places: ConsumedAndBorrowedPlaces, body: &'tcx Body<'tcx>, num_exprs: usize, -) -> DropRangesBuilder { +) -> (DropRangesBuilder, FxHashSet) { let mut drop_range_visitor = DropRangeVisitor::new(hir, tcx, typeck_results, consumed_borrowed_places, num_exprs); intravisit::walk_body(&mut drop_range_visitor, body); drop_range_visitor.drop_ranges.process_deferred_edges(); - drop_range_visitor.drop_ranges + (drop_range_visitor.drop_ranges, drop_range_visitor.places.borrowed_temporaries) } /// This struct is used to gather the information for `DropRanges` to determine the regions of the diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index 40ee6d863b5a7..a66f4b4558e14 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -6,6 +6,7 @@ use crate::{ use hir::{def_id::DefId, Body, HirId, HirIdMap}; use rustc_data_structures::stable_set::FxHashSet; use rustc_hir as hir; +use rustc_middle::hir::place::PlaceBase; use rustc_middle::ty::{ParamEnv, TyCtxt}; pub(super) fn find_consumed_and_borrowed<'a, 'tcx>( @@ -27,8 +28,12 @@ pub(super) struct ConsumedAndBorrowedPlaces { /// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is /// not considered a drop of `x`, although it would be a drop of `x.y`. pub(super) consumed: HirIdMap>, + /// A set of hir-ids of values or variables that are borrowed at some point within the body. pub(super) borrowed: FxHashSet, + + /// A set of hir-ids of values or variables that are borrowed at some point within the body. + pub(super) borrowed_temporaries: FxHashSet, } /// Works with ExprUseVisitor to find interesting values for the drop range analysis. @@ -49,6 +54,7 @@ impl<'tcx> ExprUseDelegate<'tcx> { places: ConsumedAndBorrowedPlaces { consumed: <_>::default(), borrowed: <_>::default(), + borrowed_temporaries: <_>::default(), }, } } @@ -98,10 +104,19 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { diag_expr_id: HirId, _bk: rustc_middle::ty::BorrowKind, ) { - debug!("borrow {:?}; diag_expr_id={:?}", place_with_id, diag_expr_id); + debug!("borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}"); + self.places .borrowed .insert(TrackedValue::from_place_with_projections_allowed(place_with_id)); + + // XXX -- we need to distinguish "consuming a copy" from other borrows + // + // XXX -- we need to distinguish `&*E` where `E: &T` which is not creating a temporary + // even though the place-base E is an rvalue + if let PlaceBase::Rvalue = place_with_id.place.base { + self.places.borrowed_temporaries.insert(place_with_id.hir_id); + } } fn mutate( diff --git a/foo.rs b/foo.rs new file mode 100644 index 0000000000000..e91ca1a0dd66a --- /dev/null +++ b/foo.rs @@ -0,0 +1,21 @@ +// check-pass +#![feature(generators, negative_impls)] + +struct Client; + +impl !Sync for Client {} + +fn status(_client_status: &Client) -> i16 { + 200 +} + +fn assert_send(_thing: T) {} + +// This is the same bug as issue 57017, but using yield instead of await +fn main() { + let client = Client; + let g = move || match status(&client) { + _status => yield, + }; + assert_send(g); +} From 513a9c67a59c0e1b9a7903d7e5fca4b6da974673 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 22 Feb 2022 16:02:33 -0800 Subject: [PATCH 03/24] Move test to right place --- foo.rs => src/test/ui/generator/issue-57017.rs | 1 + 1 file changed, 1 insertion(+) rename foo.rs => src/test/ui/generator/issue-57017.rs (92%) diff --git a/foo.rs b/src/test/ui/generator/issue-57017.rs similarity index 92% rename from foo.rs rename to src/test/ui/generator/issue-57017.rs index e91ca1a0dd66a..1223a3037abc7 100644 --- a/foo.rs +++ b/src/test/ui/generator/issue-57017.rs @@ -1,4 +1,5 @@ // check-pass +// compile-flags: -Zdrop-tracking #![feature(generators, negative_impls)] struct Client; From ac804f27a8ce2e02fd3a9c5eff83098258b78da6 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 22 Feb 2022 16:10:17 -0800 Subject: [PATCH 04/24] Trying to detect autorefs to avoid unnecessary borrowed temporaries This is all almost certainly wrong --- .../drop_ranges/record_consumed_borrow.rs | 10 +++++++--- compiler/rustc_typeck/src/check/upvar.rs | 3 ++- compiler/rustc_typeck/src/expr_use_visitor.rs | 13 ++++++++----- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index a66f4b4558e14..3ff7d7ad010ff 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -102,9 +102,13 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { &mut self, place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>, diag_expr_id: HirId, - _bk: rustc_middle::ty::BorrowKind, + bk: rustc_middle::ty::BorrowKind, + is_autoref: bool, ) { - debug!("borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}"); + debug!( + "borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \ + borrow_kind={bk:?}, is_autoref={is_autoref}" + ); self.places .borrowed @@ -114,7 +118,7 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { // // XXX -- we need to distinguish `&*E` where `E: &T` which is not creating a temporary // even though the place-base E is an rvalue - if let PlaceBase::Rvalue = place_with_id.place.base { + if let (false, PlaceBase::Rvalue) = (is_autoref, place_with_id.place.base) { self.places.borrowed_temporaries.insert(place_with_id.hir_id); } } diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 257846324b888..a3317f1cd7c7c 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -1792,6 +1792,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId, bk: ty::BorrowKind, + _is_autoref: bool, ) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); @@ -1826,7 +1827,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { - self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow); + self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow, false); } } diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 8c19bbd3214ee..1cce2a1da744d 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -45,6 +45,7 @@ pub trait Delegate<'tcx> { place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId, bk: ty::BorrowKind, + is_autoref: bool, ); /// The path at `assignee_place` is being assigned to. @@ -175,7 +176,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk); let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); + self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk, false); self.walk_expr(expr) } @@ -558,7 +559,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // this is an autoref of `x`. adjustment::Adjust::Deref(Some(ref deref)) => { let bk = ty::BorrowKind::from_mutbl(deref.mutbl); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); + self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk, true); } adjustment::Adjust::Borrow(ref autoref) => { @@ -590,13 +591,14 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m.into()), + true, ); } adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); - self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m)); + self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m), true); } } } @@ -669,7 +671,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match bm { ty::BindByReference(m) => { let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(place, discr_place.hir_id, bk); + delegate.borrow(place, discr_place.hir_id, bk, false); } ty::BindByValue(..) => { debug!("walk_pat binding consuming pat"); @@ -799,6 +801,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { &place_with_id, place_with_id.hir_id, upvar_borrow, + false, ); } } @@ -837,7 +840,7 @@ fn delegate_consume<'a, 'tcx>( match mode { ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), ConsumeMode::Copy => { - delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) + delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false) } } } From 87ad6683d6cc3c1e2597a3a37e03fe4330414fd3 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 23 Feb 2022 15:46:09 -0800 Subject: [PATCH 05/24] Distinguish borrows of copies from other borrows --- .../drop_ranges/record_consumed_borrow.rs | 22 ++++++++++++++++--- compiler/rustc_typeck/src/expr_use_visitor.rs | 19 ++++++++++++---- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index 3ff7d7ad010ff..b07e3a18e3fde 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -114,15 +114,31 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { .borrowed .insert(TrackedValue::from_place_with_projections_allowed(place_with_id)); - // XXX -- we need to distinguish "consuming a copy" from other borrows + // Keep track of whether this is a borrowed temporary (i.e. a borrow of an RValue) + // so that later in generator_interior we can use the correct scope. // - // XXX -- we need to distinguish `&*E` where `E: &T` which is not creating a temporary - // even though the place-base E is an rvalue + // We ignore borrows that are the result of an autoref because these will be + // immediately consumed and should not extend the temporary's lifetime. if let (false, PlaceBase::Rvalue) = (is_autoref, place_with_id.place.base) { self.places.borrowed_temporaries.insert(place_with_id.hir_id); } } + fn copy( + &mut self, + place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>, + _diag_expr_id: HirId, + ) { + debug!("copy: place_with_id = {place_with_id:?}"); + + self.places + .borrowed + .insert(TrackedValue::from_place_with_projections_allowed(place_with_id)); + + // For copied we treat this mostly like a borrow except that we don't add the place + // to borrowed_temporaries because the copy is consumed. + } + fn mutate( &mut self, assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>, diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index 1cce2a1da744d..b15f7cf2889f1 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -48,6 +48,14 @@ pub trait Delegate<'tcx> { is_autoref: bool, ); + /// The value found at `place` is being copied. + /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + // In most cases, treating a copy as a borrow is the right thing, so we forward + // this to the borrow callback by default. + self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false) + } + /// The path at `assignee_place` is being assigned to. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); @@ -598,7 +606,12 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); - self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m), true); + self.delegate.borrow( + base_place, + base_place.hir_id, + ty::BorrowKind::from_mutbl(m), + true, + ); } } } @@ -839,9 +852,7 @@ fn delegate_consume<'a, 'tcx>( match mode { ConsumeMode::Move => delegate.consume(place_with_id, diag_expr_id), - ConsumeMode::Copy => { - delegate.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false) - } + ConsumeMode::Copy => delegate.copy(place_with_id, diag_expr_id), } } From 9f0f46fa4da35bea07c3bedd7bd9e6742d375a27 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Fri, 25 Feb 2022 17:13:53 -0800 Subject: [PATCH 06/24] Update clippy to new ExprUseVisitor delegate --- src/tools/clippy/clippy_lints/src/escape.rs | 2 +- src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs | 2 +- src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs | 2 +- src/tools/clippy/clippy_utils/src/sugg.rs | 2 +- src/tools/clippy/clippy_utils/src/usage.rs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index af591dd71aa1d..5974b67eb7285 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -154,7 +154,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } } - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { self.set.remove(&lid); diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 9d8679d77c6d0..4b3d7c1ef247a 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -90,7 +90,7 @@ struct MutatePairDelegate<'a, 'tcx> { impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind, _is_autoref: bool) { if bk == ty::BorrowKind::MutBorrow { if let PlaceBase::Local(id) = cmt.place.base { if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index ebfd908a6fb74..ccd355f480a62 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -332,7 +332,7 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt { self.move_common(cmt); } - fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {} + fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) {} fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 63c442e70085a..0e97d837ec59e 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -886,7 +886,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} #[allow(clippy::too_many_lines)] - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) { if let PlaceBase::Local(id) = cmt.place.base { let map = self.cx.tcx.hir(); let span = map.span(cmt.hir_id); diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index 405e306359bc9..ae4ca77e48c37 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -64,7 +64,7 @@ impl<'tcx> MutVarsDelegate { impl<'tcx> Delegate<'tcx> for MutVarsDelegate { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind, _is_autoref: bool) { if bk == ty::BorrowKind::MutBorrow { self.update(cmt); } From 170b02702277229ccaae3ffed916bf6dc57548fc Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 1 Mar 2022 16:57:23 -0800 Subject: [PATCH 07/24] Add comments based on code review feedback --- compiler/rustc_typeck/src/check/generator_interior.rs | 8 ++++++++ compiler/rustc_typeck/src/expr_use_visitor.rs | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 30469e2ec7bbd..74e98f81439d0 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -371,6 +371,14 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> { debug!("is_borrowed_temporary: {:?}", self.drop_ranges.is_borrowed_temporary(expr)); + // Typically, the value produced by an expression is consumed by its parent in some way, + // so we only have to check if the parent contains a yield (note that the parent may, for + // example, store the value into a local variable, but then we already consider local + // variables to be live across their scope). + // + // However, in the case of temporary values, we are going to store the value into a + // temporary on the stack that is live for the current temporary scope and then return a + // reference to it. That value may be live across the entire temporary scope. let scope = if self.drop_ranges.is_borrowed_temporary(expr) { self.region_scope_tree.temporary_scope(expr.hir_id.local_id) } else { diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index b15f7cf2889f1..e839822602dd6 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -51,8 +51,8 @@ pub trait Delegate<'tcx> { /// The value found at `place` is being copied. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { - // In most cases, treating a copy as a borrow is the right thing, so we forward - // this to the borrow callback by default. + // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default + // we treat a copy of `x` as a borrow of `x`. self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false) } From 74d0866c62daaca5e80fee29b202ffea15daab1b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 7 Mar 2022 16:38:58 +0400 Subject: [PATCH 08/24] Remove redundant code from copy-suggestions --- .../src/diagnostics/conflict_errors.rs | 135 +++++++----------- 1 file changed, 55 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 2a74e1ce8b1b1..7e259abd8032f 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -12,9 +12,7 @@ use rustc_middle::mir::{ FakeReadCause, LocalDecl, LocalInfo, LocalKind, Location, Operand, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarBindingForm, }; -use rustc_middle::ty::{ - self, suggest_constraining_type_param, suggest_constraining_type_params, PredicateKind, Ty, -}; +use rustc_middle::ty::{self, suggest_constraining_type_params, PredicateKind, Ty}; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; use rustc_span::symbol::sym; use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP}; @@ -410,86 +408,63 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(ref name) => format!("`{}`", name), None => "value".to_owned(), }; - if let ty::Param(param_ty) = ty.kind() { - let tcx = self.infcx.tcx; - let generics = tcx.generics_of(self.mir_def_id()); - let param = generics.type_param(¶m_ty, tcx); - if let Some(generics) = tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| tcx.hir().get_generics(def_id)) - { - suggest_constraining_type_param( - tcx, - generics, - &mut err, - param.name.as_str(), - "Copy", - None, + + // Try to find predicates on *generic params* that would allow copying `ty` + let tcx = self.infcx.tcx; + let generics = tcx.generics_of(self.mir_def_id()); + if let Some(hir_generics) = tcx + .typeck_root_def_id(self.mir_def_id().to_def_id()) + .as_local() + .and_then(|def_id| tcx.hir().get_generics(def_id)) + { + let predicates: Result, _> = tcx.infer_ctxt().enter(|infcx| { + let mut fulfill_cx = + >::new(infcx.tcx); + + let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); + let cause = ObligationCause::new( + span, + self.mir_hir_id(), + rustc_infer::traits::ObligationCauseCode::MiscObligation, ); - } - } else { - // Try to find predicates on *generic params* that would allow copying `ty` - - let tcx = self.infcx.tcx; - let generics = tcx.generics_of(self.mir_def_id()); - if let Some(hir_generics) = tcx - .typeck_root_def_id(self.mir_def_id().to_def_id()) - .as_local() - .and_then(|def_id| tcx.hir().get_generics(def_id)) - { - let predicates: Result, _> = tcx.infer_ctxt().enter(|infcx| { - let mut fulfill_cx = - >::new(infcx.tcx); - - let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); - let cause = ObligationCause::new( - span, - self.mir_hir_id(), - rustc_infer::traits::ObligationCauseCode::MiscObligation, - ); - fulfill_cx.register_bound( - &infcx, - self.param_env, - // Erase any region vids from the type, which may not be resolved - infcx.tcx.erase_regions(ty), - copy_did, - cause, - ); - // Select all, including ambiguous predicates - let errors = fulfill_cx.select_all_or_error(&infcx); - - // Only emit suggestion if all required predicates are on generic - errors - .into_iter() - .map(|err| match err.obligation.predicate.kind().skip_binder() { - PredicateKind::Trait(predicate) => { - match predicate.self_ty().kind() { - ty::Param(param_ty) => Ok(( - generics.type_param(param_ty, tcx), - predicate - .trait_ref - .print_only_trait_path() - .to_string(), - )), - _ => Err(()), - } + fulfill_cx.register_bound( + &infcx, + self.param_env, + // Erase any region vids from the type, which may not be resolved + infcx.tcx.erase_regions(ty), + copy_did, + cause, + ); + // Select all, including ambiguous predicates + let errors = fulfill_cx.select_all_or_error(&infcx); + + // Only emit suggestion if all required predicates are on generic + errors + .into_iter() + .map(|err| match err.obligation.predicate.kind().skip_binder() { + PredicateKind::Trait(predicate) => { + match predicate.self_ty().kind() { + ty::Param(param_ty) => Ok(( + generics.type_param(param_ty, tcx), + predicate.trait_ref.print_only_trait_path().to_string(), + )), + _ => Err(()), } - _ => Err(()), - }) - .collect() - }); + } + _ => Err(()), + }) + .collect() + }); - if let Ok(predicates) = predicates { - suggest_constraining_type_params( - tcx, - hir_generics, - &mut err, - predicates.iter().map(|(param, constraint)| { - (param.name.as_str(), &**constraint, None) - }), - ); - } + if let Ok(predicates) = predicates { + suggest_constraining_type_params( + tcx, + hir_generics, + &mut err, + predicates.iter().map(|(param, constraint)| { + (param.name.as_str(), &**constraint, None) + }), + ); } } From 529fd2da894ff290668d6c1524909ba218d5822b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 8 Mar 2022 17:07:35 +0900 Subject: [PATCH 09/24] suggest adding `{ .. }` around a const function with arguments --- compiler/rustc_parse/src/parser/path.rs | 9 ++++ .../const-generics/const-generic-function.rs | 21 ++++++++ .../const-generic-function.stderr | 54 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 src/test/ui/const-generics/const-generic-function.rs create mode 100644 src/test/ui/const-generics/const-generic-function.stderr diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 5e537d7b95c4a..0bccf4dc2cef6 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -624,9 +624,18 @@ impl<'a> Parser<'a> { GenericArg::Const(self.parse_const_arg()?) } else if self.check_type() { // Parse type argument. + let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren)); + let mut snapshot = self.clone(); match self.parse_ty() { Ok(ty) => GenericArg::Type(ty), Err(err) => { + if is_const_fn { + if let Ok(expr) = snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) { + *self = snapshot; + return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); + } + } + // self.parse_fn_call_expr(); // Try to recover from possible `const` arg without braces. return self.recover_const_arg(start, err).map(Some); } diff --git a/src/test/ui/const-generics/const-generic-function.rs b/src/test/ui/const-generics/const-generic-function.rs new file mode 100644 index 0000000000000..c8d2683e53f47 --- /dev/null +++ b/src/test/ui/const-generics/const-generic-function.rs @@ -0,0 +1,21 @@ +fn foo() -> i32 { + N +} + +const fn bar(n: i32, m: i32) -> i32 { + n +} + +const fn baz() -> i32 { + 1 +} + +const FOO: i32 = 3; + +fn main() { + foo::(); //~ ERROR expected type, found function `baz` + //~| ERROR unresolved item provided when a constant was expected + foo::(); //~ ERROR expected type, found `1` + foo::(); //~ ERROR expected type, found `1` + foo::(); //~ ERROR expected type, found `2` +} diff --git a/src/test/ui/const-generics/const-generic-function.stderr b/src/test/ui/const-generics/const-generic-function.stderr new file mode 100644 index 0000000000000..5ad3f1006c17d --- /dev/null +++ b/src/test/ui/const-generics/const-generic-function.stderr @@ -0,0 +1,54 @@ +error: expected type, found `1` + --> $DIR/const-generic-function.rs:18:19 + | +LL | foo::(); + | ^ expected type + | +help: expressions must be enclosed in braces to be used as const generic arguments + | +LL | foo::<{ bar(bar(1, 1), bar(1, 1)) }>(); + | + + + +error: expected type, found `1` + --> $DIR/const-generic-function.rs:19:15 + | +LL | foo::(); + | ^ expected type + | +help: expressions must be enclosed in braces to be used as const generic arguments + | +LL | foo::<{ bar(1, 1) }>(); + | + + + +error: expected type, found `2` + --> $DIR/const-generic-function.rs:20:20 + | +LL | foo::(); + | ^ expected type + | +help: expressions must be enclosed in braces to be used as const generic arguments + | +LL | foo::<{ bar(FOO, 2) }>(); + | + + + +error[E0573]: expected type, found function `baz` + --> $DIR/const-generic-function.rs:16:11 + | +LL | foo::(); + | ^^^^^ not a type + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-generic-function.rs:16:11 + | +LL | foo::(); + | ^^^^^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | foo::<{ baz() }>(); + | + + + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0573, E0747. +For more information about an error, try `rustc --explain E0573`. From 527b1f3c2fb478cf30c9b33e945da2adaf29b6e0 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Mar 2022 12:59:46 +0900 Subject: [PATCH 10/24] initialize unclosed_delims field --- compiler/rustc_parse/src/parser/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 0bccf4dc2cef6..750d7cce0c0e7 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -626,6 +626,7 @@ impl<'a> Parser<'a> { // Parse type argument. let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren)); let mut snapshot = self.clone(); + snapshot.unclosed_delims = vec![]; match self.parse_ty() { Ok(ty) => GenericArg::Type(ty), Err(err) => { From a34015c0d0c264e98b6753da4c5454433092c02b Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Mar 2022 13:48:40 +0900 Subject: [PATCH 11/24] implement and use `diagnostic_snapshot` --- compiler/rustc_parse/src/parser/diagnostics.rs | 7 +++++++ compiler/rustc_parse/src/parser/path.rs | 3 +-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 40daf4eb28fc1..94805f4eb8b61 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -179,6 +179,13 @@ impl<'a> Parser<'a> { &self.sess.span_diagnostic } + pub(super) fn diagnostic_snapshot(&self) -> Self { + let mut snapshot = self.clone(); + // initialize unclosed_delims to avoid duplicate errors. + snapshot.unclosed_delims = vec![]; + snapshot + } + pub(super) fn span_to_snippet(&self, span: Span) -> Result { self.sess.source_map().span_to_snippet(span) } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 750d7cce0c0e7..f300b9c5ae4bd 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -625,8 +625,7 @@ impl<'a> Parser<'a> { } else if self.check_type() { // Parse type argument. let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren)); - let mut snapshot = self.clone(); - snapshot.unclosed_delims = vec![]; + let mut snapshot = self.diagnostic_snapshot(); match self.parse_ty() { Ok(ty) => GenericArg::Type(ty), Err(err) => { From 35147413585bb74837aa32448dd9b9ca78219974 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Mar 2022 14:10:34 +0900 Subject: [PATCH 12/24] remove an unnecessary comment --- compiler/rustc_parse/src/parser/path.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index f300b9c5ae4bd..c8ebf707477ac 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -635,7 +635,6 @@ impl<'a> Parser<'a> { return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } } - // self.parse_fn_call_expr(); // Try to recover from possible `const` arg without braces. return self.recover_const_arg(start, err).map(Some); } From 192acb4b98bb027cb09eaeb8906dbc94a76b9b66 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Mar 2022 16:04:14 +0900 Subject: [PATCH 13/24] take over unclosed_delims --- compiler/rustc_parse/src/parser/path.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index c8ebf707477ac..264174b0ac71d 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -631,6 +631,7 @@ impl<'a> Parser<'a> { Err(err) => { if is_const_fn { if let Ok(expr) = snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) { + snapshot.unclosed_delims.extend(self.unclosed_delims.clone()); *self = snapshot; return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } From 3ded25204b9b91cf4f14977cae81215a60409558 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 9 Mar 2022 23:13:04 +0900 Subject: [PATCH 14/24] implement `SnapshotParser` struct --- .../rustc_parse/src/parser/diagnostics.rs | 33 +++++++++++++++++-- compiler/rustc_parse/src/parser/path.rs | 6 ++-- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 94805f4eb8b61..4360399d4470c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -5,6 +5,7 @@ use super::{ SemiColonMode, SeqSep, TokenExpectType, TokenType, }; +use crate::lexer::UnmatchedBrace; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Lit, LitKind, TokenKind}; @@ -21,6 +22,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder, Handler, PResult}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, Ident}; use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP}; +use std::ops::{Deref, DerefMut}; use std::mem::take; @@ -154,6 +156,25 @@ impl AttemptLocalParseRecovery { } } +pub(super) struct SnapshotParser<'a> { + parser: Parser<'a>, + unclosed_delims: Vec, +} + +impl<'a> Deref for SnapshotParser<'a> { + type Target = Parser<'a>; + + fn deref(&self) -> &Self::Target { + &self.parser + } +} + +impl<'a> DerefMut for SnapshotParser<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.parser + } +} + impl<'a> Parser<'a> { pub(super) fn span_err>( &self, @@ -179,11 +200,17 @@ impl<'a> Parser<'a> { &self.sess.span_diagnostic } - pub(super) fn diagnostic_snapshot(&self) -> Self { + pub(super) fn restore(&mut self, snapshot: SnapshotParser<'a>) { + *self = snapshot.parser; + self.unclosed_delims.extend(snapshot.unclosed_delims.clone()); + } + + pub(super) fn diagnostic_snapshot(&self) -> SnapshotParser<'a> { let mut snapshot = self.clone(); + let unclosed_delims = self.unclosed_delims.clone(); // initialize unclosed_delims to avoid duplicate errors. - snapshot.unclosed_delims = vec![]; - snapshot + snapshot.unclosed_delims.clear(); + SnapshotParser { parser: snapshot, unclosed_delims } } pub(super) fn span_to_snippet(&self, span: Span) -> Result { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 264174b0ac71d..12d50fdba10a6 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -630,9 +630,9 @@ impl<'a> Parser<'a> { Ok(ty) => GenericArg::Type(ty), Err(err) => { if is_const_fn { - if let Ok(expr) = snapshot.parse_expr_res(Restrictions::CONST_EXPR, None) { - snapshot.unclosed_delims.extend(self.unclosed_delims.clone()); - *self = snapshot; + if let Ok(expr) = (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None) + { + self.restore(snapshot); return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } } From 2db82368574b7b751203418300345a4eb75f1147 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 10 Mar 2022 19:34:42 +0900 Subject: [PATCH 15/24] add doc comments --- compiler/rustc_parse/src/parser/diagnostics.rs | 15 ++++++++++++--- compiler/rustc_parse/src/parser/path.rs | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 4360399d4470c..e042df98edf38 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -156,6 +156,9 @@ impl AttemptLocalParseRecovery { } } +// SnapshotParser is used to create a snapshot of the parser +// without causing duplicate errors being emitted when the `Parser` +// is dropped. pub(super) struct SnapshotParser<'a> { parser: Parser<'a>, unclosed_delims: Vec, @@ -200,15 +203,21 @@ impl<'a> Parser<'a> { &self.sess.span_diagnostic } - pub(super) fn restore(&mut self, snapshot: SnapshotParser<'a>) { + /// Relace `self` with `snapshot.parser` and extend `unclosed_delims` with `snapshot.unclosed_delims`. + /// This is to avoid losing unclosed delims errors `create_snapshot_for_diagnostic` clears. + pub(super) fn restore_snapshot(&mut self, snapshot: SnapshotParser<'a>) { *self = snapshot.parser; self.unclosed_delims.extend(snapshot.unclosed_delims.clone()); } - pub(super) fn diagnostic_snapshot(&self) -> SnapshotParser<'a> { + /// Create a snapshot of the `Parser`. + pub(super) fn create_snapshot_for_diagnostic(&self) -> SnapshotParser<'a> { let mut snapshot = self.clone(); let unclosed_delims = self.unclosed_delims.clone(); - // initialize unclosed_delims to avoid duplicate errors. + // Clear `unclosed_delims` in snapshot to avoid + // duplicate errors being emitted when the `Parser` + // is dropped (which may or may not happen, depending + // if the parsing the snapshot is created for is successful) snapshot.unclosed_delims.clear(); SnapshotParser { parser: snapshot, unclosed_delims } } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 12d50fdba10a6..5d41d80833642 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -625,14 +625,14 @@ impl<'a> Parser<'a> { } else if self.check_type() { // Parse type argument. let is_const_fn = self.look_ahead(1, |t| t.kind == token::OpenDelim(token::Paren)); - let mut snapshot = self.diagnostic_snapshot(); + let mut snapshot = self.create_snapshot_for_diagnostic(); match self.parse_ty() { Ok(ty) => GenericArg::Type(ty), Err(err) => { if is_const_fn { if let Ok(expr) = (*snapshot).parse_expr_res(Restrictions::CONST_EXPR, None) { - self.restore(snapshot); + self.restore_snapshot(snapshot); return Ok(Some(self.dummy_const_arg_needs_braces(err, expr.span))); } } From 9a6532276ec45e22695f0a012a0782c97bf39a2d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Thu, 10 Mar 2022 22:11:00 +0900 Subject: [PATCH 16/24] replace `self.clone()` with `self.create_snapshot_for_diagnostic()` --- compiler/rustc_parse/src/parser/attr.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 44 +++++++++---------- compiler/rustc_parse/src/parser/expr.rs | 22 +++++----- compiler/rustc_parse/src/parser/path.rs | 4 +- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 379e47077ea18..a90eff0221082 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -151,7 +151,7 @@ impl<'a> Parser<'a> { span: Span, attr_type: OuterAttributeType, ) -> Option { - let mut snapshot = self.clone(); + let mut snapshot = self.create_snapshot_for_diagnostic(); let lo = span.lo() + BytePos(match attr_type { OuterAttributeType::Attribute => 1, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index e042df98edf38..250050a48f0a9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -481,7 +481,7 @@ impl<'a> Parser<'a> { // fn foo() -> Foo { // field: value, // } - let mut snapshot = self.clone(); + let mut snapshot = self.create_snapshot_for_diagnostic(); let path = Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None }; let struct_expr = snapshot.parse_struct_expr(None, path, AttrVec::new(), false); @@ -507,7 +507,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) .emit(); - *self = snapshot; + self.restore_snapshot(snapshot); let mut tail = self.mk_block( vec![self.mk_stmt_err(expr.span)], s, @@ -721,7 +721,7 @@ impl<'a> Parser<'a> { /// angle brackets. pub(super) fn check_turbofish_missing_angle_brackets(&mut self, segment: &mut PathSegment) { if token::ModSep == self.token.kind && segment.args.is_none() { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); let lo = self.token.span; match self.parse_angle_args(None) { @@ -755,14 +755,14 @@ impl<'a> Parser<'a> { .emit(); } else { // This doesn't look like an invalid turbofish, can't recover parse state. - *self = snapshot; + self.restore_snapshot(snapshot); } } Err(err) => { // We couldn't parse generic parameters, unlikely to be a turbofish. Rely on // generic parse error instead. err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); } } } @@ -868,7 +868,7 @@ impl<'a> Parser<'a> { // `x == y < z` (BinOpKind::Eq, AssocOp::Less | AssocOp::LessEqual | AssocOp::Greater | AssocOp::GreaterEqual) => { // Consume `z`/outer-op-rhs. - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); match self.parse_expr() { Ok(r2) => { // We are sure that outer-op-rhs could be consumed, the suggestion is @@ -878,14 +878,14 @@ impl<'a> Parser<'a> { } Err(expr_err) => { expr_err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); false } } } // `x > y == z` (BinOpKind::Lt | BinOpKind::Le | BinOpKind::Gt | BinOpKind::Ge, AssocOp::Equal) => { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); // At this point it is always valid to enclose the lhs in parentheses, no // further checks are necessary. match self.parse_expr() { @@ -895,7 +895,7 @@ impl<'a> Parser<'a> { } Err(expr_err) => { expr_err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); false } } @@ -960,7 +960,7 @@ impl<'a> Parser<'a> { || outer_op.node == AssocOp::Greater { if outer_op.node == AssocOp::Less { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); // So far we have parsed `foo Parser<'a> { { // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the // parser and bail out. - *self = snapshot.clone(); + self.restore_snapshot(snapshot); } } return if token::ModSep == self.token.kind { @@ -980,7 +980,7 @@ impl<'a> Parser<'a> { // `foo< bar >::` suggest(&mut err); - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); // `::` // Consume the rest of the likely `foo::new()` or return at `foo`. @@ -997,7 +997,7 @@ impl<'a> Parser<'a> { expr_err.cancel(); // Not entirely sure now, but we bubble the error up with the // suggestion. - *self = snapshot; + self.restore_snapshot(snapshot); Err(err) } } @@ -1051,7 +1051,7 @@ impl<'a> Parser<'a> { } fn consume_fn_args(&mut self) -> Result<(), ()> { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); // `(` // Consume the fn call arguments. @@ -1061,7 +1061,7 @@ impl<'a> Parser<'a> { if self.token.kind == token::Eof { // Not entirely sure that what we consumed were fn arguments, rollback. - *self = snapshot; + self.restore_snapshot(snapshot); Err(()) } else { // 99% certain that the suggestion is correct, continue parsing. @@ -2002,12 +2002,12 @@ impl<'a> Parser<'a> { } fn recover_const_param_decl(&mut self, ty_generics: Option<&Generics>) -> Option { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); let param = match self.parse_const_param(vec![]) { Ok(param) => param, Err(err) => { err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); return None; } }; @@ -2099,7 +2099,7 @@ impl<'a> Parser<'a> { // We perform these checks and early return to avoid taking a snapshot unnecessarily. return Err(err); } - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); if is_op_or_dot { self.bump(); } @@ -2131,7 +2131,7 @@ impl<'a> Parser<'a> { err.cancel(); } } - *self = snapshot; + self.restore_snapshot(snapshot); Err(err) } @@ -2191,7 +2191,7 @@ impl<'a> Parser<'a> { let span = self.token.span; // We only emit "unexpected `:`" error here if we can successfully parse the // whole pattern correctly in that case. - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); // Create error for "unexpected `:`". match self.expected_one_of_not_found(&[], &[]) { @@ -2203,7 +2203,7 @@ impl<'a> Parser<'a> { // reasonable error. inner_err.cancel(); err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); } Ok(mut pat) => { // We've parsed the rest of the pattern. @@ -2282,7 +2282,7 @@ impl<'a> Parser<'a> { } _ => { // Carry on as if we had not done anything. This should be unreachable. - *self = snapshot; + self.restore_snapshot(snapshot); } }; first_pat diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index df865d77b9bb4..e160385d3a4be 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -704,7 +704,7 @@ impl<'a> Parser<'a> { ExprKind::Path(None, ast::Path { segments, .. }), TokenKind::Ident(kw::For | kw::Loop | kw::While, false), ) if segments.len() == 1 => { - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); let label = Label { ident: Ident::from_str_and_span( &format!("'{}", segments[0].ident), @@ -726,7 +726,7 @@ impl<'a> Parser<'a> { } Err(err) => { err.cancel(); - *self = snapshot; + self.restore_snapshot(snapshot); } } } @@ -1886,7 +1886,7 @@ impl<'a> Parser<'a> { lo: Span, attrs: AttrVec, ) -> Option> { - let mut snapshot = self.clone(); + let mut snapshot = self.create_snapshot_for_diagnostic(); match snapshot.parse_array_or_repeat_expr(attrs, token::Brace) { Ok(arr) => { let hi = snapshot.prev_token.span; @@ -1902,7 +1902,7 @@ impl<'a> Parser<'a> { .note("to define an array, one would use square brackets instead of curly braces") .emit(); - *self = snapshot; + self.restore_snapshot(snapshot); Some(self.mk_expr_err(arr.span)) } Err(e) => { @@ -2370,7 +2370,7 @@ impl<'a> Parser<'a> { if self.token.kind != token::Semi { return None; } - let start_snapshot = self.clone(); + let start_snapshot = self.create_snapshot_for_diagnostic(); let semi_sp = self.token.span; self.bump(); // `;` let mut stmts = @@ -2418,15 +2418,15 @@ impl<'a> Parser<'a> { return Some(err(self, stmts)); } if self.token.kind == token::Comma { - *self = start_snapshot; + self.restore_snapshot(start_snapshot); return None; } - let pre_pat_snapshot = self.clone(); + let pre_pat_snapshot = self.create_snapshot_for_diagnostic(); match self.parse_pat_no_top_alt(None) { Ok(_pat) => { if self.token.kind == token::FatArrow { // Reached arm end. - *self = pre_pat_snapshot; + self.restore_snapshot(pre_pat_snapshot); return Some(err(self, stmts)); } } @@ -2435,21 +2435,21 @@ impl<'a> Parser<'a> { } } - *self = pre_pat_snapshot; + self.restore_snapshot(pre_pat_snapshot); match self.parse_stmt_without_recovery(true, ForceCollect::No) { // Consume statements for as long as possible. Ok(Some(stmt)) => { stmts.push(stmt); } Ok(None) => { - *self = start_snapshot; + self.restore_snapshot(start_snapshot); break; } // We couldn't parse either yet another statement missing it's // enclosing block nor the next arm's pattern or closing brace. Err(stmt_err) => { stmt_err.cancel(); - *self = start_snapshot; + self.restore_snapshot(start_snapshot); break; } } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 5d41d80833642..17c57867cf9cf 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -645,7 +645,7 @@ impl<'a> Parser<'a> { } else { // Fall back by trying to parse a const-expr expression. If we successfully do so, // then we should report an error that it needs to be wrapped in braces. - let snapshot = self.clone(); + let snapshot = self.create_snapshot_for_diagnostic(); match self.parse_expr_res(Restrictions::CONST_EXPR, None) { Ok(expr) => { return Ok(Some(self.dummy_const_arg_needs_braces( @@ -654,7 +654,7 @@ impl<'a> Parser<'a> { ))); } Err(err) => { - *self = snapshot; + self.restore_snapshot(snapshot); err.cancel(); return Ok(None); } From 12d8ca113ca0c9b0d8e1ca43ea9bbd83c212efc5 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 10 Mar 2022 17:14:50 -0800 Subject: [PATCH 17/24] Use projections rather than is_autoref Also includes a lengthy comment arguing the correctness. Co-authored-by: Niko Matsakis --- .../drop_ranges/record_consumed_borrow.rs | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index b07e3a18e3fde..45421a57082d8 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -6,7 +6,7 @@ use crate::{ use hir::{def_id::DefId, Body, HirId, HirIdMap}; use rustc_data_structures::stable_set::FxHashSet; use rustc_hir as hir; -use rustc_middle::hir::place::PlaceBase; +use rustc_middle::hir::place::{PlaceBase, Projection, ProjectionKind}; use rustc_middle::ty::{ParamEnv, TyCtxt}; pub(super) fn find_consumed_and_borrowed<'a, 'tcx>( @@ -114,12 +114,48 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { .borrowed .insert(TrackedValue::from_place_with_projections_allowed(place_with_id)); - // Keep track of whether this is a borrowed temporary (i.e. a borrow of an RValue) - // so that later in generator_interior we can use the correct scope. + // Ordinarily a value is consumed by it's parent, but in the special case of a + // borrowed RValue, we create a reference that lives as long as the temporary scope + // for that expression (typically, the innermost statement, but sometimes the enclosing + // block). We record this fact here so that later in generator_interior + // we can use the correct scope. // - // We ignore borrows that are the result of an autoref because these will be - // immediately consumed and should not extend the temporary's lifetime. - if let (false, PlaceBase::Rvalue) = (is_autoref, place_with_id.place.base) { + // We special case borrows through a dereference (`&*x`, `&mut *x` where `x` is + // some rvalue expression), since these are essentially a copy of a pointer. + // In other words, this borrow does not refer to the + // temporary (`*x`), but to the referent (whatever `x` is a borrow of). + // + // We were considering that we might encounter problems down the line if somehow, + // some part of the compiler were to look at this result and try to use it to + // drive a borrowck-like analysis (this does not currently happen, as of this writing). + // But even this should be fine, because the lifetime of the dereferenced reference + // found in the rvalue is only significant as an intermediate 'link' to the value we + // are producing, and we separately track whether that value is live over a yield. + // Example: + // + // ```notrust + // fn identity(x: &mut T) -> &mut T { x } + // let a: A = ...; + // let y: &'y mut A = &mut *identity(&'a mut a); + // ^^^^^^^^^^^^^^^^^^^^^^^^^ the borrow we are talking about + // ``` + // + // The expression `*identity(...)` is a deref of an rvalue, + // where the `identity(...)` (the rvalue) produces a return type + // of `&'rv mut A`, where `'a: 'rv`. We then assign this result to + // `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use, + // `a` will be considered borrowed). Other parts of the code will ensure + // that if `y` is live over a yield, `&'y mut A` appears in the generator + // state. If `'y` is live, then any sound region analysis must conclude + // that `'a` is also live. So if this causes a bug, blame some other + // part of the code! + let is_deref = place_with_id + .place + .projections + .iter() + .any(|Projection { kind, .. }| *kind == ProjectionKind::Deref); + + if let (false, PlaceBase::Rvalue) = (is_deref, place_with_id.place.base) { self.places.borrowed_temporaries.insert(place_with_id.hir_id); } } From 2fcd5427345154661f8d512745bdedaf072a55b6 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Thu, 10 Mar 2022 17:24:08 -0800 Subject: [PATCH 18/24] Remove is_autoref parameter --- .../drop_ranges/record_consumed_borrow.rs | 3 +-- compiler/rustc_typeck/src/check/upvar.rs | 3 +-- compiler/rustc_typeck/src/expr_use_visitor.rs | 18 +++++------------- src/tools/clippy/clippy_lints/src/escape.rs | 2 +- .../clippy_lints/src/loops/mut_range_bound.rs | 2 +- .../clippy_lints/src/needless_pass_by_value.rs | 2 +- src/tools/clippy/clippy_utils/src/sugg.rs | 2 +- src/tools/clippy/clippy_utils/src/usage.rs | 2 +- 8 files changed, 12 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs index 45421a57082d8..928daba0a7b39 100644 --- a/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_typeck/src/check/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -103,11 +103,10 @@ impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> { place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: rustc_middle::ty::BorrowKind, - is_autoref: bool, ) { debug!( "borrow: place_with_id = {place_with_id:?}, diag_expr_id={diag_expr_id:?}, \ - borrow_kind={bk:?}, is_autoref={is_autoref}" + borrow_kind={bk:?}" ); self.places diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index a3317f1cd7c7c..257846324b888 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -1792,7 +1792,6 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId, bk: ty::BorrowKind, - _is_autoref: bool, ) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); @@ -1827,7 +1826,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { - self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow, false); + self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow); } } diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index e839822602dd6..4313a75aee89d 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -45,7 +45,6 @@ pub trait Delegate<'tcx> { place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId, bk: ty::BorrowKind, - is_autoref: bool, ); /// The value found at `place` is being copied. @@ -53,7 +52,7 @@ pub trait Delegate<'tcx> { fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default // we treat a copy of `x` as a borrow of `x`. - self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow, false) + self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) } /// The path at `assignee_place` is being assigned to. @@ -184,7 +183,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { debug!("borrow_expr(expr={:?}, bk={:?})", expr, bk); let place_with_id = return_if_err!(self.mc.cat_expr(expr)); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk, false); + self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); self.walk_expr(expr) } @@ -567,7 +566,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // this is an autoref of `x`. adjustment::Adjust::Deref(Some(ref deref)) => { let bk = ty::BorrowKind::from_mutbl(deref.mutbl); - self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk, true); + self.delegate.borrow(&place_with_id, place_with_id.hir_id, bk); } adjustment::Adjust::Borrow(ref autoref) => { @@ -599,19 +598,13 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m.into()), - true, ); } adjustment::AutoBorrow::RawPtr(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); - self.delegate.borrow( - base_place, - base_place.hir_id, - ty::BorrowKind::from_mutbl(m), - true, - ); + self.delegate.borrow(base_place, base_place.hir_id, ty::BorrowKind::from_mutbl(m)); } } } @@ -684,7 +677,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match bm { ty::BindByReference(m) => { let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(place, discr_place.hir_id, bk, false); + delegate.borrow(place, discr_place.hir_id, bk); } ty::BindByValue(..) => { debug!("walk_pat binding consuming pat"); @@ -814,7 +807,6 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { &place_with_id, place_with_id.hir_id, upvar_borrow, - false, ); } } diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs index 5974b67eb7285..af591dd71aa1d 100644 --- a/src/tools/clippy/clippy_lints/src/escape.rs +++ b/src/tools/clippy/clippy_lints/src/escape.rs @@ -154,7 +154,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { } } - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { if cmt.place.projections.is_empty() { if let PlaceBase::Local(lid) = cmt.place.base { self.set.remove(&lid); diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs index 4b3d7c1ef247a..9d8679d77c6d0 100644 --- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs +++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs @@ -90,7 +90,7 @@ struct MutatePairDelegate<'a, 'tcx> { impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind, _is_autoref: bool) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) { if bk == ty::BorrowKind::MutBorrow { if let PlaceBase::Local(id) = cmt.place.base { if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) { diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index ccd355f480a62..ebfd908a6fb74 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -332,7 +332,7 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt { self.move_common(cmt); } - fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) {} + fn borrow(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {} fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {} diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 0e97d837ec59e..63c442e70085a 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -886,7 +886,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} #[allow(clippy::too_many_lines)] - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind, _is_autoref: bool) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) { if let PlaceBase::Local(id) = cmt.place.base { let map = self.cx.tcx.hir(); let span = map.span(cmt.hir_id); diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs index ae4ca77e48c37..405e306359bc9 100644 --- a/src/tools/clippy/clippy_utils/src/usage.rs +++ b/src/tools/clippy/clippy_utils/src/usage.rs @@ -64,7 +64,7 @@ impl<'tcx> MutVarsDelegate { impl<'tcx> Delegate<'tcx> for MutVarsDelegate { fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {} - fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind, _is_autoref: bool) { + fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) { if bk == ty::BorrowKind::MutBorrow { self.update(cmt); } From 78567df57510db92350015c2e09ff3da0e86a8ba Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 7 Feb 2022 12:22:21 -0700 Subject: [PATCH 19/24] Stabilize ADX target feature This is a continuation of #60109, which noted that while the ADX intrinsics were stabilized, the corresponding target feature never was. This PR follows the same general structure and stabilizes the ADX target feature. --- compiler/rustc_codegen_ssa/src/target_features.rs | 2 +- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_typeck/src/collect.rs | 1 - library/core/src/lib.rs | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index f37c675138177..5056ec1d3852a 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -148,7 +148,7 @@ const AARCH64_TIED_FEATURES: &[&[&str]] = &[ ]; const X86_ALLOWED_FEATURES: &[(&str, Option)] = &[ - ("adx", Some(sym::adx_target_feature)), + ("adx", None), ("aes", None), ("avx", None), ("avx2", None), diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index e49f40ff1a184..ace0c9df58d50 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -51,6 +51,8 @@ declare_features! ( /// Allows the sysV64 ABI to be specified on all platforms /// instead of just the platforms on which it is the C ABI. (accepted, abi_sysv64, "1.24.0", Some(36167), None), + /// Allows using ADX intrinsics from `core::arch::{x86, x86_64}`. + (accepted, adx_target_feature, "1.61.0", Some(44839), None), /// Allows the definition of associated constants in `trait` or `impl` blocks. (accepted, associated_consts, "1.20.0", Some(29646), None), /// Allows using associated `type`s in `trait`s. diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 16e72d0c2c565..6a4c5d4a6c7ea 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2689,7 +2689,6 @@ fn from_target_feature( Some(sym::tbm_target_feature) => rust_features.tbm_target_feature, Some(sym::wasm_target_feature) => rust_features.wasm_target_feature, Some(sym::cmpxchg16b_target_feature) => rust_features.cmpxchg16b_target_feature, - Some(sym::adx_target_feature) => rust_features.adx_target_feature, Some(sym::movbe_target_feature) => rust_features.movbe_target_feature, Some(sym::rtm_target_feature) => rust_features.rtm_target_feature, Some(sym::f16c_target_feature) => rust_features.f16c_target_feature, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index e1be20c217911..0860e1bf4ca92 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -207,7 +207,6 @@ // // Target features: #![cfg_attr(bootstrap, feature(aarch64_target_feature))] -#![feature(adx_target_feature)] #![feature(arm_target_feature)] #![feature(avx512_target_feature)] #![feature(cmpxchg16b_target_feature)] @@ -219,6 +218,7 @@ #![feature(sse4a_target_feature)] #![feature(tbm_target_feature)] #![feature(wasm_target_feature)] +#![cfg_attr(bootstrap, feature(adx_target_feature))] // allow using `core::` in intra-doc links #[allow(unused_extern_crates)] From e4f1179fa6b044adfd52d45ce35bfe4f5ad04c8f Mon Sep 17 00:00:00 2001 From: skippy10110 Date: Tue, 15 Mar 2022 19:28:53 -0300 Subject: [PATCH 20/24] Add deprecated_safe feature gate and attribute, cc #94978 --- compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_feature/src/builtin_attrs.rs | 5 +++++ compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-deprecated_safe.rs | 7 +++++++ .../feature-gate-deprecated_safe.stderr | 21 +++++++++++++++++++ 5 files changed, 36 insertions(+) create mode 100644 src/test/ui/feature-gates/feature-gate-deprecated_safe.rs create mode 100644 src/test/ui/feature-gates/feature-gate-deprecated_safe.stderr diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index d9748b19e13fe..02cdaa3b95840 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -364,6 +364,8 @@ declare_features! ( (active, default_alloc_error_handler, "1.48.0", Some(66741), None), /// Allows default type parameters to influence type inference. (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), + /// Allows using `#[deprecated_safe]` to deprecate the safeness of a function or trait + (active, deprecated_safe, "1.61.0", Some(94978), None), /// Allows having using `suggestion` in the `#[deprecated]` attribute. (active, deprecated_suggestion, "1.61.0", Some(94785), None), /// Allows `#[derive(Default)]` and `#[default]` on enums. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 9c7b8f8032496..e2f0b413ff379 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -452,6 +452,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \ as `const`, which may be removed or renamed in the future." ), + // lang-team MCP 147 + gated!( + deprecated_safe, Normal, template!(List: r#"since = "version", note = "...""#), ErrorFollowing, + experimental!(deprecated_safe), + ), // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4dd1c3fed6b36..523a1066a1c3c 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -563,6 +563,7 @@ symbols! { delay_span_bug_from_inside_query, deny, deprecated, + deprecated_safe, deprecated_suggestion, deref, deref_method, diff --git a/src/test/ui/feature-gates/feature-gate-deprecated_safe.rs b/src/test/ui/feature-gates/feature-gate-deprecated_safe.rs new file mode 100644 index 0000000000000..d5f4a4705b972 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-deprecated_safe.rs @@ -0,0 +1,7 @@ +#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature +unsafe fn deprecated_safe_fn() {} + +#[deprecated_safe(since = "TBD", note = "...")] //~ ERROR: the `#[deprecated_safe]` attribute is an experimental feature +unsafe trait DeprecatedSafeTrait {} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-deprecated_safe.stderr b/src/test/ui/feature-gates/feature-gate-deprecated_safe.stderr new file mode 100644 index 0000000000000..5e98a1faaa301 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-deprecated_safe.stderr @@ -0,0 +1,21 @@ +error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature + --> $DIR/feature-gate-deprecated_safe.rs:1:1 + | +LL | #[deprecated_safe(since = "TBD", note = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #94978 for more information + = help: add `#![feature(deprecated_safe)]` to the crate attributes to enable + +error[E0658]: the `#[deprecated_safe]` attribute is an experimental feature + --> $DIR/feature-gate-deprecated_safe.rs:4:1 + | +LL | #[deprecated_safe(since = "TBD", note = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #94978 for more information + = help: add `#![feature(deprecated_safe)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From f1cf54470bf352a758ea4f4de1c0e6217e26763e Mon Sep 17 00:00:00 2001 From: fee1-dead Date: Wed, 16 Mar 2022 21:50:18 +1100 Subject: [PATCH 21/24] Update issue-92111.rs --- src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs index d30f4edd4b25c..9bf0886084f91 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/issue-92111.rs @@ -1,7 +1,7 @@ // Regression test for #92111. // // The issue was that we normalize trait bounds before caching -// results of selection. Checking that `impl NoDrop for S` requires +// results of selection. Checking that `impl Tr for S` requires // checking `S: !Drop` because it cannot overlap with the blanket // impl. Then we save the (unsatisfied) result from checking `S: Drop`. // Then the call to `a` checks whether `S: ~const Drop` but we normalize From 01dbfb3eb264135c432cef223848416f90dac290 Mon Sep 17 00:00:00 2001 From: codehorseman Date: Wed, 16 Mar 2022 20:12:30 +0800 Subject: [PATCH 22/24] resolve the conflict in compiler/rustc_session/src/parse.rs Signed-off-by: codehorseman --- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 2 +- compiler/rustc_middle/src/mir/interpret/pointer.rs | 2 +- compiler/rustc_middle/src/ty/query.rs | 2 +- compiler/rustc_middle/src/ty/subst.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 2 +- .../rustc_mir_build/src/thir/pattern/const_to_pat.rs | 2 +- compiler/rustc_mir_transform/src/check_unsafety.rs | 2 +- compiler/rustc_mir_transform/src/const_debuginfo.rs | 6 +++--- .../src/early_otherwise_branch.rs | 2 +- compiler/rustc_mir_transform/src/simplify_try.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 2 +- compiler/rustc_session/src/options.rs | 2 +- compiler/rustc_session/src/parse.rs | 2 +- compiler/rustc_session/src/utils.rs | 4 ++-- compiler/rustc_symbol_mangling/src/lib.rs | 2 +- compiler/rustc_target/src/abi/mod.rs | 2 +- compiler/rustc_trait_selection/src/traits/mod.rs | 6 +++--- .../src/traits/select/confirmation.rs | 6 +++--- .../rustc_trait_selection/src/traits/select/mod.rs | 2 +- compiler/rustc_ty_utils/src/needs_drop.rs | 6 +++--- compiler/rustc_typeck/src/astconv/errors.rs | 2 +- compiler/rustc_typeck/src/astconv/generics.rs | 2 +- .../rustc_typeck/src/check/generator_interior.rs | 4 ++-- .../rustc_typeck/src/check/method/prelude2021.rs | 2 +- compiler/rustc_typeck/src/check/upvar.rs | 8 ++++---- compiler/rustc_typeck/src/check/wfcheck.rs | 2 +- .../wrong_number_of_generic_args.rs | 2 +- library/core/src/panic.rs | 2 +- library/std/src/sys/common/alloc.rs | 2 +- src/bootstrap/builder.rs | 2 +- src/bootstrap/compile.rs | 2 +- src/bootstrap/dist.rs | 2 +- .../armv7-unknown-linux-uclibceabi.md | 2 +- .../unstable-book/src/compiler-flags/sanitizer.md | 2 +- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/formats/renderer.rs | 2 +- src/librustdoc/html/render/mod.rs | 2 +- src/test/codegen/catch-unwind.rs | 2 +- src/test/codegen/debug-column.rs | 2 +- src/test/ui/extern/extern-static-size-overflow.rs | 2 +- src/test/ui/impl-trait/multiple-lifetimes.rs | 2 +- src/tools/cargotest/main.rs | 2 +- src/tools/clippy/clippy_lints/src/copies.rs | 2 +- .../clippy/clippy_lints/src/fallible_impl_from.rs | 6 +++--- .../clippy_lints/src/float_equality_without_abs.rs | 6 +++--- .../clippy_lints/src/only_used_in_recursion.rs | 2 +- .../src/suspicious_operation_groupings.rs | 10 +++++----- .../clippy/clippy_lints/src/trailing_empty_array.rs | 2 +- src/tools/clippy/clippy_lints/src/trait_bounds.rs | 2 +- .../clippy/clippy_lints/src/unwrap_in_result.rs | 12 ++++++------ src/tools/clippy/tests/lint_message_convention.rs | 2 +- .../tests/ui/manual_memcpy/with_loop_counters.rs | 2 +- src/tools/clippy/tests/workspace.rs | 2 +- src/tools/rustfmt/src/lists.rs | 2 +- src/tools/rustfmt/src/types.rs | 2 +- src/tools/tidy/src/pal.rs | 4 ++-- src/tools/tidy/src/style.rs | 2 +- 59 files changed, 86 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index dc9bc3440d05b..1784e4a6c63a8 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -26,7 +26,7 @@ pub(super) struct ItemLowerer<'a, 'lowering, 'hir> { } /// When we have a ty alias we *may* have two where clauses. To give the best diagnostics, we set the span -/// to the where clause that is prefered, if it exists. Otherwise, it sets the span to the other where +/// to the where clause that is preferred, if it exists. Otherwise, it sets the span to the other where /// clause if it exists. fn add_ty_alias_where_clause( generics: &mut ast::Generics, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 8539e8868e2c7..88e049410790d 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3695,7 +3695,7 @@ declare_lint! { /// ### Explanation /// /// A duplicated attribute may erroneously originate from a copy-paste and the effect of it - /// being duplicated may not be obvious or desireable. + /// being duplicated may not be obvious or desirable. /// /// For instance, doubling the `#[test]` attributes registers the test to be run twice with no /// change to its environment. diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs index c9dc5a0f3b5ec..7d101046a96b4 100644 --- a/compiler/rustc_middle/src/mir/interpret/pointer.rs +++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs @@ -99,7 +99,7 @@ impl PointerArithmetic for T {} /// mostly opaque; the `Machine` trait extends it with some more operations that also have access to /// some global state. /// We don't actually care about this `Debug` bound (we use `Provenance::fmt` to format the entire -/// pointer), but `derive` adds some unecessary bounds. +/// pointer), but `derive` adds some unnecessary bounds. pub trait Provenance: Copy + fmt::Debug { /// Says whether the `offset` field of `Pointer`s with this provenance is the actual physical address. /// If `true, ptr-to-int casts work by simply discarding the provenance. diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 03e4a7dcefd71..fe036f4f2275a 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -337,7 +337,7 @@ rustc_query_append! { [define_callbacks!][<'tcx>] } mod sealed { use super::{DefId, LocalDefId}; - /// An analogue of the `Into` trait that's intended only for query paramaters. + /// An analogue of the `Into` trait that's intended only for query parameters. /// /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the /// user call `to_def_id` to convert between them everywhere else. diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 364ba07a44167..0a6cb276f7578 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -61,7 +61,7 @@ pub fn ty_slice_as_generic_args<'a, 'tcx>(ts: &'a [Ty<'tcx>]) -> &'a [GenericArg } impl<'tcx> List> { - /// Allows to freely switch betwen `List>` and `List>`. + /// Allows to freely switch between `List>` and `List>`. /// /// As lists are interned, `List>` and `List>` have /// be interned together, see `intern_type_list` for more details. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 984f5d9985220..1b07dc6eb37ac 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -486,7 +486,7 @@ impl<'tcx> TyCtxt<'tcx> { } /// Given the `DefId`, returns the `DefId` of the innermost item that - /// has its own type-checking context or "inference enviornment". + /// has its own type-checking context or "inference environment". /// /// For example, a closure has its own `DefId`, but it is type-checked /// with the containing item. Similarly, an inline const block has its diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ae9b44cee4bf8..b4de32a3bd98e 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { ty::RawPtr(pointee) if pointee.ty.is_sized(tcx.at(span), param_env) => { PatKind::Constant { value: cv } } - // FIXME: these can have very suprising behaviour where optimization levels or other + // FIXME: these can have very surprising behaviour where optimization levels or other // compilation choices change the runtime behaviour of the match. // See https://github.com/rust-lang/rust/issues/70861 for examples. ty::FnPtr(..) | ty::RawPtr(..) => { diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 9d198ef2f7a05..f8d0e448ce7d5 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -156,7 +156,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { // temporary holding the static pointer to avoid duplicate errors // . if decl.internal && place.projection.first() == Some(&ProjectionElem::Deref) { - // If the projection root is an artifical local that we introduced when + // If the projection root is an artificial local that we introduced when // desugaring `static`, give a more specific error message // (avoid the general "raw pointer" clause below, that would only be confusing). if let Some(box LocalInfo::StaticRef { def_id, .. }) = decl.local_info { diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index ef4b27a15d8b8..3577b3d2d80c6 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -60,7 +60,7 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta } } - let mut eligable_locals = Vec::new(); + let mut eligible_locals = Vec::new(); for (local, mutating_uses) in visitor.local_mutating_uses.drain_enumerated(..) { if mutating_uses != 1 || !locals_to_debuginfo.contains(local) { continue; @@ -78,13 +78,13 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta &bb.statements[location.statement_index].kind { if let Some(local) = p.as_local() { - eligable_locals.push((local, *c)); + eligible_locals.push((local, *c)); } } } } - eligable_locals + eligible_locals } impl Visitor<'_> for LocalUseVisitor { diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs index ba234dccaa63e..2bf97e5d43c76 100644 --- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs +++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs @@ -359,7 +359,7 @@ fn verify_candidate_branch<'tcx>( if branch.statements.len() != 1 { return false; } - // ...assign the descriminant of `place` in that statement + // ...assign the discriminant of `place` in that statement let StatementKind::Assign(boxed) = &branch.statements[0].kind else { return false }; diff --git a/compiler/rustc_mir_transform/src/simplify_try.rs b/compiler/rustc_mir_transform/src/simplify_try.rs index 884c5fb765f42..ce4b45062e8de 100644 --- a/compiler/rustc_mir_transform/src/simplify_try.rs +++ b/compiler/rustc_mir_transform/src/simplify_try.rs @@ -362,7 +362,7 @@ fn optimization_applies<'tcx>( return false; } else if last_assigned_to != opt_info.local_tmp_s1 { trace!( - "NO: end of assignemnt chain does not match written enum temp: {:?} != {:?}", + "NO: end of assignment chain does not match written enum temp: {:?} != {:?}", last_assigned_to, opt_info.local_tmp_s1 ); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index b582f060395c3..028630b17c4d5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1948,7 +1948,7 @@ impl<'a> Parser<'a> { // We use an over-approximation here. // `const const`, `fn const` won't parse, but we're not stepping over other syntax either. // `pub` is added in case users got confused with the ordering like `async pub fn`, - // only if it wasn't preceeded by `default` as `default pub` is invalid. + // only if it wasn't preceded by `default` as `default pub` is invalid. let quals: &[Symbol] = if check_pub { &[kw::Pub, kw::Const, kw::Async, kw::Unsafe, kw::Extern] } else { diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1997f2133ed00..892000889dbe2 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2002,7 +2002,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) { continue 'lifetimes; } - // We want to do this only if the liftime identifier is already defined + // We want to do this only if the lifetime identifier is already defined // in the async function that generated this. Otherwise it could be // an opaque type defined by the developer and we still want this // lint to fail compilation diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index a6506dbad1600..14420909f502a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -223,7 +223,7 @@ top_level_options!( /// `true` if we're emitting a JSON blob containing the unused externs json_unused_externs: bool [UNTRACKED], - /// `true` if we're emitting a JSON job containg a future-incompat report for lints + /// `true` if we're emitting a JSON job containing a future-incompat report for lints json_future_incompat: bool [TRACKED], pretty: Option [UNTRACKED], diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 707c609d8bfb8..36bbccf1b9028 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -69,7 +69,7 @@ pub struct SymbolGallery { impl SymbolGallery { /// Insert a symbol and its span into symbol gallery. - /// If the symbol has occurred before, ignore the new occurrance. + /// If the symbol has occurred before, ignore the new occurrence. pub fn insert(&self, symbol: Symbol, span: Span) { self.symbols.lock().entry(symbol).or_insert(span); } diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs index 1a044e677a02f..a33f94013d24c 100644 --- a/compiler/rustc_session/src/utils.rs +++ b/compiler/rustc_session/src/utils.rs @@ -29,14 +29,14 @@ pub enum NativeLibKind { /// Dynamic library (e.g. `libfoo.so` on Linux) /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). Dylib { - /// Whether the dynamic library will be linked only if it satifies some undefined symbols + /// Whether the dynamic library will be linked only if it satisfies some undefined symbols as_needed: Option, }, /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library. RawDylib, /// A macOS-specific kind of dynamic libraries. Framework { - /// Whether the framework will be linked only if it satifies some undefined symbols + /// Whether the framework will be linked only if it satisfies some undefined symbols as_needed: Option, }, /// The library kind wasn't specified, `Dylib` is currently used as a default. diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 3b60f91f8c853..a5503b04ff629 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -226,7 +226,7 @@ fn compute_symbol_name<'tcx>( // If we're dealing with an instance of a function that's inlined from // another crate but we're marking it as globally shared to our - // compliation (aka we're not making an internal copy in each of our + // compilation (aka we're not making an internal copy in each of our // codegen units) then this symbol may become an exported (but hidden // visibility) symbol. This means that multiple crates may do the same // and we want to be sure to avoid any symbol conflicts here. diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index fb5e0272cc359..6082cdb78e478 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1105,7 +1105,7 @@ impl Niche { // Extend the range of valid values being reserved by moving either `v.start` or `v.end` bound. // Given an eventual `Option`, we try to maximize the chance for `None` to occupy the niche of zero. - // This is accomplished by prefering enums with 2 variants(`count==1`) and always taking the shortest path to niche zero. + // This is accomplished by preferring enums with 2 variants(`count==1`) and always taking the shortest path to niche zero. // Having `None` in niche zero can enable some special optimizations. // // Bound selection criteria: diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bf94c61e6c2ce..db1efdc265a17 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -536,7 +536,7 @@ fn prepare_vtable_segments<'tcx, T>( // the main traversal loop: // basically we want to cut the inheritance directed graph into a few non-overlapping slices of nodes - // that each node is emited after all its descendents have been emitted. + // that each node is emitted after all its descendents have been emitted. // so we convert the directed graph into a tree by skipping all previously visted nodes using a visited set. // this is done on the fly. // Each loop run emits a slice - it starts by find a "childless" unvisited node, backtracking upwards, and it @@ -551,10 +551,10 @@ fn prepare_vtable_segments<'tcx, T>( // Starting point 0 stack [D] // Loop run #0: Stack after diving in is [D B A], A is "childless" // after this point, all newly visited nodes won't have a vtable that equals to a prefix of this one. - // Loop run #0: Emiting the slice [B A] (in reverse order), B has a next-sibling node, so this slice stops here. + // Loop run #0: Emitting the slice [B A] (in reverse order), B has a next-sibling node, so this slice stops here. // Loop run #0: Stack after exiting out is [D C], C is the next starting point. // Loop run #1: Stack after diving in is [D C], C is "childless", since its child A is skipped(already emitted). - // Loop run #1: Emiting the slice [D C] (in reverse order). No one has a next-sibling node. + // Loop run #1: Emitting the slice [D C] (in reverse order). No one has a next-sibling node. // Loop run #1: Stack after exiting out is []. Now the function exits. loop { diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index c3f3baf9d3d47..05479899f3a1b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -719,7 +719,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // TraitA+Kx+'a -> TraitB+Ky+'b (trait upcasting coercion). (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See `assemble_candidates_for_unsizing` for more info. - // We already checked the compatiblity of auto traits within `assemble_candidates_for_unsizing`. + // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. let principal_a = data_a.principal().unwrap(); source_trait_ref = principal_a.with_self_ty(tcx, source); upcast_trait_ref = util::supertraits(tcx, source_trait_ref).nth(idx).unwrap(); @@ -823,7 +823,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping). (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => { // See `assemble_candidates_for_unsizing` for more info. - // We already checked the compatiblity of auto traits within `assemble_candidates_for_unsizing`. + // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. let iter = data_a .principal() .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) @@ -1084,7 +1084,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Foreign(_) => {} // These types are built-in, so we can fast-track by registering - // nested predicates for their constituient type(s) + // nested predicates for their constituent type(s) ty::Array(ty, _) | ty::Slice(ty) => { stack.push(ty); } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8af4606db8520..7d1abb662506f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -553,7 +553,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match project::poly_project_and_unify_type(self, &project_obligation) { Ok(Ok(Some(mut subobligations))) => { 'compute_res: { - // If we've previously marked this projection as 'complete', thne + // If we've previously marked this projection as 'complete', then // use the final cached result (either `EvaluatedToOk` or // `EvaluatedToOkModuloRegions`), and skip re-evaluating the // sub-obligations. diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index 6195c712c5894..c5fc4e4c66105 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -181,12 +181,12 @@ enum DtorType { /// "significant" / "insignificant". Insignificant, - /// Type has a `Drop` implentation. + /// Type has a `Drop` implantation. Significant, } // This is a helper function for `adt_drop_tys` and `adt_significant_drop_tys`. -// Depending on the implentation of `adt_has_dtor`, it is used to check if the +// Depending on the implantation of `adt_has_dtor`, it is used to check if the // ADT has a destructor or if the ADT only has a significant destructor. For // understanding significant destructor look at `adt_significant_drop_tys`. fn drop_tys_helper<'tcx>( @@ -295,7 +295,7 @@ fn adt_drop_tys<'tcx>( .map(|components| tcx.intern_type_list(&components)) } // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed -// a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitue the generic parameters +// a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitute the generic parameters // of the ADT into the outputted `ty`s. fn adt_significant_drop_tys( tcx: TyCtxt<'_>, diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 7e9abe3a250db..4cd6b32525d08 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -126,7 +126,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "the precise format of `Fn`-family traits' type parameters is subject to change", ); // Do not suggest the other syntax if we are in trait impl: - // the desugaring would contain an associated type constrait. + // the desugaring would contain an associated type constraint. if !is_impl { let args = trait_segment .args diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index e8b64587eeea6..974af3d9eba2b 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -429,7 +429,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let param_counts = gen_params.own_counts(); // Subtracting from param count to ensure type params synthesized from `impl Trait` - // cannot be explictly specified even with `explicit_generic_args_with_impl_trait` + // cannot be explicitly specified even with `explicit_generic_args_with_impl_trait` // feature enabled. let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait { gen_params diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs index 48d241700727a..8ce6b668b4dca 100644 --- a/compiler/rustc_typeck/src/check/generator_interior.rs +++ b/compiler/rustc_typeck/src/check/generator_interior.rs @@ -468,11 +468,11 @@ pub struct SuspendCheckData<'a, 'tcx> { } // Returns whether it emitted a diagnostic or not -// Note that this fn and the proceding one are based on the code +// Note that this fn and the proceeding one are based on the code // for creating must_use diagnostics // // Note that this technique was chosen over things like a `Suspend` marker trait -// as it is simpler and has precendent in the compiler +// as it is simpler and has precedent in the compiler pub fn check_must_not_suspend_ty<'tcx>( fcx: &FnCtxt<'_, 'tcx>, ty: Ty<'tcx>, diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs index dbc4adfb0a3cf..a2f1f5692c731 100644 --- a/compiler/rustc_typeck/src/check/method/prelude2021.rs +++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Creates a string version of the `expr` that includes explicit adjustments. - /// Returns the string and also a bool indicating whther this is a *precise* + /// Returns the string and also a bool indicating whether this is a *precise* /// suggestion. fn adjust_expr( &self, diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 1a94b7261f7ab..7106f8f9d7a82 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -1371,7 +1371,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // represents the case of the path being completely captured by the variable. // // eg. If `a.b` is captured and we are processing `a.b`, then we can't have the closure also - // capture `a.b.c`, because that voilates min capture. + // capture `a.b.c`, because that violates min capture. let is_completely_captured = captured_by_move_projs.iter().any(|projs| projs.is_empty()); assert!(!is_completely_captured || (captured_by_move_projs.len() == 1)); @@ -1411,7 +1411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::RawPtr(..) => unreachable!(), ty::Adt(def, substs) => { - // Multi-varaint enums are captured in entirety, + // Multi-variant enums are captured in entirety, // which would've been handled in the case of single empty slice in `captured_by_move_projs`. assert_eq!(def.variants().len(), 1); @@ -2208,8 +2208,8 @@ fn determine_place_ancestry_relation<'tcx>( } } -/// Reduces the precision of the captured place when the precision doesn't yeild any benefit from -/// borrow checking prespective, allowing us to save us on the size of the capture. +/// Reduces the precision of the captured place when the precision doesn't yield any benefit from +/// borrow checking perspective, allowing us to save us on the size of the capture. /// /// /// Fields that are read through a shared reference will always be read via a shared ref or a copy, diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 30603d6f48794..d6eeef3323cad 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1469,7 +1469,7 @@ fn check_fn_or_method<'fcx, 'tcx>( }, ) })); - // Manually call `normalize_assocaited_types_in` on the other types + // Manually call `normalize_associated_types_in` on the other types // in `FnSig`. This ensures that if the types of these fields // ever change to include projections, we will start normalizing // them automatically. diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index 05b57592572a9..d0f1db67c6e50 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -323,7 +323,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .skip(self.params_offset + self.num_provided_type_or_const_args()) .take(num_params_to_take) .map(|param| match param.kind { - // This is being infered from the item's inputs, no need to set it. + // This is being inferred from the item's inputs, no need to set it. ty::GenericParamDefKind::Type { .. } if is_used_in_input(param.def_id) => { "_".to_string() } diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 0be3f06ff6c2a..00b63dfbd0693 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -68,7 +68,7 @@ pub macro unreachable_2015 { $crate::panicking::panic("internal error: entered unreachable code") ), // Use of `unreachable_display` for non_fmt_panic lint. - // NOTE: the message ("internal error ...") is embeded directly in unreachable_display + // NOTE: the message ("internal error ...") is embedded directly in unreachable_display ($msg:expr $(,)?) => ( $crate::panicking::unreachable_display(&$msg) ), diff --git a/library/std/src/sys/common/alloc.rs b/library/std/src/sys/common/alloc.rs index e06eaf6db1a77..e8e7c51cb9ba6 100644 --- a/library/std/src/sys/common/alloc.rs +++ b/library/std/src/sys/common/alloc.rs @@ -28,7 +28,7 @@ pub const MIN_ALIGN: usize = 8; target_arch = "wasm64", )))] pub const MIN_ALIGN: usize = 16; -// The allocator on the esp-idf platform guarentees 4 byte alignment. +// The allocator on the esp-idf platform guarantees 4 byte alignment. #[cfg(all(any( all(target_arch = "riscv32", target_os = "espidf"), all(target_arch = "xtensa", target_os = "espidf"), diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 7846c6db898a8..32ccca8bcdd2c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1005,7 +1005,7 @@ impl<'a> Builder<'a> { // the rustc_llvm cache. That will always work, even though it // may mean that on the next non-check build we'll need to rebuild // rustc_llvm. But if LLVM is stale, that'll be a tiny amount - // of work comparitively, and we'd likely need to rebuild it anyway, + // of work comparatively, and we'd likely need to rebuild it anyway, // so that's okay. if crate::native::prebuilt_llvm_config(self, target).is_err() { cargo.env("RUST_CHECK", "1"); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 9cfd9f92aa7cd..e030e0bc1cf80 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1185,7 +1185,7 @@ impl Step for Assemble { for tool in LLVM_TOOLS { let tool_exe = exe(tool, target_compiler.host); let src_path = llvm_bin_dir.join(&tool_exe); - // When using `donwload-ci-llvm`, some of the tools + // When using `download-ci-llvm`, some of the tools // may not exist, so skip trying to copy them. if src_path.exists() { builder.copy(&src_path, &libdir_bin.join(&tool_exe)); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 76054122d00b1..be965971dbb6f 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -2082,7 +2082,7 @@ impl Step for RustDev { } } -/// Tarball containing a prebuilt version of the build-manifest tool, intented to be used by the +/// Tarball containing a prebuilt version of the build-manifest tool, intended to be used by the /// release process to avoid cloning the monorepo and building stuff. /// /// Should not be considered stable by end users. diff --git a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md index 71afca527d1f6..09e03e4dc6f98 100644 --- a/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md +++ b/src/doc/rustc/src/platform-support/armv7-unknown-linux-uclibceabi.md @@ -89,7 +89,7 @@ To cross compile, you'll need to: ``` * Copy the binary to your target device and run. -We specify `CC`, `CXX`, `AR`, `CFLAGS`, and `CXXFLAGS` environment variables because somtimes a project or a subproject requires the use of your `'C'` cross toolchain. Since Tomatoware has a modified sysroot we also pass via RUSTFLAGS the location of the dynamic-linker and rpath. +We specify `CC`, `CXX`, `AR`, `CFLAGS`, and `CXXFLAGS` environment variables because sometimes a project or a subproject requires the use of your `'C'` cross toolchain. Since Tomatoware has a modified sysroot we also pass via RUSTFLAGS the location of the dynamic-linker and rpath. ### Test with QEMU diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index 735521e667c91..3f60caffef5b7 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -212,7 +212,7 @@ fn add_one(x: i32) -> i32 { #[naked] pub extern "C" fn add_two(x: i32) { - // x + 2 preceeded by a landing pad/nop block + // x + 2 preceded by a landing pad/nop block unsafe { asm!( " diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c0e7cd0b1f580..d55ba0a188f39 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2050,7 +2050,7 @@ crate struct Typedef { /// alias instead of the final type. This will always have the final type, regardless of whether /// `type_` came from HIR or from metadata. /// - /// If `item_type.is_none()`, `type_` is guarenteed to come from metadata (and therefore hold the + /// If `item_type.is_none()`, `type_` is guaranteed to come from metadata (and therefore hold the /// final type). crate item_type: Option, } diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs index 81053042f67d5..2403ff4ebaa7a 100644 --- a/src/librustdoc/formats/renderer.rs +++ b/src/librustdoc/formats/renderer.rs @@ -13,7 +13,7 @@ crate trait FormatRenderer<'tcx>: Sized { /// Gives a description of the renderer. Used for performance profiling. fn descr() -> &'static str; - /// Whether to call `item` recursivly for modules + /// Whether to call `item` recursively for modules /// /// This is true for html, and false for json. See #80664 const RUN_ON_MODULE: bool; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 3dbe9f735bfc4..3666767a9d9cb 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2821,7 +2821,7 @@ fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) { let mut it = ordered_locations.into_iter().peekable(); // An example may fail to write if its source can't be read for some reason, so this method - // continues iterating until a write suceeds + // continues iterating until a write succeeds let write_and_skip_failure = |w: &mut Buffer, it: &mut Peekable<_>| { while let Some(example) = it.next() { if write_example(&mut *w, example) { diff --git a/src/test/codegen/catch-unwind.rs b/src/test/codegen/catch-unwind.rs index b89c590add0d7..3ea3a24bfae11 100644 --- a/src/test/codegen/catch-unwind.rs +++ b/src/test/codegen/catch-unwind.rs @@ -1,6 +1,6 @@ // compile-flags: -O -// On x86 the closure is inlined in foo() producting something like +// On x86 the closure is inlined in foo() producing something like // define i32 @foo() [...] { // tail call void @bar() [...] // ret i32 0 diff --git a/src/test/codegen/debug-column.rs b/src/test/codegen/debug-column.rs index 5d3afef5289bf..e61642b8e1be2 100644 --- a/src/test/codegen/debug-column.rs +++ b/src/test/codegen/debug-column.rs @@ -1,4 +1,4 @@ -// Verify that debuginfo column nubmers are 1-based byte offsets. +// Verify that debuginfo column numbers are 1-based byte offsets. // // ignore-windows // compile-flags: -C debuginfo=2 diff --git a/src/test/ui/extern/extern-static-size-overflow.rs b/src/test/ui/extern/extern-static-size-overflow.rs index 30a0c44546686..a96ce0cf47e08 100644 --- a/src/test/ui/extern/extern-static-size-overflow.rs +++ b/src/test/ui/extern/extern-static-size-overflow.rs @@ -4,7 +4,7 @@ struct ReallyBig { } // The limit for "too big for the current architecture" is dependent on the target pointer size -// however it's artifically limited on 64 bits +// however it's artificially limited on 64 bits // logic copied from rustc_target::abi::TargetDataLayout::obj_size_bound() const fn max_size() -> usize { #[cfg(target_pointer_width = "16")] diff --git a/src/test/ui/impl-trait/multiple-lifetimes.rs b/src/test/ui/impl-trait/multiple-lifetimes.rs index 92e5ea2f49df8..5407fb6dd2804 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes.rs @@ -1,4 +1,4 @@ -// Test that multiple liftimes are allowed in impl trait types. +// Test that multiple lifetimes are allowed in impl trait types. // build-pass (FIXME(62277): could be check-pass?) trait X<'x>: Sized {} diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 54ff38e39dbe4..5c33925a9ec73 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -67,7 +67,7 @@ const TEST_REPOS: &[Test] = &[ sha: "91493fe47175076f330ce5fc518f0196c0476f56", lock: None, packages: &[], - // Test the embeded sqlite variant of diesel + // Test the embedded sqlite variant of diesel // This does not require any dependency to be present, // sqlite will be compiled as part of the build process features: Some(&["sqlite", "libsqlite3-sys/bundled"]), diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs index a20aa12c9ff47..e6a0162fd0272 100644 --- a/src/tools/clippy/clippy_lints/src/copies.rs +++ b/src/tools/clippy/clippy_lints/src/copies.rs @@ -126,7 +126,7 @@ declare_clippy_lint! { /// Duplicate code is less maintainable. /// /// ### Known problems - /// * The lint doesn't check if the moved expressions modify values that are beeing used in + /// * The lint doesn't check if the moved expressions modify values that are being used in /// the if condition. The suggestion can in that case modify the behavior of the program. /// See [rust-clippy#7452](https://github.com/rust-lang/rust-clippy/issues/7452) /// diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs index 574678b554211..088d9996516e8 100644 --- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs +++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs @@ -86,9 +86,9 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[h // check for `unwrap` if let Some(arglists) = method_chain_args(expr, &["unwrap"]) { - let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); - if is_type_diagnostic_item(self.lcx, reciever_ty, sym::Option) - || is_type_diagnostic_item(self.lcx, reciever_ty, sym::Result) + let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); + if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option) + || is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result) { self.result.push(expr.span); } diff --git a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs index ca8886228de26..98aee7592ae80 100644 --- a/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs +++ b/src/tools/clippy/clippy_lints/src/float_equality_without_abs.rs @@ -20,7 +20,7 @@ declare_clippy_lint! { /// /// ### Known problems /// If the user can ensure that b is larger than a, the `.abs()` is - /// technically unneccessary. However, it will make the code more robust and doesn't have any + /// technically unnecessary. However, it will make the code more robust and doesn't have any /// large performance implications. If the abs call was deliberately left out for performance /// reasons, it is probably better to state this explicitly in the code, which then can be done /// with an allow. @@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatEqualityWithoutAbs { if_chain! { - // left hand side is a substraction + // left hand side is a subtraction if let ExprKind::Binary( Spanned { node: BinOpKind::Sub, @@ -84,7 +84,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatEqualityWithoutAbs { if let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id); if match_def_path(cx, def_id, &paths::F32_EPSILON) || match_def_path(cx, def_id, &paths::F64_EPSILON); - // values of the substractions on the left hand side are of the type float + // values of the subtractions on the left hand side are of the type float let t_val_l = cx.typeck_results().expr_ty(val_l); let t_val_r = cx.typeck_results().expr_ty(val_r); if let ty::Float(_) = t_val_l.kind(); diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index b828d9334ee0e..8e61f2347767d 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -224,7 +224,7 @@ pub fn is_array(ty: Ty<'_>) -> bool { /// This builds the graph of side effect. /// The edge `a -> b` means if `a` has side effect, `b` will have side effect. /// -/// There are some exmaple in following code: +/// There are some example in following code: /// ```rust, ignore /// let b = 1; /// let a = b; // a -> b diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs index 940a8428f7795..b5dd27ff80de4 100644 --- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs +++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs @@ -290,7 +290,7 @@ fn ident_swap_sugg( // used instead, in these cases. *applicability = Applicability::MaybeIncorrect; - // We arbitraily choose one side to suggest changing, + // We arbitrarily choose one side to suggest changing, // since we don't have a better guess. If the user // ends up duplicating a clause, the `logic_bug` lint // should catch it. @@ -374,19 +374,19 @@ fn strip_non_ident_wrappers(expr: &Expr) -> &Expr { } fn extract_related_binops(kind: &ExprKind) -> Option>> { - append_opt_vecs(chained_binops(kind), if_statment_binops(kind)) + append_opt_vecs(chained_binops(kind), if_statement_binops(kind)) } -fn if_statment_binops(kind: &ExprKind) -> Option>> { +fn if_statement_binops(kind: &ExprKind) -> Option>> { match kind { ExprKind::If(ref condition, _, _) => chained_binops(&condition.kind), - ExprKind::Paren(ref e) => if_statment_binops(&e.kind), + ExprKind::Paren(ref e) => if_statement_binops(&e.kind), ExprKind::Block(ref block, _) => { let mut output = None; for stmt in &block.stmts { match stmt.kind { StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => { - output = append_opt_vecs(output, if_statment_binops(&e.kind)); + output = append_opt_vecs(output, if_statement_binops(&e.kind)); }, _ => {}, } diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index c9b2ce476e89d..58cc057a39ed9 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -10,7 +10,7 @@ declare_clippy_lint! { /// Displays a warning when a struct with a trailing zero-sized array is declared without a `repr` attribute. /// /// ### Why is this bad? - /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjuction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed. + /// Zero-sized arrays aren't very useful in Rust itself, so such a struct is likely being created to pass to C code or in some other situation where control over memory layout matters (for example, in conjunction with manual allocation to make it easy to compute the offset of the array). Either way, `#[repr(C)]` (or another `repr` attribute) is needed. /// /// ### Example /// ```rust diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index be9d538c36267..43e0132a7ec7b 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -46,7 +46,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Duplicate bounds makes the code - /// less readable than specifing them only once. + /// less readable than specifying them only once. /// /// ### Example /// ```rust diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs index 2c13f1049b599..b32be238cd55a 100644 --- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs +++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs @@ -83,9 +83,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindExpectUnwrap<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { // check for `expect` if let Some(arglists) = method_chain_args(expr, &["expect"]) { - let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); - if is_type_diagnostic_item(self.lcx, reciever_ty, sym::Option) - || is_type_diagnostic_item(self.lcx, reciever_ty, sym::Result) + let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); + if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option) + || is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result) { self.result.push(expr.span); } @@ -93,9 +93,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindExpectUnwrap<'a, 'tcx> { // check for `unwrap` if let Some(arglists) = method_chain_args(expr, &["unwrap"]) { - let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); - if is_type_diagnostic_item(self.lcx, reciever_ty, sym::Option) - || is_type_diagnostic_item(self.lcx, reciever_ty, sym::Result) + let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs(); + if is_type_diagnostic_item(self.lcx, receiver_ty, sym::Option) + || is_type_diagnostic_item(self.lcx, receiver_ty, sym::Result) { self.result.push(expr.span); } diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs index b4d94dc983fec..dc82ba891fb1f 100644 --- a/src/tools/clippy/tests/lint_message_convention.rs +++ b/src/tools/clippy/tests/lint_message_convention.rs @@ -16,7 +16,7 @@ impl Message { fn new(path: PathBuf) -> Self { let content: String = std::fs::read_to_string(&path).unwrap(); // we don't want the first letter after "error: ", "help: " ... to be capitalized - // also no puncutation (except for "?" ?) at the end of a line + // also no punctuation (except for "?" ?) at the end of a line let regex_set: RegexSet = RegexSet::new(&[ r"error: [A-Z]", r"help: [A-Z]", diff --git a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs index ba388a05a2859..c826b082adff1 100644 --- a/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs +++ b/src/tools/clippy/tests/ui/manual_memcpy/with_loop_counters.rs @@ -59,7 +59,7 @@ pub fn manual_copy_with_counters(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) } // make sure parentheses are added properly to bitwise operators, which have lower precedence than - // arithmetric ones + // arithmetic ones let mut count = 0 << 1; for i in 0..1 << 1 { dst[count] = src[i + 2]; diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs index 677b4a4d56999..e13efb3e0164b 100644 --- a/src/tools/clippy/tests/workspace.rs +++ b/src/tools/clippy/tests/workspace.rs @@ -93,7 +93,7 @@ fn test_no_deps_ignores_path_deps_in_workspaces() { output }; - // Trigger a sucessful build, so Cargo would like to cache the build result. + // Trigger a successful build, so Cargo would like to cache the build result. successful_build(); // Make sure there's no spurious rebuild when nothing changes. diff --git a/src/tools/rustfmt/src/lists.rs b/src/tools/rustfmt/src/lists.rs index 7aa0315f18c26..29d75585eb725 100644 --- a/src/tools/rustfmt/src/lists.rs +++ b/src/tools/rustfmt/src/lists.rs @@ -575,7 +575,7 @@ where pub(crate) fn extract_pre_comment(pre_snippet: &str) -> (Option, ListItemCommentStyle) { let trimmed_pre_snippet = pre_snippet.trim(); // Both start and end are checked to support keeping a block comment inline with - // the item, even if there are preceeding line comments, while still supporting + // the item, even if there are preceding line comments, while still supporting // a snippet that starts with a block comment but also contains one or more // trailing single line comments. // https://github.com/rust-lang/rustfmt/issues/3025 diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 5de30129266a3..a49d473a13f3f 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -251,7 +251,7 @@ fn rewrite_segment( match **args { ast::GenericArgs::AngleBracketed(ref data) if !data.args.is_empty() => { // HACK: squeeze out the span between the identifier and the parameters. - // The hack is requried so that we don't remove the separator inside macro calls. + // The hack is required so that we don't remove the separator inside macro calls. // This does not work in the presence of comment, hoping that people are // sane about where to put their comment. let separator_snippet = context diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index f5ff3860afe34..c5414233f09b3 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -132,7 +132,7 @@ fn check_cfgs( continue; } - let preceeded_by_doc_comment = { + let preceded_by_doc_comment = { let pre_contents = &contents[..idx]; let pre_newline = pre_contents.rfind('\n'); let pre_doc_comment = pre_contents.rfind("///"); @@ -143,7 +143,7 @@ fn check_cfgs( } }; - if preceeded_by_doc_comment { + if preceded_by_doc_comment { continue; } diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 9861cba410df2..5a061009b6b95 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -396,7 +396,7 @@ pub fn check(path: &Path, bad: &mut bool) { }; suppressible_tidy_err!(err, skip_file_length, ""); } else if lines > (LINES * 7) / 10 { - // Just set it to something that doesn't trigger the "unneccessarily ignored" warning. + // Just set it to something that doesn't trigger the "unnecessarily ignored" warning. skip_file_length = Directive::Ignore(true); } From 243e2a698c0c6573dc5445b07e0dcb6b0167f876 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Wed, 16 Mar 2022 11:03:07 +0100 Subject: [PATCH 23/24] debuginfo: Fix ICE when generating name for type that produces a layout error. --- .../src/debuginfo/type_names.rs | 25 +++++++++++++++++-- .../debuginfo-type-name-layout-ice-94961-1.rs | 16 ++++++++++++ ...uginfo-type-name-layout-ice-94961-1.stderr | 4 +++ .../debuginfo-type-name-layout-ice-94961-2.rs | 20 +++++++++++++++ ...uginfo-type-name-layout-ice-94961-2.stderr | 4 +++ 5 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs create mode 100644 src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr create mode 100644 src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs create mode 100644 src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 4b1563ca3c97f..a67414036dc23 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -74,9 +74,30 @@ fn push_debuginfo_type_name<'tcx>( ty::Float(float_ty) => output.push_str(float_ty.name_str()), ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output), ty::Adt(def, substs) => { - let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).expect("layout error"); + // `layout_for_cpp_like_fallback` will be `Some` if we want to use the fallback encoding. + let layout_for_cpp_like_fallback = if cpp_like_debuginfo && def.is_enum() { + match tcx.layout_of(ParamEnv::reveal_all().and(t)) { + Ok(layout) => { + if !wants_c_like_enum_debuginfo(layout) { + Some(layout) + } else { + // This is a C-like enum so we don't want to use the fallback encoding + // for the name. + None + } + } + Err(e) => { + // Computing the layout can still fail here, e.g. if the target architecture + // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961. + tcx.sess.fatal(&format!("{}", e)); + } + } + } else { + // We are not emitting cpp-like debuginfo or this isn't even an enum. + None + }; - if def.is_enum() && cpp_like_debuginfo && !wants_c_like_enum_debuginfo(ty_and_layout) { + if let Some(ty_and_layout) = layout_for_cpp_like_fallback { msvc_enum_fallback( tcx, ty_and_layout, diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs new file mode 100644 index 0000000000000..78bda28485dce --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.rs @@ -0,0 +1,16 @@ +// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that +// causes a layout error. See https://github.com/rust-lang/rust/issues/94961. + +// compile-flags:-C debuginfo=2 +// build-fail +// error-pattern: too big for the current architecture +// normalize-stderr-64bit "18446744073709551615" -> "SIZE" +// normalize-stderr-32bit "4294967295" -> "SIZE" + +#![crate_type = "rlib"] + +pub struct Foo([T; usize::MAX]); + +pub fn foo() -> usize { + std::mem::size_of::>() +} diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr new file mode 100644 index 0000000000000..851dca84c3dc0 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-1.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; SIZE]` are too big for the current architecture + +error: aborting due to previous error + diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs new file mode 100644 index 0000000000000..fdc088dc0f9a5 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.rs @@ -0,0 +1,20 @@ +// Make sure the compiler does not ICE when trying to generate the debuginfo name of a type that +// causes a layout error. +// This version of the test already ICE'd before the commit that introduce the ICE described in +// https://github.com/rust-lang/rust/issues/94961. + +// compile-flags:-C debuginfo=2 +// build-fail +// error-pattern: too big for the current architecture +// normalize-stderr-64bit "18446744073709551615" -> "SIZE" +// normalize-stderr-32bit "4294967295" -> "SIZE" + +#![crate_type = "rlib"] + +pub enum Foo { + Bar([T; usize::MAX]), +} + +pub fn foo() -> usize { + std::mem::size_of::>() +} diff --git a/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr new file mode 100644 index 0000000000000..851dca84c3dc0 --- /dev/null +++ b/src/test/ui/debuginfo/debuginfo-type-name-layout-ice-94961-2.stderr @@ -0,0 +1,4 @@ +error: values of the type `[u8; SIZE]` are too big for the current architecture + +error: aborting due to previous error + From bb8d4307eb723850e98bcb52d71d860a4aba220a Mon Sep 17 00:00:00 2001 From: mark Date: Sat, 22 Jan 2022 18:49:12 -0600 Subject: [PATCH 24/24] rustc_error: make ErrorReported impossible to construct There are a few places were we have to construct it, though, and a few places that are more invasive to change. To do this, we create a constructor with a long obvious name. --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- .../rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 11 +- compiler/rustc_borrowck/src/lib.rs | 8 +- .../rustc_codegen_cranelift/src/constant.rs | 3 +- compiler/rustc_codegen_ssa/src/mir/mod.rs | 3 +- .../src/const_eval/machine.rs | 5 +- .../rustc_const_eval/src/interpret/intern.rs | 7 +- .../rustc_const_eval/src/interpret/operand.rs | 7 +- .../src/transform/check_consts/check.rs | 6 +- compiler/rustc_driver/src/lib.rs | 8 +- .../rustc_errors/src/diagnostic_builder.rs | 6 +- compiler/rustc_errors/src/lib.rs | 95 ++++++++++------ compiler/rustc_expand/src/base.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 8 +- compiler/rustc_expand/src/proc_macro.rs | 6 +- compiler/rustc_incremental/src/persist/fs.rs | 11 +- .../nice_region_error/different_lifetimes.rs | 4 +- .../mismatched_static_lifetime.rs | 4 +- .../error_reporting/nice_region_error/mod.rs | 5 +- .../nice_region_error/static_impl_trait.rs | 8 +- .../trait_impl_difference.rs | 22 ++-- .../src/infer/outlives/obligations.rs | 2 +- compiler/rustc_interface/src/passes.rs | 26 +++-- compiler/rustc_interface/src/queries.rs | 7 +- compiler/rustc_lint/src/builtin.rs | 36 +++--- compiler/rustc_lint/src/context.rs | 16 ++- compiler/rustc_lint/src/early.rs | 4 +- compiler/rustc_lint/src/levels.rs | 2 +- compiler/rustc_lint/src/non_ascii_idents.rs | 6 +- compiler/rustc_lint/src/noop_method_call.rs | 2 +- compiler/rustc_lint/src/traits.rs | 4 +- compiler/rustc_lint/src/types.rs | 6 +- compiler/rustc_lint/src/unused.rs | 10 +- compiler/rustc_metadata/src/creader.rs | 8 +- compiler/rustc_metadata/src/native_libs.rs | 50 +++++---- compiler/rustc_middle/src/lint.rs | 26 +++-- compiler/rustc_middle/src/middle/stability.rs | 4 +- .../rustc_middle/src/mir/interpret/error.rs | 4 +- compiler/rustc_middle/src/query/mod.rs | 4 +- .../src/traits/specialization_graph.rs | 10 +- compiler/rustc_middle/src/ty/adt.rs | 3 +- compiler/rustc_middle/src/ty/consts.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 20 ++-- compiler/rustc_middle/src/ty/fold.rs | 8 ++ compiler/rustc_mir_build/src/build/mod.rs | 8 +- .../rustc_mir_build/src/check_unsafety.rs | 9 +- compiler/rustc_mir_build/src/thir/cx/mod.rs | 14 ++- .../src/thir/pattern/const_to_pat.rs | 32 ++++-- .../src/check_const_item_mutation.rs | 4 +- .../src/check_packed_ref.rs | 4 +- .../rustc_mir_transform/src/const_prop.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 10 +- .../src/lexer/unescape_error_reporting.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 6 +- compiler/rustc_passes/src/check_attr.rs | 4 +- compiler/rustc_passes/src/liveness.rs | 4 +- compiler/rustc_passes/src/stability.rs | 6 +- compiler/rustc_privacy/src/lib.rs | 6 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 12 +- compiler/rustc_session/src/output.rs | 2 +- compiler/rustc_session/src/session.rs | 45 +++++--- .../src/traits/codegen.rs | 8 +- .../src/traits/const_evaluatable.rs | 27 +++-- .../src/traits/error_reporting/mod.rs | 18 +-- .../src/traits/fulfill.rs | 15 +-- .../rustc_trait_selection/src/traits/mod.rs | 14 ++- .../src/traits/on_unimplemented.rs | 38 +++---- .../src/traits/project.rs | 2 +- .../src/traits/select/mod.rs | 6 +- .../src/traits/specialize/mod.rs | 41 ++++--- compiler/rustc_ty_utils/src/instance.rs | 4 +- compiler/rustc_typeck/src/astconv/errors.rs | 7 +- compiler/rustc_typeck/src/astconv/generics.rs | 104 +++++++++--------- compiler/rustc_typeck/src/astconv/mod.rs | 37 ++++--- compiler/rustc_typeck/src/check/cast.rs | 25 +++-- compiler/rustc_typeck/src/check/check.rs | 36 +++--- .../rustc_typeck/src/check/compare_method.rs | 70 ++++++------ compiler/rustc_typeck/src/check/dropck.rs | 16 +-- compiler/rustc_typeck/src/check/expr.rs | 4 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 24 ++-- .../rustc_typeck/src/check/method/probe.rs | 4 +- compiler/rustc_typeck/src/check/writeback.rs | 10 +- compiler/rustc_typeck/src/coherence/orphan.rs | 12 +- compiler/rustc_typeck/src/collect/type_of.rs | 4 +- compiler/rustc_typeck/src/expr_use_visitor.rs | 2 +- compiler/rustc_typeck/src/lib.rs | 2 +- src/librustdoc/clean/types.rs | 4 +- src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 2 +- src/librustdoc/lib.rs | 16 ++- src/librustdoc/passes/bare_urls.rs | 2 +- .../passes/check_code_block_syntax.rs | 2 +- .../passes/check_doc_test_visibility.rs | 8 +- .../auxiliary/issue-40001-plugin.rs | 2 +- .../auxiliary/lint-for-crate-rpass.rs | 2 +- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 2 +- .../auxiliary/lint-group-plugin-test.rs | 4 +- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 2 +- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 4 +- .../rustfmt/src/parse/macros/lazy_static.rs | 2 +- src/tools/rustfmt/src/parse/macros/mod.rs | 2 +- src/tools/rustfmt/src/parse/session.rs | 2 +- 104 files changed, 704 insertions(+), 549 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c1680be9c0ad5..abf1bc739a3f7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -952,7 +952,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { sess.diagnostic().delay_span_bug( span, "unexpected delimiter in key-value attribute's value", - ) + ); } unwrap_single_token(sess, tokens, span) } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 8f0b12cb4feef..f5e6b15fcbfd1 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -440,7 +440,7 @@ impl<'a> AstValidator<'a> { attr.span, "allow, cfg, cfg_attr, deny, \ forbid, and warn are the only allowed built-in attributes in function parameters", - ) + ); } }); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 097bd07c74ce8..5b6147c72230d 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -252,11 +252,12 @@ impl<'a> PostExpansionVisitor<'a> { "wasm ABI is experimental and subject to change" ); } - abi => self - .sess - .parse_sess - .span_diagnostic - .delay_span_bug(span, &format!("unrecognized ABI not caught in lowering: {}", abi)), + abi => { + self.sess.parse_sess.span_diagnostic.delay_span_bug( + span, + &format!("unrecognized ABI not caught in lowering: {}", abi), + ); + } } } diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7502a3e39a191..c9c973bd34350 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -178,7 +178,7 @@ fn do_mir_borrowck<'a, 'tcx>( // Gather the upvars of a closure, if any. let tables = tcx.typeck_opt_const_arg(def); - if let Some(ErrorGuaranteed) = tables.tainted_by_errors { + if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors { infcx.set_tainted_by_errors(); errors.set_tainted_by_errors(); } @@ -2274,6 +2274,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } mod error { + use rustc_errors::ErrorGuaranteed; + use super::*; pub struct BorrowckErrors<'tcx> { @@ -2311,7 +2313,7 @@ mod error { // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is // set before any emission actually happens (weakening the guarantee). pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { - self.tainted_by_errors = Some(ErrorGuaranteed {}); + self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); t.buffer(&mut self.buffered); } @@ -2320,7 +2322,7 @@ mod error { } pub fn set_tainted_by_errors(&mut self) { - self.tainted_by_errors = Some(ErrorGuaranteed {}); + self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } } diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index aff3603303a98..4657791345b8e 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -1,7 +1,6 @@ //! Handling of `static`s, `const`s and promoted allocations use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::ErrorGuaranteed; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ read_target_uint, AllocId, ConstAllocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar, @@ -54,7 +53,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { { all_constants_ok = false; match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(_) | ErrorHandled::Linted => { fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); } ErrorHandled::TooGeneric => { diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 40a8e2388e26b..6c139df0a8555 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -1,5 +1,4 @@ use crate::traits::*; -use rustc_errors::ErrorGuaranteed; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; @@ -191,7 +190,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( all_consts_ok = false; match err { // errored or at least linted - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => {} + ErrorHandled::Reported(_) | ErrorHandled::Linted => {} ErrorHandled::TooGeneric => { span_bug!(const_.span, "codgen encountered polymorphic constant: {:?}", err) } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 92f4d3a677244..2b58c1e8233c1 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,4 +1,3 @@ -use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::ty::{self, Ty}; @@ -247,11 +246,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, if ecx.tcx.is_ctfe_mir_available(def.did) { Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def)) } else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst { - ecx.tcx.sess.delay_span_bug( + let guar = ecx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", ); - throw_inval!(AlreadyReported(ErrorGuaranteed {})); + throw_inval!(AlreadyReported(guar)); } else { let path = ecx.tcx.def_path_str(def.did); Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path)) diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 9f507bface221..43ab74f4b888a 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -406,8 +406,11 @@ pub fn intern_const_alloc_recursive< } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // Codegen does not like dangling pointers, and generally `tcx` assumes that // all allocations referenced anywhere actually exist. So, make sure we error here. - ecx.tcx.sess.span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); - return Err(ErrorGuaranteed); + let reported = ecx + .tcx + .sess + .span_err(ecx.tcx.span, "encountered dangling pointer in final constant"); + return Err(reported); } else if ecx.tcx.get_global_alloc(alloc_id).is_none() { // We have hit an `AllocId` that is neither in local or global memory and isn't // marked as dangling by local memory. That should be impossible. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 2fae53bb9bdf5..9000567558b84 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -4,12 +4,11 @@ use std::convert::TryFrom; use std::fmt::Write; -use rustc_errors::ErrorGuaranteed; use rustc_hir::def::Namespace; use rustc_macros::HashStable; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Printer}; -use rustc_middle::ty::{ConstInt, Ty}; +use rustc_middle::ty::{ConstInt, DelaySpanBugEmitted, Ty}; use rustc_middle::{mir, ty}; use rustc_target::abi::{Abi, HasDataLayout, Size, TagEncoding}; use rustc_target::abi::{VariantIdx, Variants}; @@ -565,7 +564,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> { match val.val() { ty::ConstKind::Param(_) | ty::ConstKind::Bound(..) => throw_inval!(TooGeneric), - ty::ConstKind::Error(_) => throw_inval!(AlreadyReported(ErrorGuaranteed)), + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => { + throw_inval!(AlreadyReported(reported)) + } ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into()) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 7dc279cc840fb..eb01e261c1a55 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -259,7 +259,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { self.tcx.sess.diagnostic().emit_diagnostic(&error); } } else { - assert!(self.tcx.sess.has_errors()); + assert!(self.tcx.sess.has_errors().is_some()); } } @@ -327,8 +327,8 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { match op.importance() { ops::DiagnosticImportance::Primary => { - self.error_emitted = Some(ErrorGuaranteed); - err.emit(); + let reported = err.emit(); + self.error_emitted = Some(reported); } ops::DiagnosticImportance::Secondary => err.buffer(&mut self.secondary_errors), diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index 43c9e9296b90a..91bb38e5a95d5 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -235,7 +235,7 @@ fn run_compiler( }; match make_input(config.opts.error_format, &matches.free) { - Err(ErrorGuaranteed) => return Err(ErrorGuaranteed), + Err(reported) => return Err(reported), Ok(Some((input, input_file_path))) => { config.input = input; config.input_path = input_file_path; @@ -465,11 +465,11 @@ fn make_input( if io::stdin().read_to_string(&mut src).is_err() { // Immediately stop compilation if there was an issue reading // the input (for example if the input stream is not UTF-8). - early_error_no_abort( + let reported = early_error_no_abort( error_format, "couldn't read from stdin, as it did not contain valid UTF-8", ); - return Err(ErrorGuaranteed); + return Err(reported); } if let Ok(path) = env::var("UNSTABLE_RUSTDOC_TEST_PATH") { let line = env::var("UNSTABLE_RUSTDOC_TEST_LINE").expect( @@ -1128,7 +1128,7 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { pub fn catch_fatal_errors R, R>(f: F) -> Result { catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| { if value.is::() { - ErrorGuaranteed + ErrorGuaranteed::unchecked_claim_error_was_emitted() } else { panic::resume_unwind(value); } diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 98b8b2a569edd..72471638a966b 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -128,7 +128,7 @@ impl EmissionGuarantee for ErrorGuaranteed { DiagnosticBuilderState::Emittable(handler) => { db.inner.state = DiagnosticBuilderState::AlreadyEmittedOrDuringCancellation; - handler.emit_diagnostic(&db.inner.diagnostic); + let guar = handler.emit_diagnostic(&db.inner.diagnostic); // Only allow a guarantee if the `level` wasn't switched to a // non-error - the field isn't `pub`, but the whole `Diagnostic` @@ -139,7 +139,7 @@ impl EmissionGuarantee for ErrorGuaranteed { from `DiagnosticBuilder`", db.inner.diagnostic.level, ); - ErrorGuaranteed + guar.unwrap() } // `.emit()` was previously called, disallowed from repeating it, // but can take advantage of the previous `.emit()`'s guarantee @@ -154,7 +154,7 @@ impl EmissionGuarantee for ErrorGuaranteed { became non-error ({:?}), after original `.emit()`", db.inner.diagnostic.level, ); - ErrorGuaranteed + ErrorGuaranteed::unchecked_claim_error_was_emitted() } } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 345247b07001b..c719e4910ce4e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -399,7 +399,7 @@ impl fmt::Display for ExplicitBug { impl error::Error for ExplicitBug {} pub use diagnostic::{Diagnostic, DiagnosticId, DiagnosticStyledString, SubDiagnostic}; -pub use diagnostic_builder::DiagnosticBuilder; +pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee}; use std::backtrace::Backtrace; /// A handler deals with errors and other compiler output. @@ -644,8 +644,8 @@ impl Handler { } /// Emit all stashed diagnostics. - pub fn emit_stashed_diagnostics(&self) { - self.inner.borrow_mut().emit_stashed_diagnostics(); + pub fn emit_stashed_diagnostics(&self) -> Option { + self.inner.borrow_mut().emit_stashed_diagnostics() } /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. @@ -805,8 +805,8 @@ impl Handler { FatalError.raise() } - pub fn span_err(&self, span: impl Into, msg: &str) { - self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span); + pub fn span_err(&self, span: impl Into, msg: &str) -> ErrorGuaranteed { + self.emit_diag_at_span(Diagnostic::new(Error { lint: false }, msg), span).unwrap() } pub fn span_err_with_code(&self, span: impl Into, msg: &str, code: DiagnosticId) { @@ -829,7 +829,7 @@ impl Handler { } #[track_caller] - pub fn delay_span_bug(&self, span: impl Into, msg: &str) { + pub fn delay_span_bug(&self, span: impl Into, msg: &str) -> ErrorGuaranteed { self.inner.borrow_mut().delay_span_bug(span, msg) } @@ -858,8 +858,8 @@ impl Handler { self.inner.borrow_mut().fatal(msg) } - pub fn err(&self, msg: &str) { - self.inner.borrow_mut().err(msg); + pub fn err(&self, msg: &str) -> ErrorGuaranteed { + self.inner.borrow_mut().err(msg) } pub fn warn(&self, msg: &str) { @@ -880,11 +880,15 @@ impl Handler { self.inner.borrow().err_count() } - pub fn has_errors(&self) -> bool { - self.inner.borrow().has_errors() + pub fn has_errors(&self) -> Option { + if self.inner.borrow().has_errors() { Some(ErrorGuaranteed(())) } else { None } } - pub fn has_errors_or_lint_errors(&self) -> bool { - self.inner.borrow().has_errors_or_lint_errors() + pub fn has_errors_or_lint_errors(&self) -> Option { + if self.inner.borrow().has_errors_or_lint_errors() { + Some(ErrorGuaranteed(())) + } else { + None + } } pub fn has_errors_or_delayed_span_bugs(&self) -> bool { self.inner.borrow().has_errors_or_delayed_span_bugs() @@ -915,13 +919,17 @@ impl Handler { self.inner.borrow_mut().force_print_diagnostic(db) } - pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) { + pub fn emit_diagnostic(&self, diagnostic: &Diagnostic) -> Option { self.inner.borrow_mut().emit_diagnostic(diagnostic) } - fn emit_diag_at_span(&self, mut diag: Diagnostic, sp: impl Into) { + fn emit_diag_at_span( + &self, + mut diag: Diagnostic, + sp: impl Into, + ) -> Option { let mut inner = self.inner.borrow_mut(); - inner.emit_diagnostic(diag.set_span(sp)); + inner.emit_diagnostic(diag.set_span(sp)) } pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { @@ -990,13 +998,20 @@ impl HandlerInner { } /// Emit all stashed diagnostics. - fn emit_stashed_diagnostics(&mut self) { + fn emit_stashed_diagnostics(&mut self) -> Option { let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::>(); - diags.iter().for_each(|diag| self.emit_diagnostic(diag)); + let mut reported = None; + diags.iter().for_each(|diag| { + if diag.is_error() { + reported = Some(ErrorGuaranteed(())); + } + self.emit_diagnostic(diag); + }); + reported } // FIXME(eddyb) this should ideally take `diagnostic` by value. - fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) { + fn emit_diagnostic(&mut self, diagnostic: &Diagnostic) -> Option { if diagnostic.level == Level::DelayedBug { // FIXME(eddyb) this should check for `has_errors` and stop pushing // once *any* errors were emitted (and truncate `delayed_span_bugs` @@ -1005,7 +1020,7 @@ impl HandlerInner { self.delayed_span_bugs.push(diagnostic.clone()); if !self.flags.report_delayed_bugs { - return; + return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } } @@ -1020,7 +1035,7 @@ impl HandlerInner { if diagnostic.has_future_breakage() { (*TRACK_DIAGNOSTICS)(diagnostic); } - return; + return None; } // The `LintExpectationId` can be stable or unstable depending on when it was created. @@ -1029,16 +1044,16 @@ impl HandlerInner { // a stable one by the `LintLevelsBuilder`. if let Level::Expect(LintExpectationId::Unstable { .. }) = diagnostic.level { self.unstable_expect_diagnostics.push(diagnostic.clone()); - return; + return None; } (*TRACK_DIAGNOSTICS)(diagnostic); if let Level::Expect(expectation_id) = diagnostic.level { self.fulfilled_expectations.insert(expectation_id); - return; + return None; } else if diagnostic.level == Allow { - return; + return None; } if let Some(ref code) = diagnostic.code { @@ -1068,8 +1083,12 @@ impl HandlerInner { } else { self.bump_err_count(); } + + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) } else { self.bump_warn_count(); + + None } } @@ -1191,7 +1210,7 @@ impl HandlerInner { } #[track_caller] - fn delay_span_bug(&mut self, sp: impl Into, msg: &str) { + fn delay_span_bug(&mut self, sp: impl Into, msg: &str) -> ErrorGuaranteed { // This is technically `self.treat_err_as_bug()` but `delay_span_bug` is called before // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. @@ -1202,7 +1221,7 @@ impl HandlerInner { let mut diagnostic = Diagnostic::new(Level::DelayedBug, msg); diagnostic.set_span(sp.into()); diagnostic.note(&format!("delayed at {}", std::panic::Location::caller())); - self.emit_diagnostic(&diagnostic) + self.emit_diagnostic(&diagnostic).unwrap() } // FIXME(eddyb) note the comment inside `impl Drop for HandlerInner`, that's @@ -1221,20 +1240,20 @@ impl HandlerInner { } fn fatal(&mut self, msg: &str) -> FatalError { - self.emit_error(Fatal, msg); + self.emit(Fatal, msg); FatalError } - fn err(&mut self, msg: &str) { - self.emit_error(Error { lint: false }, msg); + fn err(&mut self, msg: &str) -> ErrorGuaranteed { + self.emit(Error { lint: false }, msg) } /// Emit an error; level should be `Error` or `Fatal`. - fn emit_error(&mut self, level: Level, msg: &str) { + fn emit(&mut self, level: Level, msg: &str) -> ErrorGuaranteed { if self.treat_err_as_bug() { self.bug(msg); } - self.emit_diagnostic(&Diagnostic::new(level, msg)); + self.emit_diagnostic(&Diagnostic::new(level, msg)).unwrap() } fn bug(&mut self, msg: &str) -> ! { @@ -1433,9 +1452,17 @@ pub fn add_elided_lifetime_in_path_suggestion( ); } -// Useful type to use with `Result<>` indicate that an error has already -// been reported to the user, so no need to continue checking. -#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq)] -pub struct ErrorGuaranteed; +/// Useful type to use with `Result<>` indicate that an error has already +/// been reported to the user, so no need to continue checking. +#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct ErrorGuaranteed(()); + +impl ErrorGuaranteed { + /// To be used only if you really know what you are doing... ideally, we would find a way to + /// eliminate all calls to this method. + pub fn unchecked_claim_error_was_emitted() -> Self { + ErrorGuaranteed(()) + } +} rustc_data_structures::impl_stable_hash_via_hash!(ErrorGuaranteed); diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 1263f31f6aa1b..d6b308cdf85d5 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1330,7 +1330,7 @@ pub fn parse_macro_name_and_helper_attrs( let attributes_attr = list.get(1); let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr { if !attr.has_name(sym::attributes) { - diag.span_err(attr.span(), "second argument must be `attributes`") + diag.span_err(attr.span(), "second argument must be `attributes`"); } attr.meta_item_list() .unwrap_or_else(|| { diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index c3b1b34aa29b9..b93edf8da7a64 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -534,10 +534,10 @@ pub fn compile_declarative_macro( let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => { - diag.span_err(span, &format!("unknown macro transparency: `{}`", value)) + diag.span_err(span, &format!("unknown macro transparency: `{}`", value)); } Some(TransparencyError::MultipleTransparencyAttrs(old_span, new_span)) => { - diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes") + diag.span_err(vec![old_span, new_span], "multiple macro transparency attributes"); } None => {} } @@ -617,7 +617,9 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool { fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool { match *rhs { mbe::TokenTree::Delimited(..) => return true, - _ => sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"), + _ => { + sess.span_diagnostic.span_err(rhs.span(), "macro rhs must be delimited"); + } } false } diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index aefbec0e518fa..a5afb7aa4fa4e 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -31,8 +31,7 @@ impl base::ProcMacro for BangProcMacro { if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } - err.emit(); - ErrorGuaranteed + err.emit() }) } } @@ -58,8 +57,7 @@ impl base::AttrProcMacro for AttrProcMacro { if let Some(s) = e.as_str() { err.help(&format!("message: {}", s)); } - err.emit(); - ErrorGuaranteed + err.emit() }) } } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index ed7ec51d6298b..b13f0b0d3dad8 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -225,12 +225,12 @@ pub fn prepare_session_directory( let crate_dir = match crate_dir.canonicalize() { Ok(v) => v, Err(err) => { - sess.err(&format!( + let reported = sess.err(&format!( "incremental compilation: error canonicalizing path `{}`: {}", crate_dir.display(), err )); - return Err(ErrorGuaranteed); + return Err(reported); } }; @@ -489,14 +489,14 @@ fn create_dir(sess: &Session, path: &Path, dir_tag: &str) -> Result<(), ErrorGua Ok(()) } Err(err) => { - sess.err(&format!( + let reported = sess.err(&format!( "Could not create incremental compilation {} \ directory `{}`: {}", dir_tag, path.display(), err )); - Err(ErrorGuaranteed) + Err(reported) } } } @@ -545,8 +545,7 @@ fn lock_directory( ); } } - err.emit(); - Err(ErrorGuaranteed) + Err(err.emit()) } } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs index 0d6dbd8f34398..7721e00c141d7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/different_lifetimes.rs @@ -147,8 +147,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { self.suggest_adding_lifetime_params(sub, ty_sup, ty_sub, &mut err); - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } fn suggest_adding_lifetime_params( diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs index 4710eae6189a5..467054e318be5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mismatched_static_lifetime.rs @@ -98,7 +98,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let impl_span = self.tcx().def_span(*impl_def_id); err.span_note(impl_span, "...does not necessarily outlive the static lifetime introduced by the compatible `impl`"); } - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index c7bfa686c04dc..df81aea6ef9ec 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -54,10 +54,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { pub fn try_report(&self) -> Option { self.try_report_from_nll() - .map(|mut diag| { - diag.emit(); - ErrorGuaranteed - }) + .map(|mut diag| diag.emit()) .or_else(|| self.try_report_impl_not_conforming_to_trait()) .or_else(|| self.try_report_anon_anon_conflict()) .or_else(|| self.try_report_static_impl_trait()) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 99dd418015b14..4fcdcb6366683 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -84,8 +84,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ), ); if self.find_impl_on_dyn_trait(&mut err, param.param_ty, &ctxt) { - err.emit(); - return Some(ErrorGuaranteed); + let reported = err.emit(); + return Some(reported); } else { err.cancel(); } @@ -276,8 +276,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { Some((param.param_ty_span, param.param_ty.to_string())), ); - err.emit(); - Some(ErrorGuaranteed) + let reported = err.emit(); + Some(reported) } } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 3f0f50bb75af1..b1a42ee66c920 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -33,13 +33,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) = (sub_trace.values.ty(), sup_trace.values.ty(), sub_trace.cause.code()) && sup_expected_found == sub_expected_found { - self.emit_err( + let guar = self.emit_err( var_origin.span(), sub_expected, sub_found, *trait_item_def_id, ); - return Some(ErrorGuaranteed); + return Some(guar); } if let RegionResolutionError::ConcreteFailure(origin, _, _) | RegionResolutionError::GenericBoundFailure(origin, _, _) = error.clone() @@ -49,18 +49,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { trait_item_def_id, } = origin { - self.emit_associated_type_err( + let guar = self.emit_associated_type_err( span, self.infcx.tcx.item_name(impl_item_def_id), impl_item_def_id, trait_item_def_id, ); - return Some(ErrorGuaranteed); + return Some(guar); } None } - fn emit_err(&self, sp: Span, expected: Ty<'tcx>, found: Ty<'tcx>, trait_def_id: DefId) { + fn emit_err( + &self, + sp: Span, + expected: Ty<'tcx>, + found: Ty<'tcx>, + trait_def_id: DefId, + ) -> ErrorGuaranteed { let trait_sp = self.tcx().def_span(trait_def_id); let mut err = self .tcx() @@ -142,7 +148,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { argument, the other inputs and its output", ); } - err.emit(); + err.emit() } fn emit_associated_type_err( @@ -151,7 +157,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { item_name: Symbol, impl_item_def_id: DefId, trait_item_def_id: DefId, - ) { + ) -> ErrorGuaranteed { let impl_sp = self.tcx().def_span(impl_item_def_id); let trait_sp = self.tcx().def_span(trait_item_def_id); let mut err = self @@ -161,7 +167,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_label(impl_sp, "found"); err.span_label(trait_sp, "expected"); - err.emit(); + err.emit() } } diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 0224aba01ef28..5d8cc94e05c29 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -189,7 +189,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.tcx.sess.delay_span_bug( origin.span(), &format!("no region-bound-pairs for {:?}", body_id), - ) + ); } } } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 1aceb4e95e613..4f30e78f5e2aa 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -373,7 +373,7 @@ pub fn configure_and_expand( if recursion_limit_hit { // If we hit a recursion limit, exit early to avoid later passes getting overwhelmed // with a large AST - Err(ErrorGuaranteed) + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) } else { Ok(krate) } @@ -413,7 +413,7 @@ pub fn configure_and_expand( ); msg.warn("The generated documentation may be incorrect"); - msg.emit() + msg.emit(); } else { krate = sess.time("maybe_create_a_macro_crate", || { let is_test_crate = sess.opts.test; @@ -742,29 +742,30 @@ pub fn prepare_outputs( if let Some(ref input_path) = compiler.input_path { if sess.opts.will_create_output_file() { if output_contains_path(&output_paths, input_path) { - sess.err(&format!( + let reported = sess.err(&format!( "the input file \"{}\" would be overwritten by the generated \ executable", input_path.display() )); - return Err(ErrorGuaranteed); + return Err(reported); } if let Some(dir_path) = output_conflicts_with_dir(&output_paths) { - sess.err(&format!( + let reported = sess.err(&format!( "the generated executable for the input file \"{}\" conflicts with the \ existing directory \"{}\"", input_path.display(), dir_path.display() )); - return Err(ErrorGuaranteed); + return Err(reported); } } } if let Some(ref dir) = compiler.temps_dir { if fs::create_dir_all(dir).is_err() { - sess.err("failed to find or create the directory specified by `--temps-dir`"); - return Err(ErrorGuaranteed); + let reported = + sess.err("failed to find or create the directory specified by `--temps-dir`"); + return Err(reported); } } @@ -776,8 +777,9 @@ pub fn prepare_outputs( if !only_dep_info { if let Some(ref dir) = compiler.output_dir { if fs::create_dir_all(dir).is_err() { - sess.err("failed to find or create the directory specified by `--out-dir`"); - return Err(ErrorGuaranteed); + let reported = + sess.err("failed to find or create the directory specified by `--out-dir`"); + return Err(reported); } } } @@ -987,8 +989,8 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // lot of annoying errors in the ui tests (basically, // lint warnings and so on -- kindck used to do this abort, but // kindck is gone now). -nmatsakis - if sess.has_errors() { - return Err(ErrorGuaranteed); + if let Some(reported) = sess.has_errors() { + return Err(reported); } sess.time("misc_checking_3", || { diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index d0e533b457159..6373f4e9af190 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -5,7 +5,6 @@ use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal}; -use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LOCAL_CRATE; use rustc_incremental::DepGraphFuture; use rustc_lint::LintStore; @@ -121,10 +120,8 @@ impl<'tcx> Queries<'tcx> { pub fn parse(&self) -> Result<&Query> { self.parse.compute(|| { - passes::parse(self.session(), &self.compiler.input).map_err(|mut parse_error| { - parse_error.emit(); - ErrorGuaranteed - }) + passes::parse(self.session(), &self.compiler.input) + .map_err(|mut parse_error| parse_error.emit()) }) } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 47de4c9be26fe..50a3df21a3bc9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -157,7 +157,7 @@ impl BoxPointers { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if leaf_ty.is_box() { cx.struct_span_lint(BOX_POINTERS, span, |lint| { - lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit() + lint.build(&format!("type uses owned (Box type) pointers: {}", ty)).emit(); }); } } @@ -318,7 +318,7 @@ impl UnsafeCode { &self, cx: &EarlyContext<'_>, span: Span, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { // This comes from a macro that has `#[allow_internal_unsafe]`. if span.allows_unsafe() { @@ -350,7 +350,7 @@ impl EarlyLintPass for UnsafeCode { macros using unsafe without triggering \ the `unsafe_code` lint at their call site", ) - .emit() + .emit(); }); } } @@ -360,7 +360,7 @@ impl EarlyLintPass for UnsafeCode { // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { self.report_unsafe(cx, blk.span, |lint| { - lint.build("usage of an `unsafe` block").emit() + lint.build("usage of an `unsafe` block").emit(); }); } } @@ -370,12 +370,12 @@ impl EarlyLintPass for UnsafeCode { match it.kind { ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self .report_unsafe(cx, it.span, |lint| { - lint.build("declaration of an `unsafe` trait").emit() + lint.build("declaration of an `unsafe` trait").emit(); }), ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self .report_unsafe(cx, it.span, |lint| { - lint.build("implementation of an `unsafe` trait").emit() + lint.build("implementation of an `unsafe` trait").emit(); }), ast::ItemKind::Fn(..) => { @@ -450,7 +450,9 @@ impl EarlyLintPass for UnsafeCode { FnCtxt::Assoc(_) if body.is_none() => "declaration of an `unsafe` method", FnCtxt::Assoc(_) => "implementation of an `unsafe` method", }; - self.report_unsafe(cx, span, |lint| lint.build(msg).emit()); + self.report_unsafe(cx, span, |lint| { + lint.build(msg).emit(); + }); } } } @@ -559,7 +561,7 @@ impl MissingDoc { MISSING_DOCS, cx.tcx.sess.source_map().guess_head_span(sp), |lint| { - lint.build(&format!("missing documentation for {} {}", article, desc)).emit() + lint.build(&format!("missing documentation for {} {}", article, desc)).emit(); }, ); } @@ -777,7 +779,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { "type could implement `Copy`; consider adding `impl \ Copy`", ) - .emit() + .emit(); }) } } @@ -858,7 +860,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { or a manual implementation", cx.tcx.def_path_str(debug) )) - .emit() + .emit(); }); } } @@ -1278,7 +1280,9 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not { let msg = "transmuting &T to &mut T is undefined behavior, \ even if the reference is unused, consider instead using an UnsafeCell"; - cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| lint.build(msg).emit()); + cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| { + lint.build(msg).emit(); + }); } } @@ -1328,7 +1332,7 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { if let Some(items) = attr.meta_item_list() { for item in items { cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| { - lint.build("unstable feature").emit() + lint.build("unstable feature").emit(); }); } } @@ -1680,7 +1684,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { or lifetime parameters", predicate_kind_name, predicate )) - .emit() + .emit(); }); } } @@ -1915,7 +1919,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems { let attrs = cx.tcx.hir().attrs(it.hir_id()); if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) { cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| { - lint.build("cannot test inner items").emit() + lint.build("cannot test inner items").emit(); }); } } @@ -2040,7 +2044,7 @@ impl KeywordIdents { format!("r#{}", ident), Applicability::MachineApplicable, ) - .emit() + .emit(); }); } } @@ -3055,7 +3059,7 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { "this signature doesn't match the previous declaration", ) .note_expected_found(&"", expected_str, &"", found_str) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index d3c019ad70e3c..882fa4496ca26 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -593,7 +593,7 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), diagnostic: BuiltinLintDiagnostics, ) { self.lookup(lint, span, |lint| { @@ -840,19 +840,23 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ); fn struct_span_lint>( &self, lint: &'static Lint, span: S, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { self.lookup(lint, Some(span), decorate); } /// Emit a lint at the appropriate level, with no associated span. - fn lint(&self, lint: &'static Lint, decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>)) { + fn lint( + &self, + lint: &'static Lint, + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + ) { self.lookup(lint, None as Option, decorate); } } @@ -893,7 +897,7 @@ impl LintContext for LateContext<'_> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let hir_id = self.last_node_with_lint_attrs; @@ -920,7 +924,7 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { self.builder.struct_lint(lint, span.map(|s| s.into()), decorate) } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index e9b7620bf1d7f..7447f9f64b7b1 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -45,7 +45,9 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { self.context.lookup_with_diagnostics( lint_id.lint, Some(span), - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, diagnostic, ); } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 0d790e3820608..99a5720832e88 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -652,7 +652,7 @@ impl<'s> LintLevelsBuilder<'s> { &self, lint: &'static Lint, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level(lint); struct_lint_level(self.sess, lint, level, src, span, decorate) diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 264a80339ccdb..6182d2b10ed5b 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -180,13 +180,13 @@ impl EarlyLintPass for NonAsciiIdents { } has_non_ascii_idents = true; cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| { - lint.build("identifier contains non-ASCII characters").emit() + lint.build("identifier contains non-ASCII characters").emit(); }); if check_uncommon_codepoints && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed) { cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| { - lint.build("identifier contains uncommon Unicode codepoints").emit() + lint.build("identifier contains uncommon Unicode codepoints").emit(); }) } } @@ -337,7 +337,7 @@ impl EarlyLintPass for NonAsciiIdents { let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); note += &char_info; } - lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit() + lint.build(&message).note(¬e).note("please recheck to make sure their usages are indeed what you want").emit(); }); } } diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index 39b5b7afdaef1..5d734fd2ba705 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { let method = &call.ident.name; let message = format!("call to `.{}()` on a reference in this situation does nothing", &method,); - lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit() + lint.build(&message).span_label(span, "unnecessary method call").note(¬e).emit(); }); } } diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 4c7f3482776d7..5b6997bf0eeaf 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -113,7 +113,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { predicate, cx.tcx.def_path_str(needs_drop) ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }); } } @@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { instead using `{}` to detect whether a type is trivially dropped", cx.tcx.def_path_str(needs_drop) ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }); } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index ed5578c754dd5..c95905b9b1851 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -441,7 +441,7 @@ fn lint_uint_literal<'tcx>( min, max, )) - .emit() + .emit(); }); } } @@ -502,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) && !check_limits(cx, binop, &l, &r) { cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| { - lint.build("comparison is useless due to type limits").emit() + lint.build("comparison is useless due to type limits").emit(); }); } } @@ -1382,7 +1382,7 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { larger ({} bytes) than the next largest", largest )) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index abe34a8a39f14..91b72f1d2b17e 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { if !(type_permits_lack_of_use || fn_warned || op_warned) { cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| { - lint.build(&format!("unused result of type `{}`", ty)).emit() + lint.build(&format!("unused result of type `{}`", ty)).emit(); }); } @@ -368,9 +368,9 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { } else { lint.span_help(s.span, "use `drop` to clarify the intent"); } - lint.emit() + lint.emit(); } else { - lint.build("path statement with no effect").emit() + lint.build("path statement with no effect").emit(); } }); } @@ -1111,7 +1111,7 @@ impl UnusedImportBraces { }; cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| { - lint.build(&format!("braces around {} is unnecessary", node_name)).emit() + lint.build(&format!("braces around {} is unnecessary", node_name)).emit(); }); } } @@ -1170,7 +1170,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { "unnecessary allocation, use `&mut` instead" } }; - lint.build(msg).emit() + lint.build(msg).emit(); }); } } diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index f667aec03c577..a9e3b55aeeedf 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -825,11 +825,13 @@ impl<'a> CrateLoader<'a> { for (_, data) in self.cstore.iter_crate_data() { if data.has_global_allocator() { match global_allocator { - Some(other_crate) => self.sess.err(&format!( + Some(other_crate) => { + self.sess.err(&format!( "the `#[global_allocator]` in {} conflicts with global allocator in: {}", other_crate, data.name() - )), + )); + } None => global_allocator = Some(data.name()), } } @@ -864,7 +866,7 @@ impl<'a> CrateLoader<'a> { // don't perform this validation if the session has errors, as one of // those errors may indicate a circular dependency which could cause // this to stack overflow. - if self.sess.has_errors() { + if self.sess.has_errors().is_some() { return; } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index f4bc28f4da199..c3a7611239139 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -145,41 +145,49 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { ("bundle", NativeLibKind::Static { bundle, .. }) => { *bundle = Some(value); } - ("bundle", _) => sess.span_err( - span, - "bundle linking modifier is only compatible with \ + ("bundle", _) => { + sess.span_err( + span, + "bundle linking modifier is only compatible with \ `static` linking kind", - ), + ); + } ("verbatim", _) => lib.verbatim = Some(value), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { *whole_archive = Some(value); } - ("whole-archive", _) => sess.span_err( - span, - "whole-archive linking modifier is only compatible with \ + ("whole-archive", _) => { + sess.span_err( + span, + "whole-archive linking modifier is only compatible with \ `static` linking kind", - ), + ); + } ("as-needed", NativeLibKind::Dylib { as_needed }) | ("as-needed", NativeLibKind::Framework { as_needed }) => { *as_needed = Some(value); } - ("as-needed", _) => sess.span_err( - span, - "as-needed linking modifier is only compatible with \ + ("as-needed", _) => { + sess.span_err( + span, + "as-needed linking modifier is only compatible with \ `dylib` and `framework` linking kinds", - ), + ); + } - _ => sess.span_err( - span, - &format!( - "unrecognized linking modifier `{}`, expected one \ + _ => { + sess.span_err( + span, + &format!( + "unrecognized linking modifier `{}`, expected one \ of: bundle, verbatim, whole-archive, as-needed", - modifier - ), - ), + modifier + ), + ); + } } } } else { @@ -247,7 +255,9 @@ impl Collector<'_> { Some(span) => { struct_span_err!(self.tcx.sess, span, E0455, "{}", msg).emit(); } - None => self.tcx.sess.err(msg), + None => { + self.tcx.sess.err(msg); + } } } if lib.cfg.is_some() && !self.tcx.features().link_cfg { diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 1b301629b9c73..dc1fe5f2b0836 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -2,7 +2,9 @@ use std::cmp; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId}; +use rustc_errors::{ + Diagnostic, DiagnosticBuilder, DiagnosticId, EmissionGuarantee, ErrorGuaranteed, +}; use rustc_hir::HirId; use rustc_index::vec::IndexVec; use rustc_query_system::ich::StableHashingContext; @@ -220,22 +222,28 @@ impl LintExpectation { } } -pub struct LintDiagnosticBuilder<'a>(DiagnosticBuilder<'a, ()>); +pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>); -impl<'a> LintDiagnosticBuilder<'a> { - /// Return the inner DiagnosticBuilder, first setting the primary message to `msg`. - pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, ()> { +impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> { + /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`. + pub fn build(mut self, msg: &str) -> DiagnosticBuilder<'a, G> { self.0.set_primary_message(msg); self.0.set_is_lint(); self.0 } - /// Create a LintDiagnosticBuilder from some existing DiagnosticBuilder. - pub fn new(err: DiagnosticBuilder<'a, ()>) -> LintDiagnosticBuilder<'a> { + /// Create a `LintDiagnosticBuilder` from some existing `DiagnosticBuilder`. + pub fn new(err: DiagnosticBuilder<'a, G>) -> LintDiagnosticBuilder<'a, G> { LintDiagnosticBuilder(err) } } +impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> { + pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> { + LintDiagnosticBuilder(self.0.forget_guarantee()) + } +} + pub fn explain_lint_level_source( sess: &Session, lint: &'static Lint, @@ -316,7 +324,7 @@ pub fn struct_lint_level<'s, 'd>( level: Level, src: LintLevelSource, span: Option, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>) + 'd, + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) + 'd, ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. @@ -326,7 +334,7 @@ pub fn struct_lint_level<'s, 'd>( level: Level, src: LintLevelSource, span: Option, - decorate: Box FnOnce(LintDiagnosticBuilder<'b>) + 'd>, + decorate: Box FnOnce(LintDiagnosticBuilder<'b, ()>) + 'd>, ) { // Check for future incompatibility lints and issue a stronger warning. let future_incompatible = lint.future_incompatible; diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 167a097d9f852..219af6caa1ae1 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -258,7 +258,7 @@ fn late_report_deprecation( let kind = tcx.def_kind(def_id).descr(def_id); deprecation_suggestion(&mut diag, kind, suggestion, method_span); } - diag.emit() + diag.emit(); }); } @@ -483,7 +483,7 @@ impl<'tcx> TyCtxt<'tcx> { ) { let soft_handler = |lint, span, msg: &_| { self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { - lint.build(msg).emit() + lint.build(msg).emit(); }) }; match self.eval_stability(def_id, id, span, method_span) { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 2c3c61259c473..492091a4f2540 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -91,7 +91,7 @@ fn print_backtrace(backtrace: &Backtrace) { impl From for InterpErrorInfo<'_> { fn from(err: ErrorHandled) -> Self { match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(ErrorGuaranteed { .. }) | ErrorHandled::Linted => { err_inval!(ReferencedConstant) } ErrorHandled::TooGeneric => err_inval!(TooGeneric), @@ -160,7 +160,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { match self { TooGeneric => write!(f, "encountered overly generic constant"), ReferencedConstant => write!(f, "referenced constant has errors"), - AlreadyReported(ErrorGuaranteed) => { + AlreadyReported(ErrorGuaranteed { .. }) => { write!(f, "encountered constants with type errors, stopping evaluation") } Layout(ref err) => write!(f, "{}", err), diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 44b622c1e3d86..e07b174bc6aaa 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -252,7 +252,9 @@ rustc_queries! { } /// Fetch the THIR for a given body. If typeck for that body failed, returns an empty `Thir`. - query thir_body(key: ty::WithOptConstParam) -> (&'tcx Steal>, thir::ExprId) { + query thir_body(key: ty::WithOptConstParam) + -> Result<(&'tcx Steal>, thir::ExprId), ErrorGuaranteed> + { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.did.to_def_id()) } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 4ff8e61ee7437..c43ec048c3f99 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -31,12 +31,12 @@ pub struct Graph { pub children: DefIdMap, /// Whether an error was emitted while constructing the graph. - pub has_errored: bool, + pub has_errored: Option, } impl Graph { pub fn new() -> Graph { - Graph { parent: Default::default(), children: Default::default(), has_errored: false } + Graph { parent: Default::default(), children: Default::default(), has_errored: None } } /// The parent of a given impl, which is the `DefId` of the trait when the @@ -246,8 +246,10 @@ pub fn ancestors<'tcx>( ) -> Result, ErrorGuaranteed> { let specialization_graph = tcx.specialization_graph_of(trait_def_id); - if specialization_graph.has_errored || tcx.type_of(start_from_impl).references_error() { - Err(ErrorGuaranteed) + if let Some(reported) = specialization_graph.has_errored { + Err(reported) + } else if let Some(reported) = tcx.type_of(start_from_impl).error_reported() { + Err(reported) } else { Ok(Ancestors { trait_def_id, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index cad77f6436ea2..cb219c4c4e4c9 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::HashingControls; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -453,7 +452,7 @@ impl<'tcx> AdtDef<'tcx> { } Err(err) => { let msg = match err { - ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted => { + ErrorHandled::Reported(_) | ErrorHandled::Linted => { "enum discriminant evaluation failed" } ErrorHandled::TooGeneric => "enum discriminant depends on generics", diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index e72828dd52959..4b7c1d44cea29 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -264,7 +264,7 @@ impl<'tcx> Const<'tcx> { if let Some(val) = self.val().try_eval(tcx, param_env) { match val { Ok(val) => Const::from_value(tcx, val, self.ty()), - Err(ErrorGuaranteed) => tcx.const_error(self.ty()), + Err(ErrorGuaranteed { .. }) => tcx.const_error(self.ty()), } } else { self diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 494535f3d597a..f51e6c2bc1f4d 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -91,7 +91,10 @@ pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { /// except through the error-reporting functions on a [`tcx`][TyCtxt]. #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] #[derive(TyEncodable, TyDecodable, HashStable)] -pub struct DelaySpanBugEmitted(()); +pub struct DelaySpanBugEmitted { + pub reported: ErrorGuaranteed, + _priv: (), +} type InternedSet<'tcx, T> = ShardedHashMap, ()>; @@ -1236,8 +1239,8 @@ impl<'tcx> TyCtxt<'tcx> { /// ensure it gets used. #[track_caller] pub fn ty_error_with_message>(self, span: S, msg: &str) -> Ty<'tcx> { - self.sess.delay_span_bug(span, msg); - self.mk_ty(Error(DelaySpanBugEmitted(()))) + let reported = self.sess.delay_span_bug(span, msg); + self.mk_ty(Error(DelaySpanBugEmitted { reported, _priv: () })) } /// Like [TyCtxt::ty_error] but for constants. @@ -1258,8 +1261,11 @@ impl<'tcx> TyCtxt<'tcx> { span: S, msg: &str, ) -> Const<'tcx> { - self.sess.delay_span_bug(span, msg); - self.mk_const(ty::ConstS { val: ty::ConstKind::Error(DelaySpanBugEmitted(())), ty }) + let reported = self.sess.delay_span_bug(span, msg); + self.mk_const(ty::ConstS { + val: ty::ConstKind::Error(DelaySpanBugEmitted { reported, _priv: () }), + ty, + }) } pub fn consider_optimizing String>(self, msg: T) -> bool { @@ -2733,7 +2739,7 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, hir_id: HirId, span: impl Into, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, hir_id); struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate); @@ -2743,7 +2749,7 @@ impl<'tcx> TyCtxt<'tcx> { self, lint: &'static Lint, id: HirId, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a>), + decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), ) { let (level, src) = self.lint_level_at_node(lint, id); struct_lint_level(self.sess, lint, level, src, None, decorate); diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index 4922d07ae1c5d..780d380da365e 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -51,6 +51,7 @@ //! ``` use crate::mir; use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::FxHashSet; @@ -151,6 +152,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } + fn error_reported(&self) -> Option { + if self.references_error() { + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + } else { + None + } + } fn has_param_types_or_consts(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e12d075efa9b6..ab3dc8f020cc9 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -118,7 +118,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ }; let body = tcx.hir().body(body_id); - let (thir, expr) = tcx.thir_body(def); + let (thir, expr) = tcx + .thir_body(def) + .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))); // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); @@ -229,7 +231,9 @@ fn mir_build(tcx: TyCtxt<'_>, def: ty::WithOptConstParam) -> Body<'_ let return_ty = typeck_results.node_type(id); - let (thir, expr) = tcx.thir_body(def); + let (thir, expr) = tcx + .thir_body(def) + .unwrap_or_else(|_| (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0))); // We ran all queries that depended on THIR at the beginning // of `mir_build`, so now we can steal it let thir = thir.steal(); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index a96bb4e03d97a..122af3f621087 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -405,7 +405,9 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { } else { ty::WithOptConstParam::unknown(closure_id) }; - let (closure_thir, expr) = self.tcx.thir_body(closure_def); + let (closure_thir, expr) = self.tcx.thir_body(closure_def).unwrap_or_else(|_| { + (self.tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)) + }); let closure_thir = &closure_thir.borrow(); let hir_context = self.tcx.hir().local_def_id_to_hir_id(closure_id); let mut closure_visitor = @@ -606,7 +608,10 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam body, + Err(_) => return, + }; let thir = &thir.borrow(); // If `thir` is empty, a type error occurred, skip this body. if thir.exprs.is_empty() { diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index a65a3ed31f638..426596bf13c0a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -7,6 +7,7 @@ use crate::thir::util::UserAnnotatedTyHelpers; use rustc_ast as ast; use rustc_data_structures::steal::Steal; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::HirId; @@ -20,22 +21,25 @@ use rustc_span::Span; crate fn thir_body<'tcx>( tcx: TyCtxt<'tcx>, owner_def: ty::WithOptConstParam, -) -> (&'tcx Steal>, ExprId) { +) -> Result<(&'tcx Steal>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); let body = hir.body(hir.body_owned_by(hir.local_def_id_to_hir_id(owner_def.did))); let mut cx = Cx::new(tcx, owner_def); - if cx.typeck_results.tainted_by_errors.is_some() { - return (tcx.alloc_steal_thir(Thir::new()), ExprId::from_u32(0)); + if let Some(reported) = cx.typeck_results.tainted_by_errors { + return Err(reported); } let expr = cx.mirror_expr(&body.value); - (tcx.alloc_steal_thir(cx.thir), expr) + Ok((tcx.alloc_steal_thir(cx.thir), expr)) } crate fn thir_tree<'tcx>( tcx: TyCtxt<'tcx>, owner_def: ty::WithOptConstParam, ) -> String { - format!("{:#?}", thir_body(tcx, owner_def).0.steal()) + match thir_body(tcx, owner_def) { + Ok((thir, _)) => format!("{:#?}", thir.steal()), + Err(_) => "error".into(), + } } struct Cx<'tcx> { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ae9b44cee4bf8..dd7d4e3e514cd 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -194,7 +194,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } else { debug!( @@ -272,7 +274,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, id, span, - |lint| lint.build("floating-point types cannot be used in patterns").emit(), + |lint| { + lint.build("floating-point types cannot be used in patterns").emit(); + }, ); } PatKind::Constant { value: cv } @@ -284,7 +288,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, msg); } else { - tcx.sess.delay_span_bug(span, msg) + tcx.sess.delay_span_bug(span, msg); } PatKind::Wild } @@ -301,7 +305,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(self.span, &msg); } else { - tcx.sess.delay_span_bug(self.span, &msg) + tcx.sess.delay_span_bug(self.span, &msg); } PatKind::Wild } @@ -331,7 +335,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { cv.ty(), cv.ty(), ); - lint.build(&msg).emit() + lint.build(&msg).emit(); }, ); } @@ -356,7 +360,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -393,7 +397,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -471,7 +475,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| lint.build(&msg).emit(), + |lint| {lint.build(&msg).emit();}, ); } PatKind::Constant { value: cv } @@ -482,7 +486,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } } PatKind::Wild @@ -539,7 +543,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::POINTER_STRUCTURAL_MATCH, id, span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } PatKind::Constant { value: cv } @@ -550,7 +556,7 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if self.include_lint_checks { tcx.sess.span_err(span, &msg); } else { - tcx.sess.delay_span_bug(span, &msg) + tcx.sess.delay_span_bug(span, &msg); } PatKind::Wild } @@ -575,7 +581,9 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH, id, span, - |lint| lint.build(&msg).emit(), + |lint| { + lint.build(&msg).emit(); + }, ); } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 8731669b10958..097a6186cd57a 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -64,7 +64,7 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { place: &Place<'tcx>, const_item: DefId, location: Location, - decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b>) -> DiagnosticBuilder<'b, ()>, + decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) -> DiagnosticBuilder<'b, ()>, ) { // Don't lint on borrowing/assigning when a dereference is involved. // If we 'leave' the temporary via a dereference, we must @@ -88,7 +88,7 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { |lint| { decorate(lint) .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 23d59c8007135..f0367958ef8c5 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -46,7 +46,7 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { does not derive Copy (error E0133)" .to_string() }; - lint.build(&message).emit() + lint.build(&message).emit(); }); } @@ -110,7 +110,7 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { reference with a raw pointer and use `read_unaligned`/`write_unaligned` \ (loads and stores via `*p` must be properly aligned even when using raw pointers)" ) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 34c539f319194..5ed33ab9fec17 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -538,7 +538,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| { let mut err = lint.build(message); err.span_label(source_info.span, format!("{:?}", panic)); - err.emit() + err.emit(); }); } } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index ed771534c4c4c..a9dcc484b9e8d 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -180,7 +180,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; -use rustc_errors::{ErrorGuaranteed, FatalError}; +use rustc_errors::FatalError; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; @@ -716,9 +716,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { match self.tcx.const_eval_resolve(param_env, ct, None) { // The `monomorphize` call should have evaluated that constant already. Ok(val) => val, - Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => { - return; - } + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => return, Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {:?}", @@ -750,7 +748,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { substituted_constant, val ), - Err(ErrorHandled::Reported(ErrorGuaranteed) | ErrorHandled::Linted) => {} + Err(ErrorHandled::Reported(_) | ErrorHandled::Linted) => {} Err(ErrorHandled::TooGeneric) => span_bug!( self.body.source_info(location).span, "collection encountered polymorphic constant: {}", @@ -864,7 +862,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { |lint| { let mut err = lint.build(&format!("moving {} bytes", layout.size.bytes())); err.span_label(source_info.span, "value moved from here"); - err.emit() + err.emit(); }, ); } diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index c7d166319eac8..bec4561928cc2 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -202,7 +202,7 @@ pub(crate) fn emit_unescape_error( diag.emit(); } EscapeError::TooShortHexEscape => { - handler.span_err(span, "numeric character escape is too short") + handler.span_err(span, "numeric character escape is too short"); } EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index b582f060395c3..4d5c552b81bb1 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -212,10 +212,10 @@ impl<'a> Parser<'a> { if let Err(mut e) = self.expect_semi() { match tree.kind { UseTreeKind::Glob => { - e.note("the wildcard token must be last on the path").emit(); + e.note("the wildcard token must be last on the path"); } UseTreeKind::Nested(..) => { - e.note("glob-like brace syntax must be last on the path").emit(); + e.note("glob-like brace syntax must be last on the path"); } _ => (), } @@ -1485,7 +1485,7 @@ impl<'a> Parser<'a> { // Make sure an error was emitted (either by recovering an angle bracket, // or by finding an identifier as the next token), since we're // going to continue parsing - assert!(self.sess.span_diagnostic.has_errors()); + assert!(self.sess.span_diagnostic.has_errors().is_some()); } else { return Err(err); } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 06184b4797255..ebf6678d3ad37 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -169,7 +169,7 @@ impl CheckAttrVisitor<'_> { } ast::AttrStyle::Inner => "crate-level attribute should be in the root module", }; - lint.build(msg).emit() + lint.build(msg).emit(); }); } } @@ -236,7 +236,7 @@ impl CheckAttrVisitor<'_> { | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, Target::Method(MethodKind::Trait { body: false }) | Target::ForeignFn => { self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build("`#[inline]` is ignored on function prototypes").emit() + lint.build("`#[inline]` is ignored on function prototypes").emit(); }); true } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index ea99a90e937c3..7298aba7e8763 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1588,7 +1588,7 @@ impl<'tcx> Liveness<'_, 'tcx> { shorthands, Applicability::MachineApplicable, ); - err.emit() + err.emit(); }, ); } else { @@ -1611,7 +1611,7 @@ impl<'tcx> Liveness<'_, 'tcx> { non_shorthands, Applicability::MachineApplicable, ); - err.emit() + err.emit(); }, ); } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index f36a1f61aaccb..09be1dac6f163 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -128,7 +128,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { String::new(), rustc_errors::Applicability::MachineApplicable, ) - .emit() + .emit(); }); } @@ -728,10 +728,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), span, - |lint| lint + |lint| {lint .build("an `#[unstable]` annotation here has no effect") .note("see issue #55436 for more information") - .emit() + .emit();} ); } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index fdda77d01b3fe..1f286d557ca0b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1742,7 +1742,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { descr, self.tcx.crate_name(def_id.krate) )) - .emit() + .emit(); }, ); } @@ -1786,7 +1786,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { lint::builtin::PRIVATE_IN_PUBLIC, hir_id, span, - |lint| lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(), + |lint| { + lint.build(&format!("{} (error {})", make_msg(), err_code)).emit(); + }, ); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 8dec28c8ae283..1394f4083d0b9 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1997,7 +1997,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { Vec::new(), &[], ); - db.emit() + db.emit(); }, ); } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 1997f2133ed00..7e743481a51fc 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -3143,10 +3143,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { for bound in lifetime_i.bounds { match bound { hir::GenericBound::Outlives(ref lt) => match lt.name { - hir::LifetimeName::Underscore => self.tcx.sess.delay_span_bug( - lt.span, - "use of `'_` in illegal place, but not caught by lowering", - ), + hir::LifetimeName::Underscore => { + self.tcx.sess.delay_span_bug( + lt.span, + "use of `'_` in illegal place, but not caught by lowering", + ); + } hir::LifetimeName::Static => { self.insert_lifetime(lt, Region::Static); self.tcx @@ -3172,7 +3174,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { lt.span, "lowering generated `ImplicitObjectLifetimeDefault` \ outside of an object type", - ) + ); } hir::LifetimeName::Error => { // No need to do anything, error already reported. diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index bca19e84cf875..7f696da86f20e 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -100,7 +100,7 @@ pub fn validate_crate_name(sess: &Session, s: &str, sp: Option) { match sp { Some(sp) => sess.span_err(sp, s), None => sess.err(s), - } + }; err_count += 1; }; if s.is_empty() { diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index eabebfcf3eae5..7eeb6f90f99d9 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -262,7 +262,7 @@ impl Session { } diag.emit(); // If we should err, make sure we did. - if must_err && !self.has_errors() { + if must_err && !self.has_errors().is_some() { // We have skipped a feature gate, and not run into other errors... reject. self.err( "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature \ @@ -404,13 +404,13 @@ impl Session { self.span_err(sp, msg); } } - pub fn span_err>(&self, sp: S, msg: &str) { + pub fn span_err>(&self, sp: S, msg: &str) -> ErrorGuaranteed { self.diagnostic().span_err(sp, msg) } pub fn span_err_with_code>(&self, sp: S, msg: &str, code: DiagnosticId) { self.diagnostic().span_err_with_code(sp, &msg, code) } - pub fn err(&self, msg: &str) { + pub fn err(&self, msg: &str) -> ErrorGuaranteed { self.diagnostic().err(msg) } pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) -> ErrorGuaranteed { @@ -420,7 +420,7 @@ impl Session { pub fn err_count(&self) -> usize { self.diagnostic().err_count() } - pub fn has_errors(&self) -> bool { + pub fn has_errors(&self) -> Option { self.diagnostic().has_errors() } pub fn has_errors_or_delayed_span_bugs(&self) -> bool { @@ -430,9 +430,9 @@ impl Session { self.diagnostic().abort_if_errors(); } pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> { - if self.diagnostic().has_errors_or_lint_errors() { - self.diagnostic().emit_stashed_diagnostics(); - Err(ErrorGuaranteed) + if let Some(reported) = self.diagnostic().has_errors_or_lint_errors() { + let _ = self.diagnostic().emit_stashed_diagnostics(); + Err(reported) } else { Ok(()) } @@ -444,7 +444,11 @@ impl Session { { let old_count = self.err_count(); let result = f(); - if self.err_count() == old_count { Ok(result) } else { Err(ErrorGuaranteed) } + if self.err_count() == old_count { + Ok(result) + } else { + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + } } pub fn span_warn>(&self, sp: S, msg: &str) { self.diagnostic().span_warn(sp, msg) @@ -457,7 +461,7 @@ impl Session { } /// Delay a span_bug() call until abort_if_errors() #[track_caller] - pub fn delay_span_bug>(&self, sp: S, msg: &str) { + pub fn delay_span_bug>(&self, sp: S, msg: &str) -> ErrorGuaranteed { self.diagnostic().delay_span_bug(sp, msg) } @@ -1387,12 +1391,18 @@ fn validate_commandline_args_with_session_available(sess: &Session) { let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers; match unsupported_sanitizers.into_iter().count() { 0 => {} - 1 => sess - .err(&format!("{} sanitizer is not supported for this target", unsupported_sanitizers)), - _ => sess.err(&format!( - "{} sanitizers are not supported for this target", - unsupported_sanitizers - )), + 1 => { + sess.err(&format!( + "{} sanitizer is not supported for this target", + unsupported_sanitizers + )); + } + _ => { + sess.err(&format!( + "{} sanitizers are not supported for this target", + unsupported_sanitizers + )); + } } // Cannot mix and match sanitizers. let mut sanitizer_iter = sess.opts.debugging_opts.sanitizer.into_iter(); @@ -1446,7 +1456,7 @@ pub enum IncrCompSession { InvalidBecauseOfErrors { session_directory: PathBuf }, } -pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) { +pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) -> ErrorGuaranteed { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -1457,7 +1467,8 @@ pub fn early_error_no_abort(output: config::ErrorOutputType, msg: &str) { } }; let handler = rustc_errors::Handler::with_emitter(true, None, emitter); - handler.struct_fatal(msg).emit(); + let reported = handler.struct_fatal(msg).emit(); + reported } pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! { diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 3e0c8234edafb..a607fb6c1b87c 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -51,7 +51,7 @@ pub fn codegen_fulfill_obligation<'tcx>( // leading to an ambiguous result. So report this as an // overflow bug, since I believe this is the only case // where ambiguity can result. - infcx.tcx.sess.delay_span_bug( + let reported = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "encountered ambiguity selecting `{:?}` during codegen, presuming due to \ @@ -59,21 +59,21 @@ pub fn codegen_fulfill_obligation<'tcx>( trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(reported); } Err(Unimplemented) => { // This can trigger when we probe for the source of a `'static` lifetime requirement // on a trait object: `impl Foo for dyn Trait {}` has an implicit `'static` bound. // This can also trigger when we have a global bound that is not actually satisfied, // but was included during typeck due to the trivial_bounds feature. - infcx.tcx.sess.delay_span_bug( + let guar = infcx.tcx.sess.delay_span_bug( rustc_span::DUMMY_SP, &format!( "Encountered error `Unimplemented` selecting `{:?}` during codegen", trait_ref ), ); - return Err(ErrorGuaranteed); + return Err(guar); } Err(e) => { bug!("Encountered error `{:?}` selecting `{:?}` during codegen", e, trait_ref) diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index f880b28b3c8dc..40a39c4cfc2e3 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir; use rustc_middle::thir::abstract_const::{self, Node, NodeId, NotConstEvaluatable}; use rustc_middle::ty::subst::{Subst, SubstsRef}; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, DelaySpanBugEmitted, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::Span; @@ -177,8 +177,9 @@ pub fn is_const_evaluatable<'cx, 'tcx>( false => NotConstEvaluatable::MentionsParam, }), Err(ErrorHandled::Linted) => { - infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); - Err(NotConstEvaluatable::Error(ErrorGuaranteed)) + let reported = + infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); + Err(NotConstEvaluatable::Error(reported)) } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => Ok(()), @@ -244,7 +245,7 @@ impl<'tcx> AbstractConst<'tcx> { ) -> Result>, ErrorGuaranteed> { match ct.val() { ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()), - ty::ConstKind::Error(_) => Err(ErrorGuaranteed), + ty::ConstKind::Error(DelaySpanBugEmitted { reported, .. }) => Err(reported), _ => Ok(None), } } @@ -280,17 +281,19 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { } fn error(&mut self, span: Span, msg: &str) -> Result { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) .help("consider moving this anonymous constant into a `const` function") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn maybe_supported_error(&mut self, span: Span, msg: &str) -> Result { - self.tcx + let reported = self + .tcx .sess .struct_span_err(self.root_span(), "overly complex generic constant") .span_label(span, msg) @@ -298,7 +301,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { .note("this operation may be supported in the future") .emit(); - Err(ErrorGuaranteed) + Err(reported) } fn new( @@ -553,11 +556,7 @@ pub(super) fn thir_abstract_const<'tcx>( _ => return Ok(None), } - let body = tcx.thir_body(def); - if body.0.borrow().exprs.is_empty() { - // type error in constant, there is no thir - return Err(ErrorGuaranteed); - } + let body = tcx.thir_body(def)?; AbstractConstBuilder::new(tcx, (&*body.0.borrow(), body.1))? .map(AbstractConstBuilder::build) @@ -580,7 +579,7 @@ pub(super) fn try_unify_abstract_consts<'tcx>( Ok(false) })() - .unwrap_or_else(|ErrorGuaranteed| true) + .unwrap_or_else(|_: ErrorGuaranteed| true) // FIXME(generic_const_exprs): We should instead have this // method return the resulting `ty::Const` and return `ConstKind::Error` // on `ErrorGuaranteed`. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 55201d17f714d..229e108d5d640 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -63,7 +63,7 @@ pub trait InferCtxtExt<'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option, fallback_has_occurred: bool, - ); + ) -> ErrorGuaranteed; fn report_overflow_error( &self, @@ -111,7 +111,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { errors: &[FulfillmentError<'tcx>], body_id: Option, fallback_has_occurred: bool, - ) { + ) -> ErrorGuaranteed { #[derive(Debug)] struct ErrorDescriptor<'tcx> { predicate: ty::Predicate<'tcx>, @@ -190,6 +190,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { self.report_fulfillment_error(error, body_id, fallback_has_occurred); } } + + self.tcx.sess.delay_span_bug(DUMMY_SP, "expected fullfillment errors") } /// Reports that an overflow has occurred and halts compilation. We @@ -312,7 +314,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let predicate_is_const = ty::BoundConstness::ConstIfConst == trait_predicate.skip_binder().constness; - if self.tcx.sess.has_errors() && trait_predicate.references_error() { + if self.tcx.sess.has_errors().is_some() + && trait_predicate.references_error() + { return; } let trait_ref = trait_predicate.to_poly_trait_ref(); @@ -919,7 +923,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } // Already reported in the query. - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(ErrorGuaranteed)) => { + SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(_)) => { // FIXME(eddyb) remove this once `ErrorGuaranteed` becomes a proof token. self.tcx.sess.delay_span_bug(span, "`ErrorGuaranteed` without an error"); return; @@ -1857,7 +1861,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Same hacky approach as above to avoid deluging user // with error messages. if arg.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; @@ -1868,7 +1872,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { ty::PredicateKind::Subtype(data) => { if data.references_error() - || self.tcx.sess.has_errors() + || self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { // no need to overload user in such cases @@ -1910,7 +1914,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { } _ => { - if self.tcx.sess.has_errors() || self.is_tainted_by_errors() { + if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { return; } let mut err = struct_span_err!( diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 62c6c8454797a..9ac8dc59a1d1e 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::obligation_forest::ProcessResult; use rustc_data_structures::obligation_forest::{Error, ForestObligation, Outcome}; use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor}; -use rustc_errors::ErrorGuaranteed; use rustc_infer::traits::ProjectionCacheKey; use rustc_infer::traits::{SelectionError, TraitEngine, TraitEngineExt as _, TraitObligation}; use rustc_middle::mir::interpret::ErrorHandled; @@ -630,14 +629,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { ), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => { - ProcessResult::Error(CodeSelectionError( - SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error( - ErrorGuaranteed, - )), - )) - } + (Err(ErrorHandled::Reported(reported)), _) + | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( + CodeSelectionError(SelectionError::NotConstEvaluatable( + NotConstEvaluatable::Error(reported), + )), + ), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.selcx.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index bf94c61e6c2ce..a1efeb0b06b9b 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -231,8 +231,8 @@ fn do_normalize_predicates<'tcx>( match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) { Ok(predicates) => predicates, Err(errors) => { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } }; @@ -258,13 +258,15 @@ fn do_normalize_predicates<'tcx>( // represents a legitimate failure due to some kind of // unconstrained variable, and it seems better not to ICE, // all things considered. - tcx.sess.span_err(span, &fixup_err.to_string()); - return Err(ErrorGuaranteed); + let reported = tcx.sess.span_err(span, &fixup_err.to_string()); + return Err(reported); } }; if predicates.needs_infer() { - tcx.sess.delay_span_bug(span, "encountered inference variables after `fully_resolve`"); - Err(ErrorGuaranteed) + let reported = tcx + .sess + .delay_span_bug(span, "encountered inference variables after `fully_resolve`"); + Err(reported) } else { Ok(predicates) } diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs index 2f697c1fa27b7..38be28c07ff18 100644 --- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, GenericParamDefKind, TyCtxt}; use rustc_parse_format::{ParseMode, Parser, Piece, Position}; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; #[derive(Clone, Debug)] pub struct OnUnimplementedFormatString(Symbol); @@ -47,8 +47,7 @@ fn parse_error( if let Some(note) = note { diag.note(note); } - diag.emit(); - ErrorGuaranteed + diag.emit() } impl<'tcx> OnUnimplementedDirective { @@ -59,7 +58,7 @@ impl<'tcx> OnUnimplementedDirective { span: Span, is_root: bool, ) -> Result { - let mut errored = false; + let mut errored = None; let mut item_iter = items.iter(); let parse_value = |value_str| { @@ -91,8 +90,8 @@ impl<'tcx> OnUnimplementedDirective { ) })?; attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| { - if let Some(symbol) = item.value_str() && parse_value(symbol).is_err() { - errored = true; + if let Some(symbol) = item.value_str() && let Err(guar) = parse_value(symbol) { + errored = Some(guar); } true }); @@ -134,13 +133,10 @@ impl<'tcx> OnUnimplementedDirective { && note.is_none() { if let Some(items) = item.meta_item_list() { - if let Ok(subcommand) = - Self::parse(tcx, item_def_id, &items, item.span(), false) - { - subcommands.push(subcommand); - } else { - errored = true; - } + match Self::parse(tcx, item_def_id, &items, item.span(), false) { + Ok(subcommand) => subcommands.push(subcommand), + Err(reported) => errored = Some(reported), + }; continue; } } else if item.has_name(sym::append_const_msg) && append_const_msg.is_none() { @@ -163,8 +159,8 @@ impl<'tcx> OnUnimplementedDirective { ); } - if errored { - Err(ErrorGuaranteed) + if let Some(reported) = errored { + Err(reported) } else { Ok(OnUnimplementedDirective { condition, @@ -203,7 +199,9 @@ impl<'tcx> OnUnimplementedDirective { append_const_msg: None, })) } else { - return Err(ErrorGuaranteed); + let reported = + tcx.sess.delay_span_bug(DUMMY_SP, "of_item: neither meta_item_list nor value_str"); + return Err(reported); }; debug!("of_item({:?}) = {:?}", item_def_id, result); result @@ -327,7 +325,7 @@ impl<'tcx> OnUnimplementedFormatString { match generics.params.iter().find(|param| param.name == s) { Some(_) => (), None => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0230, @@ -340,20 +338,20 @@ impl<'tcx> OnUnimplementedFormatString { } ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } } } // `{:1}` and `{}` are not to be used Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => { - struct_span_err!( + let reported = struct_span_err!( tcx.sess, span, E0231, "only named substitution parameters are allowed" ) .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } }, } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 11f0507d6fd61..614a5e0480997 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1396,7 +1396,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // `rustc_ty_utils::instance::resolve_associated_item()`. let node_item = assoc_def(selcx, impl_data.impl_def_id, obligation.predicate.item_def_id) - .map_err(|ErrorGuaranteed| ())?; + .map_err(|ErrorGuaranteed { .. }| ())?; if node_item.is_final() { // Non-specializable items are always projectable. diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8af4606db8520..cf929ee3cc056 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -29,7 +29,7 @@ use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{Diagnostic, ErrorGuaranteed}; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; @@ -674,8 +674,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Err(_) => Ok(EvaluatedToErr), } } - (Err(ErrorHandled::Reported(ErrorGuaranteed)), _) - | (_, Err(ErrorHandled::Reported(ErrorGuaranteed))) => Ok(EvaluatedToErr), + (Err(ErrorHandled::Reported(_)), _) + | (_, Err(ErrorHandled::Reported(_))) => Ok(EvaluatedToErr), (Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => { span_bug!( obligation.cause.span(self.tcx()), diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index a8a53c297d1a4..79471065ccc67 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -16,14 +16,14 @@ use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine}; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::lint::LintDiagnosticBuilder; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK; use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use super::util::impl_trait_ref_and_oblig; use super::{FulfillmentContext, SelectionContext}; @@ -377,8 +377,7 @@ fn report_negative_positive_conflict( } } - sg.has_errored = true; - err.emit(); + sg.has_errored = Some(err.emit()); } fn report_conflicting_impls( @@ -394,7 +393,13 @@ fn report_conflicting_impls( // Work to be done after we've built the DiagnosticBuilder. We have to define it // now because the struct_lint methods don't return back the DiagnosticBuilder // that's passed in. - let decorate = |err: LintDiagnosticBuilder<'_>| { + fn decorate( + tcx: TyCtxt<'_>, + overlap: OverlapError, + used_to_be_allowed: Option, + impl_span: Span, + err: LintDiagnosticBuilder<'_, G>, + ) -> G { let msg = format!( "conflicting implementations of trait `{}`{}{}", overlap.trait_desc, @@ -440,17 +445,25 @@ fn report_conflicting_impls( coherence::add_placeholder_note(&mut err); } err.emit() - }; + } match used_to_be_allowed { None => { - sg.has_errored = true; - if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) { + let reported = if overlap.with_impl.is_local() + || !tcx.orphan_check_crate(()).contains(&impl_def_id) + { let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); - decorate(LintDiagnosticBuilder::new(err.forget_guarantee())); + Some(decorate( + tcx, + overlap, + used_to_be_allowed, + impl_span, + LintDiagnosticBuilder::new(err), + )) } else { - tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"); - } + Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) + }; + sg.has_errored = reported; } Some(kind) => { let lint = match kind { @@ -461,8 +474,10 @@ fn report_conflicting_impls( lint, tcx.hir().local_def_id_to_hir_id(impl_def_id), impl_span, - decorate, - ) + |ldb| { + decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb); + }, + ); } }; } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 41467ce2f622f..295a91959eb19 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -306,9 +306,9 @@ fn resolve_associated_item<'tcx>( resolved_ty, ); let span = tcx.def_span(leaf_def.item.def_id); - tcx.sess.delay_span_bug(span, &msg); + let reported = tcx.sess.delay_span_bug(span, &msg); - return Err(ErrorGuaranteed); + return Err(reported); } } diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs index 7e9abe3a250db..5f01559226c77 100644 --- a/compiler/rustc_typeck/src/astconv/errors.rs +++ b/compiler/rustc_typeck/src/astconv/errors.rs @@ -1,6 +1,6 @@ use crate::astconv::AstConv; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{pluralize, struct_span_err, Applicability}; +use rustc_errors::{pluralize, struct_span_err, Applicability, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty; @@ -195,7 +195,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty_param_name: &str, assoc_name: Ident, span: Span, - ) where + ) -> ErrorGuaranteed + where I: Iterator>, { // The fallback span is needed because `assoc_name` might be an `Fn()`'s `Output` without a @@ -231,7 +232,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label(span, format!("associated type `{}` not found", assoc_name)); } - err.emit(); + err.emit() } /// When there are any missing associated types, emit an E0191 error and attempt to supply a diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index e8b64587eeea6..d56c521d23d32 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -6,7 +6,7 @@ use crate::astconv::{ use crate::errors::AssocTypeBindingNotAllowed; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use rustc_ast::ast::ParamKindOrd; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; +use rustc_errors::{struct_span_err, Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; @@ -456,51 +456,55 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let mut invalid_args = vec![]; - let mut check_lifetime_args = |min_expected_args: usize, - max_expected_args: usize, - provided_args: usize, - late_bounds_ignore: bool| - -> bool { - if (min_expected_args..=max_expected_args).contains(&provided_args) { - return true; - } + let mut check_lifetime_args = + |min_expected_args: usize, + max_expected_args: usize, + provided_args: usize, + late_bounds_ignore: bool| { + if (min_expected_args..=max_expected_args).contains(&provided_args) { + return Ok(()); + } - if late_bounds_ignore { - return true; - } + if late_bounds_ignore { + return Ok(()); + } - if provided_args > max_expected_args { - invalid_args.extend( - gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()), - ); - }; + if provided_args > max_expected_args { + invalid_args.extend( + gen_args.args[max_expected_args..provided_args] + .iter() + .map(|arg| arg.span()), + ); + }; - let gen_args_info = if provided_args > min_expected_args { - invalid_args.extend( - gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()), - ); - let num_redundant_args = provided_args - min_expected_args; - GenericArgsInfo::ExcessLifetimes { num_redundant_args } - } else { - let num_missing_args = min_expected_args - provided_args; - GenericArgsInfo::MissingLifetimes { num_missing_args } + let gen_args_info = if provided_args > min_expected_args { + invalid_args.extend( + gen_args.args[min_expected_args..provided_args] + .iter() + .map(|arg| arg.span()), + ); + let num_redundant_args = provided_args - min_expected_args; + GenericArgsInfo::ExcessLifetimes { num_redundant_args } + } else { + let num_missing_args = min_expected_args - provided_args; + GenericArgsInfo::MissingLifetimes { num_missing_args } + }; + + let reported = WrongNumberOfGenericArgs::new( + tcx, + gen_args_info, + seg, + gen_params, + has_self as usize, + gen_args, + def_id, + ) + .diagnostic() + .emit(); + + Err(reported) }; - WrongNumberOfGenericArgs::new( - tcx, - gen_args_info, - seg, - gen_params, - has_self as usize, - gen_args, - def_id, - ) - .diagnostic() - .emit(); - - false - }; - let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes }; let max_expected_lifetime_args = param_counts.lifetimes; let num_provided_lifetime_args = gen_args.num_lifetime_params(); @@ -527,7 +531,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "check_types_and_consts" ); if (expected_min..=expected_max).contains(&provided) { - return true; + return Ok(()); } let num_default_params = expected_max - expected_min; @@ -561,7 +565,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?gen_args_info); - WrongNumberOfGenericArgs::new( + let reported = WrongNumberOfGenericArgs::new( tcx, gen_args_info, seg, @@ -573,7 +577,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .diagnostic() .emit_unless(gen_args.has_err()); - false + Err(reported) }; let args_correct = { @@ -599,11 +603,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { GenericArgCountResult { explicit_late_bound, - correct: if lifetimes_correct && args_correct { - Ok(()) - } else { - Err(GenericArgCountMismatch { reported: Some(ErrorGuaranteed), invalid_args }) - }, + correct: lifetimes_correct.and(args_correct).map_err(|reported| { + GenericArgCountMismatch { reported: Some(reported), invalid_args } + }), } } @@ -700,7 +702,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), multispan, - |lint| lint.build(msg).emit(), + |lint| { + lint.build(msg).emit(); + }, ); } diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 144953caa4c3b..b04d304d2ca15 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1570,7 +1570,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { type_str: &str, trait_str: &str, name: Symbol, - ) { + ) -> ErrorGuaranteed { let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type"); if let (true, Ok(snippet)) = ( self.tcx() @@ -1594,7 +1594,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Applicability::HasPlaceholders, ); } - err.emit(); + err.emit() } // Search for a bound on a type parameter which includes the associated item @@ -1661,13 +1661,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { (Some(bound), _) => (bound, matching_candidates.next()), (None, Some(bound)) => (bound, const_candidates.next()), (None, None) => { - self.complain_about_assoc_type_not_found( + let reported = self.complain_about_assoc_type_not_found( all_candidates, &ty_param_name(), assoc_name, span, ); - return Err(ErrorGuaranteed); + return Err(reported); } }; debug!("one_bound_for_assoc_type: bound = {:?}", bound); @@ -1752,9 +1752,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { where_bounds.join(",\n"), )); } - err.emit(); + let reported = err.emit(); if !where_bounds.is_empty() { - return Err(ErrorGuaranteed); + return Err(reported); } } @@ -1811,7 +1811,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { // A cycle error occurred, most likely. - return Err(ErrorGuaranteed); + let guar = tcx.sess.delay_span_bug(span, "expected cycle error"); + return Err(guar); }; self.one_bound_for_assoc_type( @@ -1828,10 +1829,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | Res::Def(DefKind::TyParam, param_did), ) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?, _ => { - if variant_resolution.is_some() { + let reported = if variant_resolution.is_some() { // Variant in type position let msg = format!("expected type, found variant `{}`", assoc_ident); - tcx.sess.span_err(span, &msg); + tcx.sess.span_err(span, &msg) } else if qself_ty.is_enum() { let mut err = struct_span_err!( tcx.sess, @@ -1870,17 +1871,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.span_label(sp, format!("variant `{}` not found here", assoc_ident)); } - err.emit(); - } else if !qself_ty.references_error() { + err.emit() + } else if let Some(reported) = qself_ty.error_reported() { + reported + } else { // Don't print `TyErr` to the user. self.report_ambiguous_associated_type( span, &qself_ty.to_string(), "Trait", assoc_ident.name, - ); - } - return Err(ErrorGuaranteed); + ) + }; + return Err(reported); } }; @@ -1898,8 +1901,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // but it was used in a type position. let Some(item) = item else { let msg = format!("found associated const `{assoc_ident}` when type was expected"); - tcx.sess.struct_span_err(span, &msg).emit(); - return Err(ErrorGuaranteed); + let guar = tcx.sess.struct_span_err(span, &msg).emit(); + return Err(guar); }; let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound); @@ -2737,7 +2740,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { sugg, Applicability::MachineApplicable, ) - .emit() + .emit(); }, ); } diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index d3e9820834ab9..7ce428ea12466 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -91,8 +91,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let t = self.resolve_vars_if_possible(t); - if t.references_error() { - return Err(ErrorGuaranteed); + if let Some(reported) = t.error_reported() { + return Err(reported); } if self.type_is_known_to_be_sized_modulo_regions(t, span) { @@ -139,10 +139,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Adt(..) | ty::Never | ty::Error(_) => { - self.tcx + let reported = self + .tcx .sess .delay_span_bug(span, &format!("`{:?}` should be sized but is not?", t)); - return Err(ErrorGuaranteed); + return Err(reported); } }) } @@ -174,7 +175,7 @@ pub enum CastError { } impl From for CastError { - fn from(ErrorGuaranteed: ErrorGuaranteed) -> Self { + fn from(_: ErrorGuaranteed) -> Self { CastError::ErrorGuaranteed } } @@ -213,8 +214,8 @@ impl<'a, 'tcx> CastCheck<'tcx> { // inference is more completely known. match cast_ty.kind() { ty::Dynamic(..) | ty::Slice(..) => { - check.report_cast_to_unsized_type(fcx); - Err(ErrorGuaranteed) + let reported = check.report_cast_to_unsized_type(fcx); + Err(reported) } _ => Ok(check), } @@ -588,9 +589,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { } } - fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) { - if self.cast_ty.references_error() || self.expr_ty.references_error() { - return; + fn report_cast_to_unsized_type(&self, fcx: &FnCtxt<'a, 'tcx>) -> ErrorGuaranteed { + if let Some(reported) = + self.cast_ty.error_reported().or_else(|| self.expr_ty.error_reported()) + { + return reported; } let tstr = fcx.ty_to_string(self.cast_ty); @@ -651,7 +654,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.span_help(self.expr.span, "consider using a box or reference as appropriate"); } } - err.emit(); + err.emit() } fn trivial_cast_lint(&self, fcx: &FnCtxt<'a, 'tcx>) { diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 9016a8ffe9add..e57d55fdc2377 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -49,7 +49,7 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab } None => { tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.build("use of calling convention not supported on this target").emit() + lint.build("use of calling convention not supported on this target").emit(); }); } } @@ -136,7 +136,7 @@ pub(super) fn check_fn<'a, 'tcx>( }; if let Some(header) = item { - tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple") + tcx.sess.span_err(header.span, "functions with the \"rust-call\" ABI must take a single non-self argument that is a tuple"); } }; @@ -625,11 +625,11 @@ pub(super) fn check_opaque_for_cycles<'tcx>( origin: &hir::OpaqueTyOrigin, ) -> Result<(), ErrorGuaranteed> { if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() { - match origin { + let reported = match origin { hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span), _ => opaque_type_cycle_error(tcx, def_id, span), - } - Err(ErrorGuaranteed) + }; + Err(reported) } else { Ok(()) } @@ -680,13 +680,15 @@ fn check_opaque_meets_bounds<'tcx>( trace!(?hidden_type); match infcx.at(&misc_cause, param_env).eq(opaque_defn.concrete_ty, hidden_type) { Ok(infer_ok) => inh.register_infer_ok_obligations(infer_ok), - Err(ty_err) => tcx.sess.delay_span_bug( - span, - &format!( - "could not check bounds on revealed type `{}`:\n{}", - hidden_type, ty_err, - ), - ), + Err(ty_err) => { + tcx.sess.delay_span_bug( + span, + &format!( + "could not check bounds on revealed type `{}`:\n{}", + hidden_type, ty_err, + ), + ); + } } } @@ -1422,7 +1424,7 @@ pub(super) fn check_type_params_are_used<'tcx>( if ty.references_error() { // If there is already another error, do not emit // an error for not using a type parameter. - assert!(tcx.sess.has_errors()); + assert!(tcx.sess.has_errors().is_some()); return; } @@ -1463,14 +1465,14 @@ pub(super) use wfcheck::check_trait_item as check_trait_item_well_formed; pub(super) use wfcheck::check_impl_item as check_impl_item_well_formed; -fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) { +fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) -> ErrorGuaranteed { struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing") .span_label(span, "recursive `async fn`") .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") .note( "consider using the `async_recursion` crate: https://crates.io/crates/async_recursion", ) - .emit(); + .emit() } /// Emit an error for recursive opaque types. @@ -1481,7 +1483,7 @@ fn async_opaque_type_cycle_error(tcx: TyCtxt<'_>, span: Span) { /// /// If all the return expressions evaluate to `!`, then we explain that the error will go away /// after changing it. This can happen when a user uses `panic!()` or similar as a placeholder. -fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { +fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> ErrorGuaranteed { let mut err = struct_span_err!(tcx.sess, span, E0720, "cannot resolve opaque type"); let mut label = false; @@ -1550,5 +1552,5 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) { if !label { err.span_label(span, "cannot resolve opaque type"); } - err.emit(); + err.emit() } diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs index d4a473adaf010..f5477f7103cb3 100644 --- a/compiler/rustc_typeck/src/check/compare_method.rs +++ b/compiler/rustc_typeck/src/check/compare_method.rs @@ -41,35 +41,30 @@ crate fn compare_impl_method<'tcx>( let impl_m_span = tcx.sess.source_map().guess_head_span(impl_m_span); - if let Err(ErrorGuaranteed) = - compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) - { + if let Err(_) = compare_self_type(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) { return; } - if let Err(ErrorGuaranteed) = - compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) - { + if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) { return; } - if let Err(ErrorGuaranteed) = + if let Err(_) = compare_number_of_method_arguments(tcx, impl_m, impl_m_span, trait_m, trait_item_span) { return; } - if let Err(ErrorGuaranteed) = compare_synthetic_generics(tcx, impl_m, trait_m) { + if let Err(_) = compare_synthetic_generics(tcx, impl_m, trait_m) { return; } - if let Err(ErrorGuaranteed) = - compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) + if let Err(_) = compare_predicate_entailment(tcx, impl_m, impl_m_span, trait_m, impl_trait_ref) { return; } - if let Err(ErrorGuaranteed) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) { + if let Err(_) = compare_const_param_types(tcx, impl_m, trait_m, trait_item_span) { return; } } @@ -385,16 +380,16 @@ fn compare_predicate_entailment<'tcx>( &terr, false, ); - diag.emit(); - return Err(ErrorGuaranteed); + + return Err(diag.emit()); } // Check that all obligations are satisfied by the implementation's // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of @@ -450,13 +445,13 @@ fn check_region_bounds_on_impl_item<'tcx>( .map_or(def_sp, |g| g.span) }); - tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait { + let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait { span, item_kind, ident: impl_m.ident(tcx), generics_span, }); - return Err(ErrorGuaranteed); + return Err(reported); } Ok(()) @@ -550,8 +545,8 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } (true, false) => { @@ -570,8 +565,8 @@ fn compare_self_type<'tcx>( } else { err.note_trait_signature(trait_m.name.to_string(), trait_m.signature(tcx)); } - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } } @@ -595,11 +590,9 @@ fn compare_number_of_generics<'tcx>( let item_kind = assoc_item_kind_str(impl_); - let mut err_occurred = false; + let mut err_occurred = None; for (kind, trait_count, impl_count) in matchings { if impl_count != trait_count { - err_occurred = true; - let (trait_spans, impl_trait_spans) = if let Some(def_id) = trait_.def_id.as_local() { let trait_item = tcx.hir().expect_trait_item(def_id); if trait_item.generics.params.is_empty() { @@ -690,11 +683,12 @@ fn compare_number_of_generics<'tcx>( err.span_label(*span, "`impl Trait` introduces an implicit type parameter"); } - err.emit(); + let reported = err.emit(); + err_occurred = Some(reported); } } - if err_occurred { Err(ErrorGuaranteed) } else { Ok(()) } + if let Some(reported) = err_occurred { Err(reported) } else { Ok(()) } } fn compare_number_of_method_arguments<'tcx>( @@ -772,8 +766,8 @@ fn compare_number_of_method_arguments<'tcx>( impl_number_args ), ); - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } Ok(()) @@ -789,7 +783,7 @@ fn compare_synthetic_generics<'tcx>( // 2. Explanation as to what is going on // If we get here, we already have the same number of generics, so the zip will // be okay. - let mut error_found = false; + let mut error_found = None; let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| match param.kind { @@ -918,11 +912,11 @@ fn compare_synthetic_generics<'tcx>( } _ => unreachable!(), } - err.emit(); - error_found = true; + let reported = err.emit(); + error_found = Some(reported); } } - if error_found { Err(ErrorGuaranteed) } else { Ok(()) } + if let Some(reported) = error_found { Err(reported) } else { Ok(()) } } fn compare_const_param_types<'tcx>( @@ -979,8 +973,8 @@ fn compare_const_param_types<'tcx>( trait_ty ), ); - err.emit(); - return Err(ErrorGuaranteed); + let reported = err.emit(); + return Err(reported); } } @@ -1203,8 +1197,8 @@ fn compare_type_predicate_entailment<'tcx>( // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of @@ -1427,8 +1421,8 @@ pub fn check_type_bounds<'tcx>( // version. let errors = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx); if !errors.is_empty() { - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // Finally, resolve all regions. This catches wily misuses of diff --git a/compiler/rustc_typeck/src/check/dropck.rs b/compiler/rustc_typeck/src/check/dropck.rs index 1849ece9f76d9..d38777bea5990 100644 --- a/compiler/rustc_typeck/src/check/dropck.rs +++ b/compiler/rustc_typeck/src/check/dropck.rs @@ -55,11 +55,11 @@ pub fn check_drop_impl(tcx: TyCtxt<'_>, drop_impl_did: DefId) -> Result<(), Erro // already checked by coherence, but compilation may // not have been terminated. let span = tcx.def_span(drop_impl_did); - tcx.sess.delay_span_bug( + let reported = tcx.sess.delay_span_bug( span, &format!("should have been rejected by coherence check: {}", dtor_self_type), ); - Err(ErrorGuaranteed) + Err(reported) } } } @@ -94,7 +94,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( Err(_) => { let item_span = tcx.def_span(self_type_did); let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); - struct_span_err!( + let reported = struct_span_err!( tcx.sess, drop_impl_span, E0366, @@ -109,15 +109,15 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( ), ) .emit(); - return Err(ErrorGuaranteed); + return Err(reported); } } let errors = fulfillment_cx.select_all_or_error(&infcx); if !errors.is_empty() { // this could be reached when we get lazy normalization - infcx.report_fulfillment_errors(&errors, None, false); - return Err(ErrorGuaranteed); + let reported = infcx.report_fulfillment_errors(&errors, None, false); + return Err(reported); } // NB. It seems a bit... suspicious to use an empty param-env @@ -258,7 +258,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) { let item_span = tcx.def_span(self_type_did); let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id()); - struct_span_err!( + let reported = struct_span_err!( tcx.sess, predicate_sp, E0367, @@ -268,7 +268,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( ) .span_note(item_span, "the implementor must specify the same requirement") .emit(); - result = Err(ErrorGuaranteed); + result = Err(reported); } } diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index d944bb7624177..0a720f1502503 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -667,7 +667,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // else an error would have been flagged by the // `loops` pass for using break with an expression // where you are not supposed to. - assert!(expr_opt.is_none() || self.tcx.sess.has_errors()); + assert!(expr_opt.is_none() || self.tcx.sess.has_errors().is_some()); } // If we encountered a `break`, then (no surprise) it may be possible to break from the @@ -1187,7 +1187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_cast_checks.push(cast_check); t_cast } - Err(ErrorGuaranteed) => self.tcx.ty_error(), + Err(_) => self.tcx.ty_error(), } } } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index ed70b85e3f147..e3439a6f1d963 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -315,16 +315,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // FIXME: currently we never try to compose autoderefs // and ReifyFnPointer/UnsafeFnPointer, but we could. - _ => self.tcx.sess.delay_span_bug( - expr.span, - &format!( - "while adjusting {:?}, can't compose {:?} and {:?}", - expr, - entry.get(), - adj - ), - ), - }; + _ => { + self.tcx.sess.delay_span_bug( + expr.span, + &format!( + "while adjusting {:?}, can't compose {:?} and {:?}", + expr, + entry.get(), + adj + ), + ); + } + } *entry.get_mut() = adj; } } @@ -903,7 +905,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .or_else(|error| { let result = match error { method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)), - _ => Err(ErrorGuaranteed), + _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), }; // If we have a path like `MyTrait::missing_method`, then don't register diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index e79085fdad28d..4e1645adca5d3 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -412,7 +412,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - |lint| lint.build("type annotations needed").emit(), + |lint| { + lint.build("type annotations needed").emit(); + }, ); } } else { diff --git a/compiler/rustc_typeck/src/check/writeback.rs b/compiler/rustc_typeck/src/check/writeback.rs index 62f7c382bc90c..16ffabb76a515 100644 --- a/compiler/rustc_typeck/src/check/writeback.rs +++ b/compiler/rustc_typeck/src/check/writeback.rs @@ -81,7 +81,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.is_tainted_by_errors() { // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - wbcx.typeck_results.tainted_by_errors = Some(ErrorGuaranteed); + wbcx.typeck_results.tainted_by_errors = + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results); @@ -662,7 +663,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // users of the typeck results don't produce extra errors, or worse, ICEs. if resolver.replaced_with_error { // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - self.typeck_results.tainted_by_errors = Some(ErrorGuaranteed); + self.typeck_results.tainted_by_errors = + Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); } x @@ -707,7 +709,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_type_error(&self, t: Ty<'tcx>) { - if !self.tcx.sess.has_errors() { + if !self.tcx.sess.has_errors().is_some() { self.infcx .emit_inference_failure_err( Some(self.body.id()), @@ -721,7 +723,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_const_error(&self, c: ty::Const<'tcx>) { - if !self.tcx.sess.has_errors() { + if self.tcx.sess.has_errors().is_none() { self.infcx .emit_inference_failure_err( Some(self.body.id()), diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 5dfd444133a37..4b23cc4db85ba 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -21,7 +21,7 @@ pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] { for &impl_of_trait in impls_of_trait { match orphan_check_impl(tcx, impl_of_trait) { Ok(()) => {} - Err(ErrorGuaranteed) => errors.push(impl_of_trait), + Err(_) => errors.push(impl_of_trait), } } @@ -135,17 +135,19 @@ fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua }; if let Some((msg, label)) = msg { - struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); - return Err(ErrorGuaranteed); + let reported = + struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); + return Err(reported); } } if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() { - tcx.sess + let reported = tcx + .sess .struct_span_err(sp, "cannot implement trait on type alias impl trait") .span_note(tcx.def_span(def_id), "type alias impl trait defined here") .emit(); - return Err(ErrorGuaranteed); + return Err(reported); } Ok(()) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 3247a292242a3..d422f355ad3a4 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -1,4 +1,4 @@ -use rustc_errors::{Applicability, ErrorGuaranteed, StashKey}; +use rustc_errors::{Applicability, StashKey}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -366,7 +366,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { owner, def_id, ), ); - if let Some(ErrorGuaranteed) = + if let Some(_) = tcx.typeck(owner).tainted_by_errors { // Some error in the diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs index be4958ea06276..cb59438e3432f 100644 --- a/compiler/rustc_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_typeck/src/expr_use_visitor.rs @@ -523,7 +523,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if !self.tcx().sess.has_errors() { + if !self.tcx().sess.has_errors().is_some() { span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs index d665b6d068e06..5d4dfd3caefcc 100644 --- a/compiler/rustc_typeck/src/lib.rs +++ b/compiler/rustc_typeck/src/lib.rs @@ -537,7 +537,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { check_unused::check_crate(tcx); check_for_entry_fn(tcx); - if tcx.sess.err_count() == 0 { Ok(()) } else { Err(ErrorGuaranteed) } + if let Some(reported) = tcx.sess.has_errors() { Err(reported) } else { Ok(()) } } /// A quasi-deprecated helper used in rustdoc and clippy to get diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c0e7cd0b1f580..42b7eec5d3aa9 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -834,7 +834,9 @@ impl AttributesExt for [ast::Attribute] { { match Cfg::parse(cfg_mi) { Ok(new_cfg) => cfg &= new_cfg, - Err(e) => sess.span_err(e.span, e.msg), + Err(e) => { + sess.span_err(e.span, e.msg); + } } } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2b82575f71083..bd64e2b03ce0c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -452,7 +452,7 @@ crate fn run_global_ctxt( } } - if tcx.sess.diagnostic().has_errors_or_lint_errors() { + if tcx.sess.diagnostic().has_errors_or_lint_errors().is_some() { rustc_errors::FatalError.raise(); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 728b7720f739d..8db5f8b0cff8b 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -149,7 +149,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { collector }); - if compiler.session().diagnostic().has_errors_or_lint_errors() { + if compiler.session().diagnostic().has_errors_or_lint_errors().is_some() { FatalError.raise(); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f378915172a69..f59222b780d3e 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -179,7 +179,7 @@ pub fn main() { let exit_code = rustc_driver::catch_with_exit_code(|| match get_args() { Some(args) => main_args(&args), - _ => Err(ErrorGuaranteed), + _ => Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()), }); process::exit(exit_code); } @@ -692,7 +692,13 @@ fn main_args(at_args: &[String]) -> MainResult { // codes from `from_matches` here. let options = match config::Options::from_matches(&matches) { Ok(opts) => opts, - Err(code) => return if code == 0 { Ok(()) } else { Err(ErrorGuaranteed) }, + Err(code) => { + return if code == 0 { + Ok(()) + } else { + Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + }; + } }; rustc_interface::util::run_in_thread_pool_with_globals( options.edition, @@ -705,8 +711,8 @@ fn wrap_return(diag: &rustc_errors::Handler, res: Result<(), String>) -> MainRes match res { Ok(()) => Ok(()), Err(err) => { - diag.struct_err(&err).emit(); - Err(ErrorGuaranteed) + let reported = diag.struct_err(&err).emit(); + Err(reported) } } } @@ -790,7 +796,7 @@ fn main_options(options: config::Options) -> MainResult { (resolver.clone(), resolver_caches) }; - if sess.diagnostic().has_errors_or_lint_errors() { + if sess.diagnostic().has_errors_or_lint_errors().is_some() { sess.fatal("Compilation failed, aborting rustdoc"); } diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs index 71fa71750f43a..81f371840ae46 100644 --- a/src/librustdoc/passes/bare_urls.rs +++ b/src/librustdoc/passes/bare_urls.rs @@ -80,7 +80,7 @@ impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> { format!("<{}>", url), Applicability::MachineApplicable, ) - .emit() + .emit(); }); }; diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index c4aa31ad91230..8d9b3377a6986 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { // lambda that will use the lint to start a new diagnostic and add // a suggestion to it when needed. - let diag_builder = |lint: LintDiagnosticBuilder<'_>| { + let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| { let explanation = if is_ignore { "`ignore` code blocks require valid Rust code for syntax highlighting; \ mark blocks that do not contain Rust code as text" diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index f1bb766f467af..2b17e3457d293 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -125,7 +125,9 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, - |lint| lint.build("missing code example in this documentation").emit(), + |lint| { + lint.build("missing code example in this documentation").emit(); + }, ); } } else if tests.found_tests > 0 @@ -135,7 +137,9 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - |lint| lint.build("documentation test in private item").emit(), + |lint| { + lint.build("documentation test in private item").emit(); + }, ); } } diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index ee668501ae78b..802b867a301aa 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass { let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr"); if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) { cx.lint(MISSING_ALLOWED_ATTR, |lint| { - lint.build("Missing 'allowed_attr' attribute").set_span(span).emit() + lint.build("Missing 'allowed_attr' attribute").set_span(span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index e726f8402ef9d..bc153faa8925a 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -34,7 +34,7 @@ macro_rules! fake_lint_pass { if !cx.sess().contains_name(attrs, $attr) { cx.lint(CRATE_NOT_OKAY, |lint| { let msg = format!("crate is not marked with #![{}]", $attr); - lint.build(&msg).set_span(span).emit() + lint.build(&msg).set_span(span).emit(); }); } )* diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 4bbed5029802d..29d0abfbe5388 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -30,7 +30,7 @@ impl<'tcx> LateLintPass<'tcx> for Pass { let span = cx.tcx.def_span(CRATE_DEF_ID); if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { cx.lint(CRATE_NOT_OKAY, |lint| { - lint.build("crate is not marked with #![crate_okay]").set_span(span).emit() + lint.build("crate is not marked with #![crate_okay]").set_span(span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index 98ba8b1225656..691cfb97d9218 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -23,10 +23,10 @@ impl<'tcx> LateLintPass<'tcx> for Pass { fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) { match it.ident.as_str() { "lintme" => cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }), "pleaselintme" => cx.lint(PLEASE_LINT, |lint| { - lint.build("item is named 'pleaselintme'").set_span(it.span).emit() + lint.build("item is named 'pleaselintme'").set_span(it.span).emit(); }), _ => {} } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 42368ec36a028..285754928c219 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -22,7 +22,7 @@ impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }); } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 81feddf571323..3d5dba42b5f03 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -32,12 +32,12 @@ impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit() + lint.build("item is named 'lintme'").set_span(it.span).emit(); }); } if it.ident.name.as_str() == "lintmetoo" { cx.lint(TEST_GROUP, |lint| { - lint.build("item is named 'lintmetoo'").set_span(it.span).emit() + lint.build("item is named 'lintmetoo'").set_span(it.span).emit(); }); } } diff --git a/src/tools/rustfmt/src/parse/macros/lazy_static.rs b/src/tools/rustfmt/src/parse/macros/lazy_static.rs index 4c541de04be08..a8c2feec453c8 100644 --- a/src/tools/rustfmt/src/parse/macros/lazy_static.rs +++ b/src/tools/rustfmt/src/parse/macros/lazy_static.rs @@ -16,7 +16,7 @@ pub(crate) fn parse_lazy_static( ($method:ident $(,)* $($arg:expr),* $(,)*) => { match parser.$method($($arg,)*) { Ok(val) => { - if parser.sess.span_diagnostic.has_errors() { + if parser.sess.span_diagnostic.has_errors().is_some() { parser.sess.span_diagnostic.reset_err_count(); return None; } else { diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index fd738908170f8..3728f3a19b44f 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -28,7 +28,7 @@ fn parse_macro_arg<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { let mut cloned_parser = (*parser).clone(); match $parser(&mut cloned_parser) { Ok(x) => { - if parser.sess.span_diagnostic.has_errors() { + if parser.sess.span_diagnostic.has_errors().is_some() { parser.sess.span_diagnostic.reset_err_count(); } else { // Parsing succeeded. diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 40a6d708d8ccc..a34ceed3fc91f 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -235,7 +235,7 @@ impl ParseSess { } pub(super) fn has_errors(&self) -> bool { - self.parse_sess.span_diagnostic.has_errors() + self.parse_sess.span_diagnostic.has_errors().is_some() } pub(super) fn reset_errors(&self) {