Skip to content

Commit

Permalink
Move recursion checking out of bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Nov 8, 2024
1 parent 8e5c843 commit 337df1d
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
12 changes: 11 additions & 1 deletion impl/src/attr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use proc_macro2::{Delimiter, Group, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use quote::{format_ident, quote, ToTokens};
use quote::{format_ident, quote, quote_spanned, ToTokens};
use std::collections::BTreeSet as Set;
use syn::parse::discouraged::Speculative;
use syn::parse::{End, ParseStream};
Expand All @@ -24,6 +24,7 @@ pub struct Display<'a> {
pub args: TokenStream,
pub requires_fmt_machinery: bool,
pub has_bonus_display: bool,
pub infinite_recursive: bool,
pub implied_bounds: Set<(usize, Trait)>,
pub bindings: Vec<(Ident, TokenStream)>,
}
Expand Down Expand Up @@ -177,6 +178,7 @@ fn parse_error_attribute<'a>(attrs: &mut Attrs<'a>, attr: &'a Attribute) -> Resu
args,
requires_fmt_machinery,
has_bonus_display: false,
infinite_recursive: false,
implied_bounds: Set::new(),
bindings: Vec::new(),
};
Expand Down Expand Up @@ -299,6 +301,14 @@ fn parse_token_expr(input: ParseStream, mut begin_expr: bool) -> Result<TokenStr

impl ToTokens for Display<'_> {
fn to_tokens(&self, tokens: &mut TokenStream) {
if self.infinite_recursive {
let span = self.fmt.span();
tokens.extend(quote_spanned! {span=>
#[warn(unconditional_recursion)]
fn _fmt() { _fmt() }
});
}

let fmt = &self.fmt;
let args = &self.args;

Expand Down
12 changes: 3 additions & 9 deletions impl/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl Display<'_> {
let mut read = fmt.as_str();
let mut out = String::new();
let mut has_bonus_display = false;
let mut infinite_recursive = false;
let mut implied_bounds = BTreeSet::new();
let mut bindings = Vec::new();
let mut macro_named_args = HashSet::new();
Expand Down Expand Up @@ -129,15 +130,7 @@ impl Display<'_> {
if let Some(&field) = member_index.get(&member) {
implied_bounds.insert((field, bound));
}
if member == *"self" && bound == Trait::Display {
binding_value = quote_spanned!(member.span()=>
{
#[warn(unconditional_recursion)]
fn _fmt() { _fmt() }
#member
}
);
}
infinite_recursive |= member == *"self" && bound == Trait::Display;
if macro_named_args.insert(member) {
bindings.push((local, binding_value));
} else {
Expand All @@ -148,6 +141,7 @@ impl Display<'_> {
out += read;
self.fmt = LitStr::new(&out, self.fmt.span());
self.has_bonus_display = has_bonus_display;
self.infinite_recursive = infinite_recursive;
self.implied_bounds = implied_bounds;
self.bindings = bindings;
Ok(())
Expand Down

0 comments on commit 337df1d

Please sign in to comment.