From: dylan_DPC Date: Sat, 7 Apr 2018 10:20:36 +0000 (+0530) Subject: added function to check if lints belong to an external macro X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;ds=sidebyside;h=dd0808dd24bbb351d19b805a9318eb9e105010b2;p=rust.git added function to check if lints belong to an external macro --- 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 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>(&self, /// Emit a lint at the appropriate level, for a particular span. fn span_lint>(&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>(&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 @@ 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 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 or the MIT license +// , 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) +}