| 1 | //! This module contains `Diagnostic` and the types/functions it uses for deserialization. | 
| 2 |  | 
|---|
| 3 | #[ cfg(feature = "builder")] | 
|---|
| 4 | use derive_builder::Builder; | 
|---|
| 5 | use serde::{Deserialize, Serialize}; | 
|---|
| 6 | use std::fmt; | 
|---|
| 7 |  | 
|---|
| 8 | /// The error code associated to this diagnostic. | 
|---|
| 9 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 10 | #[ cfg_attr(feature = "builder", derive(Builder))] | 
|---|
| 11 | #[ non_exhaustive] | 
|---|
| 12 | #[ cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))] | 
|---|
| 13 | pub struct DiagnosticCode { | 
|---|
| 14 | /// The code itself. | 
|---|
| 15 | pub code: String, | 
|---|
| 16 | /// An explanation for the code | 
|---|
| 17 | pub explanation: Option<String>, | 
|---|
| 18 | } | 
|---|
| 19 |  | 
|---|
| 20 | /// A line of code associated with the Diagnostic | 
|---|
| 21 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 22 | #[ cfg_attr(feature = "builder", derive(Builder))] | 
|---|
| 23 | #[ non_exhaustive] | 
|---|
| 24 | #[ cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))] | 
|---|
| 25 | pub struct DiagnosticSpanLine { | 
|---|
| 26 | /// The line of code associated with the error | 
|---|
| 27 | pub text: String, | 
|---|
| 28 | /// Start of the section of the line to highlight. 1-based, character offset in self.text | 
|---|
| 29 | pub highlight_start: usize, | 
|---|
| 30 | /// End of the section of the line to highlight. 1-based, character offset in self.text | 
|---|
| 31 | pub highlight_end: usize, | 
|---|
| 32 | } | 
|---|
| 33 |  | 
|---|
| 34 | /// Macro expansion information associated with a diagnostic. | 
|---|
| 35 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 36 | #[ cfg_attr(feature = "builder", derive(Builder))] | 
|---|
| 37 | #[ non_exhaustive] | 
|---|
| 38 | #[ cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))] | 
|---|
| 39 | pub struct DiagnosticSpanMacroExpansion { | 
|---|
| 40 | /// span where macro was applied to generate this code; note that | 
|---|
| 41 | /// this may itself derive from a macro (if | 
|---|
| 42 | /// `span.expansion.is_some()`) | 
|---|
| 43 | pub span: DiagnosticSpan, | 
|---|
| 44 |  | 
|---|
| 45 | /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") | 
|---|
| 46 | pub macro_decl_name: String, | 
|---|
| 47 |  | 
|---|
| 48 | /// span where macro was defined (if known) | 
|---|
| 49 | pub def_site_span: Option<DiagnosticSpan>, | 
|---|
| 50 | } | 
|---|
| 51 |  | 
|---|
| 52 | /// A section of the source code associated with a Diagnostic | 
|---|
| 53 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 54 | #[ cfg_attr(feature = "builder", derive(Builder))] | 
|---|
| 55 | #[ non_exhaustive] | 
|---|
| 56 | #[ cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))] | 
|---|
| 57 | pub struct DiagnosticSpan { | 
|---|
| 58 | /// The file name or the macro name this diagnostic comes from. | 
|---|
| 59 | pub file_name: String, | 
|---|
| 60 | /// The byte offset in the file where this diagnostic starts from. | 
|---|
| 61 | pub byte_start: u32, | 
|---|
| 62 | /// The byte offset in the file where this diagnostic ends. | 
|---|
| 63 | pub byte_end: u32, | 
|---|
| 64 | /// 1-based. The line in the file. | 
|---|
| 65 | pub line_start: usize, | 
|---|
| 66 | /// 1-based. The line in the file. | 
|---|
| 67 | pub line_end: usize, | 
|---|
| 68 | /// 1-based, character offset. | 
|---|
| 69 | pub column_start: usize, | 
|---|
| 70 | /// 1-based, character offset. | 
|---|
| 71 | pub column_end: usize, | 
|---|
| 72 | /// Is this a "primary" span -- meaning the point, or one of the points, | 
|---|
| 73 | /// where the error occurred? | 
|---|
| 74 | /// | 
|---|
| 75 | /// There are rare cases where multiple spans are marked as primary, | 
|---|
| 76 | /// e.g. "immutable borrow occurs here" and "mutable borrow ends here" can | 
|---|
| 77 | /// be two separate spans both "primary". Top (parent) messages should | 
|---|
| 78 | /// always have at least one primary span, unless it has 0 spans. Child | 
|---|
| 79 | /// messages may have 0 or more primary spans. | 
|---|
| 80 | pub is_primary: bool, | 
|---|
| 81 | /// Source text from the start of line_start to the end of line_end. | 
|---|
| 82 | pub text: Vec<DiagnosticSpanLine>, | 
|---|
| 83 | /// Label that should be placed at this location (if any) | 
|---|
| 84 | pub label: Option<String>, | 
|---|
| 85 | /// If we are suggesting a replacement, this will contain text | 
|---|
| 86 | /// that should be sliced in atop this span. | 
|---|
| 87 | pub suggested_replacement: Option<String>, | 
|---|
| 88 | /// If the suggestion is approximate | 
|---|
| 89 | pub suggestion_applicability: Option<Applicability>, | 
|---|
| 90 | /// Macro invocations that created the code at this span, if any. | 
|---|
| 91 | pub expansion: Option<Box<DiagnosticSpanMacroExpansion>>, | 
|---|
| 92 | } | 
|---|
| 93 |  | 
|---|
| 94 | /// Whether a suggestion can be safely applied. | 
|---|
| 95 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 96 | #[ non_exhaustive] | 
|---|
| 97 | pub enum Applicability { | 
|---|
| 98 | /// The suggested replacement can be applied automatically safely | 
|---|
| 99 | MachineApplicable, | 
|---|
| 100 | /// The suggested replacement has placeholders that will need to be manually | 
|---|
| 101 | /// replaced. | 
|---|
| 102 | HasPlaceholders, | 
|---|
| 103 | /// The suggested replacement may be incorrect in some circumstances. Needs | 
|---|
| 104 | /// human review. | 
|---|
| 105 | MaybeIncorrect, | 
|---|
| 106 | /// The suggested replacement will probably not work. | 
|---|
| 107 | Unspecified, | 
|---|
| 108 | } | 
|---|
| 109 |  | 
|---|
| 110 | /// The diagnostic level | 
|---|
| 111 | #[ derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 112 | #[ non_exhaustive] | 
|---|
| 113 | #[serde(rename_all = "lowercase")] | 
|---|
| 114 | pub enum DiagnosticLevel { | 
|---|
| 115 | /// Internal compiler error | 
|---|
| 116 | #[serde(rename = "error: internal compiler error")] | 
|---|
| 117 | Ice, | 
|---|
| 118 | /// Error | 
|---|
| 119 | Error, | 
|---|
| 120 | /// Warning | 
|---|
| 121 | Warning, | 
|---|
| 122 | /// Failure note | 
|---|
| 123 | #[serde(rename = "failure-note")] | 
|---|
| 124 | FailureNote, | 
|---|
| 125 | /// Note | 
|---|
| 126 | Note, | 
|---|
| 127 | /// Help | 
|---|
| 128 | Help, | 
|---|
| 129 | } | 
|---|
| 130 |  | 
|---|
| 131 | /// A diagnostic message generated by rustc | 
|---|
| 132 | #[ derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] | 
|---|
| 133 | #[ cfg_attr(feature = "builder", derive(Builder))] | 
|---|
| 134 | #[ non_exhaustive] | 
|---|
| 135 | #[ cfg_attr(feature = "builder", builder(pattern = "owned", setter(into)))] | 
|---|
| 136 | pub struct Diagnostic { | 
|---|
| 137 | /// The error message of this diagnostic. | 
|---|
| 138 | pub message: String, | 
|---|
| 139 | /// The associated error code for this diagnostic | 
|---|
| 140 | pub code: Option<DiagnosticCode>, | 
|---|
| 141 | /// "error: internal compiler error", "error", "warning", "note", "help" | 
|---|
| 142 | pub level: DiagnosticLevel, | 
|---|
| 143 | /// A list of source code spans this diagnostic is associated with. | 
|---|
| 144 | pub spans: Vec<DiagnosticSpan>, | 
|---|
| 145 | /// Associated diagnostic messages. | 
|---|
| 146 | pub children: Vec<Diagnostic>, | 
|---|
| 147 | /// The message as rustc would render it | 
|---|
| 148 | pub rendered: Option<String>, | 
|---|
| 149 | } | 
|---|
| 150 |  | 
|---|
| 151 | impl fmt::Display for Diagnostic { | 
|---|
| 152 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | 
|---|
| 153 | if let Some(ref rendered: &String) = self.rendered { | 
|---|
| 154 | f.write_str(data:rendered)?; | 
|---|
| 155 | } else { | 
|---|
| 156 | f.write_str(data: "cargo didn't render this message")?; | 
|---|
| 157 | } | 
|---|
| 158 | Ok(()) | 
|---|
| 159 | } | 
|---|
| 160 | } | 
|---|
| 161 |  | 
|---|