Skip to content

Commit

Permalink
Replace proc-macro-error proc-macro2-diagnostics
Browse files Browse the repository at this point in the history
Replaces the use of the 'proc-macro-error' with 'proc-macro2-diagnostics'.
The former seems to be unmaintained and is no longer updating its dependencies, which is a problem for downstream crates.
  • Loading branch information
bash authored Jun 30, 2024
1 parent 9d56af9 commit f1c4301
Show file tree
Hide file tree
Showing 22 changed files with 69 additions and 67 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ exclude = ["rustfmt.toml", ".gitignore", "README.md", "CHANGELOG.md"]
proc-macro = true

[dependencies]
proc-macro-error = { version = "1.0.4", optional = true }
proc-macro2-diagnostics = { version = "0.10", optional = true }
proc-macro2 = { version = "1.0.85", optional = true }
heck = { version = "0.4.0", optional = true }

[dev-dependencies]
duplicate_macrotest = "1.0.3"
duplicate_macrotest = "1.0.5"
doc-comment = "0.3.3"
serde = "1.0.105, < 1.0.157" # Needed because macrotest's cargo.toml uses 1.0 however fails with < 1.0.105 and >= 1.0.157 (because it uses syn v2)
regex = "1.6.0"
rustversion = "1.0.7"

[features]
default = ["pretty_errors", "module_disambiguation"]
pretty_errors = ["proc-macro-error"]
pretty_errors = ["dep:proc-macro2-diagnostics", "dep:proc-macro2"]
module_disambiguation = ["heck"]
fail-on-warnings = [] # Forces compilation to fail if any warnings are given. Used in CI.

Expand Down
45 changes: 28 additions & 17 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use proc_macro::Span;
#[cfg(feature = "pretty_errors")]
use proc_macro2::Span as Span2;
#[cfg(feature = "pretty_errors")]
use proc_macro2_diagnostics::{Diagnostic, Level};

/// Used to report errors.
///
Expand Down Expand Up @@ -69,29 +73,36 @@ impl Error
self
}

/// Returns the source span of the error and a full message including a
/// potential hint (if applicable).
///
/// If a span wasn't specified, returns the call site span.
pub fn extract(self) -> (Span, String)
/// Returns the source span of the error
/// (or a stub value if the `pretty_errors` feature is disabled).
pub fn get_span(&self) -> Span
{
#[cfg(feature = "pretty_errors")]
{
(
self.span,
if !self.hint.is_empty()
{
self.msg + "\n" + self.hint.as_str()
}
else
{
self.msg
},
)
self.span
}
#[cfg(not(feature = "pretty_errors"))]
{
(Span::call_site(), self.msg)
Span::call_site()
}
}

/// Returns the message of the error.
#[cfg(not(feature = "pretty_errors"))]
pub fn into_panic_message(self) -> String
{
self.msg
}

#[cfg(feature = "pretty_errors")]
/// Converts the error into a [`Diagnostic`] ready for emitting.
pub fn into_diagnostic(self) -> Diagnostic
{
let mut diagnostic = Diagnostic::spanned(Span2::from(self.span), Level::Error, self.msg);
if !self.hint.is_empty()
{
diagnostic = diagnostic.help(self.hint);
}
diagnostic
}
}
20 changes: 6 additions & 14 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,6 @@ use crate::{
};
use parse::*;
use proc_macro::{Delimiter, Group, Ident, Span, TokenStream};
#[cfg(feature = "pretty_errors")]
use proc_macro_error::{abort, proc_macro_error};
use std::{collections::HashMap, iter::empty};
use substitute::*;

Expand Down Expand Up @@ -1007,13 +1005,12 @@ use substitute::*;
/// substitutions groups), must all be defined at the beginning, and aren't
/// usable in the invocation itself but only in the code being duplicated.
#[proc_macro_attribute]
#[cfg_attr(feature = "pretty_errors", proc_macro_error)]
pub fn duplicate_item(attr: TokenStream, item: TokenStream) -> TokenStream
{
match duplicate_impl(attr, item)
{
Ok(result) => result,
Err(err) => abort(err),
Err(err) => emit_error(err),
}
}

Expand Down Expand Up @@ -1049,13 +1046,12 @@ pub fn duplicate_item(attr: TokenStream, item: TokenStream) -> TokenStream
/// The global substitutions (`typ1` and `typ2`) are substituted in both
/// their occurrences. Global substitutions are `;` separated.
#[proc_macro_attribute]
#[cfg_attr(feature = "pretty_errors", proc_macro_error)]
pub fn substitute_item(attr: TokenStream, item: TokenStream) -> TokenStream
{
match substitute_impl(attr, item)
{
Ok(result) => result,
Err(err) => abort(err),
Err(err) => emit_error(err),
}
}

Expand Down Expand Up @@ -1134,7 +1130,6 @@ pub fn substitute_item(attr: TokenStream, item: TokenStream) -> TokenStream
///
/// [`duplicate_item`]: attr.duplicate_item.html
#[proc_macro]
#[cfg_attr(feature = "pretty_errors", proc_macro_error)]
pub fn duplicate(stream: TokenStream) -> TokenStream
{
inline_macro_impl(stream, duplicate_impl)
Expand Down Expand Up @@ -1180,7 +1175,6 @@ pub fn duplicate(stream: TokenStream) -> TokenStream
/// The global substitutions (`typ1` and `typ2`) are substituted in both
/// their occurrences. Global substitutions are `;` separated.
#[proc_macro]
#[cfg_attr(feature = "pretty_errors", proc_macro_error)]
pub fn substitute(stream: TokenStream) -> TokenStream
{
inline_macro_impl(stream, substitute_impl)
Expand Down Expand Up @@ -1217,7 +1211,7 @@ fn inline_macro_impl(
match result
{
Ok(result) => result,
Err(err) => abort(err),
Err(err) => emit_error(err),
}
}

Expand All @@ -1243,17 +1237,15 @@ fn substitute_impl(attr: TokenStream, item: TokenStream) -> Result<TokenStream>
///
/// The `pretty_errors` feature can be enabled, the span is shown
/// with the error message.
#[allow(unused_variables)]
fn abort(err: Error) -> !
fn emit_error(err: Error) -> TokenStream
{
let (span, msg) = err.extract();
#[cfg(feature = "pretty_errors")]
{
abort!(span, msg);
err.into_diagnostic().emit_as_item_tokens().into()
}
#[cfg(not(feature = "pretty_errors"))]
{
panic!("{}", msg);
panic!("{}", err.into_panic_message());
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ pub(crate) fn parse_global_substitutions_only(attr: TokenStream) -> Result<Subst
.unwrap_or(false)
{
err = err.hint(
"Hint: Only global substitutions are allowed. Try 'duplicate' or \
'duplicate_item'.",
"Only global substitutions are allowed. Try 'duplicate' or 'duplicate_item'.",
);
}
}
Expand Down Expand Up @@ -171,7 +170,7 @@ fn validate_verbose_invocation<'a, T: SubGroupIter<'a>>(
{
let (body, span) = iter.next_group(Some(Delimiter::Bracket)).map_err(|err| {
err.hint(
"Hint: When using verbose syntax, a substitutions must be enclosed in a \
"When using verbose syntax, a substitutions must be enclosed in a \
group.\nExample:\n..\n[\n\tidentifier1 [ substitution1 ]\n\tidentifier2 [ \
substitution2 ]\n]",
)
Expand Down Expand Up @@ -228,7 +227,7 @@ fn extract_inline_substitution<'a, T: SubGroupIter<'a>>(
// No parameters, get substitution
substitution
.map(|(sub, _)| Substitution::new_simple(sub.process_all()))
.map_err(|old_err| Error::new("Expected '(' or '['.").span(old_err.extract().0))
.map_err(|old_err| Error::new("Expected '(' or '['.").span(old_err.get_span()))
}
.or_else(|err| {
stream.push_front(Token::Simple(TokenTree::Ident(ident.clone())));
Expand Down
21 changes: 10 additions & 11 deletions src/pretty_errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg_attr(not(feature = "pretty_errors"), allow(dead_code))]

/// For when substitution parameters aren't enclosed in brackets
pub(crate) const BRACKET_SUB_PARAM: &'static str = r#"Hint: Substitution parameters should be enclosed in '[]' each.
pub(crate) const BRACKET_SUB_PARAM: &'static str = r#"Substitution parameters should be enclosed in '[]' each.
Example:
sub_ident( [ parameter1 ] , [ paramter2 ] )
^^^ ^^^ ^^^ ^^^
Expand All @@ -16,21 +16,20 @@ pub(crate) const NO_INVOCATION: &'static str =
pub(crate) const NO_GROUPS: &'static str = r#"Expected substitution group."#;

/// Hint for when no substitution group is given, but at least one must be given
pub(crate) const NO_GROUPS_HINT: &'static str = "Hint: Must specify at least one substitution \
group, otherwise use 'substitute!' or \
'substitute_item'";
pub(crate) const NO_GROUPS_HINT: &'static str = "Must specify at least one substitution group, \
otherwise use 'substitute!' or 'substitute_item'";

/// For when short syntax has declared substitution identifiers but no
/// substitution groups.
pub(crate) const SHORT_SYNTAX_NO_GROUPS: &'static str = r#"Hint: Add a substitution group after the substitution identifiers.
pub(crate) const SHORT_SYNTAX_NO_GROUPS: &'static str = r#"Add a substitution group after the substitution identifiers.
Example:
name;
[SomeSubstitution];
^^^^^^^^^^^^^^^^^^^
"#;

/// For when short syntax substitutions aren't enclosed in brackets
pub(crate) const SHORT_SYNTAX_MISSING_SUB_BRACKET: &'static str = r#"Hint: Each substitution should be enclosed in '[]'.
pub(crate) const SHORT_SYNTAX_MISSING_SUB_BRACKET: &'static str = r#"Each substitution should be enclosed in '[]'.
Example:
ident1 ident2;
[ sub1 ] [ sub2 ] ;
Expand All @@ -39,7 +38,7 @@ Example:

/// For when short syntax substitution group has too few or too many
/// substitutions
pub(crate) const SHORT_SYNTAX_SUBSTITUTION_COUNT: &'static str = r#"Hint: Number of substitutions must match the number of substitutions identifiers.
pub(crate) const SHORT_SYNTAX_SUBSTITUTION_COUNT: &'static str = r#"Number of substitutions must match the number of substitutions identifiers.
Example:
ident1 ident2;
1^^^^^^ ^^^^^^2
Expand All @@ -49,7 +48,7 @@ Example:

/// For when verbose syntax substitution group has too few or too many
/// substitutions
pub(crate) const VERBOSE_SYNTAX_SUBSTITUTION_IDENTIFIERS: &'static str = r#"Hint: All substitution groups must define the same substitution identifiers.
pub(crate) const VERBOSE_SYNTAX_SUBSTITUTION_IDENTIFIERS: &'static str = r#"All substitution groups must define the same substitution identifiers.
Example:
[
ident1 [sub1]
Expand All @@ -63,7 +62,7 @@ Example:

/// For when verbose syntax substitution identifier has too few or too many
/// arguments
pub(crate) const VERBOSE_SYNTAX_SUBSTITUTION_IDENTIFIERS_ARGS: &'static str = r#"Hint: The same substitution identifier must take the same number of argument across all substitution groups.
pub(crate) const VERBOSE_SYNTAX_SUBSTITUTION_IDENTIFIERS_ARGS: &'static str = r#"The same substitution identifier must take the same number of argument across all substitution groups.
Example:
[
ident1(arg1, arg2) [sub1 arg1 arg2]
Expand All @@ -76,7 +75,7 @@ Example:
"#;

/// For when verbose syntax substitution pair is followed by a semicolon
pub(crate) const VERBOSE_SEMICOLON: &'static str = r#"Hint: Verbose syntax does not accept semicolons between substitutions.
pub(crate) const VERBOSE_SEMICOLON: &'static str = r#"Verbose syntax does not accept semicolons between substitutions.
Example:
[
name [sub1] // No semicolon
Expand All @@ -85,7 +84,7 @@ Example:
"#;

/// For when global substitutions aren't followed by ';'
pub(crate) const GLOBAL_SUB_SEMICOLON: &'static str = r#"Hint: Each global substitution should end with ';'
pub(crate) const GLOBAL_SUB_SEMICOLON: &'static str = r#"Each global substitution should end with ';'
Example:
name [sub1];
typ [sub2];
Expand Down
2 changes: 1 addition & 1 deletion src/token_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl<'a, T: SubGroupIter<'a>> TokenIter<'a, T>
let mut err = Error::new(error);
if let Some(expected_string) = expected
{
err = err.hint("Hint: Expected ".to_string() + expected_string + ".");
err = err.hint("Expected ".to_string() + expected_string + ".");
}
err
};
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/duplicate_without_duplicates
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Must specify at least one substitution group, otherwise use 'substitute!' or 'substitute_item'
= help: Must specify at least one substitution group, otherwise use 'substitute!' or 'substitute_item'
2 changes: 1 addition & 1 deletion tests/errors/hint/global_sub_semicolon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Each global substitution should end with ';'
= help: Each global substitution should end with ';'
Example:
name [sub1];
typ [sub2];
2 changes: 1 addition & 1 deletion tests/errors/hint/parameters_not_encapsulated
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Substitution parameters should be enclosed in '[]' each.
= help: Substitution parameters should be enclosed in '[]' each.
Example:
sub_ident( [ parameter1 ] , [ paramter2 ] )
^^^ ^^^ ^^^ ^^^
2 changes: 1 addition & 1 deletion tests/errors/hint/short_missing_substitution
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Number of substitutions must match the number of substitutions identifiers.
= help: Number of substitutions must match the number of substitutions identifiers.
Example:
ident1 ident2;
1^^^^^^ ^^^^^^2
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/short_missing_substitution_bracket
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Each substitution should be enclosed in '[]'.
= help: Each substitution should be enclosed in '[]'.
Example:
ident1 ident2;
[ sub1 ] [ sub2 ] ;
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/short_superfluous_substitution
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Number of substitutions must match the number of substitutions identifiers.
= help: Number of substitutions must match the number of substitutions identifiers.
Example:
ident1 ident2;
1^^^^^^ ^^^^^^2
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/short_without_duplicates
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Add a substitution group after the substitution identifiers.
= help: Add a substitution group after the substitution identifiers.
Example:
name;
[SomeSubstitution];
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/substitute_item_with_duplicate
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Expected a substitution identifier.
= help: Expected a substitution identifier.
2 changes: 1 addition & 1 deletion tests/errors/hint/substitute_item_with_duplicate_2
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Only global substitutions are allowed. Try 'duplicate' or 'duplicate_item'.
= help: Only global substitutions are allowed. Try 'duplicate' or 'duplicate_item'.
2 changes: 1 addition & 1 deletion tests/errors/hint/substitute_item_with_duplicate_3
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Only global substitutions are allowed. Try 'duplicate' or 'duplicate_item'.
= help: Only global substitutions are allowed. Try 'duplicate' or 'duplicate_item'.
2 changes: 1 addition & 1 deletion tests/errors/hint/substitute_item_with_duplicate_4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Expected a substitution identifier.
= help: Expected a substitution identifier.
4 changes: 2 additions & 2 deletions tests/errors/hint/verbose_incomplete_substitution_group
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Missing substitution for: 'ty'
Hint: All substitution groups must define the same substitution identifiers.
= help: Missing substitution for: 'ty'
All substitution groups must define the same substitution identifiers.
Example:
[
ident1 [sub1]
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/verbose_not_ident
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Hint: Expected a substitution identifier.
= help: Expected a substitution identifier.
2 changes: 1 addition & 1 deletion tests/errors/hint/verbose_semicolon
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: Verbose syntax does not accept semicolons between substitutions.
= help: Verbose syntax does not accept semicolons between substitutions.
Example:
[
name [sub1] // No semicolon
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: All substitution groups must define the same substitution identifiers.
= help: All substitution groups must define the same substitution identifiers.
Example:
[
ident1 [sub1]
Expand Down
2 changes: 1 addition & 1 deletion tests/errors/hint/verbose_wrong_argument_count
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Hint: The same substitution identifier must take the same number of argument across all substitution groups.
= help: The same substitution identifier must take the same number of argument across all substitution groups.
Example:
[
ident1(arg1, arg2) [sub1 arg1 arg2]
Expand Down

0 comments on commit f1c4301

Please sign in to comment.