| 1 | //! Data structures for handling diagnostic output from tests. | 
| 2 |  | 
|---|
| 3 | use std::path::Path; | 
|---|
| 4 |  | 
|---|
| 5 | #[ cfg(feature = "rustc")] | 
|---|
| 6 | pub mod rustc; | 
|---|
| 7 |  | 
|---|
| 8 | /// Default diagnostics extractor that does nothing. | 
|---|
| 9 | pub fn default_diagnostics_extractor(_path: &Path, _stderr: &[u8]) -> Diagnostics { | 
|---|
| 10 | Diagnostics::default() | 
|---|
| 11 | } | 
|---|
| 12 |  | 
|---|
| 13 | /// The different levels of diagnostic messages and their relative ranking. | 
|---|
| 14 | #[ derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] | 
|---|
| 15 | pub enum Level { | 
|---|
| 16 | /// internal compiler errors | 
|---|
| 17 | Ice = 5, | 
|---|
| 18 | /// ´error´ level messages | 
|---|
| 19 | Error = 4, | 
|---|
| 20 | /// ´warn´ level messages | 
|---|
| 21 | Warn = 3, | 
|---|
| 22 | /// ´help´ level messages | 
|---|
| 23 | Help = 2, | 
|---|
| 24 | /// ´note´ level messages | 
|---|
| 25 | Note = 1, | 
|---|
| 26 | /// Only used for "For more information about this error, try `rustc --explain EXXXX`". | 
|---|
| 27 | FailureNote = 0, | 
|---|
| 28 | } | 
|---|
| 29 |  | 
|---|
| 30 | impl std::str::FromStr for Level { | 
|---|
| 31 | type Err = String; | 
|---|
| 32 | fn from_str(s: &str) -> Result<Self, Self::Err> { | 
|---|
| 33 | match s { | 
|---|
| 34 | "ERROR"| "error"=> Ok(Self::Error), | 
|---|
| 35 | "WARN"| "warning"=> Ok(Self::Warn), | 
|---|
| 36 | "HELP"| "help"=> Ok(Self::Help), | 
|---|
| 37 | "NOTE"| "note"=> Ok(Self::Note), | 
|---|
| 38 | "failure-note"=> Ok(Self::FailureNote), | 
|---|
| 39 | "ICE"| "ice"=> Ok(Self::Ice), | 
|---|
| 40 | _ => Err(format!( "unknown level `{s} `")), | 
|---|
| 41 | } | 
|---|
| 42 | } | 
|---|
| 43 | } | 
|---|
| 44 |  | 
|---|
| 45 | /// A diagnostic message. | 
|---|
| 46 | #[ derive(Debug)] | 
|---|
| 47 | pub struct Message { | 
|---|
| 48 | /// The diagnostic level at which this message was emitted | 
|---|
| 49 | pub level: Level, | 
|---|
| 50 | /// The main message of the diagnostic (what will be matched for with `//~`) | 
|---|
| 51 | pub message: String, | 
|---|
| 52 | /// Information about where in the file the message was emitted | 
|---|
| 53 | pub line: Option<usize>, | 
|---|
| 54 | /// Exact span information of the message | 
|---|
| 55 | pub span: Option<spanned::Span>, | 
|---|
| 56 | /// Identifier of the message (E0XXX for rustc errors, or lint names) | 
|---|
| 57 | pub code: Option<String>, | 
|---|
| 58 | } | 
|---|
| 59 |  | 
|---|
| 60 | /// All the diagnostics that were emitted in a test. | 
|---|
| 61 | #[ derive(Default, Debug)] | 
|---|
| 62 | pub struct Diagnostics { | 
|---|
| 63 | /// Rendered and concatenated version of all diagnostics. | 
|---|
| 64 | /// This is equivalent to non-json diagnostics. | 
|---|
| 65 | pub rendered: Vec<u8>, | 
|---|
| 66 | /// Per line, a list of messages for that line. | 
|---|
| 67 | pub messages: Vec<Vec<Message>>, | 
|---|
| 68 | /// Messages not on any line (usually because they are from libstd) | 
|---|
| 69 | pub messages_from_unknown_file_or_line: Vec<Message>, | 
|---|
| 70 | } | 
|---|
| 71 |  | 
|---|