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) 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..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.map_or(false, |(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 cc5eb9c335e8c..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").map_or(true, |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_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..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.map_or(false, |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 3a83b184d83d5..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().map_or(true, |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. @@ -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/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_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_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index 7785f1a7f81fb..43c34a109d721 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -1,5 +1,19 @@ -privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private -privacy_field_is_private_is_update_syntax_label = field `{$field_name}` 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 = {$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 f5e641eb64243..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,12 +7,15 @@ use rustc_span::{Span, Symbol}; #[diag(privacy_field_is_private, code = E0451)] pub(crate) struct FieldIsPrivate { #[primary_span] - pub span: Span, - pub field_name: Symbol, + pub span: MultiSpan, + #[label] + pub struct_span: Option, + 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)] @@ -21,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 e484cfed06b33..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,31 +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, - ) { + ) -> 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, - 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( @@ -955,7 +1020,9 @@ impl<'tcx> NamePrivacyVisitor<'tcx> { fields: &[hir::ExprField<'tcx>], hir_id: hir::HirId, 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); @@ -963,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); + 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); } } @@ -990,24 +1064,35 @@ 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 => { + 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, - ); + 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()); } } } @@ -1020,11 +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); + 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/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..3d2042952b3f5 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()) + matches!(self.0.get(key), Some(Some(..))) } pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option> { @@ -888,7 +888,7 @@ impl Input { Input::File(file) => Some(file), Input::Str { name, .. } => match name { FileName::Real(real) => real.local_path(), - FileName::QuoteExpansion(_) => None, + FileName::CfgSpec(_) => None, FileName::Anon(_) => None, FileName::MacroExpansion(_) => None, FileName::ProcMacroSourceCode(_) => None, @@ -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_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 51cfbf594716c..f932d3c8073db 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -305,8 +305,8 @@ impl RealFileName { #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash, Decodable, Encodable)] pub enum FileName { Real(RealFileName), - /// Call to `quote!`. - QuoteExpansion(Hash64), + /// Strings provided as `--cfg [cfgspec]`. + CfgSpec(Hash64), /// Command line. Anon(Hash64), /// Hack in `src/librustc_ast/parse.rs`. @@ -353,7 +353,7 @@ impl fmt::Display for FileNameDisplay<'_> { Real(ref name) => { write!(fmt, "{}", name.to_string_lossy(self.display_pref)) } - QuoteExpansion(_) => write!(fmt, ""), + CfgSpec(_) => write!(fmt, ""), MacroExpansion(_) => write!(fmt, ""), Anon(_) => write!(fmt, ""), ProcMacroSourceCode(_) => write!(fmt, ""), @@ -384,7 +384,7 @@ impl FileName { | ProcMacroSourceCode(_) | CliCrateAttr(_) | Custom(_) - | QuoteExpansion(_) + | CfgSpec(_) | DocTest(_, _) | InlineAsm(_) => false, } @@ -425,7 +425,7 @@ impl FileName { pub fn cfg_spec_source_code(src: &str) -> FileName { let mut hasher = StableHasher::new(); src.hash(&mut hasher); - FileName::QuoteExpansion(hasher.finish()) + FileName::CfgSpec(hasher.finish()) } pub fn cli_crate_attr_source_code(src: &str) -> FileName { 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..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,8 +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.map_or(true, |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() { 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/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 1c49063ef5c66..b5310108dbf70 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -2875,21 +2875,26 @@ impl Config { allowed_paths.push(":!library"); } - // Look for a version to compare to based on the current commit. - // Only commits merged by bors will have CI artifacts. - let commit = match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) - { - Some(commit) => commit, - None => { - if if_unchanged { - return None; + let commit = if self.rust_info.is_managed_git_subrepository() { + // Look for a version to compare to based on the current commit. + // Only commits merged by bors will have CI artifacts. + match self.last_modified_commit(&allowed_paths, "download-rustc", if_unchanged) { + Some(commit) => commit, + None => { + if if_unchanged { + return None; + } + println!("ERROR: could not find commit hash for downloading rustc"); + println!("HELP: maybe your repository history is too shallow?"); + println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); + println!("HELP: or fetch enough history to include one upstream commit"); + crate::exit!(1); } - println!("ERROR: could not find commit hash for downloading rustc"); - println!("HELP: maybe your repository history is too shallow?"); - println!("HELP: consider setting `rust.download-rustc=false` in config.toml"); - println!("HELP: or fetch enough history to include one upstream commit"); - crate::exit!(1); } + } else { + channel::read_commit_info_file(&self.src) + .map(|info| info.sha.trim().to_owned()) + .expect("git-commit-info is missing in the project root") }; if CiEnv::is_ci() && { @@ -2971,6 +2976,11 @@ impl Config { option_name: &str, if_unchanged: bool, ) -> Option { + assert!( + self.rust_info.is_managed_git_subrepository(), + "Can't run `Config::last_modified_commit` on a non-git source." + ); + // Look for a version to compare to based on the current commit. // Only commits merged by bors will have CI artifacts. let commit = get_closest_merge_commit(Some(&self.src), &self.git_config(), &[]).unwrap(); 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", + }, ]; 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 diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 2098073409da5..95ae1b04d8611 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -739,8 +739,11 @@ 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 + | ^ 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 new file mode 100644 index 0000000000000..ff1245551b0ad --- /dev/null +++ b/tests/ui/structs/default-field-values/visibility.rs @@ -0,0 +1,42 @@ +#![feature(default_field_values)] +pub mod foo { + #[derive(Default)] + pub struct Alpha { + beta: u8 = 42, + gamma: bool = true, + } +} + +mod bar { + use crate::foo::Alpha; + fn baz() { + 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 + } +} + +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..38b9603325235 --- /dev/null +++ b/tests/ui/structs/default-field-values/visibility.stderr @@ -0,0 +1,61 @@ +error[E0451]: field `x` of struct `S` is private + --> $DIR/visibility.rs:37: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:40:9 + | +LL | let _b = baz::S { + | ------ in this type +LL | x: 0, + | ^ private field + +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:13:26 + | +LL | let _x = Alpha { .. }; + | ^^ fields `beta` and `gamma` are private + +error[E0451]: fields `beta` and `gamma` of struct `Alpha` are private + --> $DIR/visibility.rs:16:13 + | +LL | let _x = Alpha { + | ----- in this type +LL | beta: 0, + | ^^^^ private field +LL | gamma: false, + | ^^^^^ private field + +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