Skip to content

Commit

Permalink
Add docs and UI tests
Browse files Browse the repository at this point in the history
Signed-off-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
  • Loading branch information
ggwpez committed May 6, 2023
1 parent 754d153 commit 349eb67
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 40 deletions.
23 changes: 6 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
[package]
name = "proc-macro-warning"
version = "0.3.1"
edition = "2021"
license = "GPL-3.0 OR Apache-2.0"
authors = ["Oliver Tale-Yazdi <oliver@tasty.limo>"]
description = "Emit warnings from inside proc macros."
repository = "/~https://github.com/ggwpez/proc-macro-warning"
[workspace]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
proc-macro2 = { version = "1.0.56", default-features = false }
quote = { version = "1.0.26", default-features = false }
syn = { version = "2.0.15", default-features = false }

[features]
default = []
members = [
"proc-macro-warning",
"ui-tests/derive",
"ui-tests/ui",
]
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,25 @@ let warning = Warning::new_deprecated("my_macro")
let tokens = quote::quote!(#warning);
```

This works in derive-macros, but you **must** put in a span, otherwise it will not show up in the compile output.
This works in derive-macros, but you **must** set a span; otherwise it will not show up in the compile output.

The difference to a `#[deprecated]` attribute is that it emits the warning either way. For example when creating a custom `Deprecated` derive macro, it will warn without the struct being constructed.

```rust
#[derive(derive::Deprecated)]
struct Test {}

fn main() {
// Warning triggers although we never used `Test`.
// Otherwise use a normal `#[deprecated]`.
}
```

## Used In

Substrate (since [#13798](/~https://github.com/paritytech/substrate/pull/13798)) uses this to emit warnings for its FRAME eDSL on deprecated behaviour.
Substrate uses it to emit warnings for its eDSL (FRAME) on deprecated behaviour. The integration was done in [#13798](/~https://github.com/paritytech/substrate/pull/13798) and shows how to use these warnings in macro expansion.

For example not putting a `call_index` on your functions produces:
The warnings are uniformly formatted and have consistent grammar:
```pre
warning: use of deprecated constant `pallet::warnings::ImplicitCallIndex_0::_w`:
It is deprecated to use implicit call indices.
Expand All @@ -58,7 +70,7 @@ warning: use of deprecated constant `pallet::warnings::ImplicitCallIndex_0::_w`:
|
```

Or using a hard-coded weight:
A different one:
```pre
warning: use of deprecated constant `pallet::warnings::ConstantWeight_0::_w`:
It is deprecated to use hard-coded constant as call weight.
Expand Down
21 changes: 21 additions & 0 deletions proc-macro-warning/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "proc-macro-warning"
version = "0.3.1"
edition = "2021"
license = "GPL-3.0 OR Apache-2.0"
authors = ["Oliver Tale-Yazdi <oliver@tasty.limo>"]
description = "Emit warnings from inside proc macros."
repository = "/~https://github.com/ggwpez/proc-macro-warning"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
proc-macro2 = { version = "1.0.56", default-features = false }
quote = { version = "1.0.26", default-features = false }
syn = { version = "2.0.15", default-features = false }

[dev-dependencies]
derive = { path = "../ui-tests/derive" }

[features]
default = []
24 changes: 16 additions & 8 deletions src/lib.rs → proc-macro-warning/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: (GPL-3.0 or Apache-2.0)
*/

#![doc = include_str!("../README.md")]
#![doc = include_str!("../../README.md")]

use core::ops::Deref;
use proc_macro2::Span;
Expand All @@ -20,24 +20,25 @@ pub struct Warning {
pub span: Span,
}

/// Gradually build a "deprecated" `Warning`.
/// Gradually build a *deprecation* `Warning`.
///
/// # Example
/// ```
///
/// ```rust
/// use proc_macro_warning::Warning;
///
/// let warning = Warning::new_deprecated("my_macro")
/// .old("my_macro()")
/// .new("my_macro::new()")
/// .help_link("https:://example.com")
/// // Normally you use the input span, but this is an example:
/// .span(proc_macro2::Span::call_site())
/// .build();
///
/// // Use the warning in a proc macro
/// let tokens = quote::quote!(#warning);
/// let mut warnings = vec![warning];
/// // When adding more, you will need to build each with `.index`.
///
/// let warnings = vec![warning];
/// // In a proc macro you would expand them inside a module:
/// // In a proc macro you can expand them in a private module:
/// quote::quote! {
/// mod warnings {
/// #(
Expand Down Expand Up @@ -180,7 +181,7 @@ impl ToTokens for Warning {
let q = quote_spanned!(self.span =>
/// This function should not be called and only exists to emit a compiler warning.
///
/// It is a No-OP if you want try it anyway ;)
/// It is a No-OP in any case.
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
Expand All @@ -194,3 +195,10 @@ impl ToTokens for Warning {
q.to_tokens(stream);
}
}

impl Warning {
/// Consume self and quote it, according to its span, into a TokenStream.
pub fn into_token_stream(self) -> proc_macro2::TokenStream {
quote::quote! { #self }.into()
}
}
2 changes: 1 addition & 1 deletion src/test.rs → proc-macro-warning/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ fn example_works() {
let want_tokens = quote!(
/// This function should not be called and only exists to emit a compiler warning.
///
/// It is a No-OP if you want try it anyway ;)
/// It is a No-OP in any case.
#[allow(dead_code)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/derive/Cargo.toml → ui-tests/derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ publish = false
proc-macro = true

[dependencies]
proc-macro-warning = { path = "../../" }
proc-macro-warning = { path = "../../proc-macro-warning" }
quote = "1.0.26"
syn = "2.0.15"
4 changes: 3 additions & 1 deletion tests/derive/src/lib.rs → ui-tests/derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! TESTING ONLY - DO NOT USE.
use proc_macro::TokenStream;
use syn::spanned::Spanned;

Expand All @@ -22,5 +24,5 @@ fn impl_dep(input: TokenStream, span: bool) -> TokenStream {
warning
}.build();

quote::quote!{ #warning }.into()
warning.into_token_stream().into()
}
File renamed without changes.
2 changes: 2 additions & 0 deletions tests/ui/src/lib.rs → ui-tests/ui/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! TESTING ONLY - DO NOT USE.
#[test]
#[cfg(test)]
fn ui_warm() {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#[derive(derive::Deprecated)]
struct Test {

}
struct Test;

fn main() {
let _ = Test { };
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ error: use of deprecated constant `test::_w`:
Please instead bar.
--> src/warn/derive_basic.rs:2:1
|
2 | / struct Test {
3 | |
4 | | }
| |_^
2 | struct Test;
| ^^^^^^^^^^^^
|
= note: `-D deprecated` implied by `-D warnings`
8 changes: 8 additions & 0 deletions ui-tests/ui/src/warn/derive_twice_errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[derive(derive::Deprecated)]
struct Test;

#[derive(derive::Deprecated)]
struct Test2;

fn main() {
}
28 changes: 28 additions & 0 deletions ui-tests/ui/src/warn/derive_twice_errors.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0428]: the name `test` is defined multiple times
--> src/warn/derive_twice_errors.rs:5:1
|
2 | struct Test;
| ------------ previous definition of the value `test` here
...
5 | struct Test2;
| ^^^^^^^^^^^^^ `test` redefined here
|
= note: `test` must be defined only once in the value namespace of this module

error: use of deprecated constant `test::_w`:
It is deprecated to foo.
Please instead bar.
--> src/warn/derive_twice_errors.rs:2:1
|
2 | struct Test;
| ^^^^^^^^^^^^
|
= note: `-D deprecated` implied by `-D warnings`

error: use of deprecated constant `test::_w`:
It is deprecated to foo.
Please instead bar.
--> src/warn/derive_twice_errors.rs:5:1
|
5 | struct Test2;
| ^^^^^^^^^^^^^

0 comments on commit 349eb67

Please sign in to comment.