-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Stability lint for nested macros #17508
Stability lint for nested macros #17508
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @aturon (or someone else) soon. |
@vberger Thanks so much for doing this! I don't know the macro internals well enough to do more than rubber-stamp this; I'm going to ask someone who does to review. |
r? @pnkfelix |
} else { | ||
false | ||
// was this code from the current macro arguments ? | ||
skip = !( e.span.lo > info.call_site.lo && e.span.hi < info.call_site.hi ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. do we use this sort of span comparison logic elsewhere in a significant manner?
I ask because I spent some time investigating our span calculations and found that they are not always sound
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pnkfelix I must admit I assumed they where correct (as that's what is used to align the ^~~~~
in the warning message).
The only situations where I encountered some that where not reliable was when dealing with compiler built-ins, that's pretty much why I skip them.
I couldn't find any other way to check whether an expression actually was from the macro arguments or was created by the macro. I couldn't find informations about macro expansion anywhere else.
If you know where I could look to seek more reliable data, I'd be glad to use it.
@pnkfelix Ping. Would be good to move forward with this. |
@huonw Do you know the relevant macro stuff enough to properly review this? |
@@ -1470,26 +1470,31 @@ impl LintPass for Stability { | |||
} | |||
|
|||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) { | |||
// skip if `e` is not from macro arguments | |||
let skip = cx.tcx.sess.codemap().with_expn_info(e.span.expn_id, |expninfo| { | |||
// firt, check if the given expression was generated by a macro or not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/firt/fisrt/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, whoops: first
.
(Just checking my understanding.) Would it be accurate to describe this as:
*I understand that it is checking the spans at each step, but it seems that overwrites If someone wishes to experiment with the macro stack to understand better, I used a lint like the following to check what was going on: // span-lint.rs
#![feature(phase, plugin_registrar)]
#![crate_type = "dylib"]
extern crate syntax;
#[phase(plugin, link)] extern crate rustc;
use syntax::ast;
use rustc::plugin::Registry;
use rustc::lint::{Context, LintArray, LintPass};
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_lint_pass(box SpanLint);
}
declare_lint! { SPAN_LINT, Warn, "..." }
struct SpanLint;
impl LintPass for SpanLint {
fn get_lints(&self) -> LintArray {
lint_array!(SPAN_LINT)
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
let mut sp = e.span;
let mut stop = false;
cx.tcx.sess.span_warn(sp, "starts here");
while !stop {
cx.tcx.sess.codemap().with_expn_info(sp.expn_id, |expn_info| {
match expn_info {
None => stop = true,
Some(ref info) => {
sp = info.call_site;
cx.tcx.sess.span_note(sp, "continues");
}
}
})
}
}
} #![feature(phase, macro_rules)]
#[phase(plugin)]
extern crate "span-lint" as _lint;
macro_rules! bar {
($e: expr) => { $e }
}
macro_rules! foo {
($e: expr) => { bar!($e) };
() => { 1u }
}
fn main() {
foo!(1u);
foo!();
}
(I don't know how to disable the conventional stack trace printing, so just focus on the |
@huonw I just corrected including your comments. And yes, this is exactly how it works. This structure of over-writing the |
assigning self to review. (I'm not sure I'd be comfortable with using the |
It's not obvious to me that there is a solution without using the spans; certainly not one as easy as using the spans. (Maybe I'm just not being imaginative enough...) |
I'm personally happy with it (enough to r+), but @pnkfelix may have some desired tweaks. |
Oops, I lost my second commit (fixing deprecated calls in the libs) while rebasing. I'll make it back. |
It seems that all changes implied by that commit are no longer relevant. I'm thus good for review @pnkfelix . |
… r=pnkfelix Finishes the job of #17286. Now the stability lint will successfully detect patterns such as: ``` first_macro!(second_macro!(deprecated_function())); ``` ``` macro_rules! foo ( ($e: expr) => (bar!($e)) ) foo!(deprected_function()); ``` and ``` println!("{}", deprecated_function()); ``` even with more levels of nesting, such as ``` println!("{}", foo!(bar!(deprecated_function()))); ```
feat: Add landing/faq walkthrough pages This is a basic implementation of a landing and FAQ page; I've included the bare-bones information as well as a [recommended section on inlay hints](https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Landing.20Page/near/446135321). I've also added `rust-analyzer: Open Walkthrough` and `rust-analyzer: Open FAQ` commands for ease of access. I am hoping to create a small list of FAQ to include that might be useful as well as any other information I may have missed in the landing page. Feel free to share any suggestions!  cc rust-lang#13351
internal: remove rust-analyzer.openFAQ Removed no longer functional `rust-analyzer.openFAQ` command created in rust-lang#17508
internal: remove rust-analyzer.openFAQ Removed no longer functional `rust-analyzer.openFAQ` command created in rust-lang#17508
Finishes the job of #17286.
Now the stability lint will successfully detect patterns such as:
and
even with more levels of nesting, such as