Skip to content

Commit d0b1b4b

Browse files
committed
Fix test failures by requiring a use also be public
Deprecation warnings that were handled via eval_stability should now be emitted even for items which are skipping the unstable message
1 parent 69627f5 commit d0b1b4b

File tree

5 files changed

+100
-17
lines changed

5 files changed

+100
-17
lines changed

compiler/rustc_middle/src/middle/stability.rs

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
99
use rustc_data_structures::fx::FxHashMap;
1010
use rustc_errors::{Applicability, Diagnostic};
1111
use rustc_feature::GateIssue;
12-
use rustc_hir as hir;
1312
use rustc_hir::def::DefKind;
1413
use rustc_hir::def_id::{DefId, LocalDefId};
14+
use rustc_hir::{self as hir};
1515
use rustc_hir::{self, HirId};
1616
use rustc_middle::ty::print::with_no_trimmed_paths;
1717
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
@@ -306,6 +306,20 @@ fn suggestion_for_allocator_api(
306306
None
307307
}
308308

309+
/// An override option for eval_stability.
310+
pub enum EvalOverride {
311+
/// Don't emit an unstable error for the item
312+
AllowUnstable,
313+
/// Handle the item normally
314+
None,
315+
}
316+
317+
impl Default for EvalOverride {
318+
fn default() -> Self {
319+
Self::None
320+
}
321+
}
322+
309323
impl<'tcx> TyCtxt<'tcx> {
310324
/// Evaluates the stability of an item.
311325
///
@@ -322,6 +336,28 @@ impl<'tcx> TyCtxt<'tcx> {
322336
id: Option<HirId>,
323337
span: Span,
324338
method_span: Option<Span>,
339+
) -> EvalResult {
340+
self.eval_stability_override(def_id, id, span, method_span, Default::default())
341+
}
342+
343+
/// Evaluates the stability of an item.
344+
///
345+
/// Returns `EvalResult::Allow` if the item is stable, or unstable but the corresponding
346+
/// `#![feature]` has been provided. Returns `EvalResult::Deny` which describes the offending
347+
/// unstable feature otherwise.
348+
///
349+
/// If `id` is `Some(_)`, this function will also check if the item at `def_id` has been
350+
/// deprecated. If the item is indeed deprecated, we will emit a deprecation lint attached to
351+
/// `id`.
352+
///
353+
/// Pass `EvalOverride::AllowUnstable` to `eval_override` to force an unstable item to be allowed. Deprecation warnings will be emitted normally.
354+
pub fn eval_stability_override(
355+
self,
356+
def_id: DefId,
357+
id: Option<HirId>,
358+
span: Span,
359+
method_span: Option<Span>,
360+
eval_override: EvalOverride,
325361
) -> EvalResult {
326362
// Deprecated attributes apply in-crate and cross-crate.
327363
if let Some(id) = id {
@@ -419,6 +455,10 @@ impl<'tcx> TyCtxt<'tcx> {
419455
}
420456
}
421457

458+
if matches!(eval_override, EvalOverride::AllowUnstable) {
459+
return EvalResult::Allow;
460+
}
461+
422462
let suggestion = suggestion_for_allocator_api(self, def_id, span, feature);
423463
EvalResult::Deny { feature, reason, issue, suggestion, is_soft }
424464
}
@@ -445,11 +485,38 @@ impl<'tcx> TyCtxt<'tcx> {
445485
span: Span,
446486
method_span: Option<Span>,
447487
) {
448-
self.check_optional_stability(def_id, id, span, method_span, |span, def_id| {
449-
// The API could be uncallable for other reasons, for example when a private module
450-
// was referenced.
451-
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
452-
})
488+
self.check_stability_override(def_id, id, span, method_span, Default::default())
489+
}
490+
491+
/// Checks if an item is stable or error out.
492+
///
493+
/// If the item defined by `def_id` is unstable and the corresponding `#![feature]` does not
494+
/// exist, emits an error.
495+
///
496+
/// This function will also check if the item is deprecated.
497+
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
498+
///
499+
/// Pass `EvalOverride::AllowUnstable` to `eval_override` to force an unstable item to be allowed. Deprecation warnings will be emitted normally.
500+
pub fn check_stability_override(
501+
self,
502+
def_id: DefId,
503+
id: Option<HirId>,
504+
span: Span,
505+
method_span: Option<Span>,
506+
eval_override: EvalOverride,
507+
) {
508+
self.check_optional_stability(
509+
def_id,
510+
id,
511+
span,
512+
method_span,
513+
eval_override,
514+
|span, def_id| {
515+
// The API could be uncallable for other reasons, for example when a private module
516+
// was referenced.
517+
self.sess.delay_span_bug(span, &format!("encountered unmarked API: {:?}", def_id));
518+
},
519+
)
453520
}
454521

455522
/// Like `check_stability`, except that we permit items to have custom behaviour for
@@ -462,14 +529,15 @@ impl<'tcx> TyCtxt<'tcx> {
462529
id: Option<HirId>,
463530
span: Span,
464531
method_span: Option<Span>,
532+
eval_override: EvalOverride,
465533
unmarked: impl FnOnce(Span, DefId),
466534
) {
467535
let soft_handler = |lint, span, msg: &_| {
468536
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
469537
lint.build(msg).emit();
470538
})
471539
};
472-
match self.eval_stability(def_id, id, span, method_span) {
540+
match self.eval_stability_override(def_id, id, span, method_span, eval_override) {
473541
EvalResult::Allow => {}
474542
EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
475543
self.sess,

compiler/rustc_passes/src/stability.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hir::intravisit::{self, Visitor};
1313
use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
1414
use rustc_middle::hir::nested_filter;
1515
use rustc_middle::middle::privacy::AccessLevels;
16-
use rustc_middle::middle::stability::{DeprecationEntry, Index};
16+
use rustc_middle::middle::stability::{DeprecationEntry, EvalOverride, Index};
1717
use rustc_middle::ty::{self, query::Providers, TyCtxt};
1818
use rustc_session::lint;
1919
use rustc_session::lint::builtin::{INEFFECTIVE_UNSTABLE_TRAIT_IMPL, USELESS_DEPRECATED};
@@ -806,11 +806,19 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
806806
}
807807

808808
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
809-
if !is_path_reexport(self.tcx, id) {
810-
if let Some(def_id) = path.res.opt_def_id() {
811-
let method_span = path.segments.last().map(|s| s.ident.span);
812-
self.tcx.check_stability(def_id, Some(id), path.span, method_span)
813-
}
809+
if let Some(def_id) = path.res.opt_def_id() {
810+
let method_span = path.segments.last().map(|s| s.ident.span);
811+
self.tcx.check_stability_override(
812+
def_id,
813+
Some(id),
814+
path.span,
815+
method_span,
816+
if is_path_reexport(self.tcx, id) {
817+
EvalOverride::AllowUnstable
818+
} else {
819+
EvalOverride::None
820+
},
821+
)
814822
}
815823
intravisit::walk_path(self, path)
816824
}
@@ -826,6 +834,10 @@ fn is_path_reexport<'tcx>(tcx: TyCtxt<'tcx>, id: hir::HirId) -> bool {
826834
return false;
827835
}
828836

837+
if tcx.visibility(def_id) != ty::Visibility::Public {
838+
return false;
839+
}
840+
829841
true
830842
}
831843

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
426426
Some(arg.id()),
427427
arg.span(),
428428
None,
429+
Default::default(),
429430
|_, _| {
430431
// Default generic parameters may not be marked
431432
// with stability attributes, i.e. when the

src/test/ui/stability-attribute/allow-unstable-reexport.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
extern crate lint_stability;
99
extern crate lint_stability_reexport;
1010

11-
use lint_stability::unstable;
11+
#[stable(feature = "lint_stability", since = "1.0.0")]
12+
pub use lint_stability::unstable;
1213
// We want to confirm that using a re-export through another crate behaves
1314
// the same way as using an item directly
14-
use lint_stability_reexport::unstable_text;
15+
#[stable(feature = "lint_stability", since = "1.0.0")]
16+
pub use lint_stability_reexport::unstable_text;
1517

1618
fn main() {
1719
// Since we didn't enable the feature in this crate, we still can't

src/test/ui/stability-attribute/allow-unstable-reexport.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
error[E0658]: use of unstable library feature 'unstable_test_feature'
2-
--> $DIR/allow-unstable-reexport.rs:17:5
2+
--> $DIR/allow-unstable-reexport.rs:21:5
33
|
44
LL | unstable();
55
| ^^^^^^^^
66
|
77
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
88

99
error[E0658]: use of unstable library feature 'unstable_test_feature': text
10-
--> $DIR/allow-unstable-reexport.rs:18:5
10+
--> $DIR/allow-unstable-reexport.rs:22:5
1111
|
1212
LL | unstable_text();
1313
| ^^^^^^^^^^^^^

0 commit comments

Comments
 (0)