diff options
| author | Ralf Jung <post@ralfj.de> | 2024-07-26 09:06:58 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2024-07-26 14:51:04 +0200 |
| commit | 5e1f8e2d07d2a32a1f234cf80efcb703aa87a989 (patch) | |
| tree | 6a509bd12de098af59e7a3a124198dd1bf44f603 | |
| parent | 7bc7e6789ac0cd4bab726f3d18c8e1201674f1fc (diff) | |
| download | rust-5e1f8e2d07d2a32a1f234cf80efcb703aa87a989.tar.gz rust-5e1f8e2d07d2a32a1f234cf80efcb703aa87a989.zip | |
diagnostics: add a macro to make things a bit easier to read
| -rw-r--r-- | src/tools/miri/src/diagnostics.rs | 135 |
1 files changed, 59 insertions, 76 deletions
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 6d10a21293b..1bed55743d4 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -140,6 +140,15 @@ pub enum DiagLevel { Note, } +/// Generate a note/help text without a span. +macro_rules! note { + ($($tt:tt)*) => { (None, format!($($tt)*)) }; +} +/// Generate a note/help text with a span. +macro_rules! note_span { + ($span:expr, $($tt:tt)*) => { (Some($span), format!($($tt)*)) }; +} + /// Attempts to prune a stacktrace to omit the Rust runtime, and returns a bool indicating if any /// frames were pruned. If the stacktrace does not have any local frames, we conclude that it must /// 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>( let helps = match info { UnsupportedInIsolation(_) => vec![ - (None, format!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;")), - (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")), + note!("set `MIRIFLAGS=-Zmiri-disable-isolation` to disable isolation;"), + 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"), ], UnsupportedForeignItem(_) => { vec![ - (None, format!("if this is a basic API commonly used on this target, please report an issue with Miri")), - (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")), + note!("if this is a basic API commonly used on this target, please report an issue with Miri"), + 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"), ] } StackedBorrowsUb { help, history, .. } => { msg.extend(help.clone()); let mut helps = vec![ - (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")), - (None, format!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information")), + note!("this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental"), + note!("see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information"), ]; if let Some(TagHistory {created, invalidated, protected}) = history.clone() { helps.push((Some(created.1), created.0)); if let Some((msg, span)) = invalidated { - helps.push((Some(span), msg)); + helps.push(note_span!(span, "{msg}")); } if let Some((protector_msg, protector_span)) = protected { - helps.push((Some(protector_span), protector_msg)); + helps.push(note_span!(protector_span, "{protector_msg}")); } } helps }, TreeBorrowsUb { title: _, details, history } => { let mut helps = vec![ - (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")) + note!("this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental") ]; for m in details { - helps.push((None, m.clone())); + helps.push(note!("{m}")); } for event in history.events.clone() { helps.push(event); @@ -268,26 +277,26 @@ pub fn report_error<'tcx>( } MultipleSymbolDefinitions { first, first_crate, second, second_crate, .. } => vec![ - (Some(*first), format!("it's first defined here, in crate `{first_crate}`")), - (Some(*second), format!("then it's defined here again, in crate `{second_crate}`")), + note_span!(*first, "it's first defined here, in crate `{first_crate}`"), + note_span!(*second, "then it's defined here again, in crate `{second_crate}`"), ], SymbolShimClashing { link_name, span } => - vec![(Some(*span), format!("the `{link_name}` symbol is defined here"))], + vec![note_span!(*span, "the `{link_name}` symbol is defined here")], Int2PtrWithStrictProvenance => - 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"))], + vec![note!("use Strict Provenance APIs (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance, https://crates.io/crates/sptr) instead")], DataRace { op1, extra, retag_explain, .. } => { - let mut helps = vec![(Some(op1.span), format!("and (1) occurred earlier here"))]; + let mut helps = vec![note_span!(op1.span, "and (1) occurred earlier here")]; if let Some(extra) = extra { - helps.push((None, format!("{extra}"))); - 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"))); + helps.push(note!("{extra}")); + 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")); } if *retag_explain { - helps.push((None, "retags occur on all (re)borrows and as well as when references are copied or moved".to_owned())); - helps.push((None, "retags permit optimizations that insert speculative reads or writes".to_owned())); - helps.push((None, "therefore from the perspective of data races, a retag has the same implications as a read or write".to_owned())); + helps.push(note!("retags occur on all (re)borrows and as well as when references are copied or moved")); + helps.push(note!("retags permit optimizations that insert speculative reads or writes")); + helps.push(note!("therefore from the perspective of data races, a retag has the same implications as a read or write")); } - helps.push((None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"))); - helps.push((None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"))); + helps.push(note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")); + helps.push(note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")); helps } , @@ -332,32 +341,32 @@ pub fn report_error<'tcx>( let helps = match e.kind() { Unsupported(_) => vec![ - (None, format!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support")), + note!("this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support"), ], UndefinedBehavior(AlignmentCheckFailed { .. }) if ecx.machine.check_alignment == AlignmentCheck::Symbolic => vec![ - (None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")), - (None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")), + note!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior"), + note!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives"), ], UndefinedBehavior(info) => { let mut helps = vec![ - (None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")), - (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")), + note!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior"), + note!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information"), ]; match info { PointerUseAfterFree(alloc_id, _) | PointerOutOfBounds { alloc_id, .. } => { if let Some(span) = ecx.machine.allocated_span(*alloc_id) { - helps.push((Some(span), format!("{:?} was allocated here:", alloc_id))); + helps.push(note_span!(span, "{:?} was allocated here:", alloc_id)); } if let Some(span) = ecx.machine.deallocated_span(*alloc_id) { - helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id))); + helps.push(note_span!(span, "{:?} was deallocated here:", alloc_id)); } } AbiMismatchArgument { .. } | AbiMismatchReturn { .. } => { - helps.push((None, format!("this means these two types are not *guaranteed* to be ABI-compatible across all targets"))); - helps.push((None, format!("if you think this code should be accepted anyway, please report an issue with Miri"))); + helps.push(note!("this means these two types are not *guaranteed* to be ABI-compatible across all targets")); + helps.push(note!("if you think this code should be accepted anyway, please report an issue with Miri")); } _ => {}, } @@ -639,9 +648,7 @@ impl<'tcx> MiriMachine<'tcx> { let notes = match &e { ProgressReport { block_count } => { - // It is important that each progress report is slightly different, since - // identical diagnostics are being deduplicated. - vec![(None, format!("so far, {block_count} basic blocks have been executed"))] + vec![note!("so far, {block_count} basic blocks have been executed")] } _ => vec![], }; @@ -649,63 +656,39 @@ impl<'tcx> MiriMachine<'tcx> { let helps = match &e { Int2Ptr { details: true } => { let mut v = vec![ - ( - None, - format!( - "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" - ), + note!( + "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" ), - ( - None, - format!( - "see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation" - ), + note!( + "see https://doc.rust-lang.org/nightly/std/ptr/fn.with_exposed_provenance.html for more details on that operation" ), - ( - None, - format!( - "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" - ), + note!( + "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" ), - ( - None, - format!( - "you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics" - ), + note!( + "you can then set `MIRIFLAGS=-Zmiri-strict-provenance` to ensure you are not relying on `with_exposed_provenance` semantics" ), ]; if self.borrow_tracker.as_ref().is_some_and(|b| { matches!(b.borrow().borrow_tracker_method(), BorrowTrackerMethod::TreeBorrows) }) { - v.push(( - None, - format!( - "Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used" - ), - )); + v.push( + note!("Tree Borrows does not support integer-to-pointer casts, so the program is likely to go wrong when this pointer gets used") + ); } else { - v.push(( - None, - format!( - "alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning" - ), - )); + v.push( + note!("alternatively, `MIRIFLAGS=-Zmiri-permissive-provenance` disables this warning") + ); } v } ExternTypeReborrow => { vec![ - ( - None, - format!( - "`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code" - ), + note!( + "`extern type` are not compatible with the Stacked Borrows aliasing model implemented by Miri; Miri may miss bugs in this code" ), - ( - None, - format!( - "try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead" - ), + note!( + "try running with `MIRIFLAGS=-Zmiri-tree-borrows` to use the more permissive but also even more experimental Tree Borrows aliasing checks instead" ), ] } |
