diff --git a/Cargo.toml b/Cargo.toml index 8321ceb..068992b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,3 +41,7 @@ nightly = [] [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(run_ui_tests)'] } + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } +module_name_repetitions = { level = "allow" } diff --git a/proc-macro-error-attr/Cargo.toml b/proc-macro-error-attr/Cargo.toml index 5041bb3..67098fd 100644 --- a/proc-macro-error-attr/Cargo.toml +++ b/proc-macro-error-attr/Cargo.toml @@ -20,3 +20,6 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] quote = "1" proc-macro2 = "1" + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } diff --git a/proc-macro-error-attr/src/lib.rs b/proc-macro-error-attr/src/lib.rs index 2ae9003..6b711c0 100644 --- a/proc-macro-error-attr/src/lib.rs +++ b/proc-macro-error-attr/src/lib.rs @@ -7,7 +7,11 @@ use proc_macro::TokenStream; use proc_macro2::{Literal, Span, TokenStream as TokenStream2, TokenTree}; use quote::{quote, quote_spanned}; -use crate::settings::{Setting::*, *}; +use crate::settings::{ + parse_settings, + Setting::{AllowNotMacro, AssertUnwindSafe, ProcMacroHack}, + Settings, +}; mod parse; mod settings; @@ -71,7 +75,7 @@ fn impl_proc_macro_error(attr: TokenStream2, input: TokenStream2) -> Result Result proc_macro2::TokenStream { +fn gen_body(block: &TokenTree, settings: &Settings) -> proc_macro2::TokenStream { let is_proc_macro_hack = settings.is_set(ProcMacroHack); let closure = if settings.is_set(AssertUnwindSafe) { quote!(::std::panic::AssertUnwindSafe(|| #block )) diff --git a/proc-macro-error-attr/src/parse.rs b/proc-macro-error-attr/src/parse.rs index 6f4663f..eedb495 100644 --- a/proc-macro-error-attr/src/parse.rs +++ b/proc-macro-error-attr/src/parse.rs @@ -39,7 +39,7 @@ fn parse_next_attr( res } other => { - let span = other.map_or(Span::call_site(), |tt| tt.span()); + let span = other.map_or(Span::call_site(), TokenTree::span); return Err(Error::new(span, "expected `[`".to_string())); } }; diff --git a/proc-macro-error-attr/src/settings.rs b/proc-macro-error-attr/src/settings.rs index 0b7ec76..f87bd0b 100644 --- a/proc-macro-error-attr/src/settings.rs +++ b/proc-macro-error-attr/src/settings.rs @@ -3,7 +3,7 @@ use proc_macro2::{Ident, Span, TokenStream, TokenTree}; macro_rules! decl_settings { ($($val:expr => $variant:ident),+ $(,)*) => { - #[derive(PartialEq)] + #[derive(PartialEq, Clone, Copy)] pub(crate) enum Setting { $($variant),* } @@ -67,6 +67,6 @@ impl Settings { } pub(crate) fn set(&mut self, setting: Setting) { - self.0.push(setting) + self.0.push(setting); } } diff --git a/src/diagnostic.rs b/src/diagnostic.rs index c818713..0455511 100644 --- a/src/diagnostic.rs +++ b/src/diagnostic.rs @@ -18,6 +18,7 @@ pub enum Level { /// Represents a single diagnostic message #[derive(Debug)] +#[must_use = "A diagnostic does nothing unless emitted"] pub struct Diagnostic { pub(crate) level: Level, pub(crate) span_range: SpanRange, @@ -42,6 +43,7 @@ pub trait DiagnosticExt: Sealed { /// /// 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. @@ -52,6 +54,7 @@ pub trait DiagnosticExt: Sealed { /// # 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. @@ -62,6 +65,7 @@ pub trait DiagnosticExt: Sealed { /// # 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; } @@ -167,6 +171,7 @@ impl Diagnostic { } /// The message of main warning/error (no notes attached) + #[must_use] pub fn message(&self) -> &str { &self.msg } diff --git a/src/dummy.rs b/src/dummy.rs index 0da03be..5bc98bd 100644 --- a/src/dummy.rs +++ b/src/dummy.rs @@ -126,6 +126,7 @@ thread_local! { /// invocations in case you'll emit any errors. /// /// See [guide](../index.html#guide). +#[allow(clippy::must_use_candidate)] // Mutates thread local state pub fn set_dummy(dummy: TokenStream) -> Option { check_correctness(); DUMMY_IMPL.with(|old_dummy| old_dummy.replace(Some(dummy))) diff --git a/src/lib.rs b/src/lib.rs index 5fc0dbf..ebc9835 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -273,7 +273,6 @@ #![cfg_attr(feature = "nightly", feature(proc_macro_diagnostic))] #![forbid(unsafe_code)] -#![allow(clippy::needless_doctest_main)] extern crate proc_macro; @@ -304,6 +303,7 @@ mod imp; mod imp; #[derive(Debug, Clone, Copy)] +#[must_use = "A SpanRange does nothing unless used"] pub struct SpanRange { pub first: Span, pub last: Span, @@ -349,6 +349,7 @@ impl SpanRange { } /// Collapse the range into single span, preserving as much information as possible. + #[must_use] pub fn collapse(self) -> Span { self.first.join(self.last).unwrap_or(self.first) } @@ -479,12 +480,11 @@ thread_local! { struct AbortNow; fn check_correctness() { - if ENTERED_ENTRY_POINT.with(|flag| flag.get()) == 0 { - panic!( - "proc-macro-error API cannot be used outside of `entry_point` invocation, \ + assert!( + ENTERED_ENTRY_POINT.with(Cell::get) != 0, + "proc-macro-error API cannot be used outside of `entry_point` invocation, \ perhaps you forgot to annotate your #[proc_macro] function with `#[proc_macro_error]" - ); - } + ); } /// **ALL THE STUFF INSIDE IS NOT PUBLIC API!!!** @@ -525,11 +525,16 @@ pub mod __export { impl ToTokensAsSpanRange for &T { fn FIRST_ARG_MUST_EITHER_BE_Span_OR_IMPLEMENT_ToTokens_OR_BE_SpanRange(&self) -> SpanRange { let mut ts = self.to_token_stream().into_iter(); - let first = ts - .next() - .map(|tt| tt.span()) - .unwrap_or_else(Span::call_site); - let last = ts.last().map(|tt| tt.span()).unwrap_or(first); + let first = match ts.next() { + Some(t) => t.span(), + None => Span::call_site(), + }; + + let last = match ts.next() { + Some(t) => t.span(), + None => first, + }; + SpanRange { first, last } } } diff --git a/test-crate/Cargo.toml b/test-crate/Cargo.toml index 146bfd4..254cb09 100644 --- a/test-crate/Cargo.toml +++ b/test-crate/Cargo.toml @@ -20,3 +20,7 @@ proc-macro2 = "1" [dependencies.syn] version = "2" features = ["full"] + +[lints.clippy] +pedantic = { level = "warn", priority = -1 } +module_name_repetitions = { level = "allow" } diff --git a/test-crate/lib.rs b/test-crate/lib.rs index d50b983..1ecdfbc 100644 --- a/test-crate/lib.rs +++ b/test-crate/lib.rs @@ -143,7 +143,7 @@ pub fn emit_notes(input: proc_macro::TokenStream) -> proc_macro::TokenStream { #[proc_macro] #[proc_macro_error] pub fn option_ext(_input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let none: Option = None; + let none: Option<()> = None; none.expect_or_abort("Option::expect_or_abort() test"); quote!().into() }