Skip to content

Commit 92d9f64

Browse files
committed
refactor(derive-encode): emit better compilation error message
Signed-off-by: ADD-SP <[email protected]>
1 parent 2eb2dce commit 92d9f64

File tree

5 files changed

+131
-7
lines changed

5 files changed

+131
-7
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
### Changed
2222

2323
- `EncodeLabelSet::encode()` now accepts a mutable reference to its encoder parameter.
24+
- Emit better compilation error message when deriving marcos `EncodeLabelSet` and `EncodeLabelValue`.
25+
See [PR 267].
2426

2527
### Fixed
2628

derive-encode/src/lib.rs

+37-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
99
use proc_macro::TokenStream;
1010
use proc_macro2::TokenStream as TokenStream2;
11-
use quote::quote;
11+
use quote::{quote, ToTokens};
1212
use syn::DeriveInput;
1313

1414
/// Derive `prometheus_client::encoding::EncodeLabelSet`.
@@ -60,14 +60,36 @@ pub fn derive_encode_label_set(input: TokenStream) -> TokenStream {
6060
})
6161
.collect(),
6262
syn::Fields::Unnamed(_) => {
63-
panic!("Can not derive Encode for struct with unnamed fields.")
63+
return syn::Error::new_spanned(
64+
name,
65+
"Can not derive `EncodeLabelSet` for struct with unnamed fields.",
66+
)
67+
.to_compile_error()
68+
.to_token_stream()
69+
.into();
70+
}
71+
syn::Fields::Unit => {
72+
return syn::Error::new_spanned(
73+
name,
74+
"Can not derive `EncodeLabelSet` for unit struct.",
75+
)
76+
.to_compile_error()
77+
.to_token_stream()
78+
.into();
6479
}
65-
syn::Fields::Unit => panic!("Can not derive Encode for struct with unit field."),
6680
},
6781
syn::Data::Enum(syn::DataEnum { .. }) => {
68-
panic!("Can not derive Encode for enum.")
82+
return syn::Error::new_spanned(name, "Can not derive `EncodeLabelSet` for enum.")
83+
.to_compile_error()
84+
.to_token_stream()
85+
.into();
86+
}
87+
syn::Data::Union(_) => {
88+
return syn::Error::new_spanned(name, "Can not derive `EncodeLabelSet` for union.")
89+
.to_compile_error()
90+
.to_token_stream()
91+
.into()
6992
}
70-
syn::Data::Union(_) => panic!("Can not derive Encode for union."),
7193
};
7294

7395
let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
@@ -96,7 +118,10 @@ pub fn derive_encode_label_value(input: TokenStream) -> TokenStream {
96118

97119
let body = match ast.clone().data {
98120
syn::Data::Struct(_) => {
99-
panic!("Can not derive EncodeLabel for struct.")
121+
return syn::Error::new_spanned(name, "Can not derive `EncodeLabelValue` for struct.")
122+
.to_compile_error()
123+
.to_token_stream()
124+
.into();
100125
}
101126
syn::Data::Enum(syn::DataEnum { variants, .. }) => {
102127
let match_arms: TokenStream2 = variants
@@ -115,7 +140,12 @@ pub fn derive_encode_label_value(input: TokenStream) -> TokenStream {
115140
}
116141
}
117142
}
118-
syn::Data::Union(_) => panic!("Can not derive Encode for union."),
143+
syn::Data::Union(_) => {
144+
return syn::Error::new_spanned(name, "Can not derive `EncodeLabelValue` for union.")
145+
.to_compile_error()
146+
.to_token_stream()
147+
.into()
148+
}
119149
};
120150

121151
let gen = quote! {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
use prometheus_client::encoding::EncodeLabelSet;
2+
use prometheus_client::encoding::EncodeLabelValue;
3+
4+
mod A {
5+
use super::*;
6+
7+
#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
8+
struct Unnamed(String);
9+
10+
#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
11+
struct Unit;
12+
13+
#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
14+
enum Enum {
15+
A,
16+
B,
17+
}
18+
19+
#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelSet)]
20+
enum DataEnum {
21+
A,
22+
B(String),
23+
}
24+
25+
#[derive(Clone, Copy, EncodeLabelSet)]
26+
#[repr(C)]
27+
union Union {
28+
a: u32,
29+
b: u64,
30+
}
31+
}
32+
33+
mod B {
34+
use super::*;
35+
36+
#[derive(Debug, Clone, PartialEq, Eq, Hash, EncodeLabelValue)]
37+
struct Struct {
38+
a: String,
39+
b: String,
40+
}
41+
42+
#[derive(Clone, Copy, EncodeLabelValue)]
43+
#[repr(C)]
44+
union Union {
45+
a: u32,
46+
b: u64,
47+
}
48+
}
49+
50+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error: Can not derive `EncodeLabelSet` for struct with unnamed fields.
2+
--> tests/build/friendly-compilation-error-msg.rs:8:12
3+
|
4+
8 | struct Unnamed(String);
5+
| ^^^^^^^
6+
7+
error: Can not derive `EncodeLabelSet` for unit struct.
8+
--> tests/build/friendly-compilation-error-msg.rs:11:12
9+
|
10+
11 | struct Unit;
11+
| ^^^^
12+
13+
error: Can not derive `EncodeLabelSet` for enum.
14+
--> tests/build/friendly-compilation-error-msg.rs:14:10
15+
|
16+
14 | enum Enum {
17+
| ^^^^
18+
19+
error: Can not derive `EncodeLabelSet` for enum.
20+
--> tests/build/friendly-compilation-error-msg.rs:20:10
21+
|
22+
20 | enum DataEnum {
23+
| ^^^^^^^^
24+
25+
error: Can not derive `EncodeLabelSet` for union.
26+
--> tests/build/friendly-compilation-error-msg.rs:27:11
27+
|
28+
27 | union Union {
29+
| ^^^^^
30+
31+
error: Can not derive `EncodeLabelValue` for struct.
32+
--> tests/build/friendly-compilation-error-msg.rs:37:12
33+
|
34+
37 | struct Struct {
35+
| ^^^^^^
36+
37+
error: Can not derive `EncodeLabelValue` for union.
38+
--> tests/build/friendly-compilation-error-msg.rs:44:11
39+
|
40+
44 | union Union {
41+
| ^^^^^

derive-encode/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,5 @@ fn build() {
211211
let t = trybuild::TestCases::new();
212212
t.pass("tests/build/redefine-prelude-symbols.rs");
213213
t.pass("tests/build/keep-impl-generics.rs");
214+
t.compile_fail("tests/build/friendly-compilation-error-msg.rs");
214215
}

0 commit comments

Comments
 (0)