From 93a19501c2bad56e73f0ac9f3ae062b614d30832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 9 Jan 2025 23:13:00 +0000 Subject: [PATCH 01/12] Always force non-trimming of path in `unreachable_patterns` lint Creating a "trimmed DefID path" when no error is being emitted is an ICE (on purpose). If we create a trimmed path for a lint that is then silenced before being emitted causes a known ICE. This side-steps the issue by always using `with_no_trimmed_path!`. This was verified to fix https://github.com/quinn-rs/quinn/, but couldn't write a repro case for the test suite. Fix #135289. --- compiler/rustc_mir_build/src/thir/pattern/check_match.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a13b00e192167..6631086720068 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -1086,14 +1086,7 @@ fn find_fallback_pattern_typo<'tcx>( let vis = cx.tcx.visibility(item.owner_id); if vis.is_accessible_from(parent, cx.tcx) { accessible.push(item_name); - let path = if item_name == name { - // We know that the const wasn't in scope because it has the exact - // same name, so we suggest the full path. - with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id)) - } else { - // The const is likely just typoed, and nothing else. - cx.tcx.def_path_str(item.owner_id) - }; + let path = with_no_trimmed_paths!(cx.tcx.def_path_str(item.owner_id)); accessible_path.push(path); } else if name == item_name { // The const exists somewhere in this crate, but it can't be imported From 3a0554a44578afb2f69babdae39f8880d23560ae Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 13 Jan 2025 21:00:57 +0300 Subject: [PATCH 02/12] further improve panic_immediate_abort by removing rtprintpanic messages --- library/std/src/rt.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index b2492238bd37b..b08ce4ed08919 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -32,9 +32,14 @@ use crate::{mem, panic, sys}; // - nothing (so this macro is a no-op) macro_rules! rtprintpanic { ($($t:tt)*) => { + #[cfg(not(feature = "panic_immediate_abort"))] if let Some(mut out) = crate::sys::stdio::panic_output() { let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*)); } + #[cfg(feature = "panic_immediate_abort")] + { + let _ = format_args!($($t)*); + } } } From c2ed28443592adf74c6375514adac49a0d801a8a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 14 Jan 2025 17:10:44 +0100 Subject: [PATCH 03/12] remove unnecessary rustc_allowed_through_unstable_modules --- library/std/src/os/fd/raw.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 22f5528248a32..03dff94350dad 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -19,11 +19,9 @@ use crate::sys_common::{AsInner, IntoInner}; use crate::{fs, io}; /// Raw file descriptors. -#[rustc_allowed_through_unstable_modules] #[stable(feature = "rust1", since = "1.0.0")] #[cfg(not(target_os = "hermit"))] pub type RawFd = raw::c_int; -#[rustc_allowed_through_unstable_modules] #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_os = "hermit")] pub type RawFd = i32; @@ -33,7 +31,6 @@ pub type RawFd = i32; /// This is only available on unix and WASI platforms and must be imported in /// order to call the method. Windows platforms have a corresponding /// `AsRawHandle` and `AsRawSocket` set of traits. -#[rustc_allowed_through_unstable_modules] #[stable(feature = "rust1", since = "1.0.0")] pub trait AsRawFd { /// Extracts the raw file descriptor. @@ -67,7 +64,6 @@ pub trait AsRawFd { /// A trait to express the ability to construct an object from a raw file /// descriptor. -#[rustc_allowed_through_unstable_modules] #[stable(feature = "from_raw_os", since = "1.1.0")] pub trait FromRawFd { /// Constructs a new instance of `Self` from the given raw file @@ -112,7 +108,6 @@ pub trait FromRawFd { /// A trait to express the ability to consume an object and acquire ownership of /// its raw file descriptor. -#[rustc_allowed_through_unstable_modules] #[stable(feature = "into_raw_os", since = "1.4.0")] pub trait IntoRawFd { /// Consumes this object, returning the raw underlying file descriptor. From f3cf39f3bebf5bbbe5be5631fb56332f16805c57 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 14 Jan 2025 17:10:56 +0100 Subject: [PATCH 04/12] wasi/io: remove dead files --- library/std/src/os/wasi/io/fd.rs | 9 --------- library/std/src/os/wasi/io/mod.rs | 4 ++++ library/std/src/os/wasi/io/raw.rs | 20 -------------------- library/std/src/os/wasi/io/{fd => }/tests.rs | 0 4 files changed, 4 insertions(+), 29 deletions(-) delete mode 100644 library/std/src/os/wasi/io/fd.rs delete mode 100644 library/std/src/os/wasi/io/raw.rs rename library/std/src/os/wasi/io/{fd => }/tests.rs (100%) diff --git a/library/std/src/os/wasi/io/fd.rs b/library/std/src/os/wasi/io/fd.rs deleted file mode 100644 index 930aca887e3c4..0000000000000 --- a/library/std/src/os/wasi/io/fd.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Owned and borrowed file descriptors. - -#![unstable(feature = "wasi_ext", issue = "71213")] - -// Tests for this module -#[cfg(test)] -mod tests; - -pub use crate::os::fd::owned::*; diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs index 4e123a1eec8ae..5f9a735db085e 100644 --- a/library/std/src/os/wasi/io/mod.rs +++ b/library/std/src/os/wasi/io/mod.rs @@ -4,3 +4,7 @@ #[stable(feature = "io_safety_wasi", since = "1.65.0")] pub use crate::os::fd::*; + +// Tests for this module +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/wasi/io/raw.rs b/library/std/src/os/wasi/io/raw.rs deleted file mode 100644 index da3b36adad409..0000000000000 --- a/library/std/src/os/wasi/io/raw.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! WASI-specific extensions to general I/O primitives. - -#![unstable(feature = "wasi_ext", issue = "71213")] - -// NOTE: despite the fact that this module is unstable, -// stable Rust had the capability to access the stable -// re-exported items from os::fd::raw through this -// unstable module. -// In PR #95956 the stability checker was changed to check -// all path segments of an item rather than just the last, -// which caused the aforementioned stable usage to regress -// (see issue #99502). -// As a result, the items in os::fd::raw were given the -// rustc_allowed_through_unstable_modules attribute. -// No regression tests were added to ensure this property, -// as CI is not configured to test wasm32-wasi. -// If this module is stabilized, -// you may want to remove those attributes -// (assuming no other unstable modules need them). -pub use crate::os::fd::raw::*; diff --git a/library/std/src/os/wasi/io/fd/tests.rs b/library/std/src/os/wasi/io/tests.rs similarity index 100% rename from library/std/src/os/wasi/io/fd/tests.rs rename to library/std/src/os/wasi/io/tests.rs From aced46dcde90545c765d39684be8b184266760cc Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Wed, 15 Jan 2025 07:40:47 -0800 Subject: [PATCH 05/12] Add the concrete syntax for precise capturing to 1.82 release notes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will make the note findable by searching for the “use” keyword, and skimming. Many other language additions mention their syntax in the release notes, but this one only used the name of the feature. --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index c4b36ed988bd2..d8d284ca1fa87 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -359,7 +359,7 @@ Language - [`addr_of(_mut)!` macros and the newly stabilized `&raw (const|mut)` are now safe to use with all static items](https://github.com/rust-lang/rust/pull/125834) - [size_of_val_raw: for length 0 this is safe to call](https://github.com/rust-lang/rust/pull/126152/) - [Reorder trait bound modifiers *after* `for<...>` binder in trait bounds](https://github.com/rust-lang/rust/pull/127054/) -- [Stabilize opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672) +- [Stabilize `+ use<'lt>` opaque type precise capturing (RFC 3617)](https://github.com/rust-lang/rust/pull/127672) - [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679) - [Stabilize unsafe extern blocks (RFC 3484)](https://github.com/rust-lang/rust/pull/127921) - [Stabilize nested field access in `offset_of!`](https://github.com/rust-lang/rust/pull/128284) From 3e99055c4099f0ccb3e5ce5768c32af57d48c79b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 18 Jan 2025 00:30:50 +0000 Subject: [PATCH 06/12] Add test for construction of struct with private field with default value ``` error[E0451]: field `beta` of struct `Alpha` is private --> $DIR/visibility.rs:11:37 | LL | let x = crate::foo::Alpha { .. }; | ^^ field `beta` is private ``` --- .../default-field-values/visibility.rs | 29 +++++++++++++++++++ .../default-field-values/visibility.stderr | 27 +++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 tests/ui/structs/default-field-values/visibility.rs create mode 100644 tests/ui/structs/default-field-values/visibility.stderr diff --git a/tests/ui/structs/default-field-values/visibility.rs b/tests/ui/structs/default-field-values/visibility.rs new file mode 100644 index 0000000000000..e1f76a5fe2479 --- /dev/null +++ b/tests/ui/structs/default-field-values/visibility.rs @@ -0,0 +1,29 @@ +#![feature(default_field_values)] +pub mod foo { + pub struct Alpha { + beta: u8 = 42, + gamma: bool = true, + } +} + +mod bar { + fn baz() { + let x = crate::foo::Alpha { .. }; + //~^ ERROR field `beta` of struct `Alpha` is private + //~| ERROR field `gamma` of struct `Alpha` is private + } +} + +pub mod baz { + pub struct S { + x: i32 = 1, + } +} +fn main() { + let a = baz::S { + .. //~ ERROR field `x` of struct `S` is private + }; + let b = baz::S { + x: 0, //~ ERROR field `x` of struct `S` is private + }; +} diff --git a/tests/ui/structs/default-field-values/visibility.stderr b/tests/ui/structs/default-field-values/visibility.stderr new file mode 100644 index 0000000000000..63721d79be5bb --- /dev/null +++ b/tests/ui/structs/default-field-values/visibility.stderr @@ -0,0 +1,27 @@ +error[E0451]: field `x` of struct `S` is private + --> $DIR/visibility.rs:24:9 + | +LL | .. + | ^^ field `x` is private + +error[E0451]: field `x` of struct `S` is private + --> $DIR/visibility.rs:27:9 + | +LL | x: 0, + | ^^^^ private field + +error[E0451]: field `beta` of struct `Alpha` is private + --> $DIR/visibility.rs:11:37 + | +LL | let x = crate::foo::Alpha { .. }; + | ^^ field `beta` is private + +error[E0451]: field `gamma` of struct `Alpha` is private + --> $DIR/visibility.rs:11:37 + | +LL | let x = crate::foo::Alpha { .. }; + | ^^ field `gamma` is private + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0451`. From bbcf26fc33afb4695014aff22fa77dcb7d9eb715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 18 Jan 2025 01:56:22 +0000 Subject: [PATCH 07/12] Add context on private fields that are not on the same line as the struct name ``` error[E0451]: field `x` of struct `S` is private --> $DIR/visibility.rs:24:9 | LL | let a = baz::S { | ------ in this type LL | .. | ^^ field `x` is private ``` --- compiler/rustc_privacy/messages.ftl | 1 + compiler/rustc_privacy/src/errors.rs | 2 + compiler/rustc_privacy/src/lib.rs | 38 +++++++++++++++++-- tests/ui/deprecation/deprecation-lint.stderr | 3 ++ .../default-field-values/visibility.stderr | 4 ++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index 7785f1a7f81fb..5b5c10d448aa9 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -1,4 +1,5 @@ privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private + .label = in this type privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private privacy_field_is_private_label = private field diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index f5e641eb64243..23181f63a286a 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -8,6 +8,8 @@ use rustc_span::{Span, Symbol}; pub(crate) struct FieldIsPrivate { #[primary_span] pub span: Span, + #[label] + pub struct_span: Option, pub field_name: Symbol, pub variant_descr: &'static str, pub def_path_str: String, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e484cfed06b33..6ec735990053b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -925,6 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { def: ty::AdtDef<'tcx>, // definition of the struct or enum field: &'tcx ty::FieldDef, in_update_syntax: bool, + struct_span: Span, ) { if def.is_enum() { return; @@ -936,6 +937,11 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { if !field.vis.is_accessible_from(def_id, self.tcx) { self.tcx.dcx().emit_err(FieldIsPrivate { span, + struct_span: if self.tcx.sess.source_map().is_multiline(span.between(struct_span)) { + Some(struct_span) + } else { + None + }, field_name: field.name, variant_descr: def.variant_descr(), def_path_str: self.tcx.def_path_str(def.did()), @@ -955,6 +961,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { fields: &[hir::ExprField<'tcx>], hir_id: hir::HirId, span: Span, + struct_span: Span, ) { for (vf_index, variant_field) in variant.fields.iter_enumerated() { let field = @@ -963,7 +970,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { Some(field) => (field.hir_id, field.ident.span, field.span), None => (hir_id, span, span), }; - self.check_field(hir_id, use_ctxt, span, adt, variant_field, true); + self.check_field(hir_id, use_ctxt, span, adt, variant_field, true, struct_span); } } } @@ -990,10 +997,24 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { // If the expression uses FRU we need to make sure all the unmentioned fields // are checked for privacy (RFC 736). Rather than computing the set of // unmentioned fields, just check them all. - self.check_expanded_fields(adt, variant, fields, base.hir_id, base.span); + self.check_expanded_fields( + adt, + variant, + fields, + base.hir_id, + base.span, + qpath.span(), + ); } hir::StructTailExpr::DefaultFields(span) => { - self.check_expanded_fields(adt, variant, fields, expr.hir_id, span); + self.check_expanded_fields( + adt, + variant, + fields, + expr.hir_id, + span, + qpath.span(), + ); } hir::StructTailExpr::None => { for field in fields { @@ -1006,6 +1027,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { adt, &variant.fields[index], false, + qpath.span(), ); } } @@ -1023,7 +1045,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { for field in fields { let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span); let index = self.typeck_results().field_index(field.hir_id); - self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false); + self.check_field( + hir_id, + use_ctxt, + span, + adt, + &variant.fields[index], + false, + qpath.span(), + ); } } diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 2098073409da5..075bb42fa9a7a 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -739,6 +739,9 @@ LL | _) error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private --> $DIR/deprecation-lint.rs:280:13 | +LL | let _ = nested::DeprecatedStruct { + | ------------------------ in this type +LL | LL | i: 0 | ^^^^ private field diff --git a/tests/ui/structs/default-field-values/visibility.stderr b/tests/ui/structs/default-field-values/visibility.stderr index 63721d79be5bb..666782933d3fd 100644 --- a/tests/ui/structs/default-field-values/visibility.stderr +++ b/tests/ui/structs/default-field-values/visibility.stderr @@ -1,12 +1,16 @@ error[E0451]: field `x` of struct `S` is private --> $DIR/visibility.rs:24:9 | +LL | let a = baz::S { + | ------ in this type LL | .. | ^^ field `x` is private error[E0451]: field `x` of struct `S` is private --> $DIR/visibility.rs:27:9 | +LL | let b = baz::S { + | ------ in this type LL | x: 0, | ^^^^ private field From deef3ebaec2ff0ff818161f3b9b86a42bed5fe36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 18 Jan 2025 20:07:05 +0000 Subject: [PATCH 08/12] Emit a single privacy error for multiple fields on the same struct expression Collect all unreachable fields in a single struct literal struct and emit a single error, instead of one error per private field. ``` error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private --> $DIR/visibility.rs:18:13 | LL | let _x = Alpha { | ----- in this type LL | beta: 0, | ^^^^^^^ private field LL | .. | ^^ field `gamma` is private ``` --- compiler/rustc_privacy/messages.ftl | 17 +- compiler/rustc_privacy/src/errors.rs | 12 +- compiler/rustc_privacy/src/lib.rs | 147 ++++++++++++------ tests/ui/deprecation/deprecation-lint.stderr | 2 +- tests/ui/error-codes/E0451.stderr | 2 +- .../issue-82772-match-box-as-struct.stderr | 2 +- .../privacy/private-struct-field-ctor.stderr | 2 +- .../private-struct-field-pattern.stderr | 2 +- .../restricted/struct-literal-field.stderr | 2 +- tests/ui/privacy/union-field-privacy-1.stderr | 2 +- .../default-field-values/visibility.rs | 23 ++- .../default-field-values/visibility.stderr | 62 ++++++-- tests/ui/typeck/issue-82772.stderr | 6 +- 13 files changed, 199 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index 5b5c10d448aa9..43c34a109d721 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -1,6 +1,19 @@ -privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private +privacy_field_is_private = + {$len -> + [1] field + *[other] fields + } {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> + [1] is + *[other] are + } private .label = in this type -privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private +privacy_field_is_private_is_update_syntax_label = {$rest_len -> + [1] field + *[other] fields + } {$rest_field_names} {$rest_len -> + [1] is + *[other] are + } private privacy_field_is_private_label = private field privacy_from_private_dep_in_public_interface = diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 23181f63a286a..4d1d58c08528c 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -1,5 +1,5 @@ -use rustc_errors::DiagArgFromDisplay; use rustc_errors::codes::*; +use rustc_errors::{DiagArgFromDisplay, MultiSpan}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; @@ -7,14 +7,15 @@ use rustc_span::{Span, Symbol}; #[diag(privacy_field_is_private, code = E0451)] pub(crate) struct FieldIsPrivate { #[primary_span] - pub span: Span, + pub span: MultiSpan, #[label] pub struct_span: Option, - pub field_name: Symbol, + pub field_names: String, pub variant_descr: &'static str, pub def_path_str: String, #[subdiagnostic] - pub label: FieldIsPrivateLabel, + pub labels: Vec, + pub len: usize, } #[derive(Subdiagnostic)] @@ -23,7 +24,8 @@ pub(crate) enum FieldIsPrivateLabel { IsUpdateSyntax { #[primary_span] span: Span, - field_name: Symbol, + rest_field_names: String, + rest_len: usize, }, #[label(privacy_field_is_private_label)] Other { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 6ec735990053b..cb7b0815a49c4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -24,6 +24,7 @@ use rustc_ast::MacroDef; use rustc_ast::visit::{VisitorResult, try_visit}; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; +use rustc_errors::MultiSpan; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId, LocalModDefId}; use rustc_hir::intravisit::{self, Visitor}; @@ -38,7 +39,7 @@ use rustc_middle::ty::{ use rustc_middle::{bug, span_bug}; use rustc_session::lint; use rustc_span::hygiene::Transparency; -use rustc_span::{Ident, Span, kw, sym}; +use rustc_span::{Ident, Span, Symbol, kw, sym}; use tracing::debug; use {rustc_attr_parsing as attr, rustc_hir as hir}; @@ -921,37 +922,95 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { &mut self, hir_id: hir::HirId, // ID of the field use use_ctxt: Span, // syntax context of the field name at the use site - span: Span, // span of the field pattern, e.g., `x: 0` def: ty::AdtDef<'tcx>, // definition of the struct or enum field: &'tcx ty::FieldDef, - in_update_syntax: bool, - struct_span: Span, - ) { + ) -> bool { if def.is_enum() { - return; + return true; } // definition of the field let ident = Ident::new(kw::Empty, use_ctxt); let def_id = self.tcx.adjust_ident_and_get_scope(ident, def.did(), hir_id).1; - if !field.vis.is_accessible_from(def_id, self.tcx) { - self.tcx.dcx().emit_err(FieldIsPrivate { - span, - struct_span: if self.tcx.sess.source_map().is_multiline(span.between(struct_span)) { - Some(struct_span) - } else { - None - }, - field_name: field.name, - variant_descr: def.variant_descr(), - def_path_str: self.tcx.def_path_str(def.did()), - label: if in_update_syntax { - FieldIsPrivateLabel::IsUpdateSyntax { span, field_name: field.name } - } else { - FieldIsPrivateLabel::Other { span } - }, - }); + !field.vis.is_accessible_from(def_id, self.tcx) + } + + // Checks that a field in a struct constructor (expression or pattern) is accessible. + fn emit_unreachable_field_error( + &mut self, + fields: Vec<(Symbol, Span, bool /* field is present */)>, + def: ty::AdtDef<'tcx>, // definition of the struct or enum + update_syntax: Option, + struct_span: Span, + ) { + if def.is_enum() || fields.is_empty() { + return; } + + // error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + // --> $DIR/visibility.rs:18:13 + // | + // LL | let _x = Alpha { + // | ----- in this type # from `def` + // LL | beta: 0, + // | ^^^^^^^ private field # `fields.2` is `true` + // LL | .. + // | ^^ field `gamma` is private # `fields.2` is `false` + + // Get the list of all private fields for the main message. + let field_names: Vec<_> = fields.iter().map(|(name, _, _)| name).collect(); + let field_names = match &field_names[..] { + [] => return, + [name] => format!("`{name}`"), + [fields @ .., last] => format!( + "{} and `{last}`", + fields.iter().map(|f| format!("`{f}`")).collect::>().join(", "), + ), + }; + let span: MultiSpan = fields.iter().map(|(_, span, _)| *span).collect::>().into(); + + // Get the list of all private fields when pointing at the `..rest`. + let rest_field_names: Vec<_> = + fields.iter().filter(|(_, _, is_present)| !is_present).map(|(n, _, _)| n).collect(); + let rest_len = rest_field_names.len(); + let rest_field_names = match &rest_field_names[..] { + [] => String::new(), + [name] => format!("`{name}`"), + [fields @ .., last] => format!( + "{} and `{last}`", + fields.iter().map(|f| format!("`{f}`")).collect::>().join(", "), + ), + }; + // Get all the labels for each field or `..rest` in the primary MultiSpan. + let labels = fields + .iter() + .filter(|(_, _, is_present)| *is_present) + .map(|(_, span, _)| FieldIsPrivateLabel::Other { span: *span }) + .chain(update_syntax.iter().map(|span| FieldIsPrivateLabel::IsUpdateSyntax { + span: *span, + rest_field_names: rest_field_names.clone(), + rest_len, + })) + .collect(); + + self.tcx.dcx().emit_err(FieldIsPrivate { + span, + struct_span: if self + .tcx + .sess + .source_map() + .is_multiline(fields[0].1.between(struct_span)) + { + Some(struct_span) + } else { + None + }, + field_names: field_names.clone(), + variant_descr: def.variant_descr(), + def_path_str: self.tcx.def_path_str(def.did()), + labels, + len: fields.len(), + }); } fn check_expanded_fields( @@ -963,6 +1022,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { span: Span, struct_span: Span, ) { + let mut failed_fields = vec![]; for (vf_index, variant_field) in variant.fields.iter_enumerated() { let field = fields.iter().find(|f| self.typeck_results().field_index(f.hir_id) == vf_index); @@ -970,8 +1030,15 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { Some(field) => (field.hir_id, field.ident.span, field.span), None => (hir_id, span, span), }; - self.check_field(hir_id, use_ctxt, span, adt, variant_field, true, struct_span); + if self.check_field(hir_id, use_ctxt, adt, variant_field) { + let name = match field { + Some(field) => field.ident.name, + None => variant_field.name, + }; + failed_fields.push((name, span, field.is_some())); + } } + self.emit_unreachable_field_error(failed_fields, adt, Some(span), struct_span); } } @@ -1017,19 +1084,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { ); } hir::StructTailExpr::None => { + let mut failed_fields = vec![]; for field in fields { - let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span); + let (hir_id, use_ctxt) = (field.hir_id, field.ident.span); let index = self.typeck_results().field_index(field.hir_id); - self.check_field( - hir_id, - use_ctxt, - span, - adt, - &variant.fields[index], - false, - qpath.span(), - ); + if self.check_field(hir_id, use_ctxt, adt, &variant.fields[index]) { + failed_fields.push((field.ident.name, field.ident.span, true)); + } } + self.emit_unreachable_field_error(failed_fields, adt, None, qpath.span()); } } } @@ -1042,19 +1105,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { let res = self.typeck_results().qpath_res(qpath, pat.hir_id); let adt = self.typeck_results().pat_ty(pat).ty_adt_def().unwrap(); let variant = adt.variant_of_res(res); + let mut failed_fields = vec![]; for field in fields { - let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span); + let (hir_id, use_ctxt) = (field.hir_id, field.ident.span); let index = self.typeck_results().field_index(field.hir_id); - self.check_field( - hir_id, - use_ctxt, - span, - adt, - &variant.fields[index], - false, - qpath.span(), - ); + if self.check_field(hir_id, use_ctxt, adt, &variant.fields[index]) { + failed_fields.push((field.ident.name, field.ident.span, true)); + } } + self.emit_unreachable_field_error(failed_fields, adt, None, qpath.span()); } intravisit::walk_pat(self, pat); diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 075bb42fa9a7a..95ae1b04d8611 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -743,7 +743,7 @@ LL | let _ = nested::DeprecatedStruct { | ------------------------ in this type LL | LL | i: 0 - | ^^^^ private field + | ^ private field error: aborting due to 123 previous errors diff --git a/tests/ui/error-codes/E0451.stderr b/tests/ui/error-codes/E0451.stderr index 419cf117efe04..2cd30095c80d5 100644 --- a/tests/ui/error-codes/E0451.stderr +++ b/tests/ui/error-codes/E0451.stderr @@ -8,7 +8,7 @@ error[E0451]: field `b` of struct `Foo` is private --> $DIR/E0451.rs:18:29 | LL | let f = bar::Foo{ a: 0, b: 0 }; - | ^^^^ private field + | ^ private field error: aborting due to 2 previous errors diff --git a/tests/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr b/tests/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr index ba7573839ed29..ee21b4c8d46d8 100644 --- a/tests/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr +++ b/tests/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr @@ -2,7 +2,7 @@ error[E0451]: field `1` of struct `Box` is private --> $DIR/issue-82772-match-box-as-struct.rs:4:15 | LL | let Box { 1: _, .. }: Box<()>; - | ^^^^ private field + | ^ private field error: aborting due to 1 previous error diff --git a/tests/ui/privacy/private-struct-field-ctor.stderr b/tests/ui/privacy/private-struct-field-ctor.stderr index 2a35537237a3e..8eb1bf7990b86 100644 --- a/tests/ui/privacy/private-struct-field-ctor.stderr +++ b/tests/ui/privacy/private-struct-field-ctor.stderr @@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `Foo` is private --> $DIR/private-struct-field-ctor.rs:8:22 | LL | let s = a::Foo { x: 1 }; - | ^^^^ private field + | ^ private field error: aborting due to 1 previous error diff --git a/tests/ui/privacy/private-struct-field-pattern.stderr b/tests/ui/privacy/private-struct-field-pattern.stderr index de24d1e09622b..5609596721d40 100644 --- a/tests/ui/privacy/private-struct-field-pattern.stderr +++ b/tests/ui/privacy/private-struct-field-pattern.stderr @@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `Foo` is private --> $DIR/private-struct-field-pattern.rs:15:15 | LL | Foo { x: _ } => {} - | ^^^^ private field + | ^ private field error: aborting due to 1 previous error diff --git a/tests/ui/privacy/restricted/struct-literal-field.stderr b/tests/ui/privacy/restricted/struct-literal-field.stderr index dcdadf1da4bf7..e1cf7c2fadbfe 100644 --- a/tests/ui/privacy/restricted/struct-literal-field.stderr +++ b/tests/ui/privacy/restricted/struct-literal-field.stderr @@ -2,7 +2,7 @@ error[E0451]: field `x` of struct `S` is private --> $DIR/struct-literal-field.rs:18:9 | LL | S { x: 0 }; - | ^^^^ private field + | ^ private field error: aborting due to 1 previous error diff --git a/tests/ui/privacy/union-field-privacy-1.stderr b/tests/ui/privacy/union-field-privacy-1.stderr index b1f0b785ea767..6f883b16d0200 100644 --- a/tests/ui/privacy/union-field-privacy-1.stderr +++ b/tests/ui/privacy/union-field-privacy-1.stderr @@ -2,7 +2,7 @@ error[E0451]: field `c` of union `U` is private --> $DIR/union-field-privacy-1.rs:12:20 | LL | let u = m::U { c: 0 }; - | ^^^^ private field + | ^ private field error[E0451]: field `c` of union `U` is private --> $DIR/union-field-privacy-1.rs:16:16 diff --git a/tests/ui/structs/default-field-values/visibility.rs b/tests/ui/structs/default-field-values/visibility.rs index e1f76a5fe2479..ff1245551b0ad 100644 --- a/tests/ui/structs/default-field-values/visibility.rs +++ b/tests/ui/structs/default-field-values/visibility.rs @@ -1,5 +1,6 @@ #![feature(default_field_values)] pub mod foo { + #[derive(Default)] pub struct Alpha { beta: u8 = 42, gamma: bool = true, @@ -7,10 +8,22 @@ pub mod foo { } mod bar { + use crate::foo::Alpha; fn baz() { - let x = crate::foo::Alpha { .. }; - //~^ ERROR field `beta` of struct `Alpha` is private - //~| ERROR field `gamma` of struct `Alpha` is private + let _x = Alpha { .. }; + //~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private + let _x = Alpha { + beta: 0, //~ ERROR fields `beta` and `gamma` of struct `Alpha` are private + gamma: false, + }; + let _x = Alpha { + beta: 0, //~ ERROR fields `beta` and `gamma` of struct `Alpha` are private + .. + }; + let _x = Alpha { beta: 0, .. }; + //~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private + let _x = Alpha { beta: 0, ..Default::default() }; + //~^ ERROR fields `beta` and `gamma` of struct `Alpha` are private } } @@ -20,10 +33,10 @@ pub mod baz { } } fn main() { - let a = baz::S { + let _a = baz::S { .. //~ ERROR field `x` of struct `S` is private }; - let b = baz::S { + let _b = baz::S { x: 0, //~ ERROR field `x` of struct `S` is private }; } diff --git a/tests/ui/structs/default-field-values/visibility.stderr b/tests/ui/structs/default-field-values/visibility.stderr index 666782933d3fd..38b9603325235 100644 --- a/tests/ui/structs/default-field-values/visibility.stderr +++ b/tests/ui/structs/default-field-values/visibility.stderr @@ -1,31 +1,61 @@ error[E0451]: field `x` of struct `S` is private - --> $DIR/visibility.rs:24:9 + --> $DIR/visibility.rs:37:9 | -LL | let a = baz::S { - | ------ in this type +LL | let _a = baz::S { + | ------ in this type LL | .. | ^^ field `x` is private error[E0451]: field `x` of struct `S` is private - --> $DIR/visibility.rs:27:9 + --> $DIR/visibility.rs:40:9 | -LL | let b = baz::S { - | ------ in this type +LL | let _b = baz::S { + | ------ in this type LL | x: 0, - | ^^^^ private field + | ^ private field -error[E0451]: field `beta` of struct `Alpha` is private - --> $DIR/visibility.rs:11:37 +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:13:26 | -LL | let x = crate::foo::Alpha { .. }; - | ^^ field `beta` is private +LL | let _x = Alpha { .. }; + | ^^ fields `beta` and `gamma` are private -error[E0451]: field `gamma` of struct `Alpha` is private - --> $DIR/visibility.rs:11:37 +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:16:13 | -LL | let x = crate::foo::Alpha { .. }; - | ^^ field `gamma` is private +LL | let _x = Alpha { + | ----- in this type +LL | beta: 0, + | ^^^^ private field +LL | gamma: false, + | ^^^^^ private field -error: aborting due to 4 previous errors +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:20:13 + | +LL | let _x = Alpha { + | ----- in this type +LL | beta: 0, + | ^^^^^^^ private field +LL | .. + | ^^ field `gamma` is private + +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:23:26 + | +LL | let _x = Alpha { beta: 0, .. }; + | ^^^^^^^ ^^ field `gamma` is private + | | + | private field + +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:25:26 + | +LL | let _x = Alpha { beta: 0, ..Default::default() }; + | ^^^^^^^ ^^^^^^^^^^^^^^^^^^ field `gamma` is private + | | + | private field + +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0451`. diff --git a/tests/ui/typeck/issue-82772.stderr b/tests/ui/typeck/issue-82772.stderr index 321143cb9683d..a314306137a48 100644 --- a/tests/ui/typeck/issue-82772.stderr +++ b/tests/ui/typeck/issue-82772.stderr @@ -2,19 +2,19 @@ error[E0451]: field `0` of struct `Box` is private --> $DIR/issue-82772.rs:5:15 | LL | let Box { 0: _, .. }: Box<()>; - | ^^^^ private field + | ^ private field error[E0451]: field `1` of struct `Box` is private --> $DIR/issue-82772.rs:6:15 | LL | let Box { 1: _, .. }: Box<()>; - | ^^^^ private field + | ^ private field error[E0451]: field `1` of struct `ModPrivateStruct` is private --> $DIR/issue-82772.rs:7:28 | LL | let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default(); - | ^^^^ private field + | ^ private field error: aborting due to 3 previous errors From 2e69bd2ce9b9037b22e46545495f32421c06d153 Mon Sep 17 00:00:00 2001 From: Noratrieb <48135649+Noratrieb@users.noreply.github.com> Date: Sun, 19 Jan 2025 14:24:46 +0100 Subject: [PATCH 09/12] Add debug assertions to compiler profile Working on the compiler without debug assertions is not a very productive way to work on the compiler. --- src/bootstrap/defaults/config.compiler.toml | 2 ++ src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml index a737de3bd0856..269b90106e3aa 100644 --- a/src/bootstrap/defaults/config.compiler.toml +++ b/src/bootstrap/defaults/config.compiler.toml @@ -8,6 +8,8 @@ compiler-docs = true # where adding `debug!()` appears to do nothing. # However, it makes running the compiler slightly slower. debug-logging = true +# Enables debug assertions, which guard from many mistakes when working on the compiler. +debug-assertions = true # Get actually-useful information from backtraces, profiling, etc. with minimal added bytes debuginfo-level = "line-tables-only" # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower. diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 85d17c8fa5077..a3eb781f1476a 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -335,4 +335,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "Some stamp names in the build artifacts may have changed slightly (e.g., from `llvm-finished-building` to `.llvm-stamp`).", }, + ChangeInfo { + change_id: 135729, + severity: ChangeSeverity::Info, + summary: "Change the compiler profile to default to rust.debug-assertions = true", + }, ]; From 64d667ae78f96102fb71286106ba3d0186f411c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Sun, 19 Jan 2025 17:39:37 +0100 Subject: [PATCH 10/12] rustdoc: Fix flaky doctest test --- .../doctest/doctest-no-run-invalid-langstring-124577.rs | 1 + .../doctest/doctest-no-run-invalid-langstring-124577.stdout | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs index 571bc94e30f98..db2ccefb0fb1f 100644 --- a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.rs @@ -1,4 +1,5 @@ //@ compile-flags:--test +//@ normalize-stdout: "finished in \d+\.\d+s" -> "finished in $$TIME" //@ check-pass #![allow(rustdoc::invalid_codeblock_attributes)] diff --git a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout index e5c27bebbdb23..7326c0a25a069 100644 --- a/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout +++ b/tests/rustdoc-ui/doctest/doctest-no-run-invalid-langstring-124577.stdout @@ -1,5 +1,5 @@ running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME From 264fa0fc5430f3a9a52a92df706d7c9ac5af4f85 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 19 Jan 2025 19:15:00 +0000 Subject: [PATCH 11/12] Run `clippy --fix` for `unnecessary_map_or` lint --- compiler/rustc_ast_lowering/src/delegation.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 2 +- .../rustc_attr_parsing/src/attributes/repr.rs | 2 +- .../src/diagnostics/conflict_errors.rs | 2 +- .../src/diagnostics/explain_borrow.rs | 4 +-- .../src/debuginfo/metadata.rs | 2 +- compiler/rustc_errors/src/emitter.rs | 2 +- compiler/rustc_errors/src/json.rs | 2 +- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_expand/src/config.rs | 2 +- compiler/rustc_expand/src/mbe/diagnostics.rs | 2 +- compiler/rustc_hir/src/def.rs | 2 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 9 +++---- .../rustc_hir_typeck/src/method/suggest.rs | 25 ++++++++++--------- compiler/rustc_index/src/interval.rs | 2 +- compiler/rustc_lint/src/expect.rs | 2 +- compiler/rustc_metadata/src/creader.rs | 2 +- .../interpret/allocation/provenance_map.rs | 4 +-- compiler/rustc_middle/src/ty/closure.rs | 2 +- compiler/rustc_middle/src/ty/instance.rs | 2 +- compiler/rustc_middle/src/ty/sty.rs | 4 +-- compiler/rustc_middle/src/values.rs | 2 +- .../rustc_mir_build/src/check_unsafety.rs | 2 +- .../src/framework/graphviz.rs | 2 +- .../rustc_mir_transform/src/coverage/graph.rs | 2 +- .../src/canonicalizer.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 2 +- compiler/rustc_passes/src/dead.rs | 2 +- compiler/rustc_resolve/src/check_unused.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 6 ++--- compiler/rustc_resolve/src/imports.rs | 2 +- compiler/rustc_resolve/src/late.rs | 4 +-- .../rustc_resolve/src/late/diagnostics.rs | 6 ++--- compiler/rustc_resolve/src/lib.rs | 2 +- compiler/rustc_resolve/src/macros.rs | 2 +- compiler/rustc_resolve/src/rustdoc.rs | 5 +--- compiler/rustc_session/src/config.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 3 +-- 39 files changed, 61 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index 266e77c0e02e6..f9fe4938ca8bc 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -72,7 +72,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if let Some(local_sig_id) = def_id.as_local() { // The value may be missing due to recursive delegation. // Error will be emitted later during HIR ty lowering. - self.resolver.delegation_fn_sigs.get(&local_sig_id).map_or(false, |sig| sig.has_self) + self.resolver.delegation_fn_sigs.get(&local_sig_id).is_some_and(|sig| sig.has_self) } else { match self.tcx.def_kind(def_id) { DefKind::Fn => false, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 94746212138dc..d6f0af9ad38da 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -83,7 +83,7 @@ impl<'a> PostExpansionVisitor<'a> { feature_err_issue(&self.sess, feature, span, GateIssue::Language, explain).emit(); } Err(abi::AbiDisabled::Unrecognized) => { - if self.sess.opts.pretty.map_or(true, |ppm| ppm.needs_hir()) { + if self.sess.opts.pretty.is_none_or(|ppm| ppm.needs_hir()) { self.sess.dcx().span_delayed_bug( span, format!( diff --git a/compiler/rustc_attr_parsing/src/attributes/repr.rs b/compiler/rustc_attr_parsing/src/attributes/repr.rs index 124f0aa3effa1..28c381160b874 100644 --- a/compiler/rustc_attr_parsing/src/attributes/repr.rs +++ b/compiler/rustc_attr_parsing/src/attributes/repr.rs @@ -166,7 +166,7 @@ pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec MirBorrowckCtxt<'_, 'infcx, 'tcx> { // To support cases like `|| { v.call(|this| v.get()) }` // FIXME: actually support such cases (need to figure out how to move from the // capture place to original local). - && self.res.as_ref().map_or(true, |(prev_res, _)| prev_res.span.contains(ex.span)) + && self.res.as_ref().is_none_or(|(prev_res, _)| prev_res.span.contains(ex.span)) { self.res = Some((ex, closure)); } diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 5c0c1d0eb86af..2656e0bb6a452 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -131,10 +131,10 @@ impl<'tcx> BorrowExplanation<'tcx> { && let Ok(pat) = tcx.sess.source_map().span_to_snippet(pat.span) { suggest_rewrite_if_let(tcx, expr, &pat, init, conseq, alt, err); - } else if path_span.map_or(true, |path_span| path_span == var_or_use_span) { + } else if path_span.is_none_or(|path_span| path_span == var_or_use_span) { // We can use `var_or_use_span` if either `path_span` is not present, or both // spans are the same. - if borrow_span.map_or(true, |sp| !sp.overlaps(var_or_use_span)) { + if borrow_span.is_none_or(|sp| !sp.overlaps(var_or_use_span)) { err.span_label( var_or_use_span, format!("{borrow_desc}borrow later {message}"), diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 88e43e1c678ad..8d782a618fc07 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -442,7 +442,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> // (or if there is no allocator argument). ty::Adt(def, args) if def.is_box() - && args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) => + && args.get(1).is_none_or(|arg| cx.layout_of(arg.expect_ty()).is_1zst()) => { build_pointer_or_reference_di_node(cx, t, t.expect_boxed_ty(), unique_type_id) } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index f938352820df7..991dfa1821a9b 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -3146,7 +3146,7 @@ impl FileWithAnnotatedLines { add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line()); } let line_end = ann.line_end - 1; - let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| !filter(&s)); + let end_is_empty = file.get_line(line_end - 1).is_some_and(|s| !filter(&s)); if middle < line_end && !end_is_empty { add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line()); } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 97df7f9265aa4..6a3f8ca497a57 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -463,7 +463,7 @@ impl DiagnosticSpan { // is an empty string, increase the length to include the newline so we don't // leave an empty line if start.col.0 == 0 - && suggestion.map_or(false, |(s, _)| s.is_empty()) + && suggestion.is_some_and(|(s, _)| s.is_empty()) && let Ok(after) = je.sm.span_to_next_source(span) && after.starts_with('\n') { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index cc5eb9c335e8c..6e5958a20d0b9 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1717,7 +1717,7 @@ impl DiagCtxtInner { let bugs: Vec<_> = std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(); - let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); + let backtrace = std::env::var_os("RUST_BACKTRACE").is_none_or(|x| &x != "0"); let decorate = backtrace || self.ice_file.is_none(); let mut out = self .ice_file diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 3e3f35332e0d5..83255b820178f 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -391,7 +391,7 @@ impl<'a> StripUnconfigured<'a> { validate_attr::deny_builtin_meta_unsafety(&self.sess.psess, &meta_item); ( - parse_cfg(&meta_item, self.sess).map_or(true, |meta_item| { + parse_cfg(&meta_item, self.sess).is_none_or(|meta_item| { attr::cfg_matches(meta_item, &self.sess, self.lint_node_id, self.features) }), Some(meta_item), diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs index 9f48835e15d7b..e60a9e83184fb 100644 --- a/compiler/rustc_expand/src/mbe/diagnostics.rs +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -159,7 +159,7 @@ impl<'dcx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'dcx, 'match if self .best_failure .as_ref() - .map_or(true, |failure| failure.is_better_position(*approx_position)) + .is_none_or(|failure| failure.is_better_position(*approx_position)) { self.best_failure = Some(BestFailure { token: token.clone(), diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 705de389e072e..7e3a8561da08b 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -794,7 +794,7 @@ impl Res { /// Always returns `true` if `self` is `Res::Err` pub fn matches_ns(&self, ns: Namespace) -> bool { - self.ns().map_or(true, |actual_ns| actual_ns == ns) + self.ns().is_none_or(|actual_ns| actual_ns == ns) } /// Returns whether such a resolved path can occur in a tuple struct/variant pattern diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 46eed2db2364f..8e78fb3e2191f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1210,7 +1210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // - foo((), "current", 42u32, "next") // + foo((), 42u32) { - prev_extra_idx.map_or(true, |prev_extra_idx| { + prev_extra_idx.is_none_or(|prev_extra_idx| { prev_extra_idx + 1 == arg_idx.index() }) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 53e055fdeef44..16294970f0531 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1143,7 +1143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.may_coerce(found, ty) } hir::FnRetTy::DefaultReturn(_) if in_closure => { - self.ret_coercion.as_ref().map_or(false, |ret| { + self.ret_coercion.as_ref().is_some_and(|ret| { let ret_ty = ret.borrow().expected_ty(); self.may_coerce(found, ret_ty) }) @@ -1784,14 +1784,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let results = self.typeck_results.borrow(); // First, look for a `Clone::clone` call if segment.ident.name == sym::clone - && results.type_dependent_def_id(expr.hir_id).map_or( - false, - |did| { + && results.type_dependent_def_id(expr.hir_id).is_some_and(|did| { let assoc_item = self.tcx.associated_item(did); assoc_item.container == ty::AssocItemContainer::Trait && assoc_item.container_id(self.tcx) == clone_trait_did - }, - ) + }) // If that clone call hasn't already dereferenced the self type (i.e. don't give this // diagnostic in cases where we have `(&&T).clone()` and we expect `T`). && !results.expr_adjustments(callee_expr).iter().any(|adj| matches!(adj.kind, ty::adjustment::Adjust::Deref(..))) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index b3d87ef4ad2bf..89843da9d7bcc 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -3761,18 +3761,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::TraitFn::Required([ident, ..]) => { ident.name == kw::SelfLower } - hir::TraitFn::Provided(body_id) => { - self.tcx.hir().body(*body_id).params.first().map_or( - false, - |param| { - matches!( - param.pat.kind, - hir::PatKind::Binding(_, _, ident, _) - if ident.name == kw::SelfLower - ) - }, - ) - } + hir::TraitFn::Provided(body_id) => self + .tcx + .hir() + .body(*body_id) + .params + .first() + .is_some_and(|param| { + matches!( + param.pat.kind, + hir::PatKind::Binding(_, _, ident, _) + if ident.name == kw::SelfLower + ) + }), _ => false, }; diff --git a/compiler/rustc_index/src/interval.rs b/compiler/rustc_index/src/interval.rs index 34f541a8cc639..a3d87f59567fe 100644 --- a/compiler/rustc_index/src/interval.rs +++ b/compiler/rustc_index/src/interval.rs @@ -258,7 +258,7 @@ impl IntervalSet { } current = Some(*end); } - current.map_or(true, |x| x < self.domain as u32) + current.is_none_or(|x| x < self.domain as u32) } } diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 289e2c9b72243..ef79f1301e5f6 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -57,7 +57,7 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option) { let expect_id = canonicalize_id(expect_id); if !fulfilled_expectations.contains(&expect_id) - && tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter)) + && tool_filter.is_none_or(|filter| expectation.lint_tool == Some(filter)) { let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale }); let note = expectation.is_unfulfilled_lint_expectations; diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 6512176cc4a90..586b38ff14443 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -417,7 +417,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Any descendants of `std` should be private. These crates are usually not marked // private in metadata, so we ignore that field. if extern_private.is_none() - && dep_root.map_or(false, |d| STDLIB_STABLE_CRATES.contains(&d.name)) + && dep_root.is_some_and(|d| STDLIB_STABLE_CRATES.contains(&d.name)) { return true; } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index 3a83b184d83d5..ab4d59185a52b 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -97,7 +97,7 @@ impl ProvenanceMap { debug_assert!(prov.len() <= 1); if let Some(entry) = prov.first() { // If it overlaps with this byte, it is on this byte. - debug_assert!(self.bytes.as_ref().map_or(true, |b| b.get(&offset).is_none())); + debug_assert!(self.bytes.as_ref().is_none_or(|b| b.get(&offset).is_none())); Some(entry.1) } else { // Look up per-byte provenance. @@ -301,7 +301,7 @@ impl ProvenanceMap { // For really small copies, make sure we don't start before `src` does. let entry_start = cmp::max(entry.0, src.start); for offset in entry_start..src.end() { - if bytes.last().map_or(true, |bytes_entry| bytes_entry.0 < offset) { + if bytes.last().is_none_or(|bytes_entry| bytes_entry.0 < offset) { // The last entry, if it exists, has a lower offset than us. bytes.push((offset, entry.1)); } else { diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 33d39b137b6d9..c4d5367e2f03a 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -433,7 +433,7 @@ pub fn analyze_coroutine_closure_captures<'a, 'tcx: 'a, T>( // A parent matches a child if they share the same prefix of projections. // The child may have more, if it is capturing sub-fields out of // something that is captured by-move in the parent closure. - while child_captures.peek().map_or(false, |(_, child_capture)| { + while child_captures.peek().is_some_and(|(_, child_capture)| { child_prefix_matches_parent_projections(parent_capture, child_capture) }) { let (child_field_idx, child_capture) = child_captures.next().unwrap(); diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index e4ded2c30f539..b7a648aae3f19 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -328,7 +328,7 @@ impl<'tcx> InstanceKind<'tcx> { // We include enums without destructors to allow, say, optimizing // drops of `Option::None` before LTO. We also respect the intent of // `#[inline]` on `Drop::drop` implementations. - return ty.ty_adt_def().map_or(true, |adt_def| { + return ty.ty_adt_def().is_none_or(|adt_def| { match *self { ty::InstanceKind::DropGlue(..) => adt_def.destructor(tcx).map(|dtor| dtor.did), ty::InstanceKind::AsyncDropGlueCtorShim(..) => { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index bf37ae05c8251..a9a47c87a3882 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1894,11 +1894,11 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false, - ty::Tuple(tys) => tys.last().map_or(true, |ty| ty.is_trivially_sized(tcx)), + ty::Tuple(tys) => tys.last().is_none_or(|ty| ty.is_trivially_sized(tcx)), ty::Adt(def, args) => def .sized_constraint(tcx) - .map_or(true, |ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)), + .is_none_or(|ty| ty.instantiate(tcx, args).is_trivially_sized(tcx)), ty::Alias(..) | ty::Param(_) | ty::Placeholder(..) | ty::Bound(..) => false, diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 390909bb0ab0c..9120a248d95f6 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -360,7 +360,7 @@ fn find_item_ty_spans( if let Res::Def(kind, def_id) = path.res && matches!(kind, DefKind::Enum | DefKind::Struct | DefKind::Union) { - let check_params = def_id.as_local().map_or(true, |def_id| { + let check_params = def_id.as_local().is_none_or(|def_id| { if def_id == needle { spans.push(ty.span); } diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 5eed9ef798d01..995bc311b7c48 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -266,7 +266,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> { // place, i.e. the expression is a place expression and not a dereference // (since dereferencing something leads us to a different place). ExprKind::Deref { .. } => {} - ref kind if ExprCategory::of(kind).map_or(true, |cat| cat == ExprCategory::Place) => { + ref kind if ExprCategory::of(kind).is_none_or(|cat| cat == ExprCategory::Place) => { visit::walk_expr(self, expr); } diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs index e457b514936bf..9ccabb46c6332 100644 --- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs +++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs @@ -608,7 +608,7 @@ where let before = diffs_before.as_mut().map(next_in_dataflow_order); assert!(diffs_after.is_empty()); - assert!(diffs_before.as_ref().map_or(true, ExactSizeIterator::is_empty)); + assert!(diffs_before.as_ref().is_none_or(ExactSizeIterator::is_empty)); let terminator = self.cursor.body()[block].terminator(); let mut terminator_str = String::new(); diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 25dc7f31227c8..392b54c8d819b 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -135,7 +135,7 @@ impl CoverageGraph { bb_to_bcb[bb] = Some(bcb); } - let is_out_summable = basic_blocks.last().map_or(false, |&bb| { + let is_out_summable = basic_blocks.last().is_some_and(|&bb| { bcb_filtered_successors(mir_body[bb].terminator()).is_out_summable() }); let bcb_data = BasicCoverageBlockData { basic_blocks, is_out_summable }; diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 8a54a4ece983e..62a7c84bc2807 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -273,7 +273,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { // // For this we set `next_orig_uv` to the next smallest, not yet compressed, // universe of the input. - if next_orig_uv.map_or(true, |curr_next_uv| uv.cannot_name(curr_next_uv)) { + if next_orig_uv.is_none_or(|curr_next_uv| uv.cannot_name(curr_next_uv)) { next_orig_uv = Some(uv); } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 7533e75ffe261..5cd02128287e2 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -2095,7 +2095,7 @@ impl<'a> Parser<'a> { // point literal here, since there's no use of the exponent // syntax that also constitutes a valid integer, so we need // not check for that. - if suffix.map_or(true, |s| s == sym::f32 || s == sym::f64) + if suffix.is_none_or(|s| s == sym::f32 || s == sym::f64) && symbol.as_str().chars().all(|c| c.is_numeric() || c == '_') && self.token.span.hi() == next_token.span.lo() { diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index c5dc8e68fe847..34deb854e0fed 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -1231,7 +1231,7 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { continue; } - let is_positional = variant.fields.raw.first().map_or(false, |field| { + let is_positional = variant.fields.raw.first().is_some_and(|field| { field.name.as_str().starts_with(|c: char| c.is_ascii_digit()) }); let report_on = diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 5a605df88c207..1c1e8494ffc7c 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -397,7 +397,7 @@ impl Resolver<'_, '_> { } ImportKind::ExternCrate { id, .. } => { let def_id = self.local_def_id(id); - if self.extern_crate_map.get(&def_id).map_or(true, |&cnum| { + if self.extern_crate_map.get(&def_id).is_none_or(|&cnum| { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) && !tcx.has_global_allocator(cnum) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index dc26d4de57a7c..c6d10191547fe 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -322,7 +322,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let duplicate = new_binding.res().opt_def_id() == old_binding.res().opt_def_id(); let has_dummy_span = new_binding.span.is_dummy() || old_binding.span.is_dummy(); let from_item = - self.extern_prelude.get(&ident).map_or(true, |entry| entry.introduced_by_item); + self.extern_prelude.get(&ident).is_none_or(|entry| entry.introduced_by_item); // Only suggest removing an import if both bindings are to the same def, if both spans // aren't dummy spans. Further, if both bindings are imports, then the ident must have // been introduced by an item. @@ -537,7 +537,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ) { module.for_each_child(self, |_this, ident, _ns, binding| { let res = binding.res(); - if filter_fn(res) && ctxt.map_or(true, |ctxt| ctxt == ident.span.ctxt()) { + if filter_fn(res) && ctxt.is_none_or(|ctxt| ctxt == ident.span.ctxt()) { names.push(TypoSuggestion::typo_from_ident(ident, res)); } }); @@ -1229,7 +1229,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { _ => res.opt_def_id(), }; let child_doc_visible = doc_visible - && (did.map_or(true, |did| did.is_local() || !this.tcx.is_doc_hidden(did))); + && did.is_none_or(|did| did.is_local() || !this.tcx.is_doc_hidden(did)); // collect results based on the filter function // avoid suggesting anything from the same module in which we are resolving diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index cad45d3c29319..29b4d913c82da 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -289,7 +289,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let ImportKind::Glob { ref max_vis, .. } = import.kind { if vis == import_vis - || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self.tcx)) + || max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)) { max_vis.set(Some(vis.expect_local())) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1a0292ebbde63..bbcbb5d1ce474 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -612,7 +612,7 @@ impl MaybeExported<'_> { return vis.kind.is_pub(); } }; - def_id.map_or(true, |def_id| r.effective_visibilities.is_exported(def_id)) + def_id.is_none_or(|def_id| r.effective_visibilities.is_exported(def_id)) } } @@ -5104,7 +5104,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { fn def_id_matches_path(tcx: TyCtxt<'_>, mut def_id: DefId, expected_path: &[&str]) -> bool { let mut path = expected_path.iter().rev(); while let (Some(parent), Some(next_step)) = (tcx.opt_parent(def_id), path.next()) { - if !tcx.opt_item_name(def_id).map_or(false, |n| n.as_str() == *next_step) { + if !tcx.opt_item_name(def_id).is_some_and(|n| n.as_str() == *next_step) { return false; } def_id = parent; diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 2936d722aa7f0..17c92c7b501cc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1696,7 +1696,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { ) => { // Don't suggest macro if it's unstable. let suggestable = def_id.is_local() - || self.r.tcx.lookup_stability(def_id).map_or(true, |s| s.is_stable()); + || self.r.tcx.lookup_stability(def_id).is_none_or(|s| s.is_stable()); err.span_label(span, fallback_label.to_string()); @@ -2135,7 +2135,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .r .delegation_fn_sigs .get(&self.r.local_def_id(assoc_item.id)) - .map_or(false, |sig| sig.has_self) => + .is_some_and(|sig| sig.has_self) => { AssocSuggestion::MethodWithSelf { called } } @@ -2166,7 +2166,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { .r .delegation_fn_sigs .get(&def_id) - .map_or(false, |sig| sig.has_self), + .is_some_and(|sig| sig.has_self), None => self .r .tcx diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 8e457e68eecf0..3b18e480be442 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1242,7 +1242,7 @@ impl<'ra> ResolverArenas<'ra> { no_implicit_prelude, )))); let def_id = module.opt_def_id(); - if def_id.map_or(true, |def_id| def_id.is_local()) { + if def_id.is_none_or(|def_id| def_id.is_local()) { self.local_modules.borrow_mut().push(module); } if let Some(def_id) = def_id { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 25e35fead7e83..a26a7cbfca0cf 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1055,7 +1055,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { span: Span, ) { if let Some(Res::NonMacroAttr(kind)) = res { - if kind != NonMacroAttrKind::Tool && binding.map_or(true, |b| b.is_import()) { + if kind != NonMacroAttrKind::Tool && binding.is_none_or(|b| b.is_import()) { let binding_span = binding.map(|binding| binding.span); self.dcx().emit_err(errors::CannotUseThroughAnImport { span, diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 7998596c59eff..fecb973501933 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -350,10 +350,7 @@ pub fn strip_generics_from_path(path_str: &str) -> Result, MalformedGen /// If there are no doc-comments, return true. /// FIXME(#78591): Support both inner and outer attributes on the same item. pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { - attrs - .iter() - .find(|a| a.doc_str().is_some()) - .map_or(true, |a| a.style() == ast::AttrStyle::Inner) + attrs.iter().find(|a| a.doc_str().is_some()).is_none_or(|a| a.style() == ast::AttrStyle::Inner) } /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 21afb7df7cb3a..9cd93817b4ce5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -675,7 +675,7 @@ impl OutputTypes { /// Returns `true` if user specified a name and not just produced type pub fn contains_explicit_name(&self, key: &OutputType) -> bool { - self.0.get(key).map_or(false, |f| f.is_some()) + self.0.get(key).is_some_and(|f| f.is_some()) } pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option> { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 3416a17624e91..33603ea66dbc3 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -420,8 +420,7 @@ fn make_elided_region_spans_suggs<'a>( let mut process_consecutive_brackets = |span: Option, spans_suggs: &mut Vec<(Span, String)>| { - if span - .is_some_and(|span| bracket_span.map_or(true, |bracket_span| span == bracket_span)) + if span.is_some_and(|span| bracket_span.is_none_or(|bracket_span| span == bracket_span)) { consecutive_brackets += 1; } else if let Some(bracket_span) = bracket_span.take() { From 1951d86a35c2b7d5c5434493f1897425cbfd8e96 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sun, 19 Jan 2025 20:50:43 +0000 Subject: [PATCH 12/12] Manual cleanup of some `is_{or_none|some_and}` usages --- compiler/rustc_errors/src/json.rs | 3 ++- compiler/rustc_errors/src/lib.rs | 3 ++- compiler/rustc_metadata/src/creader.rs | 3 ++- .../src/mir/interpret/allocation/provenance_map.rs | 2 +- compiler/rustc_middle/src/ty/diagnostics.rs | 2 +- compiler/rustc_session/src/config.rs | 4 ++-- .../infer/nice_region_error/static_impl_trait.rs | 3 ++- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 6a3f8ca497a57..c1188665a05f4 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -463,7 +463,8 @@ impl DiagnosticSpan { // is an empty string, increase the length to include the newline so we don't // leave an empty line if start.col.0 == 0 - && suggestion.is_some_and(|(s, _)| s.is_empty()) + && let Some((suggestion, _)) = suggestion + && suggestion.is_empty() && let Ok(after) = je.sm.span_to_next_source(span) && after.starts_with('\n') { diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6e5958a20d0b9..549729548f537 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -35,6 +35,7 @@ use std::backtrace::{Backtrace, BacktraceStatus}; use std::borrow::Cow; use std::cell::Cell; use std::error::Report; +use std::ffi::OsStr; use std::hash::Hash; use std::io::Write; use std::num::NonZero; @@ -1717,7 +1718,7 @@ impl DiagCtxtInner { let bugs: Vec<_> = std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect(); - let backtrace = std::env::var_os("RUST_BACKTRACE").is_none_or(|x| &x != "0"); + let backtrace = std::env::var_os("RUST_BACKTRACE").as_deref() != Some(OsStr::new("0")); let decorate = backtrace || self.ice_file.is_none(); let mut out = self .ice_file diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 586b38ff14443..a6db12f893255 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -417,7 +417,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { // Any descendants of `std` should be private. These crates are usually not marked // private in metadata, so we ignore that field. if extern_private.is_none() - && dep_root.is_some_and(|d| STDLIB_STABLE_CRATES.contains(&d.name)) + && let Some(dep) = dep_root + && STDLIB_STABLE_CRATES.contains(&dep.name) { return true; } diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs index ab4d59185a52b..78196b0536190 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs @@ -97,7 +97,7 @@ impl ProvenanceMap { debug_assert!(prov.len() <= 1); if let Some(entry) = prov.first() { // If it overlaps with this byte, it is on this byte. - debug_assert!(self.bytes.as_ref().is_none_or(|b| b.get(&offset).is_none())); + debug_assert!(self.bytes.as_ref().is_none_or(|b| !b.contains_key(&offset))); Some(entry.1) } else { // Look up per-byte provenance. diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 77745599afb92..e4187d2760c3d 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -336,7 +336,7 @@ pub fn suggest_constraining_type_params<'a>( .collect(); constraints - .retain(|(_, def_id, _)| def_id.map_or(true, |def| !bound_trait_defs.contains(&def))); + .retain(|(_, def_id, _)| def_id.is_none_or(|def| !bound_trait_defs.contains(&def))); if constraints.is_empty() { continue; diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 9cd93817b4ce5..e9d0fc04c1363 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -675,7 +675,7 @@ impl OutputTypes { /// Returns `true` if user specified a name and not just produced type pub fn contains_explicit_name(&self, key: &OutputType) -> bool { - self.0.get(key).is_some_and(|f| f.is_some()) + matches!(self.0.get(key), Some(Some(..))) } pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option> { @@ -1951,7 +1951,7 @@ fn collect_print_requests( matches: &getopts::Matches, ) -> Vec { let mut prints = Vec::::new(); - if cg.target_cpu.as_ref().is_some_and(|s| s == "help") { + if cg.target_cpu.as_deref() == Some("help") { prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout }); cg.target_cpu = None; }; diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs index 33603ea66dbc3..503090b579716 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/static_impl_trait.rs @@ -420,7 +420,8 @@ fn make_elided_region_spans_suggs<'a>( let mut process_consecutive_brackets = |span: Option, spans_suggs: &mut Vec<(Span, String)>| { - if span.is_some_and(|span| bracket_span.is_none_or(|bracket_span| span == bracket_span)) + if let Some(span) = span + && bracket_span.is_none_or(|bracket_span| span == bracket_span) { consecutive_brackets += 1; } else if let Some(bracket_span) = bracket_span.take() {