1use std::num::NonZero;
5
6use rustc_ast::NodeId;
7use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer, LintDiagnostic, 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, SOFT_UNSTABLE};
15use rustc_session::lint::{BuiltinLintDiag, 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 is_soft: bool,
72 span: Span,
73 soft_handler: impl FnOnce(&'static Lint, Span, String),
74 kind: UnstableKind,
75) {
76 let qual = match kind {
77 UnstableKind::Regular => "",
78 UnstableKind::Const(_) => " const",
79 };
80
81 let msg = match reason {
82 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}"),
83 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}`"),
84 };
85
86 if is_soft {
87 soft_handler(SOFT_UNSTABLE, span, msg)
88 } else {
89 let mut err = feature_err_issue(sess, feature, span, GateIssue::Library(issue), msg);
90 if let Some((inner_types, msg, sugg, applicability)) = suggestion {
91 err.span_suggestion(inner_types, msg, sugg, applicability);
92 }
93 if let UnstableKind::Const(kw) = kind {
94 err.span_label(kw, "trait is not stable as const yet");
95 }
96 err.emit();
97 }
98}
99
100fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
101 if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
102}
103
104#[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();
diag.store_args();
diag.arg("kind", __binding_1);
diag.arg("suggestion", __binding_2);
let __message =
diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("replace the use of the deprecated {$kind}")));
diag.span_suggestions_with_style(__binding_0, __message,
__code_0, rustc_errors::Applicability::MachineApplicable,
rustc_errors::SuggestionStyle::ShowAlways);
diag.restore_args();
}
}
}
}
};Subdiagnostic)]
105#[suggestion(
106 "replace the use of the deprecated {$kind}",
107 code = "{suggestion}",
108 style = "verbose",
109 applicability = "machine-applicable"
110)]
111pub struct DeprecationSuggestion {
112 #[primary_span]
113 pub span: Span,
114
115 pub kind: String,
116 pub suggestion: Symbol,
117}
118
119pub struct Deprecated {
120 pub sub: Option<DeprecationSuggestion>,
121
122 pub kind: String,
123 pub path: String,
124 pub note: Option<Symbol>,
125 pub since_kind: DeprecatedSinceKind,
126}
127
128impl<'a, G: EmissionGuarantee> rustc_errors::Diagnostic<'a, G> for Deprecated {
129 fn into_diag(
130 self,
131 dcx: rustc_errors::DiagCtxtHandle<'a>,
132 level: rustc_errors::Level,
133 ) -> Diag<'a, G> {
134 let mut diag = Diag::new(dcx, level, "");
135 self.decorate_lint(&mut diag);
136 diag
137 }
138}
139
140impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for Deprecated {
141 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
142 diag.primary_message(match &self.since_kind {
143 DeprecatedSinceKind::InEffect => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use of deprecated {$kind} `{$path}`{$has_note ->\n [true] : {$note}\n *[other] {\"\"}\n }"))msg!(
144 "use of deprecated {$kind} `{$path}`{$has_note ->
145 [true] : {$note}
146 *[other] {\"\"}
147 }"
148 ),
149 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!(
150 "use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
151 [true] : {$note}
152 *[other] {\"\"}
153 }"
154 ),
155 DeprecatedSinceKind::InVersion(_) => {
156 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!(
157 "use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
158 [true] : {$note}
159 *[other] {\"\"}
160 }"
161 )
162 }
163 });
164 diag.arg("kind", self.kind);
165 diag.arg("path", self.path);
166 if let DeprecatedSinceKind::InVersion(version) = self.since_kind {
167 diag.arg("version", version);
168 }
169 if let Some(note) = self.note {
170 diag.arg("has_note", true);
171 diag.arg("note", note);
172 } else {
173 diag.arg("has_note", false);
174 }
175 if let Some(sub) = self.sub {
176 diag.subdiagnostic(sub);
177 }
178 }
179}
180
181fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
182 if is_in_effect {
183 DeprecatedSinceKind::InEffect
184 } else {
185 match since {
186 DeprecatedSince::RustcVersion(version) => {
187 DeprecatedSinceKind::InVersion(version.to_string())
188 }
189 DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
190 DeprecatedSince::NonStandard(_)
191 | DeprecatedSince::Unspecified
192 | DeprecatedSince::Err => {
193 {
::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:?}")
194 }
195 }
196 }
197}
198
199pub fn early_report_macro_deprecation(
200 lint_buffer: &mut LintBuffer,
201 depr: &Deprecation,
202 span: Span,
203 node_id: NodeId,
204 path: String,
205) {
206 if span.in_derive_expansion() {
207 return;
208 }
209
210 let is_in_effect = depr.is_in_effect();
211 let diag = BuiltinLintDiag::DeprecatedMacro {
212 suggestion: depr.suggestion,
213 suggestion_span: span,
214 note: depr.note.map(|ident| ident.name),
215 path,
216 since_kind: deprecated_since_kind(is_in_effect, depr.since),
217 };
218 lint_buffer.buffer_lint(deprecation_lint(is_in_effect), node_id, span, diag);
219}
220
221fn late_report_deprecation(
222 tcx: TyCtxt<'_>,
223 depr: &Deprecation,
224 span: Span,
225 method_span: Option<Span>,
226 hir_id: HirId,
227 def_id: DefId,
228) {
229 if span.in_derive_expansion() {
230 return;
231 }
232
233 let is_in_effect = depr.is_in_effect();
234 let lint = deprecation_lint(is_in_effect);
235
236 if tcx.lint_level_at_node(lint, hir_id).level == Level::Allow {
240 return;
241 }
242
243 let def_path = { let _guard = NoTrimmedGuard::new(); tcx.def_path_str(def_id) }with_no_trimmed_paths!(tcx.def_path_str(def_id));
244 let def_kind = tcx.def_descr(def_id);
245
246 let method_span = method_span.unwrap_or(span);
247 let suggestion =
248 if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None };
249 let diag = Deprecated {
250 sub: suggestion.map(|suggestion| DeprecationSuggestion {
251 span: method_span,
252 kind: def_kind.to_owned(),
253 suggestion,
254 }),
255 kind: def_kind.to_owned(),
256 path: def_path,
257 note: depr.note.map(|ident| ident.name),
258 since_kind: deprecated_since_kind(is_in_effect, depr.since),
259 };
260 tcx.emit_node_span_lint(lint, hir_id, method_span, diag);
261}
262
263pub enum EvalResult {
265 Allow,
268 Deny {
271 feature: Symbol,
272 reason: Option<Symbol>,
273 issue: Option<NonZero<u32>>,
274 suggestion: Option<(Span, String, String, Applicability)>,
275 is_soft: bool,
276 },
277 Unmarked,
279}
280
281fn suggestion_for_allocator_api(
283 tcx: TyCtxt<'_>,
284 def_id: DefId,
285 span: Span,
286 feature: Symbol,
287) -> Option<(Span, String, String, Applicability)> {
288 if feature == sym::allocator_api {
289 if let Some(trait_) = tcx.opt_parent(def_id) {
290 if tcx.is_diagnostic_item(sym::Vec, trait_) {
291 let sm = tcx.sess.psess.source_map();
292 let inner_types = sm.span_extend_to_prev_char(span, '<', true);
293 if let Ok(snippet) = sm.span_to_snippet(inner_types) {
294 return Some((
295 inner_types,
296 "consider wrapping the inner types in tuple".to_string(),
297 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("({0})", snippet))
})format!("({snippet})"),
298 Applicability::MaybeIncorrect,
299 ));
300 }
301 }
302 }
303 }
304 None
305}
306
307pub enum AllowUnstable {
309 Yes,
311 No,
313}
314
315impl<'tcx> TyCtxt<'tcx> {
316 pub fn eval_stability(
326 self,
327 def_id: DefId,
328 id: Option<HirId>,
329 span: Span,
330 method_span: Option<Span>,
331 ) -> EvalResult {
332 self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
333 }
334
335 pub fn eval_stability_allow_unstable(
347 self,
348 def_id: DefId,
349 id: Option<HirId>,
350 span: Span,
351 method_span: Option<Span>,
352 allow_unstable: AllowUnstable,
353 ) -> EvalResult {
354 if let Some(id) = id {
356 if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
357 let parent_def_id = self.hir_get_parent_item(id);
358 let skip = self
359 .lookup_deprecation_entry(parent_def_id.to_def_id())
360 .is_some_and(|parent_depr| parent_depr.same_origin(&depr_entry));
361
362 let depr_attr = &depr_entry.attr;
369 if !skip || depr_attr.is_since_rustc_version() {
370 late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
371 }
372 };
373 }
374
375 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
376 if !is_staged_api {
377 return EvalResult::Allow;
378 }
379
380 let cross_crate = !def_id.is_local();
382 if !cross_crate {
383 return EvalResult::Allow;
384 }
385
386 let stability = self.lookup_stability(def_id);
387 {
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:387",
"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(387u32),
::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!(
388 "stability: \
389 inspecting def_id={:?} span={:?} of stability={:?}",
390 def_id, span, stability
391 );
392
393 match stability {
394 Some(Stability {
395 level: hir::StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. },
396 feature,
397 ..
398 }) => {
399 if span.allows_unstable(feature) {
400 {
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:400",
"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(400u32),
::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);
401 return EvalResult::Allow;
402 }
403 if self.features().enabled(feature) {
404 return EvalResult::Allow;
405 }
406
407 if let Some(implied_by) = implied_by
411 && self.features().enabled(implied_by)
412 {
413 return EvalResult::Allow;
414 }
415
416 if feature == sym::rustc_private
426 && issue == NonZero::new(27812)
427 && self.sess.opts.unstable_opts.force_unstable_if_unmarked
428 {
429 return EvalResult::Allow;
430 }
431
432 if #[allow(non_exhaustive_omitted_patterns)] match allow_unstable {
AllowUnstable::Yes => true,
_ => false,
}matches!(allow_unstable, AllowUnstable::Yes) {
433 return EvalResult::Allow;
434 }
435
436 let suggestion = suggestion_for_allocator_api(self, def_id, span, feature);
437 EvalResult::Deny {
438 feature,
439 reason: reason.to_opt_reason(),
440 issue,
441 suggestion,
442 is_soft,
443 }
444 }
445 Some(_) => {
446 EvalResult::Allow
449 }
450 None => EvalResult::Unmarked,
451 }
452 }
453
454 pub fn eval_default_body_stability(self, def_id: DefId, span: Span) -> EvalResult {
460 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
461 if !is_staged_api {
462 return EvalResult::Allow;
463 }
464
465 let cross_crate = !def_id.is_local();
467 if !cross_crate {
468 return EvalResult::Allow;
469 }
470
471 let stability = self.lookup_default_body_stability(def_id);
472 {
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:472",
"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(472u32),
::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!(
473 "body stability: inspecting def_id={def_id:?} span={span:?} of stability={stability:?}"
474 );
475
476 match stability {
477 Some(DefaultBodyStability {
478 level: hir::StabilityLevel::Unstable { reason, issue, is_soft, .. },
479 feature,
480 }) => {
481 if span.allows_unstable(feature) {
482 {
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:482",
"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(482u32),
::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);
483 return EvalResult::Allow;
484 }
485 if self.features().enabled(feature) {
486 return EvalResult::Allow;
487 }
488
489 EvalResult::Deny {
490 feature,
491 reason: reason.to_opt_reason(),
492 issue,
493 suggestion: None,
494 is_soft,
495 }
496 }
497 Some(_) => {
498 EvalResult::Allow
500 }
501 None => EvalResult::Unmarked,
502 }
503 }
504
505 pub fn check_stability(
515 self,
516 def_id: DefId,
517 id: Option<HirId>,
518 span: Span,
519 method_span: Option<Span>,
520 ) -> bool {
521 self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
522 }
523
524 pub fn check_stability_allow_unstable(
536 self,
537 def_id: DefId,
538 id: Option<HirId>,
539 span: Span,
540 method_span: Option<Span>,
541 allow_unstable: AllowUnstable,
542 ) -> bool {
543 self.check_optional_stability(
544 def_id,
545 id,
546 span,
547 method_span,
548 allow_unstable,
549 |span, def_id| {
550 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:?}"));
553 },
554 )
555 }
556
557 pub fn check_optional_stability(
564 self,
565 def_id: DefId,
566 id: Option<HirId>,
567 span: Span,
568 method_span: Option<Span>,
569 allow_unstable: AllowUnstable,
570 unmarked: impl FnOnce(Span, DefId),
571 ) -> bool {
572 let soft_handler = |lint, span, msg: String| {
573 self.node_span_lint(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
574 lint.primary_message(msg);
575 })
576 };
577 let eval_result =
578 self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
579 let is_allowed = #[allow(non_exhaustive_omitted_patterns)] match eval_result {
EvalResult::Allow => true,
_ => false,
}matches!(eval_result, EvalResult::Allow);
580 match eval_result {
581 EvalResult::Allow => {}
582 EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
583 self.sess,
584 feature,
585 reason,
586 issue,
587 suggestion,
588 is_soft,
589 span,
590 soft_handler,
591 UnstableKind::Regular,
592 ),
593 EvalResult::Unmarked => unmarked(span, def_id),
594 }
595
596 is_allowed
597 }
598
599 pub fn check_const_stability(self, def_id: DefId, span: Span, const_kw_span: Span) {
607 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
608 if !is_staged_api {
609 return;
610 }
611
612 let cross_crate = !def_id.is_local();
614 if !cross_crate {
615 return;
616 }
617
618 let stability = self.lookup_const_stability(def_id);
619 {
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:619",
"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(619u32),
::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!(
620 "stability: \
621 inspecting def_id={:?} span={:?} of stability={:?}",
622 def_id, span, stability
623 );
624
625 match stability {
626 Some(ConstStability {
627 level: hir::StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. },
628 feature,
629 ..
630 }) => {
631 if !!is_soft { ::core::panicking::panic("assertion failed: !is_soft") };assert!(!is_soft);
632
633 if span.allows_unstable(feature) {
634 {
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:634",
"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(634u32),
::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);
635 return;
636 }
637 if self.features().enabled(feature) {
638 return;
639 }
640
641 if let Some(implied_by) = implied_by
645 && self.features().enabled(implied_by)
646 {
647 return;
648 }
649
650 report_unstable(
651 self.sess,
652 feature,
653 reason.to_opt_reason(),
654 issue,
655 None,
656 false,
657 span,
658 |_, _, _| {},
659 UnstableKind::Const(const_kw_span),
660 );
661 }
662 Some(_) | None => {}
663 }
664 }
665
666 pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
667 self.lookup_deprecation_entry(id).map(|depr| depr.attr)
668 }
669}