about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-09-01 14:54:57 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-09-07 21:37:51 +0300
commitf7434aef26bc413469fc0dfeadecabf75e18bd38 (patch)
tree3cac9e58eec901a58254d7b842e811d2fa06edac /src/librustc
parentef54f57c5b9d894a38179d09b00610c1b337b086 (diff)
downloadrust-f7434aef26bc413469fc0dfeadecabf75e18bd38.tar.gz
rust-f7434aef26bc413469fc0dfeadecabf75e18bd38.zip
Support "soft" feature-gating using a lint
Use it for feature-gating `#[bench]`
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/ich/impls_syntax.rs3
-rw-r--r--src/librustc/lint/builtin.rs7
-rw-r--r--src/librustc/middle/stability.rs22
3 files changed, 25 insertions, 7 deletions
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 646060bc8be..a33181e5925 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -115,9 +115,10 @@ for ::syntax::attr::StabilityLevel {
                                           hasher: &mut StableHasher<W>) {
         mem::discriminant(self).hash_stable(hcx, hasher);
         match *self {
-            ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
+            ::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => {
                 reason.hash_stable(hcx, hasher);
                 issue.hash_stable(hcx, hasher);
+                is_soft.hash_stable(hcx, hasher);
             }
             ::syntax::attr::StabilityLevel::Stable { ref since } => {
                 since.hash_stable(hcx, hasher);
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 6d9a6bb77dd..dd290572d7b 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -395,6 +395,12 @@ declare_lint! {
     "reservation of a two-phased borrow conflicts with other shared borrows"
 }
 
+declare_lint! {
+    pub SOFT_UNSTABLE,
+    Deny,
+    "a feature gate that doesn't break dependent crates"
+}
+
 declare_lint_pass! {
     /// Does nothing as a lint pass, but registers some `Lint`s
     /// that are used by other parts of the compiler.
@@ -460,6 +466,7 @@ declare_lint_pass! {
         NESTED_IMPL_TRAIT,
         MUTABLE_BORROW_RESERVATION_CONFLICT,
         INDIRECT_STRUCTURAL_MATCH,
+        SOFT_UNSTABLE,
     ]
 }
 
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index d02259bf301..c06a0feb6a9 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -438,6 +438,7 @@ impl<'tcx> Index<'tcx> {
                     level: attr::StabilityLevel::Unstable {
                         reason: Some(Symbol::intern(reason)),
                         issue: 27812,
+                        is_soft: false,
                     },
                     feature: sym::rustc_private,
                     rustc_depr: None,
@@ -480,7 +481,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 pub fn report_unstable(
-    sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, span: Span
+    sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, is_soft: bool, span: Span
 ) {
     let msg = match reason {
         Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
@@ -505,7 +506,13 @@ pub fn report_unstable(
     let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
     let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
     if fresh {
-        emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg);
+        if is_soft {
+            sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg);
+        } else {
+            emit_feature_err(
+                &sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
+            );
+        }
     }
 }
 
@@ -621,6 +628,7 @@ pub enum EvalResult {
         feature: Symbol,
         reason: Option<Symbol>,
         issue: u32,
+        is_soft: bool,
     },
     /// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
     Unmarked,
@@ -720,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         match stability {
-            Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
+            Some(&Stability {
+                level: attr::Unstable { reason, issue, is_soft }, feature, ..
+            }) => {
                 if span.allows_unstable(feature) {
                     debug!("stability: skipping span={:?} since it is internal", span);
                     return EvalResult::Allow;
@@ -744,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> {
                     }
                 }
 
-                EvalResult::Deny { feature, reason, issue }
+                EvalResult::Deny { feature, reason, issue, is_soft }
             }
             Some(_) => {
                 // Stable APIs are always ok to call and deprecated APIs are
@@ -767,8 +777,8 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
         match self.eval_stability(def_id, id, span) {
             EvalResult::Allow => {}
-            EvalResult::Deny { feature, reason, issue } =>
-                report_unstable(self.sess, feature, reason, issue, span),
+            EvalResult::Deny { feature, reason, issue, is_soft } =>
+                report_unstable(self.sess, feature, reason, issue, is_soft, span),
             EvalResult::Unmarked => {
                 // The API could be uncallable for other reasons, for example when a private module
                 // was referenced.