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;
/// 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,
check_crate, check_ast_crate,
FutureIncompatibleInfo, BufferedEarlyLint};
+use codemap::{ExpnFormat, ExpnInfo, Span };
+
/// Specification of a single lint.
#[derive(Copy, Clone, Debug)]
pub struct Lint {
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))
+}
--- /dev/null
+// 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)
+}