Skip to content

Conversation

sabiwara
Copy link
Contributor

@sabiwara sabiwara commented Aug 5, 2025

Close #14676

Alternative to #14677

I've tried a couple approaches here, but eventually I think this is probably the way to go:

  • protect macro args before expansion by adding stop_generated: true
  • remove these as part of linify and stop marking as generated

Also tried:

  1. working with unquotes as originally discussed: I think this is the wrong thing to consider, since macros internally might be building AST by calling quote multiple times and injecting smaller blocks into bigger blocks => what we want is to stop at macro args, no matter how the macro is implemented internally?
  2. linify to only mark generated if no line in the meta -> kinda works for real-world cases but not when just trying out quote + Macro.expand in the shell or tests
  3. rather than stop_generated, stop_linify: true altogether (since we probably shouldn't add lines of the macro in injected args?) => seems reasonable but breaks with left variables undefined in ExUnit, I could try to fix it but figured this might be too risky of a change

The current stop_generated approach still breaks some tests though, so I'm not 100% sure it's the right approach.

@josevalim
Copy link
Member

Thank you! I like this approach and agree with your decisions. ❤️

One suggestion: what if we go with generated: false for those entries then?

Given setting {generated, true} already has to traverse metadata so we don't add it twice, if we do {generated, false}, we only have to traverse metadata once, looking for either true or false, and acting accordingly. Plus one fewer metadata option in general.

Thoughts?

@sabiwara
Copy link
Contributor Author

sabiwara commented Aug 6, 2025

we only have to traverse metadata once, looking for either true or false, and acting accordingly

Oh that's a good idea.
Intent-wise, it might be slightly confusing and less "greppable" than the explicit stop_generated, but I think it might be worth the trade-off.
Let me give it a shot!

@sabiwara
Copy link
Contributor Author

sabiwara commented Aug 6, 2025

@josevalim I tried but it adds more failing tests, I haven't pinpointed the exact cause but I think it makes it arguably harder to reason about potential side effects, given that several places in the code are using Keyword.take(meta, [:generated]) or equivalents.
So I think it's safer to stick to the specific meta approach, also the new meta doesn't necessarily need to be documented since it is "transient", i.e. it is added before expansion but removed afterwards, WDYT?

Copy link
Member

@josevalim josevalim left a comment

Choose a reason for hiding this comment

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

Let's go with this one then!

Also, let's not backport this one, so we have more time to test it in the wild.

@sabiwara
Copy link
Contributor Author

sabiwara commented Aug 6, 2025

Also, let's not backport this one, so we have more time to test it in the wild.

I was thinking the same 🤝

@sabiwara sabiwara merged commit 67042e8 into elixir-lang:main Aug 6, 2025
10 of 13 checks passed
@sabiwara sabiwara deleted the macro-stop-linify-at-args branch August 6, 2025 20:54
ggVGc pushed a commit to ggVGc/elixir-verbatim that referenced this pull request Sep 12, 2025
* Stop propagating generated on macro arguments

* Explicitly mark assert as generated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

ExUnit assert swallowing unused variable warning

2 participants