-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tracking Issue for proc_macro_expand
#90765
Comments
FYI: allowing #[proc_macro]
pub fn expand_into(stream: TokenStream) -> TokenStream {
let mut parts = stream.into_iter();
let Some(TokenTree::Group(unexpanded)) = parts.next() else { panic!() };
let into = parts.collect::<TokenStream>();
let expanded = unexpanded.expand_expr().unwrap();
quote!(#into!(#expanded)).into()
} By combining it with a safe macro that emits macro_rules! helper {
({
let $output:ident;
let mut $x1:ident = $x2:ident;
let mut $x3:ident = $e:expr;
}) => {
let mut $output = $e;
};
}
let future = async {
let value = 5;
let reference = &value;
yield_now().await;
println!("{reference}");
};
expand_into!([{ let pinned; pin_mut!(future) }] helper);
// expands to: let pinned = unsafe { Pin::new_unchecked(&mut future) };
let _ = pinned.poll(cx);
let moved_future = future;
pin_mut!(moved_future);
moved_future.poll(cx); // oops! So if the functionality of |
Or a simpler albeit more conceptual example: //! crate a
#[macro_export]
macro_rules! fancy_block {() => (
unsafe {} // needless but harmless unsafe: SOUND
)} //! dependent, which uses no `unsafe` code:
fn main() {
match! ::a::fancy_block!() {
( $some_ident:ident {} ) => (
$some_ident {
::core::hint::unreachable_unchecked()
}
);
}
}
|
5: Add experimental cfg for using the proc-macro-expand API r=Nemo157 a=Nemo157 rust-lang/rust#90765 Co-authored-by: Wim Looman <[email protected]>
I noticed an issue with this feature while working on the bridge, and opened a PR to fix it (#101414), so it should be fixed shortly. Effectively, because |
Just dropping in here, because this feature is precisely what I need for my own project. I didn't understand the problem outlined in the two examples at first, but I think if I had to sum it up it would be this: some macros expand to code snippets that really shouldn't be tampered with, and I'm not really a fan of the "emit an error if the expansion contains an Instead of that, here's my wild idea: maybe there's a way to mark these un-tamperable macros as So that means when a sealed macro is expanded, that expansion is properly done and can be passed forward, and will appear in the final generated code (somehow)... but the proc-macro doing the expanding can't actually read its contents. Which is inconvenient, so maybe that's where an Now I have zero experience with the compiler development, so I don't really know how this could or should be implemented, but the idea I had was this:
I don't know if putting "dummy tokens" into
Sorry that this got long. Also I have no idea how anything works, so if this is complete nonsense feel free to disregard. I'm just really looking forward to this feature, because I think it'd really boost the capabilities of proc macros! Edit: Doubly sorry for not realizing the discussion had moved to #87264. Because I think my |
It seems like this feature hasn't had much progress, and appears stalled on the more general cases. |
This will be very useful with macros such as |
Feature gate:
#![feature(proc_macro_expand)]
This is a tracking issue for the
TokenStream::expand_expr
function for use in proc-macros. This function allows eagerly expanding TokenStreams containing expressions from within a proc-macro, such that they can be modified, giving proc-macros similar functionality to built-in macros likeformat_args!
,concat!
andinclude!
.Public API
Steps / History
Unresolved Questions
#[allow_internal_unstable]
) be expandable or left unexpanded?include!
?The text was updated successfully, but these errors were encountered: