Skip to content

Commit

Permalink
Merge pull request #108 from ninevra/raw-idents
Browse files Browse the repository at this point in the history
Support raw-identifier fields in format strings
  • Loading branch information
dtolnay committed Nov 4, 2020
2 parents fbe9804 + 5fc018d commit 7014b69
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
14 changes: 12 additions & 2 deletions impl/src/fmt.rs
Expand Up @@ -5,7 +5,7 @@ use quote::{format_ident, quote_spanned};
use std::collections::HashSet as Set;
use syn::ext::IdentExt;
use syn::parse::{ParseStream, Parser};
use syn::{Ident, Index, LitStr, Member, Result, Token};
use syn::{parse_str, Ident, Index, LitStr, Member, Result, Token};

impl Display<'_> {
// Transform `"error {var}"` to `"error {}", var`.
Expand Down Expand Up @@ -55,7 +55,9 @@ impl Display<'_> {
}
'a'..='z' | 'A'..='Z' | '_' => {
let ident = take_ident(&mut read);
Member::Named(Ident::new(&ident, span))
let mut ident = parse_str::<Ident>(&ident).unwrap();
ident.set_span(span);
Member::Named(ident)
}
_ => continue,
};
Expand All @@ -64,6 +66,10 @@ impl Display<'_> {
Member::Named(ident) => ident.clone(),
};
let mut formatvar = local.clone();
if formatvar.to_string().starts_with("r#") {
// Replace the "r#" prefix.
formatvar = format_ident!("raw_field_{}", formatvar);
}
if formatvar.to_string().starts_with('_') {
// Work around leading underscore being rejected by 1.40 and
// older compilers. https://github.com/rust-lang/rust/pull/66847
Expand Down Expand Up @@ -125,6 +131,10 @@ fn take_int(read: &mut &str) -> String {

fn take_ident(read: &mut &str) -> String {
let mut ident = String::new();
if let Some(rest) = read.strip_prefix("r#") {
ident.push_str("r#");
*read = rest;
}
for (i, ch) in read.char_indices() {
match ch {
'a'..='z' | 'A'..='Z' | '0'..='9' | '_' => ident.push(ch),
Expand Down
48 changes: 48 additions & 0 deletions tests/test_display.rs
Expand Up @@ -230,3 +230,51 @@ fn test_macro_rules() {
assert("0", Error0::Repro(0));
assert("0", Error1::Repro(0));
}

#[test]
fn test_raw() {
#[derive(Error, Debug)]
#[error("braced raw error: {r#fn}")]
struct Error {
r#fn: String,
}

assert(
"braced raw error: T",
Error {
r#fn: "T".to_owned(),
},
);
}

#[test]
fn test_raw_enum() {
#[derive(Error, Debug)]
enum Error {
#[error("braced raw error: {r#fn}")]
Braced { r#fn: String },
}

assert(
"braced raw error: T",
Error::Braced {
r#fn: "T".to_owned(),
},
);
}

#[test]
fn test_raw_conflict() {
#[derive(Error, Debug)]
enum Error {
#[error("braced raw error: {r#func}, {func}", func = "U")]
Braced { r#func: String },
}

assert(
"braced raw error: T, U",
Error::Braced {
r#func: "T".to_owned(),
},
);
}

0 comments on commit 7014b69

Please sign in to comment.