-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Destabilise the internals of format_args!
#22953
Comments
😍 |
@alexcrichton Does this need to be finished before 1.0? Some other observations:
|
@rprichard yeah it would be nice to get this done, but it's not necessarily the end of the world if it slips through the cracks for now. The Due to the |
@alexcrichton Thanks for looking at this. It looks like |
Ah yeah I'm not too familiar with how the |
@rprichard ah, yeah, I guess you do need the span of the macro (i.e the one passed into the function) rather than the expression/arguments. |
@huonw Currently, I've modified I then tried writing a simple syntax plugin (easier to experiment with, faster iteration times), and I've noticed that with a simple macro that evaluates to its last argument, I don't get stability errors, even if that argument is unstable! Here's the code for the plugin I'm working with. |
Ah! I think plugins are handled differently to the built-in ones in a fairly subtle (and apparently buggy) way. Specifically the registry overrides the definition span, which is used to check for If I make the following change the stability error occurs as expected: --- a/foo_macros.rs
+++ b/foo_macros.rs
@@ -99,6 +99,6 @@ fn expand_foo(cx: &mut ExtCtxt, sp: Span, args: &[ast::TokenTree])
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
let expander: MacroExpanderFn = expand_foo;
- reg.register_syntax_extension(token::intern("foo"),
- NormalTT(Box::new(expander), None, true));
+ reg.syntax_exts.push((token::intern("foo"),
+ NormalTT(Box::new(expander), None, true)));
} (Abusing the fact that the registry has public fields to stop it changing the |
(FWIW, your plugin + my bug-workaround seems to behave correctly wrt being inside a macro_rules marked with |
(Filed #23964.) |
@huonw With your change to I made a reduced plugin demonstrating the problem. |
This appears to be because the span passed into the syntax extension appears to be the span of the outer macro invocation, rather than the span of the internal plugin invocation, which is what the stability checking assumes. Hm. |
Yes, when we expand an expression macro, we use It looks like using I also thought it was interesting that when we expand an expression macro, we replace the fully expanded OTOH, maybe this change makes sense: diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index ee2cf90..fdb5716 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -80,7 +80,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
fully_expanded.map(|e| ast::Expr {
id: ast::DUMMY_NODE_ID,
node: e.node,
- span: span,
+ span: fld.new_span(span),
})
} |
To elaborate more, even if the expanded macro is |
Using |
I guess it might if the macro is defined/imported inside the expansion of another macro. (e.g. (I'm not sure I'm interpreting the question right.)
Hm, I'm struggling to visualise what effect that will have, do you happen to have a before/after diagnostics listing? (Also, including
I think those tests will just have to be marked as expected-fails (with |
I think my question was confused -- by "macro span," I was thinking of the span passed to a syntax extension. That span is sometimes I'm wondering whether, say, the expression passed to My current guess is that a macro definition span has no backtrace, but I can't find a test case where it would matter.
Adding the macro_rules! nested_expr {
() => (fake)
}
macro_rules! call_nested_expr_sum { //~ NOTE in expansion of
() => { 1 + nested_expr!(); } //~ ERROR unresolved name
}
fn main() {
call_nested_expr_sum!(); //~ NOTE expansion site
} Without the
With the
I'm actually not sure what the total impact is of using fn main() {
let x = format_args!("abc");
} from:
to:
The difference is the first span that the borrow checker highlights. I was a little concerned that the
It affects a lot of tests -- in my testing, 550 of 2032 pretty tests failed. I'm currently destabilizing all the v1 things, so |
This issue is blocked on #23616. |
I can't think of somewhere it would matter either... if there are problems later we can fix them as they come.
Thanks, looks good.
Argh. That's not so great. I'm inclined to agree with Niko: #23616 (comment). Unfortunately, I guess that still requires adding feature flags to 550 tests, and that is some druggery I wouldn't wish on anyone; although it seems to me that large parts might automatable (e.g. insert (If we do decide to follow Niko's suggestion, it's totally cool if you're not up to doing this boring part.) |
@alexcrichton recently destabilized the internals of I speculate that that commit fixed most of the tests that were failing for this issue. i.e. The majority of tests that use I'll work on this issue again soon, probably after rebasing my other macro-related PR. |
#22899 should mean that contents of
core::fmt::rt::v1
used byformat_args!
can probably be made#[unstable]
.cc @eddyb
The text was updated successfully, but these errors were encountered: