1use std::num::NonZero;
5
6use rustc_ast::NodeId;
7use rustc_errors::{Applicability, Diag, Diagnostic, EmissionGuarantee, LintBuffer, msg};
8use rustc_feature::GateIssue;
9use rustc_hir::attrs::{DeprecatedSince, Deprecation};
10use rustc_hir::def_id::{DefId, LocalDefId};
11use rustc_hir::{self as hir, ConstStability, DefaultBodyStability, HirId, Stability};
12use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic};
13use rustc_session::Session;
14use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE};
15use rustc_session::lint::{DeprecatedSinceKind, Level, Lint};
16use rustc_session::parse::feature_err_issue;
17use rustc_span::{Span, Symbol, sym};
18use tracing::debug;
19
20pub use self::StabilityLevel::*;
21use crate::ty::TyCtxt;
22use crate::ty::print::with_no_trimmed_paths;
23
24#[derive(#[automatically_derived]
impl ::core::cmp::PartialEq for StabilityLevel {
#[inline]
fn eq(&self, other: &StabilityLevel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::clone::Clone for StabilityLevel {
#[inline]
fn clone(&self) -> StabilityLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for StabilityLevel { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for StabilityLevel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
StabilityLevel::Unstable => "Unstable",
StabilityLevel::Stable => "Stable",
})
}
}Debug)]
25pub enum StabilityLevel {
26 Unstable,
27 Stable,
28}
29
30#[derive(#[automatically_derived]
impl ::core::marker::Copy for UnstableKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for UnstableKind {
#[inline]
fn clone(&self) -> UnstableKind {
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
31pub enum UnstableKind {
32 Regular,
34 Const(Span),
36}
37
38#[derive(#[automatically_derived]
impl ::core::marker::Copy for DeprecationEntry { }Copy, #[automatically_derived]
impl ::core::clone::Clone for DeprecationEntry {
#[inline]
fn clone(&self) -> DeprecationEntry {
let _: ::core::clone::AssertParamIsClone<Deprecation>;
let _: ::core::clone::AssertParamIsClone<Option<LocalDefId>>;
*self
}
}Clone, const _: () =
{
impl<'__ctx>
::rustc_data_structures::stable_hasher::HashStable<::rustc_middle::ich::StableHashingContext<'__ctx>>
for DeprecationEntry {
#[inline]
fn hash_stable(&self,
__hcx: &mut ::rustc_middle::ich::StableHashingContext<'__ctx>,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
DeprecationEntry {
attr: ref __binding_0, origin: ref __binding_1 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable, #[automatically_derived]
impl ::core::fmt::Debug for DeprecationEntry {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"DeprecationEntry", "attr", &self.attr, "origin", &&self.origin)
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for DeprecationEntry {
fn encode(&self, __encoder: &mut __E) {
match *self {
DeprecationEntry {
attr: ref __binding_0, origin: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for DeprecationEntry {
fn decode(__decoder: &mut __D) -> Self {
DeprecationEntry {
attr: ::rustc_serialize::Decodable::decode(__decoder),
origin: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
40pub struct DeprecationEntry {
41 pub attr: Deprecation,
43 origin: Option<LocalDefId>,
46}
47
48impl DeprecationEntry {
49 pub fn local(attr: Deprecation, def_id: LocalDefId) -> DeprecationEntry {
50 DeprecationEntry { attr, origin: Some(def_id) }
51 }
52
53 pub fn external(attr: Deprecation) -> DeprecationEntry {
54 DeprecationEntry { attr, origin: None }
55 }
56
57 pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
58 match (self.origin, other.origin) {
59 (Some(o1), Some(o2)) => o1 == o2,
60 _ => false,
61 }
62 }
63}
64
65pub fn report_unstable(
66 sess: &Session,
67 feature: Symbol,
68 reason: Option<Symbol>,
69 issue: Option<NonZero<u32>>,
70 suggestion: Option<(Span, String, String, Applicability)>,
71 span: Span,
72 kind: UnstableKind,
73) {
74 let qual = match kind {
75 UnstableKind::Regular => "",
76 UnstableKind::Const(_) => " const",
77 };
78
79 let msg = match reason {
80 Some(r) => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("use of unstable{0} library feature `{1}`: {2}",
qual, feature, r))
})format!("use of unstable{qual} library feature `{feature}`: {r}"),
81 None => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("use of unstable{0} library feature `{1}`",
qual, feature))
})format!("use of unstable{qual} library feature `{feature}`"),
82 };
83
84 let mut err = feature_err_issue(sess, feature, span, GateIssue::Library(issue), msg);
85 if let Some((inner_types, msg, sugg, applicability)) = suggestion {
86 err.span_suggestion(inner_types, msg, sugg, applicability);
87 }
88 if let UnstableKind::Const(kw) = kind {
89 err.span_label(kw, "trait is not stable as const yet");
90 }
91 err.emit();
92}
93
94fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
95 if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
96}
97
98#[derive(const _: () =
{
impl rustc_errors::Subdiagnostic for DeprecationSuggestion {
fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
where __G: rustc_errors::EmissionGuarantee {
match self {
DeprecationSuggestion {
span: __binding_0,
kind: __binding_1,
suggestion: __binding_2 } => {
let __code_0 =
[::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}", __binding_2))
})].into_iter();
let mut sub_args = rustc_errors::DiagArgMap::default();
sub_args.insert("kind".into(),
rustc_errors::IntoDiagArg::into_diag_arg(__binding_1,
&mut diag.long_ty_path));
sub_args.insert("suggestion".into(),
rustc_errors::IntoDiagArg::into_diag_arg(__binding_2,
&mut diag.long_ty_path));
let __message =
rustc_errors::format_diag_message(&rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("replace the use of the deprecated {$kind}")),
&sub_args);
diag.span_suggestions_with_style(__binding_0, __message,
__code_0, rustc_errors::Applicability::MachineApplicable,
rustc_errors::SuggestionStyle::ShowAlways);
}
}
}
}
};Subdiagnostic)]
99#[suggestion(
100 "replace the use of the deprecated {$kind}",
101 code = "{suggestion}",
102 style = "verbose",
103 applicability = "machine-applicable"
104)]
105pub struct DeprecationSuggestion {
106 #[primary_span]
107 pub span: Span,
108
109 pub kind: String,
110 pub suggestion: Symbol,
111}
112
113pub struct Deprecated {
114 pub sub: Option<DeprecationSuggestion>,
115
116 pub kind: String,
117 pub path: String,
118 pub note: Option<Symbol>,
119 pub since_kind: DeprecatedSinceKind,
120}
121
122impl<'a, G: EmissionGuarantee> rustc_errors::Diagnostic<'a, G> for Deprecated {
123 fn into_diag(
124 self,
125 dcx: rustc_errors::DiagCtxtHandle<'a>,
126 level: rustc_errors::Level,
127 ) -> Diag<'a, G> {
128 let Self { sub, kind, path, note, since_kind } = self;
129 let mut diag = Diag::new(dcx, level, match &since_kind {
130 DeprecatedSinceKind::InEffect => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use of deprecated {$kind} `{$path}`{$has_note ->\n [true] : {$note}\n *[other] {\"\"}\n }"))msg!(
131 "use of deprecated {$kind} `{$path}`{$has_note ->
132 [true] : {$note}
133 *[other] {\"\"}
134 }"
135 ),
136 DeprecatedSinceKind::InFuture => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->\n [true] : {$note}\n *[other] {\"\"}\n }"))msg!(
137 "use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
138 [true] : {$note}
139 *[other] {\"\"}
140 }"
141 ),
142 DeprecatedSinceKind::InVersion(_) => {
143 rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->\n [true] : {$note}\n *[other] {\"\"}\n }"))msg!(
144 "use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
145 [true] : {$note}
146 *[other] {\"\"}
147 }"
148 )
149 }
150 })
151 .with_arg("kind", kind)
152 .with_arg("path", path);
153 if let DeprecatedSinceKind::InVersion(version) = since_kind {
154 diag.arg("version", version);
155 }
156 if let Some(note) = note {
157 diag.arg("has_note", true);
158 diag.arg("note", note);
159 } else {
160 diag.arg("has_note", false);
161 }
162 if let Some(sub) = sub {
163 diag.subdiagnostic(sub);
164 }
165 diag
166 }
167}
168
169fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
170 if is_in_effect {
171 DeprecatedSinceKind::InEffect
172 } else {
173 match since {
174 DeprecatedSince::RustcVersion(version) => {
175 DeprecatedSinceKind::InVersion(version.to_string())
176 }
177 DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
178 DeprecatedSince::NonStandard(_)
179 | DeprecatedSince::Unspecified
180 | DeprecatedSince::Err => {
181 {
::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
format_args!("this deprecation is always in effect; {0:?}",
since)));
}unreachable!("this deprecation is always in effect; {since:?}")
182 }
183 }
184 }
185}
186
187pub fn early_report_macro_deprecation(
188 lint_buffer: &mut LintBuffer,
189 depr: &Deprecation,
190 suggestion_span: Span,
191 node_id: NodeId,
192 path: String,
193) {
194 if suggestion_span.in_derive_expansion() {
195 return;
196 }
197
198 let is_in_effect = depr.is_in_effect();
199 let suggestion = depr.suggestion;
200 let note = depr.note.map(|ident| ident.name);
201 let since_kind = deprecated_since_kind(is_in_effect, depr.since);
202 lint_buffer.dyn_buffer_lint(
203 deprecation_lint(is_in_effect),
204 node_id,
205 suggestion_span,
206 move |dcx, level| {
207 let sub = suggestion.map(|suggestion| DeprecationSuggestion {
208 span: suggestion_span,
209 kind: "macro".to_owned(),
210 suggestion,
211 });
212
213 Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }
214 .into_diag(dcx, level)
215 },
216 );
217}
218
219fn late_report_deprecation(
220 tcx: TyCtxt<'_>,
221 depr: &Deprecation,
222 span: Span,
223 method_span: Option<Span>,
224 hir_id: HirId,
225 def_id: DefId,
226) {
227 if span.in_derive_expansion() {
228 return;
229 }
230
231 let is_in_effect = depr.is_in_effect();
232 let lint = deprecation_lint(is_in_effect);
233
234 if tcx.lint_level_at_node(lint, hir_id).level == Level::Allow {
238 return;
239 }
240
241 let def_path = { let _guard = NoTrimmedGuard::new(); tcx.def_path_str(def_id) }with_no_trimmed_paths!(tcx.def_path_str(def_id));
242 let def_kind = tcx.def_descr(def_id);
243
244 let method_span = method_span.unwrap_or(span);
245 let suggestion =
246 if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None };
247 let diag = Deprecated {
248 sub: suggestion.map(|suggestion| DeprecationSuggestion {
249 span: method_span,
250 kind: def_kind.to_owned(),
251 suggestion,
252 }),
253 kind: def_kind.to_owned(),
254 path: def_path,
255 note: depr.note.map(|ident| ident.name),
256 since_kind: deprecated_since_kind(is_in_effect, depr.since),
257 };
258 tcx.emit_node_span_lint(lint, hir_id, method_span, diag);
259}
260
261pub enum EvalResult {
263 Allow,
266 Deny {
269 feature: Symbol,
270 reason: Option<Symbol>,
271 issue: Option<NonZero<u32>>,
272 suggestion: Option<(Span, String, String, Applicability)>,
273 },
274 Unmarked,
276}
277
278fn suggestion_for_allocator_api(
280 tcx: TyCtxt<'_>,
281 def_id: DefId,
282 span: Span,
283 feature: Symbol,
284) -> Option<(Span, String, String, Applicability)> {
285 if feature == sym::allocator_api {
286 if let Some(trait_) = tcx.opt_parent(def_id) {
287 if tcx.is_diagnostic_item(sym::Vec, trait_) {
288 let sm = tcx.sess.psess.source_map();
289 let inner_types = sm.span_extend_to_prev_char(span, '<', true);
290 if let Ok(snippet) = sm.span_to_snippet(inner_types) {
291 return Some((
292 inner_types,
293 "consider wrapping the inner types in tuple".to_string(),
294 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("({0})", snippet))
})format!("({snippet})"),
295 Applicability::MaybeIncorrect,
296 ));
297 }
298 }
299 }
300 }
301 None
302}
303
304pub enum AllowUnstable {
306 Yes,
308 No,
310}
311
312impl<'tcx> TyCtxt<'tcx> {
313 pub fn eval_stability(
323 self,
324 def_id: DefId,
325 id: Option<HirId>,
326 span: Span,
327 method_span: Option<Span>,
328 ) -> EvalResult {
329 self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
330 }
331
332 pub fn eval_stability_allow_unstable(
344 self,
345 def_id: DefId,
346 id: Option<HirId>,
347 span: Span,
348 method_span: Option<Span>,
349 allow_unstable: AllowUnstable,
350 ) -> EvalResult {
351 if let Some(id) = id {
353 if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
354 let parent_def_id = self.hir_get_parent_item(id);
355 let skip = self
356 .lookup_deprecation_entry(parent_def_id.to_def_id())
357 .is_some_and(|parent_depr| parent_depr.same_origin(&depr_entry));
358
359 let depr_attr = &depr_entry.attr;
366 if !skip || depr_attr.is_since_rustc_version() {
367 late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
368 }
369 };
370 }
371
372 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
373 if !is_staged_api {
374 return EvalResult::Allow;
375 }
376
377 let cross_crate = !def_id.is_local();
379 if !cross_crate {
380 return EvalResult::Allow;
381 }
382
383 let stability = self.lookup_stability(def_id);
384 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:384",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(384u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn Value))])
});
} else { ; }
};debug!(
385 "stability: \
386 inspecting def_id={:?} span={:?} of stability={:?}",
387 def_id, span, stability
388 );
389
390 match stability {
391 Some(Stability {
392 level: hir::StabilityLevel::Unstable { reason, issue, implied_by, .. },
393 feature,
394 ..
395 }) => {
396 if span.allows_unstable(feature) {
397 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:397",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(397u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("stability: skipping span={0:?} since it is internal",
span) as &dyn Value))])
});
} else { ; }
};debug!("stability: skipping span={:?} since it is internal", span);
398 return EvalResult::Allow;
399 }
400 if self.features().enabled(feature) {
401 return EvalResult::Allow;
402 }
403
404 if let Some(implied_by) = implied_by
408 && self.features().enabled(implied_by)
409 {
410 return EvalResult::Allow;
411 }
412
413 if feature == sym::rustc_private
423 && issue == NonZero::new(27812)
424 && self.sess.opts.unstable_opts.force_unstable_if_unmarked
425 {
426 return EvalResult::Allow;
427 }
428
429 if #[allow(non_exhaustive_omitted_patterns)] match allow_unstable {
AllowUnstable::Yes => true,
_ => false,
}matches!(allow_unstable, AllowUnstable::Yes) {
430 return EvalResult::Allow;
431 }
432
433 let suggestion = suggestion_for_allocator_api(self, def_id, span, feature);
434 EvalResult::Deny { feature, reason: reason.to_opt_reason(), issue, suggestion }
435 }
436 Some(_) => {
437 EvalResult::Allow
440 }
441 None => EvalResult::Unmarked,
442 }
443 }
444
445 pub fn eval_default_body_stability(self, def_id: DefId, span: Span) -> EvalResult {
451 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
452 if !is_staged_api {
453 return EvalResult::Allow;
454 }
455
456 let cross_crate = !def_id.is_local();
458 if !cross_crate {
459 return EvalResult::Allow;
460 }
461
462 let stability = self.lookup_default_body_stability(def_id);
463 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:463",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(463u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("body stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn Value))])
});
} else { ; }
};debug!(
464 "body stability: inspecting def_id={def_id:?} span={span:?} of stability={stability:?}"
465 );
466
467 match stability {
468 Some(DefaultBodyStability {
469 level: hir::StabilityLevel::Unstable { reason, issue, .. },
470 feature,
471 }) => {
472 if span.allows_unstable(feature) {
473 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:473",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(473u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("body stability: skipping span={0:?} since it is internal",
span) as &dyn Value))])
});
} else { ; }
};debug!("body stability: skipping span={:?} since it is internal", span);
474 return EvalResult::Allow;
475 }
476 if self.features().enabled(feature) {
477 return EvalResult::Allow;
478 }
479
480 EvalResult::Deny {
481 feature,
482 reason: reason.to_opt_reason(),
483 issue,
484 suggestion: None,
485 }
486 }
487 Some(_) => {
488 EvalResult::Allow
490 }
491 None => EvalResult::Unmarked,
492 }
493 }
494
495 pub fn check_stability(
505 self,
506 def_id: DefId,
507 id: Option<HirId>,
508 span: Span,
509 method_span: Option<Span>,
510 ) -> bool {
511 self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
512 }
513
514 pub fn check_stability_allow_unstable(
526 self,
527 def_id: DefId,
528 id: Option<HirId>,
529 span: Span,
530 method_span: Option<Span>,
531 allow_unstable: AllowUnstable,
532 ) -> bool {
533 self.check_optional_stability(
534 def_id,
535 id,
536 span,
537 method_span,
538 allow_unstable,
539 |span, def_id| {
540 self.dcx().span_delayed_bug(span, ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("encountered unmarked API: {0:?}",
def_id))
})format!("encountered unmarked API: {def_id:?}"));
543 },
544 )
545 }
546
547 pub fn check_optional_stability(
554 self,
555 def_id: DefId,
556 id: Option<HirId>,
557 span: Span,
558 method_span: Option<Span>,
559 allow_unstable: AllowUnstable,
560 unmarked: impl FnOnce(Span, DefId),
561 ) -> bool {
562 let eval_result =
563 self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
564 let is_allowed = #[allow(non_exhaustive_omitted_patterns)] match eval_result {
EvalResult::Allow => true,
_ => false,
}matches!(eval_result, EvalResult::Allow);
565 match eval_result {
566 EvalResult::Allow => {}
567 EvalResult::Deny { feature, reason, issue, suggestion } => report_unstable(
568 self.sess,
569 feature,
570 reason,
571 issue,
572 suggestion,
573 span,
574 UnstableKind::Regular,
575 ),
576 EvalResult::Unmarked => unmarked(span, def_id),
577 }
578
579 is_allowed
580 }
581
582 pub fn check_const_stability(self, def_id: DefId, span: Span, const_kw_span: Span) {
590 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
591 if !is_staged_api {
592 return;
593 }
594
595 let cross_crate = !def_id.is_local();
597 if !cross_crate {
598 return;
599 }
600
601 let stability = self.lookup_const_stability(def_id);
602 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:602",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(602u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn Value))])
});
} else { ; }
};debug!(
603 "stability: \
604 inspecting def_id={:?} span={:?} of stability={:?}",
605 def_id, span, stability
606 );
607
608 match stability {
609 Some(ConstStability {
610 level: hir::StabilityLevel::Unstable { reason, issue, implied_by, .. },
611 feature,
612 ..
613 }) => {
614 if span.allows_unstable(feature) {
615 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_middle/src/middle/stability.rs:615",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(615u32),
::tracing_core::__macro_support::Option::Some("rustc_middle::middle::stability"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("body stability: skipping span={0:?} since it is internal",
span) as &dyn Value))])
});
} else { ; }
};debug!("body stability: skipping span={:?} since it is internal", span);
616 return;
617 }
618 if self.features().enabled(feature) {
619 return;
620 }
621
622 if let Some(implied_by) = implied_by
626 && self.features().enabled(implied_by)
627 {
628 return;
629 }
630
631 report_unstable(
632 self.sess,
633 feature,
634 reason.to_opt_reason(),
635 issue,
636 None,
637 span,
638 UnstableKind::Const(const_kw_span),
639 );
640 }
641 Some(_) | None => {}
642 }
643 }
644
645 pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
646 self.lookup_deprecation_entry(id).map(|depr| depr.attr)
647 }
648}