Skip to content

Conversation

bungcip
Copy link
Contributor

@bungcip bungcip commented Aug 28, 2025

  • remove unused function & impl
    • impl<'a> Make<Unsafety> for &'a str
    • impl<'a> Make<Constness> for &'a str
    • impl Make<TokenStream> for Vec<String>
    • impl Make<PathArguments> for ParenthesizedGenericArguments
    • fn parenthesized_args
  • refactor mk().vis() usage so we can remove impl<'a> Make<Visibility> for &'a str
  • refactor mk().set_mutbl() usage so we can remove impl<'a> Make<Mutability> for &'a str
  • refactor mk().unary_expr() usage so we can remove impl<'a> Make<UnOp> for &'a str
  • unify impl Make<TokenStream> for Vec<&str>, impl Make<TokenStream> for Vec<u64>, and impl Make<TokenStream> for Vec<Meta> functionality to use fn comma_separated

- remove unused function & impl
  - `impl<'a> Make<Unsafety> for &'a str`
  - `impl<'a> Make<Constness> for &'a str`
  - `impl Make<TokenStream> for Vec<String>`
  - `impl Make<PathArguments> for ParenthesizedGenericArguments`
  - `fn parenthesized_args`
- refactor mk().vis() usage so we can remove `impl<'a> Make<Visibility> for &'a str`
- refactor mk().set_mutbl() usage so we can remove `impl<'a> Make<Mutability> for &'a str`
- refactor mk().unary_expr() usage so we can remove `impl<'a> Make<UnOp> for &'a str`
- unify `impl Make<TokenStream> for Vec<&str>`, `impl Make<TokenStream> for Vec<u64>`, and `impl Make<TokenStream> for Vec<Meta>` functionality to use comma_separated function
@@ -667,12 +667,13 @@ impl StructureState {
/// * Negating something of the form `!<expr>` produces `<expr>`
///
fn not(bool_expr: &Expr) -> Box<Expr> {
use syn::UnOp;
Copy link
Contributor

Choose a reason for hiding this comment

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

If this can be hoisted to the top-level, that'd be preferable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

maybe we can create a new module, lets call it transform, which contain all helper function that transform a rust AST to another rust AST. so we can put helper function like this not() and unparen() in there. However i prefer doing that in another PR rather than this

@@ -336,82 +290,29 @@ impl Make<TokenStream> for Vec<TokenTree> {
}
}

impl Make<TokenStream> for Vec<String> {
Copy link
Contributor

Choose a reason for hiding this comment

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

With an iterator-based fn comma_separated, you can simplify this to:

impl Make<TokenStream> for Vec<&str> {
    fn make(self, _mk: &Builder) -> TokenStream {
        comma_separated(self.iter().map(|&s| Ident::new(s, Span::call_site())))
    }
}

impl Make<TokenStream> for Vec<u64> {
    fn make(self, _mk: &Builder) -> TokenStream {
        comma_separated(self.iter().map(|&s| Literal::u64_unsuffixed(s)))
    }
}

impl Make<TokenStream> for Vec<Meta> {
    fn make(self, _mk: &Builder) -> TokenStream {
        comma_separated(self.iter())
    }
}

Comment on lines +164 to +179
fn comma_separated<T, F>(items: Vec<T>, f: F) -> TokenStream
where
F: Fn(&mut TokenStream, T),
{
let mut tokens = TokenStream::new();
let mut first = true;
for item in items {
if !first {
TokenTree::Punct(Punct::new(',', Spacing::Alone)).to_tokens(&mut tokens);
} else {
first = false;
}
f(&mut tokens, item);
}
tokens
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
fn comma_separated<T, F>(items: Vec<T>, f: F) -> TokenStream
where
F: Fn(&mut TokenStream, T),
{
let mut tokens = TokenStream::new();
let mut first = true;
for item in items {
if !first {
TokenTree::Punct(Punct::new(',', Spacing::Alone)).to_tokens(&mut tokens);
} else {
first = false;
}
f(&mut tokens, item);
}
tokens
}
fn comma_separated<I, T>(items: I) -> TokenStream
where
I: Iterator<Item = T>,
T: ToTokens + Clone,
{
let items = items.map(|items| items.to_token_stream());
let comma = TokenTree::Punct(Punct::new(',', Spacing::Alone)).into_token_stream();
intersperse(items, comma).collect()
}

If you add itertools to c2rust-ast-builder (which we already use for c2rust-transpile), this could be a lot simpler.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if it is ok to add new dependencies crate, i will add it tomorrow. cannot wait for rust-lang/rust#79524 to become stable😃

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, you can use itertools. It shouldn't be an issue since we already use it in c2rust-transpile.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

$ cargo build
  Downloaded pathdiff v0.2.3
  Downloaded cfg-if v1.0.3
  ....
  Downloaded linux-raw-sys v0.9.4
  Downloaded 114 crates (12.7 MB) in 31.19s (largest was `linux-raw-sys` at 2.3 MB)
error: package `clap v4.5.47` cannot be built because it requires rustc 1.74 or newer, while the currently active rustc version is 1.65.0-nightly

just simply adding itertools in c2rust-ast-builder, and running usual cargo update + cargo build fails when somehow clap suddenly upgraded to 4.5 🤣. maybe I will just wait until #1227 landed

Copy link
Contributor

Choose a reason for hiding this comment

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

We can't use cargo update. But just adding itertools should work; I prototyped it and it seemed to work fine.

Comment on lines -288 to -290
"deref" | "*" => UnOp::Deref(Default::default()),
"not" | "!" => UnOp::Not(Default::default()),
"neg" | "-" => UnOp::Neg(Default::default()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure getting rid of all of these is helpful. "!" is pretty easy to read and understand (although things like "not" and the other non-standard spellings for things seem bad). It has the downside of not being as easily searchable since it's not tied to a symbol like UnOp::Not, but it's also easier to read and write in a bunch of ways.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think is more readable for all unary_expr() usage in transpile to just use mk().deref_expr(), mk().neg_expr(), and mk().not_expr(). I can create follow up PR for the refactor

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the original motivation for this was to isolate the actual types of the syntax library from the code using the builder API as much as possible. This was nice when we changed from using the rustc syntax tree to syn. But I don't think we anticipate any such switch in the future, and I don't think we desperately need to keep this coupling loose anymore. I'm slightly in favor of the not_expr()/etc. refactor you suggest, but I don't think using UnOp enum values in core translator code is verboten at this point.

@ahomescu
Copy link
Contributor

ahomescu commented Sep 2, 2025

#1328 restores c2rust-refactor which also uses the AST builder. I need to check whether it's using any of the methods this PR is removing.

@bungcip
Copy link
Contributor Author

bungcip commented Sep 3, 2025

@ahomescu, correct me if i am wrong, but i think c2rust-refactor dont use c2rust-ast-builder. it seems to use rustc_ast

@ahomescu
Copy link
Contributor

ahomescu commented Sep 9, 2025

@ahomescu, correct me if i am wrong, but i think c2rust-refactor dont use c2rust-ast-builder. it seems to use rustc_ast

Right, the new PR completely forks the AST builder used by the transpiler (based on syn) from the one used by c2rust-refactor.

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.

4 participants