added function to check if lints belong to an external macro
This commit is contained in:
parent
4bff385fda
commit
dd0808dd24
3 changed files with 53 additions and 2 deletions
|
|
@ -29,7 +29,7 @@ use self::TargetLint::*;
|
|||
use std::slice;
|
||||
use rustc_data_structures::sync::{RwLock, ReadGuard};
|
||||
use lint::{EarlyLintPassObject, LateLintPassObject};
|
||||
use lint::{Level, Lint, LintId, LintPass, LintBuffer};
|
||||
use lint::{self, Level, Lint, LintId, LintPass, LintBuffer};
|
||||
use lint::builtin::BuiltinLintDiagnostics;
|
||||
use lint::levels::{LintLevelSets, LintLevelsBuilder};
|
||||
use middle::privacy::AccessLevels;
|
||||
|
|
@ -468,7 +468,14 @@ pub trait LintContext<'tcx>: Sized {
|
|||
|
||||
/// Emit a lint at the appropriate level, for a particular span.
|
||||
fn span_lint<S: Into<MultiSpan>>(&self, lint: &'static Lint, span: S, msg: &str) {
|
||||
self.lookup_and_emit(lint, Some(span), msg);
|
||||
match self.lints().future_incompatible(LintId::of(lint)) {
|
||||
Some(_) => self.lookup_and_emit(lint, Some(span), msg),
|
||||
None => {
|
||||
if !lint::in_external_macro(lint, span) {
|
||||
self.lookup_and_emit(lint, Some(span), msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn struct_span_lint<S: Into<MultiSpan>>(&self,
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
|
|||
check_crate, check_ast_crate,
|
||||
FutureIncompatibleInfo, BufferedEarlyLint};
|
||||
|
||||
use codemap::{ExpnFormat, ExpnInfo, Span };
|
||||
|
||||
/// Specification of a single lint.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct Lint {
|
||||
|
|
@ -669,3 +671,30 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
|
|||
pub fn provide(providers: &mut Providers) {
|
||||
providers.lint_levels = lint_levels;
|
||||
}
|
||||
|
||||
pub fn in_external_macro<'a, T: LintContext<'a>>(cx: &T, span: Span) -> bool {
|
||||
/// Invokes `in_macro` with the expansion info of the given span slightly
|
||||
/// heavy, try to use
|
||||
/// this after other checks have already happened.
|
||||
fn in_macro_ext<'a, T: LintContext<'a>>(cx: &T, info: &ExpnInfo) -> bool {
|
||||
// no ExpnInfo = no macro
|
||||
if let ExpnFormat::MacroAttribute(..) = info.callee.format {
|
||||
// these are all plugins
|
||||
return true;
|
||||
}
|
||||
// no span for the callee = external macro
|
||||
info.callee.span.map_or(true, |span| {
|
||||
// no snippet = external macro or compiler-builtin expansion
|
||||
cx.sess()
|
||||
.codemap()
|
||||
.span_to_snippet(span)
|
||||
.ok()
|
||||
.map_or(true, |code| !code.starts_with("macro_rules"))
|
||||
})
|
||||
}
|
||||
|
||||
span.ctxt()
|
||||
.outer()
|
||||
.expn_info()
|
||||
.map_or(false, |info| in_macro_ext(cx, &info))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
#![feature(nll)]
|
||||
#![deny(elided_lifetime_in_path)]
|
||||
|
||||
fn main() {
|
||||
format!("foo {}", 22)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue