mirror of
https://github.com/dtolnay/thiserror.git
synced 2025-04-03 21:07:38 +03:00
Reject display attribute on a field
This commit is contained in:
parent
10d1f640da
commit
aa123cfe0c
5 changed files with 40 additions and 4 deletions
|
@ -8,12 +8,13 @@ use syn::{
|
|||
};
|
||||
|
||||
pub struct Attrs<'a> {
|
||||
pub display: Option<Display>,
|
||||
pub display: Option<Display<'a>>,
|
||||
pub source: Option<Source<'a>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Display {
|
||||
pub struct Display<'a> {
|
||||
pub original: &'a Attribute,
|
||||
pub fmt: LitStr,
|
||||
pub args: TokenStream,
|
||||
pub was_shorthand: bool,
|
||||
|
@ -54,6 +55,7 @@ pub fn get(input: &[Attribute]) -> Result<Attrs> {
|
|||
fn parse_display(attr: &Attribute) -> Result<Display> {
|
||||
attr.parse_args_with(|input: ParseStream| {
|
||||
let mut display = Display {
|
||||
original: attr,
|
||||
fmt: input.parse()?,
|
||||
args: parse_token_expr(input, false)?,
|
||||
was_shorthand: false,
|
||||
|
@ -116,7 +118,7 @@ fn parse_source(attr: &Attribute) -> Result<Source> {
|
|||
Ok(Source { original: attr })
|
||||
}
|
||||
|
||||
impl ToTokens for Display {
|
||||
impl ToTokens for Display<'_> {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
let fmt = &self.fmt;
|
||||
let args = &self.args;
|
||||
|
|
|
@ -3,7 +3,7 @@ use proc_macro2::TokenStream;
|
|||
use quote::quote_spanned;
|
||||
use syn::{Ident, LitStr};
|
||||
|
||||
impl Display {
|
||||
impl Display<'_> {
|
||||
// Transform `"error {var}"` to `"error {}", var`.
|
||||
pub fn expand_shorthand(&mut self) {
|
||||
if !self.args.is_empty() {
|
||||
|
|
|
@ -17,6 +17,9 @@ impl Struct<'_> {
|
|||
fn validate(&self) -> Result<()> {
|
||||
check_no_source(&self.attrs)?;
|
||||
find_duplicate_source(&self.fields)?;
|
||||
for field in &self.fields {
|
||||
field.validate()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +45,21 @@ impl Variant<'_> {
|
|||
fn validate(&self) -> Result<()> {
|
||||
check_no_source(&self.attrs)?;
|
||||
find_duplicate_source(&self.fields)?;
|
||||
for field in &self.fields {
|
||||
field.validate()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Field<'_> {
|
||||
fn validate(&self) -> Result<()> {
|
||||
if let Some(display) = &self.attrs.display {
|
||||
return Err(Error::new_spanned(
|
||||
display.original,
|
||||
"not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant",
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
11
tests/ui/unexpected-field-fmt.rs
Normal file
11
tests/ui/unexpected-field-fmt.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
What {
|
||||
#[error("...")]
|
||||
io: std::io::Error,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() {}
|
5
tests/ui/unexpected-field-fmt.stderr
Normal file
5
tests/ui/unexpected-field-fmt.stderr
Normal file
|
@ -0,0 +1,5 @@
|
|||
error: not expected here; the #[error(...)] attribute belongs on top of a struct or an enum variant
|
||||
--> $DIR/unexpected-field-fmt.rs:6:9
|
||||
|
|
||||
6 | #[error("...")]
|
||||
| ^^^^^^^^^^^^^^^
|
Loading…
Add table
Add a link
Reference in a new issue