Skip to content

Commit 4ea7797

Browse files
authored
Rollup merge of #64066 - petrochenkov:softstab, r=matthewjasper
Support "soft" feature-gating using a lint Use it for feature-gating `#[bench]`. Closes #63798.
2 parents 83e2b5e + 74d8679 commit 4ea7797

File tree

10 files changed

+67
-28
lines changed

10 files changed

+67
-28
lines changed

src/libcore/macros.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1236,8 +1236,10 @@ pub(crate) mod builtin {
12361236
pub macro test($item:item) { /* compiler built-in */ }
12371237

12381238
/// Attribute macro applied to a function to turn it into a benchmark test.
1239-
#[unstable(feature = "test", issue = "50297",
1240-
reason = "`bench` is a part of custom test frameworks which are unstable")]
1239+
#[cfg_attr(not(boostrap_stdarch_ignore_this), unstable(soft, feature = "test", issue = "50297",
1240+
reason = "`bench` is a part of custom test frameworks which are unstable"))]
1241+
#[cfg_attr(boostrap_stdarch_ignore_this, unstable(feature = "test", issue = "50297",
1242+
reason = "`bench` is a part of custom test frameworks which are unstable"))]
12411243
#[allow_internal_unstable(test, rustc_attrs)]
12421244
#[rustc_builtin_macro]
12431245
pub macro bench($item:item) { /* compiler built-in */ }

src/librustc/ich/impls_syntax.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,10 @@ for ::syntax::attr::StabilityLevel {
115115
hasher: &mut StableHasher<W>) {
116116
mem::discriminant(self).hash_stable(hcx, hasher);
117117
match *self {
118-
::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue } => {
118+
::syntax::attr::StabilityLevel::Unstable { ref reason, ref issue, ref is_soft } => {
119119
reason.hash_stable(hcx, hasher);
120120
issue.hash_stable(hcx, hasher);
121+
is_soft.hash_stable(hcx, hasher);
121122
}
122123
::syntax::attr::StabilityLevel::Stable { ref since } => {
123124
since.hash_stable(hcx, hasher);

src/librustc/lint/builtin.rs

+7
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,12 @@ declare_lint! {
395395
"reservation of a two-phased borrow conflicts with other shared borrows"
396396
}
397397

398+
declare_lint! {
399+
pub SOFT_UNSTABLE,
400+
Deny,
401+
"a feature gate that doesn't break dependent crates"
402+
}
403+
398404
declare_lint_pass! {
399405
/// Does nothing as a lint pass, but registers some `Lint`s
400406
/// that are used by other parts of the compiler.
@@ -460,6 +466,7 @@ declare_lint_pass! {
460466
NESTED_IMPL_TRAIT,
461467
MUTABLE_BORROW_RESERVATION_CONFLICT,
462468
INDIRECT_STRUCTURAL_MATCH,
469+
SOFT_UNSTABLE,
463470
]
464471
}
465472

src/librustc/middle/stability.rs

+16-6
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ impl<'tcx> Index<'tcx> {
438438
level: attr::StabilityLevel::Unstable {
439439
reason: Some(Symbol::intern(reason)),
440440
issue: 27812,
441+
is_soft: false,
441442
},
442443
feature: sym::rustc_private,
443444
rustc_depr: None,
@@ -480,7 +481,7 @@ pub fn provide(providers: &mut Providers<'_>) {
480481
}
481482

482483
pub fn report_unstable(
483-
sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, span: Span
484+
sess: &Session, feature: Symbol, reason: Option<Symbol>, issue: u32, is_soft: bool, span: Span
484485
) {
485486
let msg = match reason {
486487
Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
@@ -505,7 +506,13 @@ pub fn report_unstable(
505506
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
506507
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
507508
if fresh {
508-
emit_feature_err(&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg);
509+
if is_soft {
510+
sess.buffer_lint(lint::builtin::SOFT_UNSTABLE, CRATE_NODE_ID, span, &msg);
511+
} else {
512+
emit_feature_err(
513+
&sess.parse_sess, feature, span, GateIssue::Library(Some(issue)), &msg
514+
);
515+
}
509516
}
510517
}
511518

@@ -621,6 +628,7 @@ pub enum EvalResult {
621628
feature: Symbol,
622629
reason: Option<Symbol>,
623630
issue: u32,
631+
is_soft: bool,
624632
},
625633
/// The item does not have the `#[stable]` or `#[unstable]` marker assigned.
626634
Unmarked,
@@ -720,7 +728,9 @@ impl<'tcx> TyCtxt<'tcx> {
720728
}
721729

722730
match stability {
723-
Some(&Stability { level: attr::Unstable { reason, issue }, feature, .. }) => {
731+
Some(&Stability {
732+
level: attr::Unstable { reason, issue, is_soft }, feature, ..
733+
}) => {
724734
if span.allows_unstable(feature) {
725735
debug!("stability: skipping span={:?} since it is internal", span);
726736
return EvalResult::Allow;
@@ -744,7 +754,7 @@ impl<'tcx> TyCtxt<'tcx> {
744754
}
745755
}
746756

747-
EvalResult::Deny { feature, reason, issue }
757+
EvalResult::Deny { feature, reason, issue, is_soft }
748758
}
749759
Some(_) => {
750760
// Stable APIs are always ok to call and deprecated APIs are
@@ -767,8 +777,8 @@ impl<'tcx> TyCtxt<'tcx> {
767777
pub fn check_stability(self, def_id: DefId, id: Option<HirId>, span: Span) {
768778
match self.eval_stability(def_id, id, span) {
769779
EvalResult::Allow => {}
770-
EvalResult::Deny { feature, reason, issue } =>
771-
report_unstable(self.sess, feature, reason, issue, span),
780+
EvalResult::Deny { feature, reason, issue, is_soft } =>
781+
report_unstable(self.sess, feature, reason, issue, is_soft, span),
772782
EvalResult::Unmarked => {
773783
// The API could be uncallable for other reasons, for example when a private module
774784
// was referenced.

src/librustc_lint/lib.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,12 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
435435
id: LintId::of(INDIRECT_STRUCTURAL_MATCH),
436436
reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
437437
edition: None,
438-
}
438+
},
439+
FutureIncompatibleInfo {
440+
id: LintId::of(SOFT_UNSTABLE),
441+
reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
442+
edition: None,
443+
},
439444
]);
440445

441446
// Register renamed and removed lints.

src/librustc_resolve/macros.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -774,10 +774,10 @@ impl<'a> Resolver<'a> {
774774
fn check_stability_and_deprecation(&self, ext: &SyntaxExtension, path: &ast::Path) {
775775
let span = path.span;
776776
if let Some(stability) = &ext.stability {
777-
if let StabilityLevel::Unstable { reason, issue } = stability.level {
777+
if let StabilityLevel::Unstable { reason, issue, is_soft } = stability.level {
778778
let feature = stability.feature;
779779
if !self.active_features.contains(&feature) && !span.allows_unstable(feature) {
780-
stability::report_unstable(self.session, feature, reason, issue, span);
780+
stability::report_unstable(self.session, feature, reason, issue, is_soft, span);
781781
}
782782
}
783783
if let Some(depr) = &stability.rustc_depr {

src/libsyntax/attr/builtin.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,10 @@ pub struct Stability {
154154
#[derive(RustcEncodable, RustcDecodable, PartialEq, PartialOrd, Copy, Clone, Debug, Eq, Hash)]
155155
pub enum StabilityLevel {
156156
// Reason for the current stability level and the relevant rust-lang issue
157-
Unstable { reason: Option<Symbol>, issue: u32 },
157+
Unstable { reason: Option<Symbol>, issue: u32, is_soft: bool },
158158
Stable { since: Symbol },
159159
}
160160

161-
impl Stability {
162-
pub fn unstable(feature: Symbol, reason: Option<Symbol>, issue: u32) -> Stability {
163-
Stability {
164-
level: StabilityLevel::Unstable { reason, issue },
165-
feature,
166-
rustc_depr: None,
167-
const_stability: None,
168-
promotable: false,
169-
allow_const_fn_ptr: false,
170-
}
171-
}
172-
}
173-
174161
impl StabilityLevel {
175162
pub fn is_unstable(&self) -> bool {
176163
if let StabilityLevel::Unstable {..} = *self {
@@ -356,19 +343,27 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
356343
let mut feature = None;
357344
let mut reason = None;
358345
let mut issue = None;
346+
let mut is_soft = false;
359347
for meta in metas {
360348
if let Some(mi) = meta.meta_item() {
361349
match mi.name_or_empty() {
362350
sym::feature => if !get(mi, &mut feature) { continue 'outer },
363351
sym::reason => if !get(mi, &mut reason) { continue 'outer },
364352
sym::issue => if !get(mi, &mut issue) { continue 'outer },
353+
sym::soft => {
354+
if !mi.is_word() {
355+
let msg = "`soft` should not have any arguments";
356+
sess.span_diagnostic.span_err(mi.span, msg);
357+
}
358+
is_soft = true;
359+
}
365360
_ => {
366361
handle_errors(
367362
sess,
368363
meta.span(),
369364
AttrError::UnknownMetaItem(
370365
mi.path.to_string(),
371-
&["feature", "reason", "issue"]
366+
&["feature", "reason", "issue", "soft"]
372367
),
373368
);
374369
continue 'outer
@@ -400,7 +395,8 @@ fn find_stability_generic<'a, I>(sess: &ParseSess,
400395
"incorrect 'issue'");
401396
continue
402397
}
403-
}
398+
},
399+
is_soft,
404400
},
405401
feature,
406402
rustc_depr: None,

src/libsyntax_pos/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ symbols! {
626626
size,
627627
slice_patterns,
628628
slicing_syntax,
629+
soft,
629630
Some,
630631
specialization,
631632
speed,

src/test/ui/feature-gates/bench.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[bench] //~ ERROR use of unstable library feature 'test'
2+
//~| WARN this was previously accepted
3+
fn bench() {}
4+
5+
fn main() {}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
2+
--> $DIR/bench.rs:1:3
3+
|
4+
LL | #[bench]
5+
| ^^^^^
6+
|
7+
= note: `#[deny(soft_unstable)]` on by default
8+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9+
= note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266>
10+
11+
error: aborting due to previous error
12+

0 commit comments

Comments
 (0)