Skip to content

Conversation

@mi-caren
Copy link
Member

No description provided.

@paolobarbolini
Copy link
Member

paolobarbolini commented Sep 17, 2025

More context @dodomorandi and why this is necessary: there are cases in which we need to generate a one-element tuple. The current implementation doesn't leave a trailing comma, so what gets generated is (unwrapped{some_number}.{some_other_number}). Rust doesn't see this as a tuple, so the map's value is T, not (T,). This then messes the presenter, which expects the value to always be a tuple.

let mut accumulator = ::benzina::__private::indexmap::map::Entry::or_insert(
::benzina::__private::IndexMap::entry(&mut #accumulator_index, #id),
(#(#or_insert),*)
(#(#or_insert),*,)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base idea is perfect, the only thing that is not convincing me is what happens when or_insert is empty. In that case the expression (,) is being created, but that is not valid.

Do we have any guarantee or_insert is never empty? If not we could just create a branch that creates a token stream with the current expansion if or_insert is not empty and, in the other case, it just creates a unit.

Copy link
Member

@paolobarbolini paolobarbolini Sep 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make some kind of helper for generating tuples that also handles the unit case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea indeed!

@mi-caren mi-caren force-pushed the tuple-comma branch 2 times, most recently from eb7b659 to 0c25b19 Compare September 19, 2025 09:14
Copy link
Member

@paolobarbolini paolobarbolini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment on lines 117 to 124
fn tuple_from_vec(vec: &[impl ToTokens]) -> TokenStream {
if vec.is_empty() {
quote! { () }
} else {
quote! { (#(#vec),*,) }
}
}

Copy link
Member

@paolobarbolini paolobarbolini Sep 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd move this to utils.rs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extreme nitpick mode on: I would propose a couple of renames and a change of input type:

fn tuple_from_tokenizables<I>(tokenizables: I) -> TokenStream
where
    I: IntoIterator<Item: ToTokens, IntoIter: ExactSizeIterator>,
{
    let tokenizables = tokenizables.into_iter();
    if tokenizables.len() == 0 {
        quote! { () }
    } else {
        quote! { (#(#tokenizables),*,) }
    }
}

tokenizables is not the best name I could think of, if you have a better proposal feel free to go on.

Unfortunately ExactSizeIterator::is_empty is still unstable, the following approach could be possible but I don't think it's worth it.

fn tuple_from_tokenizables<I>(tokenizables: I) -> TokenStream
where
    I: IntoIterator<Item: ToTokens>,
{
    let mut tokenizables = tokenizables.into_iter();
    if let Some(tokenizable) = tokenizables.next() {
        quote! { (#tokenizable, #(#tokenizables),*,) }
    } else {
        quote! { () }
    }
}

Said that, you can also go on with the current implementation. My proposal is useful in case you do not have a slice of tokenizable elements.

@paolobarbolini paolobarbolini merged commit d24275a into M4SS-Code:main Sep 19, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants