about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-10-28 21:01:07 +0000
committerbors <bors@rust-lang.org>2017-10-28 21:01:07 +0000
commit269cf5026cdac6ff47f886a948e99101316d7091 (patch)
treecda80a57ee48dc8fbcdf330e20670482f483edd8
parent2e6a1a9fb49f30e41316fb374b12301a3445ae8d (diff)
parentbb0049bcd21ca8c9707207de4669fadfd7362367 (diff)
downloadrust-269cf5026cdac6ff47f886a948e99101316d7091.tar.gz
rust-269cf5026cdac6ff47f886a948e99101316d7091.zip
Auto merge of #45540 - virgil-palanciuc:master, r=estebank
Avoid repetition on “use of unstable library feature 'rustc_private'”

This PR fixes the error by only emitting it when the span contains a real file (is not inside a macro) - and making sure it's emitted only once per span.
The first check was needed because spans-within-macros seem to differ a lot and "fixing" them to the real location is not trivial (and the method that does this is private to another module). It also feels like there always will be an error on import, with the real file name, so not sure there's a point to re-emit the same error at macro use.

Fix #44953.
-rw-r--r--src/librustc/middle/stability.rs28
-rw-r--r--src/librustc/session/mod.rs15
2 files changed, 36 insertions, 7 deletions
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index 4e4fc8b3118..b30d5e38488 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -18,8 +18,9 @@ use hir::def::Def;
 use hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId, LOCAL_CRATE};
 use ty::{self, TyCtxt};
 use middle::privacy::AccessLevels;
+use session::DiagnosticMessageId;
 use syntax::symbol::Symbol;
-use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::{Span, MultiSpan, DUMMY_SP};
 use syntax::ast;
 use syntax::ast::{NodeId, Attribute};
 use syntax::feature_gate::{GateIssue, emit_feature_err, find_lang_feature_accepted_version};
@@ -597,8 +598,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                            feature.as_str(), &r),
                     None => format!("use of unstable library feature '{}'", &feature)
                 };
-                emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
-                                 GateIssue::Library(Some(issue)), &msg);
+
+
+                let msp: MultiSpan = span.into();
+                let cm = &self.sess.parse_sess.codemap();
+                let span_key = msp.primary_span().and_then(|sp: Span|
+                    if sp != DUMMY_SP {
+                        let file = cm.lookup_char_pos(sp.lo()).file;
+                        if file.name.starts_with("<") && file.name.ends_with(" macros>") {
+                            None
+                        } else {
+                            Some(span)
+                        }
+                    } else {
+                        None
+                    }
+                );
+
+                let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
+                let fresh = self.sess.one_time_diagnostics.borrow_mut().insert(error_id);
+                if fresh {
+                    emit_feature_err(&self.sess.parse_sess, &feature.as_str(), span,
+                                     GateIssue::Library(Some(issue)), &msg);
+                }
             }
             Some(_) => {
                 // Stable APIs are always ok to call and deprecated APIs are
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index c87881341da..be35cc8e4a1 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -75,10 +75,10 @@ pub struct Session {
     pub working_dir: (String, bool),
     pub lint_store: RefCell<lint::LintStore>,
     pub buffered_lints: RefCell<Option<lint::LintBuffer>>,
-    /// Set of (LintId, Option<Span>, message) tuples tracking lint
+    /// Set of (DiagnosticId, Option<Span>, message) tuples tracking
     /// (sub)diagnostics that have been set once, but should not be set again,
-    /// in order to avoid redundantly verbose output (Issue #24690).
-    pub one_time_diagnostics: RefCell<FxHashSet<(lint::LintId, Option<Span>, String)>>,
+    /// in order to avoid redundantly verbose output (Issue #24690, #44953).
+    pub one_time_diagnostics: RefCell<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
     pub plugin_llvm_passes: RefCell<Vec<String>>,
     pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
     pub crate_types: RefCell<Vec<config::CrateType>>,
@@ -164,6 +164,13 @@ enum DiagnosticBuilderMethod {
     // add more variants as needed to support one-time diagnostics
 }
 
+/// Diagnostic message id - used in order to avoid emitting the same message more than once
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
+pub enum DiagnosticMessageId {
+    LintId(lint::LintId),
+    StabilityId(u32)
+}
+
 impl Session {
     pub fn local_crate_disambiguator(&self) -> CrateDisambiguator {
         match *self.crate_disambiguator.borrow() {
@@ -360,7 +367,7 @@ impl Session {
                 do_method()
             },
             _ => {
-                let lint_id = lint::LintId::of(lint);
+                let lint_id = DiagnosticMessageId::LintId(lint::LintId::of(lint));
                 let id_span_message = (lint_id, span, message.to_owned());
                 let fresh = self.one_time_diagnostics.borrow_mut().insert(id_span_message);
                 if fresh {