diff --git a/impl/src/fmt.rs b/impl/src/fmt.rs index 8b571d98..d555c247 100644 --- a/impl/src/fmt.rs +++ b/impl/src/fmt.rs @@ -69,6 +69,20 @@ impl Display<'_> { } _ => continue, }; + let formatvar = match &member { + MemberUnraw::Unnamed(index) => IdentUnraw::new(format_ident!("_{}", index)), + MemberUnraw::Named(ident) => ident.clone(), + }; + out += &formatvar.to_string(); + if !named_args.insert(formatvar.clone()) { + // Already specified in the format argument list. + continue; + } + if !has_trailing_comma { + args.extend(quote_spanned!(span=> ,)); + } + let local = formatvar.to_local(); + args.extend(quote_spanned!(span=> #formatvar = #local)); if let Some(&field) = member_index.get(&member) { let end_spec = match read.find('}') { Some(end_spec) => end_spec, @@ -83,28 +97,15 @@ impl Display<'_> { Some('b') => Trait::Binary, Some('e') => Trait::LowerExp, Some('E') => Trait::UpperExp, - Some(_) | None => Trait::Display, + Some(_) => Trait::Display, + None => { + has_bonus_display = true; + args.extend(quote_spanned!(span=> .as_display())); + Trait::Display + } }; implied_bounds.insert((field, bound)); } - let formatvar = match &member { - MemberUnraw::Unnamed(index) => IdentUnraw::new(format_ident!("_{}", index)), - MemberUnraw::Named(ident) => ident.clone(), - }; - out += &formatvar.to_string(); - if !named_args.insert(formatvar.clone()) { - // Already specified in the format argument list. - continue; - } - if !has_trailing_comma { - args.extend(quote_spanned!(span=> ,)); - } - let local = formatvar.to_local(); - args.extend(quote_spanned!(span=> #formatvar = #local)); - if read.starts_with('}') && member_index.contains_key(&member) { - has_bonus_display = true; - args.extend(quote_spanned!(span=> .as_display())); - } has_trailing_comma = false; } diff --git a/tests/test_generics.rs b/tests/test_generics.rs index d7790e2d..4d49edf5 100644 --- a/tests/test_generics.rs +++ b/tests/test_generics.rs @@ -159,3 +159,16 @@ pub struct StructFromGeneric { #[derive(Error, Debug)] #[error(transparent)] pub struct StructTransparentGeneric(pub E); + +// Regression test for https://github.com/dtolnay/thiserror/issues/345 +#[test] +fn test_no_bound_on_named_fmt() { + #[derive(Error, Debug)] + #[error("{thing}", thing = "...")] + struct Error { + thing: T, + } + + let error = Error { thing: DebugOnly }; + assert_eq!(error.to_string(), "..."); +}