about summary refs log tree commit diff
diff options
context:
space:
mode:
authordylan_DPC <dylan.dpc@gmail.com>2018-04-07 15:50:36 +0530
committerAlex Crichton <alex@alexcrichton.com>2018-07-17 09:33:41 -0700
commitdd0808dd24bbb351d19b805a9318eb9e105010b2 (patch)
tree5ea6bd01e7140e70e06eb9c28a26be03660d6d74
parent4bff385fdadb999f19afb7b1482df7863034d742 (diff)
added function to check if lints belong to an external macro
-rw-r--r--src/librustc/lint/context.rs11
-rw-r--r--src/librustc/lint/mod.rs29
-rw-r--r--src/test/ui/in-band-lifetimes/ellided-lifetimes-macro-checks.rs15
3 files changed, 53 insertions, 2 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 2a44845b980..a5517e85d44 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -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,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index bff596e21e5..62a39873e76 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -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))
+}
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
index 00000000000..9e53cbfb3ad
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/ellided-lifetimes-macro-checks.rs
@@ -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)
+}