Skip to content

Commit 5e1f8e2

Browse files
committed
diagnostics: add a macro to make things a bit easier to read
1 parent 7bc7e67 commit 5e1f8e2

File tree

1 file changed

+59
-76
lines changed

1 file changed

+59
-76
lines changed

src/tools/miri/src/diagnostics.rs

+59-76
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ pub enum DiagLevel {
140140
Note,
141141
}
142142

143+
/// Generate a note/help text without a span.
144+
macro_rules! note {
145+
($($tt:tt)*) => { (None, format!($($tt)*)) };
146+
}
147+
/// Generate a note/help text with a span.
148+
macro_rules! note_span {
149+
($span:expr, $($tt:tt)*) => { (Some($span), format!($($tt)*)) };
150+
}
151+
143152
/// Attempts to prune a stacktrace to omit the Rust runtime, and returns a bool indicating if any
144153
/// frames were pruned. If the stacktrace does not have any local frames, we conclude that it must
145154
/// be pointing to a problem in the Rust runtime itself, and do not prune it at all.
@@ -228,38 +237,38 @@ pub fn report_error<'tcx>(
228237
let helps = match info {
229238
UnsupportedInIsolation(_) =>
230239
vec![
231-
(None, format!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;")),
232-
(None, format!("or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning")),
240+
note!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;"),
241+
note!("or set `MIRIFLAGS=-Zmiri-isolation-error=warn` to make Miri return an error code from isolated operations (if supported for that operation) and continue with a warning"),
233242
],
234243
UnsupportedForeignItem(_) => {
235244
vec![
236-
(None, format!("if this is a basic API commonly used on this target, please report an issue with Miri")),
237-
(None, format!("however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases")),
245+
note!("if this is a basic API commonly used on this target, please report an issue with Miri"),
246+
note!("however, note that Miri does not aim to support every FFI function out there; for instance, we will not support APIs for things such as GUIs, scripting languages, or databases"),
238247
]
239248
}
240249
StackedBorrowsUb { help, history, .. } => {
241250
msg.extend(help.clone());
242251
let mut helps = vec![
243-
(None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental")),
244-
(None, format!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information")),
252+
note!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental"),
253+
note!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information"),
245254
];
246255
if let Some(TagHistory {created, invalidated, protected}) = history.clone() {
247256
helps.push((Some(created.1), created.0));
248257
if let Some((msg, span)) = invalidated {
249-
helps.push((Some(span), msg));
258+
helps.push(note_span!(span, "{msg}"));
250259
}
251260
if let Some((protector_msg, protector_span)) = protected {
252-
helps.push((Some(protector_span), protector_msg));
261+
helps.push(note_span!(protector_span, "{protector_msg}"));
253262
}
254263
}
255264
helps
256265
},
257266
TreeBorrowsUb { title: _, details, history } => {
258267
let mut helps = vec![
259-
(None, format!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental"))
268+
note!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental")
260269
];
261270
for m in details {
262-
helps.push((None, m.clone()));
271+
helps.push(note!("{m}"));
263272
}
264273
for event in history.events.clone() {
265274
helps.push(event);
@@ -268,26 +277,26 @@ pub fn report_error<'tcx>(
268277
}
269278
MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } =>
270279
vec![
271-
(Some(*first), format!("it's first defined here, in crate `{first_crate}`")),
272-
(Some(*second), format!("then it's defined here again, in crate `{second_crate}`")),
280+
note_span!(*first, "it's first defined here, in crate `{first_crate}`"),
281+
note_span!(*second, "then it's defined here again, in crate `{second_crate}`"),
273282
],
274283
SymbolShimClashing { link_name, span } =>
275-
vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))],
284+
vec![note_span!(*span, "the `{link_name}` symbol is defined here")],
276285
Int2PtrWithStrictProvenance =>
277-
vec![(None, format!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"))],
286+
vec![note!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead")],
278287
DataRace { op1, extra, retag_explain, .. } => {
279-
let mut helps = vec![(Some(op1.span), format!("and (1) occurred earlier here"))];
288+
let mut helps = vec![note_span!(op1.span, "and (1) occurred earlier here")];
280289
if let Some(extra) = extra {
281-
helps.push((None, format!("{extra}")));
282-
helps.push((None, format!("see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model")));
290+
helps.push(note!("{extra}"));
291+
helps.push(note!("see https://doc.rust-lang.org/nightly/std/sync/atomic/index.html#memory-model-for-atomic-accesses for more information about the Rust memory model"));
283292
}
284293
if *retag_explain {
285-
helps.push((None, "retags occur on all (re)borrows and as well as when references are copied or moved".to_owned()));
286-
helps.push((None, "retags permit optimizations that insert speculative reads or writes".to_owned()));
287-
helps.push((None, "therefore from the perspective of data races, a retag has the same implications as a read or write".to_owned()));
294+
helps.push(note!("retags occur on all (re)borrows and as well as when references are copied or moved"));
295+
helps.push(note!("retags permit optimizations that insert speculative reads or writes"));
296+
helps.push(note!("therefore from the perspective of data races, a retag has the same implications as a read or write"));
288297
}
289-
helps.push((None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")));
290-
helps.push((None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")));
298+
helps.push(note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"));
299+
helps.push(note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"));
291300
helps
292301
}
293302
,
@@ -332,32 +341,32 @@ pub fn report_error<'tcx>(
332341
let helps = match e.kind() {
333342
Unsupported(_) =>
334343
vec![
335-
(None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support")),
344+
note!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support"),
336345
],
337346
UndefinedBehavior(AlignmentCheckFailed { .. })
338347
if ecx.machine.check_alignment == AlignmentCheck::Symbolic
339348
=>
340349
vec![
341-
(None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")),
342-
(None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")),
350+
note!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior"),
351+
note!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives"),
343352
],
344353
UndefinedBehavior(info) => {
345354
let mut helps = vec![
346-
(None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")),
347-
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
355+
note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"),
356+
note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"),
348357
];
349358
match info {
350359
PointerUseAfterFree(alloc_id, _) | PointerOutOfBounds { alloc_id, .. } => {
351360
if let Some(span) = ecx.machine.allocated_span(*alloc_id) {
352-
helps.push((Some(span), format!("{:?} was allocated here:", alloc_id)));
361+
helps.push(note_span!(span, "{:?} was allocated here:", alloc_id));
353362
}
354363
if let Some(span) = ecx.machine.deallocated_span(*alloc_id) {
355-
helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id)));
364+
helps.push(note_span!(span, "{:?} was deallocated here:", alloc_id));
356365
}
357366
}
358367
AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => {
359-
helps.push((None, format!("this means these two types are not *guaranteed* to be ABI-compatible across all targets")));
360-
helps.push((None, format!("if you think this code should be accepted anyway, please report an issue with Miri")));
368+
helps.push(note!("this means these two types are not *guaranteed* to be ABI-compatible across all targets"));
369+
helps.push(note!("if you think this code should be accepted anyway, please report an issue with Miri"));
361370
}
362371
_ => {},
363372
}
@@ -639,73 +648,47 @@ impl<'tcx> MiriMachine<'tcx> {
639648

640649
let notes = match &e {
641650
ProgressReport { block_count } => {
642-
// It is important that each progress report is slightly different, since
643-
// identical diagnostics are being deduplicated.
644-
vec![(None, format!("so far, {block_count} basic blocks have been executed"))]
651+
vec![note!("so far, {block_count} basic blocks have been executed")]
645652
}
646653
_ => vec![],
647654
};
648655

649656
let helps = match &e {
650657
Int2Ptr { details: true } => {
651658
let mut v = vec![
652-
(
653-
None,
654-
format!(
655-
"this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program"
656-
),
659+
note!(
660+
"this program is using integer-to-pointer casts or (equivalently) `ptr::with_exposed_provenance`, which means that Miri might miss pointer bugs in this program"
657661
),
658-
(
659-
None,
660-
format!(
661-
"see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation"
662-
),
662+
note!(
663+
"see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation"
663664
),
664-
(
665-
None,
666-
format!(
667-
"to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"
668-
),
665+
note!(
666+
"to ensure that Miri does not miss bugs in your program, use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead"
669667
),
670-
(
671-
None,
672-
format!(
673-
"you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics"
674-
),
668+
note!(
669+
"you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics"
675670
),
676671
];
677672
if self.borrow_tracker.as_ref().is_some_and(|b| {
678673
matches!(b.borrow().borrow_tracker_method(), BorrowTrackerMethod::TreeBorrows)
679674
}) {
680-
v.push((
681-
None,
682-
format!(
683-
"Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used"
684-
),
685-
));
675+
v.push(
676+
note!("Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used")
677+
);
686678
} else {
687-
v.push((
688-
None,
689-
format!(
690-
"alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning"
691-
),
692-
));
679+
v.push(
680+
note!("alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning")
681+
);
693682
}
694683
v
695684
}
696685
ExternTypeReborrow => {
697686
vec![
698-
(
699-
None,
700-
format!(
701-
"`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code"
702-
),
687+
note!(
688+
"`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code"
703689
),
704-
(
705-
None,
706-
format!(
707-
"try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead"
708-
),
690+
note!(
691+
"try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead"
709692
),
710693
]
711694
}

0 commit comments

Comments
 (0)