usecrate::{abort_now, check_correctness, sealed::Sealed, SpanRange}; use proc_macro2::Span; use proc_macro2::TokenStream;
use quote::{quote_spanned, ToTokens};
/// Represents a diagnostic level /// /// # Warnings /// /// Warnings are ignored on stable/beta #[derive(Debug, PartialEq)] #[non_exhaustive] pubenum Level {
Error,
Warning,
}
/// Represents a single diagnostic message #[derive(Debug)] #[must_use = "A diagnostic does nothing unless emitted"] pubstruct Diagnostic { pub(crate) level: Level, pub(crate) span_range: SpanRange, pub(crate) msg: String, pub(crate) suggestions: Vec<(SuggestionKind, String, Option<SpanRange>)>, pub(crate) children: Vec<(SpanRange, String)>,
}
/// A collection of methods that do not exist in `proc_macro::Diagnostic` /// but still useful to have around. /// /// This trait is sealed and cannot be implemented outside of `proc_macro_error`. pubtrait DiagnosticExt: Sealed { /// Create a new diagnostic message that points to the `span_range`. /// /// This function is the same as `Diagnostic::spanned` but produces considerably /// better error messages for multi-token spans on stable. fn spanned_range(span_range: SpanRange, level: Level, message: String) -> Self;
/// Add another error message to self such that it will be emitted right after /// the main message. /// /// This function is the same as `Diagnostic::span_error` but produces considerably /// better error messages for multi-token spans on stable. #[must_use] fn span_range_error(self, span_range: SpanRange, msg: String) -> Self;
/// Attach a "help" note to your main message, the note will have it's own span on nightly. /// /// This function is the same as `Diagnostic::span_help` but produces considerably /// better error messages for multi-token spans on stable. /// /// # Span /// /// The span is ignored on stable, the note effectively inherits its parent's (main message) span #[must_use] fn span_range_help(self, span_range: SpanRange, msg: String) -> Self;
/// Attach a note to your main message, the note will have it's own span on nightly. /// /// This function is the same as `Diagnostic::span_note` but produces considerably /// better error messages for multi-token spans on stable. /// /// # Span /// /// The span is ignored on stable, the note effectively inherits its parent's (main message) span #[must_use] fn span_range_note(self, span_range: SpanRange, msg: String) -> Self;
}
impl Diagnostic { /// Create a new diagnostic message that points to `Span::call_site()` pubfn new(level: Level, message: String) -> Self {
Diagnostic::spanned(Span::call_site(), level, message)
}
/// Create a new diagnostic message that points to the `span` pubfn spanned(span: Span, level: Level, message: String) -> Self {
Diagnostic::spanned_range(
SpanRange {
first: span,
last: span,
},
level,
message,
)
}
/// Add another error message to self such that it will be emitted right after /// the main message. pubfn span_error(self, span: Span, msg: String) -> Self { self.span_range_error(
SpanRange {
first: span,
last: span,
},
msg,
)
}
/// Attach a "help" note to your main message, the note will have it's own span on nightly. /// /// # Span /// /// The span is ignored on stable, the note effectively inherits its parent's (main message) span pubfn span_help(self, span: Span, msg: String) -> Self { self.span_range_help(
SpanRange {
first: span,
last: span,
},
msg,
)
}
/// Attach a "help" note to your main message. pubfn help(mutself, msg: String) -> Self { self.suggestions.push((SuggestionKind::Help, msg, None)); self
}
/// Attach a note to your main message, the note will have it's own span on nightly. /// /// # Span /// /// The span is ignored on stable, the note effectively inherits its parent's (main message) span pubfn span_note(self, span: Span, msg: String) -> Self { self.span_range_note(
SpanRange {
first: span,
last: span,
},
msg,
)
}
/// Attach a note to your main message pubfn note(mutself, msg: String) -> Self { self.suggestions.push((SuggestionKind::Note, msg, None)); self
}
/// The message of main warning/error (no notes attached) #[must_use] pubfn message(&self) -> &str {
&self.msg
}
/// Abort the proc-macro's execution and display the diagnostic. /// /// # Warnings /// /// Warnings are not emitted on stable and beta, but this function will abort anyway. pubfn abort(self) -> ! { self.emit();
abort_now()
}
/// Display the diagnostic while not aborting macro execution. /// /// # Warnings /// /// Warnings are ignored on stable/beta pubfn emit(self) {
check_correctness(); crate::imp::emit_diagnostic(self);
}
}
/// **NOT PUBLIC API! NOTHING TO SEE HERE!!!** #[doc(hidden)] impl Diagnostic { pubfn span_suggestion(self, span: Span, suggestion: &str, msg: String) -> Self { match suggestion { "help" | "hint" => self.span_help(span, msg),
_ => self.span_note(span, msg),
}
}
let lit = match ts.next().unwrap() {
TokenTree::Group(group) => { // Currently `syn` builds `compile_error!` invocations // exclusively in `ident{"..."}` (braced) form which is not // followed by `;` (semicolon). // // But if it changes to `ident("...");` (parenthesized) // or `ident["..."];` (bracketed) form, // we will need to skip the `;` as well. // Highly unlikely, but better safe than sorry.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.