]> git.lizzy.rs Git - rust.git/commitdiff
added function to check if lints belong to an external macro
authordylan_DPC <dylan.dpc@gmail.com>
Sat, 7 Apr 2018 10:20:36 +0000 (15:50 +0530)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 17 Jul 2018 16:33:41 +0000 (09:33 -0700)
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/test/ui/in-band-lifetimes/ellided-lifetimes-macro-checks.rs [new file with mode: 0644]

index 2a44845b980dba83a0d3e511b4cc86869cf67c8f..a5517e85d444241348e14964e84ac89d575bdd94 100644 (file)
@@ -29,7 +29,7 @@
 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 @@ fn lookup<S: Into<MultiSpan>>(&self,
 
     /// 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,
index bff596e21e53abd5cba6fcc8082241d97654f2a4..62a39873e7694d8d1f5651a7a6ed545becb034ce 100644 (file)
@@ -54,6 +54,8 @@
                         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 @@ fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) {
 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))
+}
diff --git a/src/test/ui/in-band-lifetimes/ellided-lifetimes-macro-checks.rs b/src/test/ui/in-band-lifetimes/ellided-lifetimes-macro-checks.rs
new file mode 100644 (file)
index 0000000..9e53cbf
--- /dev/null
@@ -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)
+}