Skip to content

Commit bc3e301

Browse files
committed
Auto merge of rust-lang#134992 - Zalathar:rollup-pldy5w6, r=Zalathar
Rollup of 6 pull requests Successful merges: - rust-lang#131439 (Remove allowing static_mut_refs lint) - rust-lang#133292 (E0277: suggest dereferencing function arguments in more cases) - rust-lang#134877 (add suggestion for wrongly ordered format parameters) - rust-lang#134945 (Some small nits to the borrowck suggestions for mutating a map through index) - rust-lang#134950 (bootstrap: Overhaul and simplify the `tool_check_step!` macro) - rust-lang#134979 (Provide structured suggestion for `impl Default` of type where all fields have defaults) r? `@ghost` `@rustbot` modify labels: rollup
2 parents a8953d8 + 65cb7c6 commit bc3e301

File tree

24 files changed

+482
-229
lines changed

24 files changed

+482
-229
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
575575
// ---------- place
576576
self.err.multipart_suggestions(
577577
format!(
578-
"to modify a `{}`, use `.get_mut()`, `.insert()` or the entry API",
578+
"use `.insert()` to insert a value into a `{}`, `.get_mut()` \
579+
to modify it, or the entry API for more flexibility",
579580
self.ty,
580581
),
581582
vec![
@@ -592,16 +593,17 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
592593
(rv.span.shrink_to_hi(), ")".to_string()),
593594
],
594595
vec![
595-
// val.get_mut(index).map(|v| { *v = rv; });
596+
// if let Some(v) = val.get_mut(index) { *v = rv; }
597+
(val.span.shrink_to_lo(), "if let Some(val) = ".to_string()),
596598
(
597599
val.span.shrink_to_hi().with_hi(index.span.lo()),
598600
".get_mut(".to_string(),
599601
),
600602
(
601603
index.span.shrink_to_hi().with_hi(place.span.hi()),
602-
").map(|val| { *val".to_string(),
604+
") { *val".to_string(),
603605
),
604-
(rv.span.shrink_to_hi(), "; })".to_string()),
606+
(rv.span.shrink_to_hi(), "; }".to_string()),
605607
],
606608
vec![
607609
// let x = val.entry(index).or_insert(rv);
@@ -622,21 +624,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
622624
self.suggested = true;
623625
} else if let hir::ExprKind::MethodCall(_path, receiver, _, sp) = expr.kind
624626
&& let hir::ExprKind::Index(val, index, _) = receiver.kind
625-
&& expr.span == self.assign_span
627+
&& receiver.span == self.assign_span
626628
{
627629
// val[index].path(args..);
628630
self.err.multipart_suggestion(
629631
format!("to modify a `{}` use `.get_mut()`", self.ty),
630632
vec![
633+
(val.span.shrink_to_lo(), "if let Some(val) = ".to_string()),
631634
(
632635
val.span.shrink_to_hi().with_hi(index.span.lo()),
633636
".get_mut(".to_string(),
634637
),
635638
(
636639
index.span.shrink_to_hi().with_hi(receiver.span.hi()),
637-
").map(|val| val".to_string(),
640+
") { val".to_string(),
638641
),
639-
(sp.shrink_to_hi(), ")".to_string()),
642+
(sp.shrink_to_hi(), "; }".to_string()),
640643
],
641644
Applicability::MachineApplicable,
642645
);

Diff for: compiler/rustc_builtin_macros/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ builtin_macros_format_redundant_args = redundant {$n ->
197197
198198
builtin_macros_format_remove_raw_ident = remove the `r#`
199199
200+
builtin_macros_format_reorder_format_parameter = did you mean `{$replacement}`?
201+
200202
builtin_macros_format_requires_string = requires at least a format string argument
201203
202204
builtin_macros_format_string_invalid = invalid format string: {$desc}

Diff for: compiler/rustc_builtin_macros/src/errors.rs

+11
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,17 @@ pub(crate) enum InvalidFormatStringSuggestion {
618618
#[primary_span]
619619
span: Span,
620620
},
621+
#[suggestion(
622+
builtin_macros_format_reorder_format_parameter,
623+
code = "{replacement}",
624+
style = "verbose",
625+
applicability = "machine-applicable"
626+
)]
627+
ReorderFormatParameter {
628+
#[primary_span]
629+
span: Span,
630+
replacement: String,
631+
},
621632
}
622633

623634
#[derive(Diagnostic)]

Diff for: compiler/rustc_builtin_macros/src/format.rs

+7
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,13 @@ fn make_format_args(
321321
e.sugg_ = Some(errors::InvalidFormatStringSuggestion::RemoveRawIdent { span })
322322
}
323323
}
324+
parse::Suggestion::ReorderFormatParameter(span, replacement) => {
325+
let span = fmt_span.from_inner(InnerSpan::new(span.start, span.end));
326+
e.sugg_ = Some(errors::InvalidFormatStringSuggestion::ReorderFormatParameter {
327+
span,
328+
replacement,
329+
});
330+
}
324331
}
325332
let guar = ecx.dcx().emit_err(e);
326333
return ExpandResult::Ready(Err(guar));

Diff for: compiler/rustc_driver_impl/src/signal_handler.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! Primarily used to extract a backtrace from stack overflow
33
44
use std::alloc::{Layout, alloc};
5-
use std::{fmt, mem, ptr};
5+
use std::{fmt, mem, ptr, slice};
66

77
use rustc_interface::util::{DEFAULT_STACK_SIZE, STACK_SIZE};
88

@@ -35,20 +35,22 @@ macro raw_errln($tokens:tt) {
3535
}
3636

3737
/// Signal handler installed for SIGSEGV
38-
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
39-
#[allow(static_mut_refs)]
40-
extern "C" fn print_stack_trace(_: libc::c_int) {
38+
///
39+
/// # Safety
40+
///
41+
/// Caller must ensure that this function is not re-entered.
42+
unsafe extern "C" fn print_stack_trace(_: libc::c_int) {
4143
const MAX_FRAMES: usize = 256;
42-
// Reserve data segment so we don't have to malloc in a signal handler, which might fail
43-
// in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking
44-
static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] = [ptr::null_mut(); MAX_FRAMES];
4544
let stack = unsafe {
45+
// Reserve data segment so we don't have to malloc in a signal handler, which might fail
46+
// in incredibly undesirable and unexpected ways due to e.g. the allocator deadlocking
47+
static mut STACK_TRACE: [*mut libc::c_void; MAX_FRAMES] = [ptr::null_mut(); MAX_FRAMES];
4648
// Collect return addresses
47-
let depth = libc::backtrace(STACK_TRACE.as_mut_ptr(), MAX_FRAMES as i32);
49+
let depth = libc::backtrace(&raw mut STACK_TRACE as _, MAX_FRAMES as i32);
4850
if depth == 0 {
4951
return;
5052
}
51-
&STACK_TRACE.as_slice()[0..(depth as _)]
53+
slice::from_raw_parts(&raw const STACK_TRACE as _, depth as _)
5254
};
5355

5456
// Just a stack trace is cryptic. Explain what we're doing.

Diff for: compiler/rustc_lint/src/default_could_be_derived.rs

+26-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
use rustc_data_structures::fx::FxHashMap;
2-
use rustc_errors::Diag;
2+
use rustc_errors::{Applicability, Diag};
33
use rustc_hir as hir;
44
use rustc_middle::ty;
5+
use rustc_middle::ty::TyCtxt;
56
use rustc_session::{declare_lint, impl_lint_pass};
67
use rustc_span::Symbol;
8+
use rustc_span::def_id::DefId;
79
use rustc_span::symbol::sym;
810

911
use crate::{LateContext, LateLintPass};
@@ -149,13 +151,16 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived {
149151
let hir_id = cx.tcx.local_def_id_to_hir_id(local);
150152
let hir::Node::Item(item) = cx.tcx.hir_node(hir_id) else { return };
151153
cx.tcx.node_span_lint(DEFAULT_OVERRIDES_DEFAULT_FIELDS, hir_id, item.span, |diag| {
152-
mk_lint(diag, orig_fields, fields);
154+
mk_lint(cx.tcx, diag, type_def_id, parent, orig_fields, fields);
153155
});
154156
}
155157
}
156158

157159
fn mk_lint(
160+
tcx: TyCtxt<'_>,
158161
diag: &mut Diag<'_, ()>,
162+
type_def_id: DefId,
163+
impl_def_id: DefId,
159164
orig_fields: FxHashMap<Symbol, &hir::FieldDef<'_>>,
160165
fields: &[hir::ExprField<'_>],
161166
) {
@@ -175,11 +180,24 @@ fn mk_lint(
175180
}
176181
}
177182

178-
diag.help(if removed_all_fields {
179-
"to avoid divergence in behavior between `Struct { .. }` and \
180-
`<Struct as Default>::default()`, derive the `Default`"
183+
if removed_all_fields {
184+
let msg = "to avoid divergence in behavior between `Struct { .. }` and \
185+
`<Struct as Default>::default()`, derive the `Default`";
186+
if let Some(hir::Node::Item(impl_)) = tcx.hir().get_if_local(impl_def_id) {
187+
diag.multipart_suggestion_verbose(
188+
msg,
189+
vec![
190+
(tcx.def_span(type_def_id).shrink_to_lo(), "#[derive(Default)] ".to_string()),
191+
(impl_.span, String::new()),
192+
],
193+
Applicability::MachineApplicable,
194+
);
195+
} else {
196+
diag.help(msg);
197+
}
181198
} else {
182-
"use the default values in the `impl` with `Struct { mandatory_field, .. }` to avoid them \
183-
diverging over time"
184-
});
199+
let msg = "use the default values in the `impl` with `Struct { mandatory_field, .. }` to \
200+
avoid them diverging over time";
201+
diag.help(msg);
202+
}
185203
}

Diff for: compiler/rustc_parse_format/src/lib.rs

+35
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,11 @@ pub enum Suggestion {
221221
/// Remove `r#` from identifier:
222222
/// `format!("{r#foo}")` -> `format!("{foo}")`
223223
RemoveRawIdent(InnerSpan),
224+
/// Reorder format parameter:
225+
/// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
226+
/// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
227+
/// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
228+
ReorderFormatParameter(InnerSpan, string::String),
224229
}
225230

226231
/// The parser structure for interpreting the input format string. This is
@@ -731,6 +736,12 @@ impl<'a> Parser<'a> {
731736
}
732737
} else if self.consume('?') {
733738
spec.ty = "?";
739+
if let Some(&(_, maybe)) = self.cur.peek() {
740+
match maybe {
741+
'#' | 'x' | 'X' => self.suggest_format_parameter(maybe),
742+
_ => (),
743+
}
744+
}
734745
} else {
735746
spec.ty = self.word();
736747
if !spec.ty.is_empty() {
@@ -932,6 +943,30 @@ impl<'a> Parser<'a> {
932943
}
933944
}
934945
}
946+
947+
fn suggest_format_parameter(&mut self, c: char) {
948+
let replacement = match c {
949+
'#' => "#?",
950+
'x' => "x?",
951+
'X' => "X?",
952+
_ => return,
953+
};
954+
let Some(pos) = self.consume_pos(c) else {
955+
return;
956+
};
957+
958+
let span = self.span(pos - 1, pos + 1);
959+
let pos = self.to_span_index(pos);
960+
961+
self.errors.insert(0, ParseError {
962+
description: format!("expected `}}`, found `{c}`"),
963+
note: None,
964+
label: "expected `'}'`".into(),
965+
span: pos.to(pos),
966+
secondary_label: None,
967+
suggestion: Suggestion::ReorderFormatParameter(span, format!("{replacement}")),
968+
})
969+
}
935970
}
936971

937972
/// Finds the indices of all characters that have been processed and differ between the actual

0 commit comments

Comments
 (0)