Skip to content

Commit 5f1330d

Browse files
committed
Move rustc_middle::middle::stability to rustc_crate.
1 parent a86535c commit 5f1330d

File tree

10 files changed

+232
-214
lines changed

10 files changed

+232
-214
lines changed

compiler/rustc_crate/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ pub mod cstore;
1515
pub mod dependency_format;
1616
pub mod limits;
1717
pub mod privacy;
18+
pub mod stability;
1819

1920
#[derive(HashStable_Generic)]
2021
pub struct LibFeatures {

compiler/rustc_crate/src/stability.rs

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
//! A pass that annotates every item and method with its stability level,
2+
//! propagating default levels lexically from parent to children ast nodes.
3+
4+
pub use self::StabilityLevel::*;
5+
6+
use rustc_ast::CRATE_NODE_ID;
7+
use rustc_attr::{self as attr, ConstStability, Deprecation, Stability};
8+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
9+
use rustc_errors::{Applicability, DiagnosticBuilder};
10+
use rustc_feature::GateIssue;
11+
use rustc_hir::def_id::CrateNum;
12+
use rustc_hir::{self, HirId};
13+
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
14+
use rustc_session::lint::{BuiltinLintDiagnostics, Lint, LintBuffer};
15+
use rustc_session::parse::feature_err_issue;
16+
use rustc_session::{DiagnosticMessageId, Session};
17+
use rustc_span::symbol::Symbol;
18+
use rustc_span::{MultiSpan, Span};
19+
20+
use std::num::NonZeroU32;
21+
22+
#[derive(PartialEq, Clone, Copy, Debug)]
23+
pub enum StabilityLevel {
24+
Unstable,
25+
Stable,
26+
}
27+
28+
impl StabilityLevel {
29+
pub fn from_attr_level(level: &attr::StabilityLevel) -> Self {
30+
if level.is_stable() { Stable } else { Unstable }
31+
}
32+
}
33+
34+
/// An entry in the `depr_map`.
35+
#[derive(Clone, HashStable_Generic)]
36+
pub struct DeprecationEntry {
37+
/// The metadata of the attribute associated with this entry.
38+
pub attr: Deprecation,
39+
/// The `DefId` where the attr was originally attached. `None` for non-local
40+
/// `DefId`'s.
41+
origin: Option<HirId>,
42+
}
43+
44+
impl DeprecationEntry {
45+
pub fn local(attr: Deprecation, id: HirId) -> DeprecationEntry {
46+
DeprecationEntry { attr, origin: Some(id) }
47+
}
48+
49+
pub fn external(attr: Deprecation) -> DeprecationEntry {
50+
DeprecationEntry { attr, origin: None }
51+
}
52+
53+
pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
54+
match (self.origin, other.origin) {
55+
(Some(o1), Some(o2)) => o1 == o2,
56+
_ => false,
57+
}
58+
}
59+
}
60+
61+
/// A stability index, giving the stability level for items and methods.
62+
#[derive(HashStable_Generic)]
63+
pub struct Index<'tcx> {
64+
/// This is mostly a cache, except the stabilities of local items
65+
/// are filled by the annotator.
66+
pub stab_map: FxHashMap<HirId, &'tcx Stability>,
67+
pub const_stab_map: FxHashMap<HirId, &'tcx ConstStability>,
68+
pub depr_map: FxHashMap<HirId, DeprecationEntry>,
69+
70+
/// Maps for each crate whether it is part of the staged API.
71+
pub staged_api: FxHashMap<CrateNum, bool>,
72+
73+
/// Features enabled for this crate.
74+
pub active_features: FxHashSet<Symbol>,
75+
}
76+
77+
impl<'tcx> Index<'tcx> {
78+
pub fn local_stability(&self, id: HirId) -> Option<&'tcx Stability> {
79+
self.stab_map.get(&id).cloned()
80+
}
81+
82+
pub fn local_const_stability(&self, id: HirId) -> Option<&'tcx ConstStability> {
83+
self.const_stab_map.get(&id).cloned()
84+
}
85+
86+
pub fn local_deprecation_entry(&self, id: HirId) -> Option<DeprecationEntry> {
87+
self.depr_map.get(&id).cloned()
88+
}
89+
}
90+
91+
pub fn report_unstable(
92+
sess: &Session,
93+
feature: Symbol,
94+
reason: Option<Symbol>,
95+
issue: Option<NonZeroU32>,
96+
is_soft: bool,
97+
span: Span,
98+
soft_handler: impl FnOnce(&'static Lint, Span, &str),
99+
) {
100+
let msg = match reason {
101+
Some(r) => format!("use of unstable library feature '{}': {}", feature, r),
102+
None => format!("use of unstable library feature '{}'", &feature),
103+
};
104+
105+
let msp: MultiSpan = span.into();
106+
let sm = &sess.parse_sess.source_map();
107+
let span_key = msp.primary_span().and_then(|sp: Span| {
108+
if !sp.is_dummy() {
109+
let file = sm.lookup_char_pos(sp.lo()).file;
110+
if file.is_imported() { None } else { Some(span) }
111+
} else {
112+
None
113+
}
114+
});
115+
116+
let error_id = (DiagnosticMessageId::StabilityId(issue), span_key, msg.clone());
117+
let fresh = sess.one_time_diagnostics.borrow_mut().insert(error_id);
118+
if fresh {
119+
if is_soft {
120+
soft_handler(SOFT_UNSTABLE, span, &msg)
121+
} else {
122+
feature_err_issue(&sess.parse_sess, feature, span, GateIssue::Library(issue), &msg)
123+
.emit();
124+
}
125+
}
126+
}
127+
128+
/// Checks whether an item marked with `deprecated(since="X")` is currently
129+
/// deprecated (i.e., whether X is not greater than the current rustc version).
130+
pub fn deprecation_in_effect(is_since_rustc_version: bool, since: Option<&str>) -> bool {
131+
let since = if let Some(since) = since {
132+
if is_since_rustc_version {
133+
since
134+
} else {
135+
// We assume that the deprecation is in effect if it's not a
136+
// rustc version.
137+
return true;
138+
}
139+
} else {
140+
// If since attribute is not set, then we're definitely in effect.
141+
return true;
142+
};
143+
fn parse_version(ver: &str) -> Vec<u32> {
144+
// We ignore non-integer components of the version (e.g., "nightly").
145+
ver.split(|c| c == '.' || c == '-').flat_map(|s| s.parse()).collect()
146+
}
147+
148+
if let Some(rustc) = option_env!("CFG_RELEASE") {
149+
let since: Vec<u32> = parse_version(&since);
150+
let rustc: Vec<u32> = parse_version(rustc);
151+
// We simply treat invalid `since` attributes as relating to a previous
152+
// Rust version, thus always displaying the warning.
153+
if since.len() != 3 {
154+
return true;
155+
}
156+
since <= rustc
157+
} else {
158+
// By default, a deprecation warning applies to
159+
// the current version of the compiler.
160+
true
161+
}
162+
}
163+
164+
pub fn deprecation_suggestion(
165+
diag: &mut DiagnosticBuilder<'_>,
166+
kind: &str,
167+
suggestion: Option<Symbol>,
168+
span: Span,
169+
) {
170+
if let Some(suggestion) = suggestion {
171+
diag.span_suggestion(
172+
span,
173+
&format!("replace the use of the deprecated {}", kind),
174+
suggestion.to_string(),
175+
Applicability::MachineApplicable,
176+
);
177+
}
178+
}
179+
180+
pub fn deprecation_message(depr: &Deprecation, kind: &str, path: &str) -> (String, &'static Lint) {
181+
let (message, lint) = if deprecation_in_effect(
182+
depr.is_since_rustc_version,
183+
depr.since.map(Symbol::as_str).as_deref(),
184+
) {
185+
(format!("use of deprecated {} `{}`", kind, path), DEPRECATED)
186+
} else {
187+
(
188+
format!(
189+
"use of {} `{}` that will be deprecated in future version {}",
190+
kind,
191+
path,
192+
depr.since.unwrap()
193+
),
194+
DEPRECATED_IN_FUTURE,
195+
)
196+
};
197+
let message = match depr.note {
198+
Some(reason) => format!("{}: {}", message, reason),
199+
None => message,
200+
};
201+
(message, lint)
202+
}
203+
204+
pub fn early_report_deprecation<'a>(
205+
lint_buffer: &'a mut LintBuffer,
206+
message: &str,
207+
suggestion: Option<Symbol>,
208+
lint: &'static Lint,
209+
span: Span,
210+
) {
211+
if span.in_derive_expansion() {
212+
return;
213+
}
214+
215+
let diag = BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span);
216+
lint_buffer.buffer_lint_with_diagnostic(lint, CRATE_NODE_ID, span, message, diag);
217+
}

compiler/rustc_lint/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject};
2121
use rustc_ast as ast;
2222
use rustc_ast::util::lev_distance::find_best_match_for_name;
2323
use rustc_crate::privacy::AccessLevels;
24+
use rustc_crate::stability;
2425
use rustc_data_structures::fx::FxHashMap;
2526
use rustc_data_structures::sync;
2627
use rustc_errors::{add_elided_lifetime_in_path_suggestion, struct_span_err, Applicability};
@@ -29,7 +30,6 @@ use rustc_hir::def::Res;
2930
use rustc_hir::def_id::{CrateNum, DefId};
3031
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
3132
use rustc_middle::lint::LintDiagnosticBuilder;
32-
use rustc_middle::middle::stability;
3333
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
3434
use rustc_middle::ty::print::with_no_trimmed_paths;
3535
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, Ty, TyCtxt};

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::rmeta;
77
use rustc_ast as ast;
88
use rustc_ast::expand::allocator::AllocatorKind;
99
use rustc_crate::cstore::{CrateSource, CrateStore, ForeignModule};
10+
use rustc_crate::stability::DeprecationEntry;
1011
use rustc_data_structures::stable_map::FxHashMap;
1112
use rustc_data_structures::svh::Svh;
1213
use rustc_hir as hir;
@@ -15,7 +16,6 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}
1516
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
1617
use rustc_middle::hir::exports::Export;
1718
use rustc_middle::middle::exported_symbols::ExportedSymbol;
18-
use rustc_middle::middle::stability::DeprecationEntry;
1919
use rustc_middle::ty::query::Providers;
2020
use rustc_middle::ty::{self, TyCtxt};
2121
use rustc_session::utils::NativeLibKind;

0 commit comments

Comments
 (0)