1use std::num::NonZero;
5
6use rustc_ast::NodeId;
7use rustc_attr_ir::{
8 ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability, StabilityLevel,
9};
10use rustc_errors::{Diag, Diagnostic, LintBuffer, msg};
11use rustc_feature::GateIssue;
12use rustc_hir::def_id::{DefId, LocalDefId};
13use rustc_hir::{self as hir, HirId};
14use rustc_lint_defs::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE};
15use rustc_lint_defs::{DeprecatedSinceKind, Lint};
16use rustc_macros::{Decodable, Encodable, StableHash, Subdiagnostic};
17use rustc_session::Session;
18use rustc_session::diagnostics::feature_err_issue;
19use rustc_span::{Span, Symbol, sym};
20use tracing::debug;
21
22use crate::ty::TyCtxt;
23use crate::ty::print::with_no_trimmed_paths;
24
25#[derive(#[automatically_derived]
impl ::core::marker::Copy for UnstableKind { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for UnstableKind { }
#[automatically_derived]
impl ::core::clone::Clone for UnstableKind {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Span>;
*self
}
}Clone)]
26pub enum UnstableKind {
27 Regular,
29 Const(Span),
31}
32
33#[derive(#[automatically_derived]
impl ::core::marker::Copy for DeprecationEntry { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DeprecationEntry { }
#[automatically_derived]
impl ::core::clone::Clone for DeprecationEntry {
#[inline]
fn clone(&self) -> Self {
let _: ::core::clone::AssertParamIsClone<Deprecation>;
let _: ::core::clone::AssertParamIsClone<Option<LocalDefId>>;
*self
}
}Clone, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
DeprecationEntry {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
DeprecationEntry {
attr: ref __binding_0, origin: ref __binding_1 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, #[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) {
let DeprecationEntry {
attr: ref __binding_0, origin: ref __binding_1 } = *self;
::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)]
35pub struct DeprecationEntry {
36 pub attr: Deprecation,
38 origin: Option<LocalDefId>,
41}
42
43impl DeprecationEntry {
44 pub fn local(attr: Deprecation, def_id: LocalDefId) -> DeprecationEntry {
45 DeprecationEntry { attr, origin: Some(def_id) }
46 }
47
48 pub fn external(attr: Deprecation) -> DeprecationEntry {
49 DeprecationEntry { attr, origin: None }
50 }
51
52 pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
53 match (self.origin, other.origin) {
54 (Some(o1), Some(o2)) => o1 == o2,
55 _ => false,
56 }
57 }
58}
59
60pub fn report_unstable(
61 sess: &Session,
62 feature: Symbol,
63 reason: Option<Symbol>,
64 issue: Option<NonZero<u32>>,
65 span: Span,
66 kind: UnstableKind,
67) {
68 let qual = match kind {
69 UnstableKind::Regular => "",
70 UnstableKind::Const(_) => " const",
71 };
72
73 let msg = match reason {
74 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}"),
75 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}`"),
76 };
77
78 let mut err = feature_err_issue(sess, feature, span, GateIssue::Library(issue), msg);
79 if let UnstableKind::Const(kw) = kind {
80 err.span_label(kw, "trait is not stable as const yet");
81 }
82 err.emit();
83}
84
85fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
86 if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
87}
88
89#[derive(const _: () =
{
impl rustc_errors::Subdiagnostic for DeprecationSuggestion {
fn add_to_diag(self, diag: &mut rustc_errors::Diag<'_>) {
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));
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)]
90#[suggestion(
91 "replace the use of the deprecated {$kind}",
92 code = "{suggestion}",
93 style = "verbose",
94 applicability = "machine-applicable"
95)]
96pub(crate) struct DeprecationSuggestion {
97 #[primary_span]
98 pub span: Span,
99
100 pub kind: String,
101 pub suggestion: Symbol,
102}
103
104pub(crate) struct Deprecated {
105 pub sub: Option<DeprecationSuggestion>,
106
107 pub kind: String,
108 pub path: String,
109 pub note: Option<Symbol>,
110 pub since_kind: DeprecatedSinceKind,
111}
112
113impl<'a> rustc_errors::Diagnostic<'a> for Deprecated {
114 fn into_diag(
115 self,
116 dcx: rustc_errors::DiagCtxtHandle<'a>,
117 level: rustc_errors::Level,
118 ) -> Diag<'a> {
119 let Self { sub, kind, path, note, since_kind } = self;
120 let mut diag = Diag::new(dcx, level, match &since_kind {
121 DeprecatedSinceKind::InEffect => rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("use of deprecated {$kind} `{$path}`{$has_note ->\n [true] : {$note}\n *[other] {\"\"}\n }"))msg!(
122 "use of deprecated {$kind} `{$path}`{$has_note ->
123 [true] : {$note}
124 *[other] {\"\"}
125 }"
126 ),
127 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!(
128 "use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
129 [true] : {$note}
130 *[other] {\"\"}
131 }"
132 ),
133 DeprecatedSinceKind::InVersion(_) => {
134 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!(
135 "use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
136 [true] : {$note}
137 *[other] {\"\"}
138 }"
139 )
140 }
141 })
142 .with_arg("kind", kind)
143 .with_arg("path", path);
144 if let DeprecatedSinceKind::InVersion(version) = since_kind {
145 diag.arg("version", version);
146 }
147 if let Some(note) = note {
148 diag.arg("has_note", true);
149 diag.arg("note", note);
150 } else {
151 diag.arg("has_note", false);
152 }
153 if let Some(sub) = sub {
154 diag.subdiagnostic(sub);
155 }
156 diag
157 }
158}
159
160fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
161 if is_in_effect {
162 DeprecatedSinceKind::InEffect
163 } else {
164 match since {
165 DeprecatedSince::RustcVersion(version) => {
166 DeprecatedSinceKind::InVersion(version.to_string())
167 }
168 DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
169 DeprecatedSince::NonStandard(_)
170 | DeprecatedSince::Unspecified
171 | DeprecatedSince::Err => {
172 {
::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:?}")
173 }
174 }
175 }
176}
177
178pub fn early_report_macro_deprecation(
179 lint_buffer: &mut LintBuffer,
180 depr: &Deprecation,
181 suggestion_span: Span,
182 node_id: NodeId,
183 path: String,
184) {
185 if suggestion_span.in_derive_expansion() {
186 return;
187 }
188
189 let is_in_effect = depr.is_in_effect();
190 let suggestion = depr.suggestion;
191 let note = depr.note.map(|ident| ident.name);
192 let since_kind = deprecated_since_kind(is_in_effect, depr.since);
193 lint_buffer.dyn_buffer_lint(
194 deprecation_lint(is_in_effect),
195 node_id,
196 suggestion_span,
197 move |dcx, level| {
198 let sub = suggestion.map(|suggestion| DeprecationSuggestion {
199 span: suggestion_span,
200 kind: "macro".to_owned(),
201 suggestion,
202 });
203
204 Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }
205 .into_diag(dcx, level)
206 },
207 );
208}
209
210fn late_report_deprecation(
211 tcx: TyCtxt<'_>,
212 depr: &Deprecation,
213 span: Span,
214 method_span: Option<Span>,
215 hir_id: HirId,
216 def_id: DefId,
217) {
218 if span.in_derive_expansion() {
219 return;
220 }
221
222 let is_in_effect = depr.is_in_effect();
223 let lint = deprecation_lint(is_in_effect);
224
225 if tcx.lint_level_spec_at_node(lint, hir_id).is_allow() {
229 return;
230 }
231
232 let def_path = { let _guard = NoTrimmedGuard::new(); tcx.def_path_str(def_id) }with_no_trimmed_paths!(tcx.def_path_str(def_id));
233 let def_kind = tcx.def_descr(def_id);
234
235 let method_span = method_span.unwrap_or(span);
236 let suggestion =
237 if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None };
238 let diag = Deprecated {
239 sub: suggestion.map(|suggestion| DeprecationSuggestion {
240 span: method_span,
241 kind: def_kind.to_owned(),
242 suggestion,
243 }),
244 kind: def_kind.to_owned(),
245 path: def_path,
246 note: depr.note.map(|ident| ident.name),
247 since_kind: deprecated_since_kind(is_in_effect, depr.since),
248 };
249 tcx.emit_node_span_lint(lint, hir_id, method_span, diag);
250}
251
252pub enum EvalResult {
254 Allow,
257 Deny { feature: Symbol, reason: Option<Symbol>, issue: Option<NonZero<u32>> },
260 Unmarked,
262}
263
264pub enum AllowUnstable {
266 Yes,
268 No,
270}
271
272impl<'tcx> TyCtxt<'tcx> {
273 pub fn eval_stability(
283 self,
284 def_id: DefId,
285 id: Option<HirId>,
286 span: Span,
287 method_span: Option<Span>,
288 ) -> EvalResult {
289 self.eval_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
290 }
291
292 pub fn eval_stability_allow_unstable(
304 self,
305 def_id: DefId,
306 id: Option<HirId>,
307 span: Span,
308 method_span: Option<Span>,
309 allow_unstable: AllowUnstable,
310 ) -> EvalResult {
311 if let Some(id) = id {
313 if let Some(depr_entry) = self.lookup_deprecation_entry(def_id) {
314 let parent_def_id = self.hir_get_parent_item(id);
315 let skip = self
316 .lookup_deprecation_entry(parent_def_id.to_def_id())
317 .is_some_and(|parent_depr| parent_depr.same_origin(&depr_entry));
318
319 let depr_attr = &depr_entry.attr;
326 if !skip || depr_attr.is_since_rustc_version() {
327 late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
328 }
329 };
330 }
331
332 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
333 if !is_staged_api {
334 return EvalResult::Allow;
335 }
336
337 let cross_crate = !def_id.is_local();
339 if !cross_crate {
340 return EvalResult::Allow;
341 }
342
343 let stability = self.lookup_stability(def_id);
344 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:344",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(344u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
345 "stability: \
346 inspecting def_id={:?} span={:?} of stability={:?}",
347 def_id, span, stability
348 );
349
350 match stability {
351 Some(Stability {
352 level: StabilityLevel::Unstable { reason, issue, implied_by, .. },
353 feature,
354 ..
355 }) => {
356 if span.allows_unstable(feature) {
357 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:357",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(357u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("stability: skipping span={0:?} since it is internal",
span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("stability: skipping span={:?} since it is internal", span);
358 return EvalResult::Allow;
359 }
360 if self.features().enabled(feature) {
361 return EvalResult::Allow;
362 }
363
364 if let Some(implied_by) = implied_by
368 && self.features().enabled(implied_by)
369 {
370 return EvalResult::Allow;
371 }
372
373 if feature == sym::rustc_private
383 && issue == NonZero::new(27812)
384 && self.sess.opts.unstable_opts.force_unstable_if_unmarked
385 {
386 return EvalResult::Allow;
387 }
388
389 if #[allow(non_exhaustive_omitted_patterns)] match allow_unstable {
AllowUnstable::Yes => true,
_ => false,
}matches!(allow_unstable, AllowUnstable::Yes) {
390 return EvalResult::Allow;
391 }
392
393 EvalResult::Deny { feature, reason: reason.to_opt_reason(), issue }
394 }
395 Some(_) => {
396 EvalResult::Allow
399 }
400 None => EvalResult::Unmarked,
401 }
402 }
403
404 pub fn eval_default_body_stability(self, def_id: DefId, span: Span) -> EvalResult {
410 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
411 if !is_staged_api {
412 return EvalResult::Allow;
413 }
414
415 let cross_crate = !def_id.is_local();
417 if !cross_crate {
418 return EvalResult::Allow;
419 }
420
421 let stability = self.lookup_default_body_stability(def_id);
422 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:422",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(422u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("body stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
423 "body stability: inspecting def_id={def_id:?} span={span:?} of stability={stability:?}"
424 );
425
426 match stability {
427 Some(DefaultBodyStability {
428 level: StabilityLevel::Unstable { reason, issue, .. },
429 feature,
430 }) => {
431 if span.allows_unstable(feature) {
432 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:432",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(432u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("body stability: skipping span={0:?} since it is internal",
span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("body stability: skipping span={:?} since it is internal", span);
433 return EvalResult::Allow;
434 }
435 if self.features().enabled(feature) {
436 return EvalResult::Allow;
437 }
438
439 EvalResult::Deny { feature, reason: reason.to_opt_reason(), issue }
440 }
441 Some(_) => {
442 EvalResult::Allow
444 }
445 None => EvalResult::Unmarked,
446 }
447 }
448
449 pub fn check_stability(
459 self,
460 def_id: DefId,
461 id: Option<HirId>,
462 span: Span,
463 method_span: Option<Span>,
464 ) -> bool {
465 self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
466 }
467
468 pub fn check_stability_allow_unstable(
480 self,
481 def_id: DefId,
482 id: Option<HirId>,
483 span: Span,
484 method_span: Option<Span>,
485 allow_unstable: AllowUnstable,
486 ) -> bool {
487 self.check_optional_stability(
488 def_id,
489 id,
490 span,
491 method_span,
492 allow_unstable,
493 |span, def_id| {
494 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:?}"));
497 },
498 )
499 }
500
501 pub fn check_optional_stability(
508 self,
509 def_id: DefId,
510 id: Option<HirId>,
511 span: Span,
512 method_span: Option<Span>,
513 allow_unstable: AllowUnstable,
514 unmarked: impl FnOnce(Span, DefId),
515 ) -> bool {
516 let eval_result =
517 self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
518 let is_allowed = #[allow(non_exhaustive_omitted_patterns)] match eval_result {
EvalResult::Allow => true,
_ => false,
}matches!(eval_result, EvalResult::Allow);
519 match eval_result {
520 EvalResult::Allow => {}
521 EvalResult::Deny { feature, reason, issue } => {
522 report_unstable(self.sess, feature, reason, issue, span, UnstableKind::Regular)
523 }
524 EvalResult::Unmarked => unmarked(span, def_id),
525 }
526
527 is_allowed
528 }
529
530 pub fn check_const_stability(self, def_id: DefId, span: Span, const_kw_span: Span) {
538 let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
539 if !is_staged_api {
540 return;
541 }
542
543 let cross_crate = !def_id.is_local();
545 if !cross_crate {
546 return;
547 }
548
549 let stability = self.lookup_const_stability(def_id);
550 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:550",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(550u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("stability: inspecting def_id={0:?} span={1:?} of stability={2:?}",
def_id, span, stability) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
551 "stability: \
552 inspecting def_id={:?} span={:?} of stability={:?}",
553 def_id, span, stability
554 );
555
556 match stability {
557 Some(ConstStability {
558 level: StabilityLevel::Unstable { reason, issue, implied_by, .. },
559 feature,
560 ..
561 }) => {
562 if span.allows_unstable(feature) {
563 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs:563",
"rustc_middle::middle::stability", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/c1070d69382b8d2f2eb65119c738a77d9e324c9e/compiler/rustc_middle/src/middle/stability.rs"),
::tracing_core::__macro_support::Option::Some(563u32),
::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};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("body stability: skipping span={0:?} since it is internal",
span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("body stability: skipping span={:?} since it is internal", span);
564 return;
565 }
566 if self.features().enabled(feature) {
567 return;
568 }
569
570 if let Some(implied_by) = implied_by
574 && self.features().enabled(implied_by)
575 {
576 return;
577 }
578
579 report_unstable(
580 self.sess,
581 feature,
582 reason.to_opt_reason(),
583 issue,
584 span,
585 UnstableKind::Const(const_kw_span),
586 );
587 }
588 Some(_) | None => {}
589 }
590 }
591
592 pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
593 self.lookup_deprecation_entry(id).map(|depr| depr.attr)
594 }
595}