Skip to content

Commit 78d9d99

Browse files
committed
Add errors on invalid forward usage and compile_fail tests for them
1 parent 92ae1cb commit 78d9d99

File tree

7 files changed

+83
-2
lines changed

7 files changed

+83
-2
lines changed

impl/src/error.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use proc_macro2::TokenStream;
1+
use proc_macro2::{Span, TokenStream};
22
use quote::quote;
33
use syn::{spanned::Spanned as _, Error, Result};
44

@@ -390,7 +390,12 @@ fn parse_fields_impl<'input, 'state, P>(
390390
where
391391
P: Fn(&str, &syn::Field, usize) -> bool,
392392
{
393-
let MultiFieldData { fields, infos, .. } = state.enabled_fields_data();
393+
let MultiFieldData {
394+
fields,
395+
infos,
396+
variant_info,
397+
..
398+
} = state.enabled_fields_data();
394399

395400
let iter = fields
396401
.iter()
@@ -418,6 +423,11 @@ where
418423

419424
if let Some((index, _, _)) = source {
420425
parsed_fields.source = Some(index);
426+
} else if variant_info.forward {
427+
return Err(syn::Error::new(
428+
Span::call_site(),
429+
"`#[error(forward)]` cannot be used when an error has no source",
430+
));
421431
}
422432

423433
if let Some((index, _, _)) = backtrace {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
use derive_more::Error;
2+
3+
#[derive(Debug, Error)]
4+
#[error(forward)]
5+
enum Foo {
6+
Bar,
7+
Baz {
8+
source: Box<dyn Error + Send + 'static>,
9+
},
10+
}
11+
12+
impl ::core::fmt::Display for Foo {
13+
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
14+
write!(f, "")
15+
}
16+
}
17+
18+
fn main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: `#[error(forward)]` cannot be used when an error has no source
2+
--> tests/compile_fail/error/forward_no_source_enum.rs:3:17
3+
|
4+
3 | #[derive(Debug, Error)]
5+
| ^^^^^
6+
|
7+
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use derive_more::Error;
2+
3+
#[derive(Debug, Error)]
4+
#[error(forward)]
5+
struct Foo;
6+
7+
impl ::core::fmt::Display for Foo {
8+
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
9+
write!(f, "")
10+
}
11+
}
12+
13+
fn main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: `#[error(forward)]` cannot be used when an error has no source
2+
--> tests/compile_fail/error/forward_no_source_struct.rs:3:17
3+
|
4+
3 | #[derive(Debug, Error)]
5+
| ^^^^^
6+
|
7+
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use derive_more::Error;
2+
3+
#[derive(Debug, Error)]
4+
enum Foo {
5+
#[error(forward)]
6+
Bar,
7+
#[error(forward)]
8+
Baz {
9+
source: Box<dyn Error + Send + 'static>,
10+
},
11+
}
12+
13+
impl ::core::fmt::Display for Foo {
14+
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
15+
write!(f, "")
16+
}
17+
}
18+
19+
fn main() {}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
error: `#[error(forward)]` cannot be used when an error has no source
2+
--> tests/compile_fail/error/forward_no_source_variant.rs:3:17
3+
|
4+
3 | #[derive(Debug, Error)]
5+
| ^^^^^
6+
|
7+
= note: this error originates in the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)