| author | bors <bors@rust-lang.org> 2026-06-22 19:20:35 UTC |
| committer | bors <bors@rust-lang.org> 2026-06-22 19:20:35 UTC |
| log | 4429659e4745016bd3f26a4a421843edc7fbc422 |
| tree | 160a37350d4c487d39377ddaab99637198a7cbcf |
| parent | cddcbec198760511240bf0e728193bf4d700acb4 |
| parent | 3809a10081595a5399485d8d59382e1d7d934aad |
Rollup of 8 pull requests
Successful merges:
- rust-lang/rust#158242 (Fix linking for wasm with crate metadata included)
- rust-lang/rust#157978 (Avoid `&raw` recovery ICE after trailing comma)
- rust-lang/rust#158119 (Refactor `proc_macro_decls_static`)
- rust-lang/rust#158171 (rustdoc: Avoid ICE on unevaluated `type const` projections in array lengths)
- rust-lang/rust#158172 (update `asm_experimental_reg` comments)
- rust-lang/rust#158230 (Include `Item::stability` info in rustdoc JSON.)
- rust-lang/rust#158258 (Use an unexpanded span for actually written down opt out params)
- rust-lang/rust#158262 (Change compiler leads in triagebot.toml)37 files changed, 753 insertions(+), 109 deletions(-)
compiler/rustc_codegen_ssa/src/back/linker.rs+7-1| ... | ... | @@ -1817,7 +1817,13 @@ pub(crate) fn exported_symbols( |
| 1817 | 1817 | exported_symbols_for_non_proc_macro(tcx, crate_type) |
| 1818 | 1818 | }; |
| 1819 | 1819 | |
| 1820 | if crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro { | |
| 1820 | // Preserve the metadata symbol to ensure the metadata section doesn't get removed by the | |
| 1821 | // linker. On wasm however the metadata is put in a custom section, to which symbols can't | |
| 1822 | // refer, so there is no metadata symbol there. Luckily custom sections are always preserved by | |
| 1823 | // the linker. | |
| 1824 | if (crate_type == CrateType::Dylib || crate_type == CrateType::ProcMacro) | |
| 1825 | && !tcx.sess.target.is_like_wasm | |
| 1826 | { | |
| 1821 | 1827 | let metadata_symbol_name = exported_symbols::metadata_symbol_name(tcx); |
| 1822 | 1828 | symbols.push((metadata_symbol_name, SymbolExportKind::Data)); |
| 1823 | 1829 | } |
compiler/rustc_hir/src/hir.rs+1| ... | ... | @@ -4570,6 +4570,7 @@ impl<'hir> Item<'hir> { |
| 4570 | 4570 | HirId::make_owner(self.owner_id.def_id) |
| 4571 | 4571 | } |
| 4572 | 4572 | |
| 4573 | #[inline] | |
| 4573 | 4574 | pub fn item_id(&self) -> ItemId { |
| 4574 | 4575 | ItemId { owner_id: self.owner_id } |
| 4575 | 4576 | } |
compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs+9-10| ... | ... | @@ -25,17 +25,17 @@ use crate::hir_ty_lowering::{ |
| 25 | 25 | #[derive(Debug, Default)] |
| 26 | 26 | struct CollectedBound { |
| 27 | 27 | /// `Trait` |
| 28 | positive: bool, | |
| 28 | positive: Option<Span>, | |
| 29 | 29 | /// `?Trait` |
| 30 | maybe: bool, | |
| 30 | maybe: Option<Span>, | |
| 31 | 31 | /// `!Trait` |
| 32 | negative: bool, | |
| 32 | negative: Option<Span>, | |
| 33 | 33 | } |
| 34 | 34 | |
| 35 | 35 | impl CollectedBound { |
| 36 | 36 | /// Returns `true` if any of `Trait`, `?Trait` or `!Trait` were encountered. |
| 37 | 37 | fn any(&self) -> bool { |
| 38 | self.positive || self.maybe || self.negative | |
| 38 | self.positive.is_some() || self.maybe.is_some() || self.negative.is_some() | |
| 39 | 39 | } |
| 40 | 40 | } |
| 41 | 41 | |
| ... | ... | @@ -96,9 +96,9 @@ fn collect_bounds<'a, 'tcx>( |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | match ptr.modifiers.polarity { |
| 99 | hir::BoundPolarity::Maybe(_) => collect_into.maybe = true, | |
| 100 | hir::BoundPolarity::Negative(_) => collect_into.negative = true, | |
| 101 | hir::BoundPolarity::Positive => collect_into.positive = true, | |
| 99 | hir::BoundPolarity::Maybe(_) => collect_into.maybe = Some(ptr.span), | |
| 100 | hir::BoundPolarity::Negative(_) => collect_into.negative = Some(ptr.span), | |
| 101 | hir::BoundPolarity::Positive => collect_into.positive = Some(ptr.span), | |
| 102 | 102 | } |
| 103 | 103 | }); |
| 104 | 104 | collect_into |
| ... | ... | @@ -180,10 +180,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { |
| 180 | 180 | ImpliedBoundsContext::TyParam(..) | ImpliedBoundsContext::AssociatedTypeOrImplTrait => { |
| 181 | 181 | } |
| 182 | 182 | } |
| 183 | ||
| 184 | 183 | let collected = collect_sizedness_bounds(tcx, hir_bounds, context, span); |
| 185 | if (collected.sized.maybe || collected.sized.negative) | |
| 186 | && !collected.sized.positive | |
| 184 | if let Some(span) = collected.sized.maybe.or(collected.sized.negative) | |
| 185 | && collected.sized.positive.is_none() | |
| 187 | 186 | && !collected.meta_sized.any() |
| 188 | 187 | && !collected.pointee_sized.any() |
| 189 | 188 | { |
compiler/rustc_interface/src/lib.rs-1| ... | ... | @@ -10,7 +10,6 @@ pub mod diagnostics; |
| 10 | 10 | pub mod interface; |
| 11 | 11 | mod limits; |
| 12 | 12 | pub mod passes; |
| 13 | mod proc_macro_decls; | |
| 14 | 13 | mod queries; |
| 15 | 14 | pub mod util; |
| 16 | 15 |
compiler/rustc_interface/src/passes.rs+2-2| ... | ... | @@ -49,7 +49,7 @@ use rustc_trait_selection::{solve, traits}; |
| 49 | 49 | use tracing::{info, instrument}; |
| 50 | 50 | |
| 51 | 51 | use crate::interface::Compiler; |
| 52 | use crate::{diagnostics, limits, proc_macro_decls, util}; | |
| 52 | use crate::{diagnostics, limits, util}; | |
| 53 | 53 | |
| 54 | 54 | pub fn parse<'a>(sess: &'a Session) -> ast::Crate { |
| 55 | 55 | let mut krate = sess |
| ... | ... | @@ -897,9 +897,9 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| { |
| 897 | 897 | providers.queries.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).2; |
| 898 | 898 | providers.queries.early_lint_checks = early_lint_checks; |
| 899 | 899 | providers.queries.env_var_os = env_var_os; |
| 900 | providers.queries.proc_macro_decls_static = |tcx, _| tcx.hir_crate_items(()).proc_macro_decls(); | |
| 900 | 901 | rustc_ast_lowering::provide(&mut providers.queries); |
| 901 | 902 | limits::provide(&mut providers.queries); |
| 902 | proc_macro_decls::provide(&mut providers.queries); | |
| 903 | 903 | rustc_expand::provide(&mut providers.queries); |
| 904 | 904 | rustc_const_eval::provide(providers); |
| 905 | 905 | rustc_middle::hir::provide(&mut providers.queries); |
compiler/rustc_interface/src/proc_macro_decls.rs deleted-20| ... | ... | @@ -1,20 +0,0 @@ |
| 1 | use rustc_hir::def_id::LocalDefId; | |
| 2 | use rustc_hir::find_attr; | |
| 3 | use rustc_middle::query::Providers; | |
| 4 | use rustc_middle::ty::TyCtxt; | |
| 5 | ||
| 6 | fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option<LocalDefId> { | |
| 7 | let mut decls = None; | |
| 8 | ||
| 9 | for id in tcx.hir_free_items() { | |
| 10 | if find_attr!(tcx, id.hir_id(), RustcProcMacroDecls) { | |
| 11 | decls = Some(id.owner_id.def_id); | |
| 12 | } | |
| 13 | } | |
| 14 | ||
| 15 | decls | |
| 16 | } | |
| 17 | ||
| 18 | pub(crate) fn provide(providers: &mut Providers) { | |
| 19 | *providers = Providers { proc_macro_decls_static, ..*providers }; | |
| 20 | } |
compiler/rustc_middle/src/hir/map.rs+28-23| ... | ... | @@ -1275,8 +1275,10 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod |
| 1275 | 1275 | opaques, |
| 1276 | 1276 | nested_bodies, |
| 1277 | 1277 | eiis, |
| 1278 | proc_macro_decls, | |
| 1278 | 1279 | .. |
| 1279 | 1280 | } = collector; |
| 1281 | ||
| 1280 | 1282 | ModuleItems { |
| 1281 | 1283 | add_root: false, |
| 1282 | 1284 | submodules: submodules.into_boxed_slice(), |
| ... | ... | @@ -1288,6 +1290,7 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalModDefId) -> Mod |
| 1288 | 1290 | opaques: opaques.into_boxed_slice(), |
| 1289 | 1291 | nested_bodies: nested_bodies.into_boxed_slice(), |
| 1290 | 1292 | eiis: eiis.into_boxed_slice(), |
| 1293 | proc_macro_decls, | |
| 1291 | 1294 | } |
| 1292 | 1295 | } |
| 1293 | 1296 | |
| ... | ... | @@ -1310,6 +1313,7 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { |
| 1310 | 1313 | opaques, |
| 1311 | 1314 | nested_bodies, |
| 1312 | 1315 | eiis, |
| 1316 | proc_macro_decls, | |
| 1313 | 1317 | .. |
| 1314 | 1318 | } = collector; |
| 1315 | 1319 | |
| ... | ... | @@ -1324,40 +1328,32 @@ pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { |
| 1324 | 1328 | opaques: opaques.into_boxed_slice(), |
| 1325 | 1329 | nested_bodies: nested_bodies.into_boxed_slice(), |
| 1326 | 1330 | eiis: eiis.into_boxed_slice(), |
| 1331 | proc_macro_decls, | |
| 1327 | 1332 | } |
| 1328 | 1333 | } |
| 1329 | 1334 | |
| 1330 | 1335 | struct ItemCollector<'tcx> { |
| 1331 | 1336 | // When true, it collects all items in the create, |
| 1332 | 1337 | // otherwise it collects items in some module. |
| 1338 | // Converting this to generic const didn't lead to significant perf improvements | |
| 1339 | // (see <https://github.com/rust-lang/rust/pull/158119#issuecomment-4751513679>). | |
| 1333 | 1340 | crate_collector: bool, |
| 1334 | 1341 | tcx: TyCtxt<'tcx>, |
| 1335 | submodules: Vec<OwnerId>, | |
| 1336 | items: Vec<ItemId>, | |
| 1337 | trait_items: Vec<TraitItemId>, | |
| 1338 | impl_items: Vec<ImplItemId>, | |
| 1339 | foreign_items: Vec<ForeignItemId>, | |
| 1340 | body_owners: Vec<LocalDefId>, | |
| 1341 | opaques: Vec<LocalDefId>, | |
| 1342 | nested_bodies: Vec<LocalDefId>, | |
| 1343 | eiis: Vec<LocalDefId>, | |
| 1342 | submodules: Vec<OwnerId> = vec![], | |
| 1343 | items: Vec<ItemId> = vec![], | |
| 1344 | trait_items: Vec<TraitItemId> = vec![], | |
| 1345 | impl_items: Vec<ImplItemId> = vec![], | |
| 1346 | foreign_items: Vec<ForeignItemId> = vec![], | |
| 1347 | body_owners: Vec<LocalDefId> = vec![], | |
| 1348 | opaques: Vec<LocalDefId> = vec![], | |
| 1349 | nested_bodies: Vec<LocalDefId> = vec![], | |
| 1350 | eiis: Vec<LocalDefId> = vec![], | |
| 1351 | proc_macro_decls: Option<LocalDefId> = None, | |
| 1344 | 1352 | } |
| 1345 | 1353 | |
| 1346 | 1354 | impl<'tcx> ItemCollector<'tcx> { |
| 1347 | 1355 | fn new(tcx: TyCtxt<'tcx>, crate_collector: bool) -> ItemCollector<'tcx> { |
| 1348 | ItemCollector { | |
| 1349 | crate_collector, | |
| 1350 | tcx, | |
| 1351 | submodules: Vec::default(), | |
| 1352 | items: Vec::default(), | |
| 1353 | trait_items: Vec::default(), | |
| 1354 | impl_items: Vec::default(), | |
| 1355 | foreign_items: Vec::default(), | |
| 1356 | body_owners: Vec::default(), | |
| 1357 | opaques: Vec::default(), | |
| 1358 | nested_bodies: Vec::default(), | |
| 1359 | eiis: Vec::default(), | |
| 1360 | } | |
| 1356 | ItemCollector { crate_collector, tcx, .. } | |
| 1361 | 1357 | } |
| 1362 | 1358 | } |
| 1363 | 1359 | |
| ... | ... | @@ -1373,7 +1369,16 @@ impl<'hir> Visitor<'hir> for ItemCollector<'hir> { |
| 1373 | 1369 | self.body_owners.push(item.owner_id.def_id); |
| 1374 | 1370 | } |
| 1375 | 1371 | |
| 1376 | self.items.push(item.item_id()); | |
| 1372 | let item_id = item.item_id(); | |
| 1373 | ||
| 1374 | if self.crate_collector | |
| 1375 | && self.proc_macro_decls.is_none() | |
| 1376 | && find_attr!(self.tcx, item_id.hir_id(), RustcProcMacroDecls) | |
| 1377 | { | |
| 1378 | self.proc_macro_decls = Some(item_id.owner_id.def_id); | |
| 1379 | } | |
| 1380 | ||
| 1381 | self.items.push(item_id); | |
| 1377 | 1382 | |
| 1378 | 1383 | if let ItemKind::Static(..) | ItemKind::Fn { .. } | ItemKind::Macro(..) = &item.kind |
| 1379 | 1384 | && item.eii |
compiler/rustc_middle/src/hir/mod.rs+8| ... | ... | @@ -39,6 +39,9 @@ pub struct ModuleItems { |
| 39 | 39 | |
| 40 | 40 | /// Statics and functions with an `EiiImpls` or `EiiExternTarget` attribute |
| 41 | 41 | eiis: Box<[LocalDefId]>, |
| 42 | ||
| 43 | // only filled with hir_crate_items, not with hir_module_items | |
| 44 | proc_macro_decls: Option<LocalDefId>, | |
| 42 | 45 | } |
| 43 | 46 | |
| 44 | 47 | impl ModuleItems { |
| ... | ... | @@ -56,6 +59,11 @@ impl ModuleItems { |
| 56 | 59 | self.trait_items.iter().copied() |
| 57 | 60 | } |
| 58 | 61 | |
| 62 | #[inline] | |
| 63 | pub fn proc_macro_decls(&self) -> Option<LocalDefId> { | |
| 64 | self.proc_macro_decls | |
| 65 | } | |
| 66 | ||
| 59 | 67 | pub fn eiis(&self) -> impl Iterator<Item = LocalDefId> { |
| 60 | 68 | self.eiis.iter().copied() |
| 61 | 69 | } |
compiler/rustc_parse/src/parser/expr.rs+4-2| ... | ... | @@ -1304,8 +1304,10 @@ impl<'a> Parser<'a> { |
| 1304 | 1304 | let err_span = self.prev_token.span.to(self.token.span); |
| 1305 | 1305 | let mut args = thin_vec![self.mk_expr_err(err_span, guar)]; |
| 1306 | 1306 | while !self.token.kind.is_close_delim_or_eof() { |
| 1307 | if self.eat(exp!(Comma)) && !self.token.kind.is_close_delim_or_eof() { | |
| 1308 | args.push(self.mk_expr_err(self.prev_token.span.shrink_to_hi(), guar)); | |
| 1307 | if self.eat(exp!(Comma)) { | |
| 1308 | if !self.token.kind.is_close_delim_or_eof() { | |
| 1309 | args.push(self.mk_expr_err(self.prev_token.span.shrink_to_hi(), guar)); | |
| 1310 | } | |
| 1309 | 1311 | } else { |
| 1310 | 1312 | self.parse_token_tree(); |
| 1311 | 1313 | } |
src/doc/unstable-book/src/language-features/asm-experimental-reg.md+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | # `asm_experimental_arch` | |
| 1 | # `asm_experimental_reg` | |
| 2 | 2 | |
| 3 | 3 | The tracking issue for this feature is: [#133416] |
| 4 | 4 |
src/librustdoc/clean/mod.rs+4-1| ... | ... | @@ -2152,7 +2152,10 @@ pub(crate) fn clean_middle_ty<'tcx>( |
| 2152 | 2152 | format!("{pat:?}").into_boxed_str(), |
| 2153 | 2153 | ), |
| 2154 | 2154 | ty::Array(ty, n) => { |
| 2155 | let n = cx.tcx.normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(n)); | |
| 2155 | let n = cx | |
| 2156 | .tcx | |
| 2157 | .try_normalize_erasing_regions(cx.typing_env(), Unnormalized::new_wip(n)) | |
| 2158 | .unwrap_or(n); | |
| 2156 | 2159 | let n = print_const(cx.tcx, n); |
| 2157 | 2160 | Array(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None, None)), n.into()) |
| 2158 | 2161 | } |
src/librustdoc/clean/utils.rs+10-2| ... | ... | @@ -351,8 +351,16 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { |
| 351 | 351 | pub(crate) fn print_const(tcx: TyCtxt<'_>, n: ty::Const<'_>) -> String { |
| 352 | 352 | match n.kind() { |
| 353 | 353 | ty::ConstKind::Unevaluated(ty::UnevaluatedConst { kind, .. }) => match kind { |
| 354 | ty::UnevaluatedConstKind::Projection { def_id } | |
| 355 | | ty::UnevaluatedConstKind::Inherent { def_id } | |
| 354 | ty::UnevaluatedConstKind::Projection { def_id } => { | |
| 355 | if let Some(local_def_id) = def_id.as_local() | |
| 356 | && let Some(body_id) = tcx.hir_maybe_body_owned_by(local_def_id) | |
| 357 | { | |
| 358 | rendered_const(tcx, body_id, local_def_id) | |
| 359 | } else { | |
| 360 | n.to_string() | |
| 361 | } | |
| 362 | } | |
| 363 | ty::UnevaluatedConstKind::Inherent { def_id } | |
| 356 | 364 | | ty::UnevaluatedConstKind::Free { def_id } |
| 357 | 365 | | ty::UnevaluatedConstKind::Anon { def_id } => { |
| 358 | 366 | if let Some(local_def_id) = def_id.as_local() |
src/librustdoc/json/conversions.rs+45| ... | ... | @@ -69,12 +69,37 @@ impl JsonRenderer<'_> { |
| 69 | 69 | } |
| 70 | 70 | _ => from_clean_item(item, self), |
| 71 | 71 | }; |
| 72 | ||
| 73 | // Rustdoc JSON keeps re-exports as `Use` items, so their stability describes | |
| 74 | // the local `pub use` declaration. The imported target item's stability | |
| 75 | // remains available through `inner.use.id`. | |
| 76 | // | |
| 77 | // We use raw stability attributes here instead of `clean::Item::stability()`, | |
| 78 | // which is the effective stability rustdoc uses for rendering paths. | |
| 79 | // For example, a stable `pub use` inside an unstable module is effectively unstable | |
| 80 | // through that module path, but the `Use` declaration itself is still stable. | |
| 81 | // In that example, `clean::Item::stability()` would return "unstable" as | |
| 82 | // the effective stability, which is appropriate for HTML but makes JSON uses harder. | |
| 83 | // | |
| 84 | // JSON consumers already have to do path-based reasoning to reconstruct item reachability, | |
| 85 | // names, and stability. Keeping component-wise stability allows them to easily reconstruct | |
| 86 | // stability from the module, use item, and target item records. | |
| 87 | let stability_def_id = if matches!(&item.kind, clean::ImportItem(_)) { | |
| 88 | item.inline_stmt_id | |
| 89 | .map(|def_id| def_id.to_def_id()) | |
| 90 | .or_else(|| item.item_id.as_def_id()) | |
| 91 | } else { | |
| 92 | item.item_id.as_def_id() | |
| 93 | }; | |
| 94 | let stability = stability_def_id.and_then(|def_id| self.tcx.lookup_stability(def_id)); | |
| 95 | ||
| 72 | 96 | Some(Item { |
| 73 | 97 | id, |
| 74 | 98 | crate_id: item_id.krate().as_u32(), |
| 75 | 99 | name: name.map(|sym| sym.to_string()), |
| 76 | 100 | span: span.and_then(|span| span.into_json(self)), |
| 77 | 101 | visibility: visibility.into_json(self), |
| 102 | stability: stability.map(|s| Box::new(s.into_json(self))), | |
| 78 | 103 | docs, |
| 79 | 104 | attrs, |
| 80 | 105 | deprecation: deprecation.into_json(self), |
| ... | ... | @@ -203,6 +228,24 @@ impl FromClean<attrs::Deprecation> for Deprecation { |
| 203 | 228 | } |
| 204 | 229 | } |
| 205 | 230 | |
| 231 | impl FromClean<hir::Stability> for Stability { | |
| 232 | fn from_clean(stab: &hir::Stability, _renderer: &JsonRenderer<'_>) -> Self { | |
| 233 | let feature = stab.feature.to_string(); | |
| 234 | let level = match stab.level { | |
| 235 | hir::StabilityLevel::Stable { since, .. } => StabilityLevel::Stable { | |
| 236 | since: match since { | |
| 237 | hir::StableSince::Version(since) => Some(since.to_string()), | |
| 238 | hir::StableSince::Current => Some(hir::RustcVersion::CURRENT.to_string()), | |
| 239 | // Match rustdoc HTML: malformed stable-since values are omitted. | |
| 240 | hir::StableSince::Err(_) => None, | |
| 241 | }, | |
| 242 | }, | |
| 243 | hir::StabilityLevel::Unstable { .. } => StabilityLevel::Unstable, | |
| 244 | }; | |
| 245 | Stability { feature, level } | |
| 246 | } | |
| 247 | } | |
| 248 | ||
| 206 | 249 | impl FromClean<clean::GenericArgs> for Option<Box<GenericArgs>> { |
| 207 | 250 | fn from_clean(generic_args: &clean::GenericArgs, renderer: &JsonRenderer<'_>) -> Self { |
| 208 | 251 | use clean::GenericArgs::*; |
| ... | ... | @@ -922,6 +965,8 @@ fn maybe_from_hir_attr(attr: &hir::Attribute, item_id: ItemId, tcx: TyCtxt<'_>) |
| 922 | 965 | |
| 923 | 966 | vec![match kind { |
| 924 | 967 | AK::Deprecated { .. } => return Vec::new(), // Handled separately into Item::deprecation. |
| 968 | AK::Stability { .. } => return Vec::new(), // Handled separately into Item::stability | |
| 969 | ||
| 925 | 970 | AK::DocComment { .. } => unreachable!("doc comments stripped out earlier"), |
| 926 | 971 | |
| 927 | 972 | AK::MacroExport { .. } => Attribute::MacroExport, |
src/librustdoc/json/mod.rs+1-1| ... | ... | @@ -361,6 +361,6 @@ mod size_asserts { |
| 361 | 361 | // tidy-alphabetical-end |
| 362 | 362 | |
| 363 | 363 | // These contains a `PathBuf`, which is different sizes on different OSes. |
| 364 | static_assert_size!(Item, 528 + size_of::<std::path::PathBuf>()); | |
| 364 | static_assert_size!(Item, 536 + size_of::<std::path::PathBuf>()); | |
| 365 | 365 | static_assert_size!(ExternalCrate, 48 + size_of::<std::path::PathBuf>()); |
| 366 | 366 | } |
src/rustdoc-json-types/lib.rs+61-3| ... | ... | @@ -114,8 +114,8 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc |
| 114 | 114 | // will instead cause conflicts. See #94591 for more. (This paragraph and the "Latest feature" line |
| 115 | 115 | // are deliberately not in a doc comment, because they need not be in public docs.) |
| 116 | 116 | // |
| 117 | // Latest feature: Add `ExternCrate::path`. | |
| 118 | pub const FORMAT_VERSION: u32 = 57; | |
| 117 | // Latest feature: Add `Item::stability`. | |
| 118 | pub const FORMAT_VERSION: u32 = 58; | |
| 119 | 119 | |
| 120 | 120 | /// The root of the emitted JSON blob. |
| 121 | 121 | /// |
| ... | ... | @@ -282,7 +282,10 @@ pub struct Item { |
| 282 | 282 | pub links: HashMap<String, Id>, |
| 283 | 283 | /// Attributes on this item. |
| 284 | 284 | /// |
| 285 | /// Does not include `#[deprecated]` attributes: see the [`Self::deprecation`] field instead. | |
| 285 | /// Does not include: | |
| 286 | /// - `#[doc = "Doc Comment"]` or `/// Doc comment`: see [`Self::docs`] instead. | |
| 287 | /// - `#[deprecated]` attributes: see the [`Self::deprecation`] field instead. | |
| 288 | /// - `#[stable]` and `#[unstable]` attributes: see the [`Self::stability`] field instead. | |
| 286 | 289 | /// |
| 287 | 290 | /// Attributes appear in pretty-printed Rust form, regardless of their formatting |
| 288 | 291 | /// in the original source code. For example: |
| ... | ... | @@ -294,10 +297,64 @@ pub struct Item { |
| 294 | 297 | pub attrs: Vec<Attribute>, |
| 295 | 298 | /// Information about the item’s deprecation, if present. |
| 296 | 299 | pub deprecation: Option<Deprecation>, |
| 300 | ||
| 301 | /// Stability information for this item, if any. | |
| 302 | /// | |
| 303 | /// This describes whether the item itself is stable or unstable, as noted by a `#[stable]` or | |
| 304 | /// `#[unstable]` attribute. It does not capture const stability, default-body stability, etc. | |
| 305 | /// | |
| 306 | /// Whether a path to an item is stable depends on the stability of containing modules | |
| 307 | /// or re-exports along that path. For example, a stable item can be reachable through both an | |
| 308 | /// unstable module and a stable re-export. | |
| 309 | /// | |
| 310 | /// For items whose inner kind is [`ItemEnum::Use`], this is the stability of the import itself, | |
| 311 | /// not the item being imported. This allows users to determine the stability of paths | |
| 312 | /// that involve re-exports. | |
| 313 | /// | |
| 314 | /// Associated items can inherit instability from their enclosing unstable trait or impl. | |
| 315 | /// Unannotated associated items in stable traits or impls may have no separate stability value. | |
| 316 | /// | |
| 317 | /// Currently, Rust's `#[stable]` and `#[unstable]` attributes are themselves not stable. | |
| 318 | /// As a result, this field is primarily populated for standard-library items; | |
| 319 | /// most ordinary third-party crates usually have no data here. | |
| 320 | pub stability: Option<Box<Stability>>, | |
| 321 | ||
| 297 | 322 | /// The type-specific fields describing this item. |
| 298 | 323 | pub inner: ItemEnum, |
| 299 | 324 | } |
| 300 | 325 | |
| 326 | /// Stability information for an item. | |
| 327 | /// | |
| 328 | /// This only refers to regular item stability: whether the item is stable or unstable | |
| 329 | /// as represented by the `#[stable]` or `#[unstable]` attributes. | |
| 330 | /// Const stability and default-body stability are different things and not captured here. | |
| 331 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
| 332 | #[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] | |
| 333 | #[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] | |
| 334 | pub struct Stability { | |
| 335 | /// The stability feature associated with this item. | |
| 336 | /// | |
| 337 | /// For unstable items, this is the feature gate associated with the item. | |
| 338 | /// For stable items, this is the historical label recorded when the item was stabilized. | |
| 339 | pub feature: String, | |
| 340 | ||
| 341 | #[serde(flatten)] | |
| 342 | pub level: StabilityLevel, | |
| 343 | } | |
| 344 | ||
| 345 | /// Whether an item is stable or unstable as regular public API. | |
| 346 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] | |
| 347 | #[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] | |
| 348 | #[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] | |
| 349 | #[serde(tag = "level", rename_all = "snake_case")] | |
| 350 | pub enum StabilityLevel { | |
| 351 | Stable { | |
| 352 | /// The Rust version in which this item became stable, if available. | |
| 353 | since: Option<String>, | |
| 354 | }, | |
| 355 | Unstable, | |
| 356 | } | |
| 357 | ||
| 301 | 358 | #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] |
| 302 | 359 | #[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] |
| 303 | 360 | #[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] |
| ... | ... | @@ -307,6 +364,7 @@ pub struct Item { |
| 307 | 364 | /// This doesn't include: |
| 308 | 365 | /// - `#[doc = "Doc Comment"]` or `/// Doc comment`. These are in [`Item::docs`] instead. |
| 309 | 366 | /// - `#[deprecated]`. These are in [`Item::deprecation`] instead. |
| 367 | /// - `#[stable]` and `#[unstable]`. These are in [`Item::stability`] instead. | |
| 310 | 368 | pub enum Attribute { |
| 311 | 369 | /// `#[non_exhaustive]` |
| 312 | 370 | NonExhaustive, |
src/tools/jsondoclint/src/validator/tests.rs+7| ... | ... | @@ -33,6 +33,7 @@ fn errors_on_missing_links() { |
| 33 | 33 | links: FxHashMap::from_iter([("Not Found".to_owned(), Id(1))]), |
| 34 | 34 | attrs: vec![], |
| 35 | 35 | deprecation: None, |
| 36 | stability: None, | |
| 36 | 37 | inner: ItemEnum::Module(Module { |
| 37 | 38 | is_crate: true, |
| 38 | 39 | items: vec![], |
| ... | ... | @@ -81,6 +82,7 @@ fn errors_on_local_in_paths_and_not_index() { |
| 81 | 82 | links: FxHashMap::from_iter([("prim@i32".to_owned(), Id(2))]), |
| 82 | 83 | attrs: Vec::new(), |
| 83 | 84 | deprecation: None, |
| 85 | stability: None, | |
| 84 | 86 | inner: ItemEnum::Module(Module { |
| 85 | 87 | is_crate: true, |
| 86 | 88 | items: vec![Id(1)], |
| ... | ... | @@ -100,6 +102,7 @@ fn errors_on_local_in_paths_and_not_index() { |
| 100 | 102 | links: FxHashMap::default(), |
| 101 | 103 | attrs: Vec::new(), |
| 102 | 104 | deprecation: None, |
| 105 | stability: None, | |
| 103 | 106 | inner: ItemEnum::Primitive(Primitive { name: "i32".to_owned(), impls: vec![] }), |
| 104 | 107 | }, |
| 105 | 108 | ), |
| ... | ... | @@ -153,6 +156,7 @@ fn errors_on_missing_path() { |
| 153 | 156 | links: FxHashMap::default(), |
| 154 | 157 | attrs: Vec::new(), |
| 155 | 158 | deprecation: None, |
| 159 | stability: None, | |
| 156 | 160 | inner: ItemEnum::Module(Module { |
| 157 | 161 | is_crate: true, |
| 158 | 162 | items: vec![Id(1), Id(2)], |
| ... | ... | @@ -172,6 +176,7 @@ fn errors_on_missing_path() { |
| 172 | 176 | links: FxHashMap::default(), |
| 173 | 177 | attrs: Vec::new(), |
| 174 | 178 | deprecation: None, |
| 179 | stability: None, | |
| 175 | 180 | inner: ItemEnum::Struct(Struct { |
| 176 | 181 | kind: StructKind::Unit, |
| 177 | 182 | generics: generics.clone(), |
| ... | ... | @@ -191,6 +196,7 @@ fn errors_on_missing_path() { |
| 191 | 196 | links: FxHashMap::default(), |
| 192 | 197 | attrs: Vec::new(), |
| 193 | 198 | deprecation: None, |
| 199 | stability: None, | |
| 194 | 200 | inner: ItemEnum::Function(Function { |
| 195 | 201 | sig: FunctionSignature { |
| 196 | 202 | inputs: vec![], |
| ... | ... | @@ -253,6 +259,7 @@ fn checks_local_crate_id_is_correct() { |
| 253 | 259 | links: FxHashMap::default(), |
| 254 | 260 | attrs: Vec::new(), |
| 255 | 261 | deprecation: None, |
| 262 | stability: None, | |
| 256 | 263 | inner: ItemEnum::Module(Module { |
| 257 | 264 | is_crate: true, |
| 258 | 265 | items: vec![], |
tests/rustdoc-html/type-const-associated-const-no-body.rs created+20| ... | ... | @@ -0,0 +1,20 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/149287> | |
| 2 | //! and <https://github.com/rust-lang/rust/issues/158155> | |
| 3 | ||
| 4 | #![crate_name = "foo"] | |
| 5 | #![feature(min_generic_const_args)] | |
| 6 | #![expect(incomplete_features)] | |
| 7 | ||
| 8 | pub trait Tr { | |
| 9 | type const SIZE: usize; | |
| 10 | } | |
| 11 | ||
| 12 | //@ has 'foo/fn.mk_array.html' | |
| 13 | //@ has - '//pre[@class="rust item-decl"]/code' '[(); <T as Tr>::SIZE]' | |
| 14 | pub fn mk_array<T: Tr>() -> [(); <T as Tr>::SIZE] { | |
| 15 | [(); T::SIZE] | |
| 16 | } | |
| 17 | ||
| 18 | //@ has 'foo/type.Arr.html' | |
| 19 | //@ has - '//pre[@class="rust item-decl"]/code' '[(); <T as Tr>::SIZE]' | |
| 20 | pub type Arr<T> = [(); <T as Tr>::SIZE]; |
tests/rustdoc-json/attrs/stability/associated_items.rs created+66| ... | ... | @@ -0,0 +1,66 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | // Trait-associated item declarations only. Items defined inside impl blocks are tested in | |
| 4 | // `impls.rs` because they have different parent-item behavior. | |
| 5 | ||
| 6 | //@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.level" '"stable"' | |
| 7 | //@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.feature" '"stable_trait_with_associated_items"' | |
| 8 | //@ is "$.index[?(@.name=='StableTraitWithAssociatedItems')].stability.since" '"1.0.0"' | |
| 9 | #[stable(feature = "stable_trait_with_associated_items", since = "1.0.0")] | |
| 10 | pub trait StableTraitWithAssociatedItems { | |
| 11 | // Stable trait-associated items need their own stability attributes in staged API crates. | |
| 12 | //@ is "$.index[?(@.name=='StableAssocType')].stability.level" '"stable"' | |
| 13 | //@ is "$.index[?(@.name=='StableAssocType')].stability.feature" '"stable_assoc_type_feature"' | |
| 14 | //@ is "$.index[?(@.name=='StableAssocType')].stability.since" '"1.1.0"' | |
| 15 | //@ is "$.index[?(@.name=='StableAssocType')].attrs" [] | |
| 16 | #[stable(feature = "stable_assoc_type_feature", since = "1.1.0")] | |
| 17 | type StableAssocType; | |
| 18 | ||
| 19 | //@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.level" '"unstable"' | |
| 20 | //@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.feature" '"unstable_assoc_const_in_stable_trait"' | |
| 21 | //@ !has "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT')].stability.since" | |
| 22 | #[unstable(feature = "unstable_assoc_const_in_stable_trait", issue = "none")] | |
| 23 | const UNSTABLE_ASSOC_CONST_IN_STABLE_TRAIT: usize = 0; | |
| 24 | ||
| 25 | //@ is "$.index[?(@.name=='unstable_provided_method')].stability.level" '"unstable"' | |
| 26 | //@ is "$.index[?(@.name=='unstable_provided_method')].stability.feature" '"unstable_provided_method_feature"' | |
| 27 | //@ !has "$.index[?(@.name=='unstable_provided_method')].stability.since" | |
| 28 | #[unstable(feature = "unstable_provided_method_feature", issue = "none")] | |
| 29 | fn unstable_provided_method(&self) {} | |
| 30 | } | |
| 31 | ||
| 32 | //@ is "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.level" '"unstable"' | |
| 33 | //@ is "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.feature" '"unstable_trait_with_unannotated_associated_items"' | |
| 34 | //@ !has "$.index[?(@.name=='UnstableTraitWithUnannotatedAssociatedItems')].stability.since" | |
| 35 | #[unstable(feature = "unstable_trait_with_unannotated_associated_items", issue = "none")] | |
| 36 | pub trait UnstableTraitWithUnannotatedAssociatedItems { | |
| 37 | // Unannotated associated items in unstable traits inherit the trait's unstable stability. | |
| 38 | //@ is "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.level" '"unstable"' | |
| 39 | //@ is "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.feature" '"unstable_trait_with_unannotated_associated_items"' | |
| 40 | //@ !has "$.index[?(@.name=='UnannotatedAssocTypeInUnstableTrait')].stability.since" | |
| 41 | type UnannotatedAssocTypeInUnstableTrait; | |
| 42 | ||
| 43 | //@ is "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.level" '"unstable"' | |
| 44 | //@ is "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.feature" '"unstable_trait_with_unannotated_associated_items"' | |
| 45 | //@ !has "$.index[?(@.name=='UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT')].stability.since" | |
| 46 | const UNANNOTATED_ASSOC_CONST_IN_UNSTABLE_TRAIT: usize; | |
| 47 | ||
| 48 | //@ is "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.level" '"unstable"' | |
| 49 | //@ is "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.feature" '"unstable_trait_with_unannotated_associated_items"' | |
| 50 | //@ !has "$.index[?(@.name=='unannotated_required_method_in_unstable_trait')].stability.since" | |
| 51 | fn unannotated_required_method_in_unstable_trait(&self); | |
| 52 | } | |
| 53 | ||
| 54 | //@ is "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.level" '"unstable"' | |
| 55 | //@ is "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.feature" '"unstable_trait_with_explicit_associated_item"' | |
| 56 | //@ !has "$.index[?(@.name=='UnstableTraitWithExplicitAssociatedItem')].stability.since" | |
| 57 | #[unstable(feature = "unstable_trait_with_explicit_associated_item", issue = "none")] | |
| 58 | pub trait UnstableTraitWithExplicitAssociatedItem { | |
| 59 | // It's possble to override the parent's instability with another `#[unstable]` attribute, | |
| 60 | // for example to specify a different feature gate for that item. | |
| 61 | //@ is "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.level" '"unstable"' | |
| 62 | //@ is "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.feature" '"unstable_assoc_type_in_unstable_trait"' | |
| 63 | //@ !has "$.index[?(@.name=='UnstableAssocTypeInUnstableTrait')].stability.since" | |
| 64 | #[unstable(feature = "unstable_assoc_type_in_unstable_trait", issue = "none")] | |
| 65 | type UnstableAssocTypeInUnstableTrait; | |
| 66 | } |
tests/rustdoc-json/attrs/stability/impls.rs created+136| ... | ... | @@ -0,0 +1,136 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | // Impl blocks and items defined inside impl blocks only. Trait-associated item declarations are | |
| 4 | // tested in `associated_items.rs`; any trait items below are scaffolding for impl-item assertions. | |
| 5 | // Staged API still requires stability attributes on stable trait items even when the assertions | |
| 6 | // below focus on the corresponding impl items. | |
| 7 | ||
| 8 | #[stable(feature = "stable_impl_target", since = "1.0.0")] | |
| 9 | pub struct StableImplTarget; | |
| 10 | ||
| 11 | #[stable(feature = "stable_trait_for_impl", since = "1.0.0")] | |
| 12 | pub trait StableTraitForImpl { | |
| 13 | #[stable(feature = "stable_trait_output", since = "1.0.0")] | |
| 14 | type StableOutput; | |
| 15 | ||
| 16 | #[stable(feature = "stable_trait_assoc_const", since = "1.0.0")] | |
| 17 | const STABLE_ASSOC_CONST: usize; | |
| 18 | ||
| 19 | #[stable(feature = "stable_trait_method", since = "1.0.0")] | |
| 20 | fn stable_trait_method(&self); | |
| 21 | } | |
| 22 | ||
| 23 | #[stable(feature = "stable_trait_with_unstable_method_for_impl", since = "1.0.0")] | |
| 24 | pub trait StableTraitWithUnstableMethodForImpl { | |
| 25 | #[unstable(feature = "unstable_trait_method_for_stable_impl", issue = "none")] | |
| 26 | fn unstable_trait_method_for_stable_impl(&self); | |
| 27 | } | |
| 28 | ||
| 29 | #[unstable(feature = "unstable_trait_for_impl", issue = "none")] | |
| 30 | pub trait UnstableTraitForImpl { | |
| 31 | type UnstableOutput; | |
| 32 | const UNSTABLE_ASSOC_CONST: usize; | |
| 33 | fn unstable_trait_method(&self); | |
| 34 | } | |
| 35 | ||
| 36 | //@ is "$.index[?(@.docs=='stable inherent impl')].stability.level" '"stable"' | |
| 37 | //@ is "$.index[?(@.docs=='stable inherent impl')].stability.feature" '"stable_inherent_impl"' | |
| 38 | //@ is "$.index[?(@.docs=='stable inherent impl')].stability.since" '"2.0.0"' | |
| 39 | /// stable inherent impl | |
| 40 | #[stable(feature = "stable_inherent_impl", since = "2.0.0")] | |
| 41 | impl StableImplTarget { | |
| 42 | //@ is "$.index[?(@.name=='stable_inherent_method')].stability.level" '"stable"' | |
| 43 | //@ is "$.index[?(@.name=='stable_inherent_method')].stability.feature" '"stable_inherent_method_feature"' | |
| 44 | //@ is "$.index[?(@.name=='stable_inherent_method')].stability.since" '"2.1.0"' | |
| 45 | //@ is "$.index[?(@.name=='stable_inherent_method')].attrs" [] | |
| 46 | #[stable(feature = "stable_inherent_method_feature", since = "2.1.0")] | |
| 47 | pub fn stable_inherent_method(&self) {} | |
| 48 | ||
| 49 | //@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_IMPL')].stability.level" '"unstable"' | |
| 50 | //@ is "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_IMPL')].stability.feature" '"unstable_assoc_const_in_impl_feature"' | |
| 51 | //@ !has "$.index[?(@.name=='UNSTABLE_ASSOC_CONST_IN_IMPL')].stability.since" | |
| 52 | #[unstable(feature = "unstable_assoc_const_in_impl_feature", issue = "none")] | |
| 53 | pub const UNSTABLE_ASSOC_CONST_IN_IMPL: usize = 2; | |
| 54 | } | |
| 55 | ||
| 56 | //@ is "$.index[?(@.docs=='unstable inherent impl')].stability.level" '"unstable"' | |
| 57 | //@ is "$.index[?(@.docs=='unstable inherent impl')].stability.feature" '"unstable_inherent_impl"' | |
| 58 | //@ !has "$.index[?(@.docs=='unstable inherent impl')].stability.since" | |
| 59 | /// unstable inherent impl | |
| 60 | #[unstable(feature = "unstable_inherent_impl", issue = "none")] | |
| 61 | impl StableImplTarget { | |
| 62 | // The instability of the inherent `impl` block is inherited by the item. | |
| 63 | //@ is "$.index[?(@.name=='method_inside_unstable_inherent_impl')].stability.level" '"unstable"' | |
| 64 | //@ is "$.index[?(@.name=='method_inside_unstable_inherent_impl')].stability.feature" '"unstable_inherent_impl"' | |
| 65 | //@ !has "$.index[?(@.name=='method_inside_unstable_inherent_impl')].stability.since" | |
| 66 | pub fn method_inside_unstable_inherent_impl(&self) {} | |
| 67 | } | |
| 68 | ||
| 69 | // For trait impl items, `stability: null` means the implementation item has no separate | |
| 70 | // stability attribute of its own. To decide whether the implemented method/type/const is usable, | |
| 71 | // consumers need to combine the trait item stability with the impl block stability. | |
| 72 | // | |
| 73 | // The stable impl below intentionally does not copy either stable or unstable trait-item | |
| 74 | // stability onto the implemented item. The unstable impl case is different: rustc records the | |
| 75 | // impl block's instability on contained impl items, so JSON exposes that inherited instability. | |
| 76 | ||
| 77 | //@ is "$.index[?(@.docs=='stable trait impl with unstable trait method')].stability.level" '"stable"' | |
| 78 | //@ is "$.index[?(@.docs=='stable trait impl with unstable trait method')].stability.feature" '"stable_trait_impl_with_unstable_trait_method"' | |
| 79 | //@ is "$.index[?(@.docs=='stable trait impl with unstable trait method')].stability.since" '"3.0.0"' | |
| 80 | /// stable trait impl with unstable trait method | |
| 81 | #[stable(feature = "stable_trait_impl_with_unstable_trait_method", since = "3.0.0")] | |
| 82 | impl StableTraitWithUnstableMethodForImpl for StableImplTarget { | |
| 83 | // The impl item has no separate stability record; the trait method is unstable. | |
| 84 | //@ is "$.index[?(@.docs=='method for unstable trait item inside stable trait impl')].stability" null | |
| 85 | /// method for unstable trait item inside stable trait impl | |
| 86 | fn unstable_trait_method_for_stable_impl(&self) {} | |
| 87 | } | |
| 88 | ||
| 89 | //@ is "$.index[?(@.docs=='stable trait impl')].stability.level" '"stable"' | |
| 90 | //@ is "$.index[?(@.docs=='stable trait impl')].stability.feature" '"stable_trait_impl"' | |
| 91 | //@ is "$.index[?(@.docs=='stable trait impl')].stability.since" '"3.0.0"' | |
| 92 | /// stable trait impl | |
| 93 | #[stable(feature = "stable_trait_impl", since = "3.0.0")] | |
| 94 | impl StableTraitForImpl for StableImplTarget { | |
| 95 | // These impl items likewise have no separate stability records. | |
| 96 | // Their trait item declarations and the impl block are all stable. | |
| 97 | ||
| 98 | //@ is "$.index[?(@.docs=='assoc type inside stable trait impl')].stability" null | |
| 99 | /// assoc type inside stable trait impl | |
| 100 | type StableOutput = usize; | |
| 101 | ||
| 102 | //@ is "$.index[?(@.docs=='assoc const inside stable trait impl')].stability" null | |
| 103 | /// assoc const inside stable trait impl | |
| 104 | const STABLE_ASSOC_CONST: usize = 0; | |
| 105 | ||
| 106 | //@ is "$.index[?(@.docs=='method inside stable trait impl')].stability" null | |
| 107 | /// method inside stable trait impl | |
| 108 | fn stable_trait_method(&self) {} | |
| 109 | } | |
| 110 | ||
| 111 | //@ is "$.index[?(@.docs=='unstable trait impl')].stability.level" '"unstable"' | |
| 112 | //@ is "$.index[?(@.docs=='unstable trait impl')].stability.feature" '"unstable_trait_impl"' | |
| 113 | //@ !has "$.index[?(@.docs=='unstable trait impl')].stability.since" | |
| 114 | /// unstable trait impl | |
| 115 | #[unstable(feature = "unstable_trait_impl", issue = "none")] | |
| 116 | impl UnstableTraitForImpl for StableImplTarget { | |
| 117 | // These associated items inherit the impl block's instability in rustdoc JSON. | |
| 118 | ||
| 119 | //@ is "$.index[?(@.docs=='assoc type inside unstable trait impl')].stability.level" '"unstable"' | |
| 120 | //@ is "$.index[?(@.docs=='assoc type inside unstable trait impl')].stability.feature" '"unstable_trait_impl"' | |
| 121 | //@ !has "$.index[?(@.docs=='assoc type inside unstable trait impl')].stability.since" | |
| 122 | /// assoc type inside unstable trait impl | |
| 123 | type UnstableOutput = usize; | |
| 124 | ||
| 125 | //@ is "$.index[?(@.docs=='assoc const inside unstable trait impl')].stability.level" '"unstable"' | |
| 126 | //@ is "$.index[?(@.docs=='assoc const inside unstable trait impl')].stability.feature" '"unstable_trait_impl"' | |
| 127 | //@ !has "$.index[?(@.docs=='assoc const inside unstable trait impl')].stability.since" | |
| 128 | /// assoc const inside unstable trait impl | |
| 129 | const UNSTABLE_ASSOC_CONST: usize = 0; | |
| 130 | ||
| 131 | //@ is "$.index[?(@.docs=='method inside unstable trait impl')].stability.level" '"unstable"' | |
| 132 | //@ is "$.index[?(@.docs=='method inside unstable trait impl')].stability.feature" '"unstable_trait_impl"' | |
| 133 | //@ !has "$.index[?(@.docs=='method inside unstable trait impl')].stability.since" | |
| 134 | /// method inside unstable trait impl | |
| 135 | fn unstable_trait_method(&self) {} | |
| 136 | } |
tests/rustdoc-json/attrs/stability/item_kinds.rs created+46| ... | ... | @@ -0,0 +1,46 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | // Mirrors standard-library stability on item kinds that are distinct from ordinary functions, | |
| 4 | // modules, structs, enums, traits, and impls. | |
| 5 | ||
| 6 | //@ is "$.index[?(@.name=='STABLE_CONST')].stability.level" '"stable"' | |
| 7 | //@ is "$.index[?(@.name=='STABLE_CONST')].stability.feature" '"stable_const_feature"' | |
| 8 | //@ is "$.index[?(@.name=='STABLE_CONST')].stability.since" '"1.0.0"' | |
| 9 | #[stable(feature = "stable_const_feature", since = "1.0.0")] | |
| 10 | pub const STABLE_CONST: usize = 0; | |
| 11 | ||
| 12 | //@ is "$.index[?(@.name=='UNSTABLE_STATIC')].stability.level" '"unstable"' | |
| 13 | //@ is "$.index[?(@.name=='UNSTABLE_STATIC')].stability.feature" '"unstable_static_feature"' | |
| 14 | //@ !has "$.index[?(@.name=='UNSTABLE_STATIC')].stability.since" | |
| 15 | #[unstable(feature = "unstable_static_feature", issue = "none")] | |
| 16 | pub static UNSTABLE_STATIC: usize = 0; | |
| 17 | ||
| 18 | //@ is "$.index[?(@.name=='StableTypeAlias')].stability.level" '"stable"' | |
| 19 | //@ is "$.index[?(@.name=='StableTypeAlias')].stability.feature" '"stable_type_alias_feature"' | |
| 20 | //@ is "$.index[?(@.name=='StableTypeAlias')].stability.since" '"1.1.0"' | |
| 21 | #[stable(feature = "stable_type_alias_feature", since = "1.1.0")] | |
| 22 | pub type StableTypeAlias = usize; | |
| 23 | ||
| 24 | //@ is "$.index[?(@.name=='StableUnion')].stability.level" '"stable"' | |
| 25 | //@ is "$.index[?(@.name=='StableUnion')].stability.feature" '"stable_union_feature"' | |
| 26 | //@ is "$.index[?(@.name=='StableUnion')].stability.since" '"1.3.0"' | |
| 27 | #[stable(feature = "stable_union_feature", since = "1.3.0")] | |
| 28 | pub union StableUnion { | |
| 29 | storage: usize, | |
| 30 | } | |
| 31 | ||
| 32 | //@ is "$.index[?(@.inner.extern_crate.name=='stable_extern_crate_self')].stability.level" '"stable"' | |
| 33 | //@ is "$.index[?(@.inner.extern_crate.name=='stable_extern_crate_self')].stability.feature" '"stable_extern_crate_feature"' | |
| 34 | //@ is "$.index[?(@.inner.extern_crate.name=='stable_extern_crate_self')].stability.since" '"1.4.0"' | |
| 35 | #[stable(feature = "stable_extern_crate_feature", since = "1.4.0")] | |
| 36 | pub extern crate self as stable_extern_crate_self; | |
| 37 | ||
| 38 | //@ is "$.index[?(@.name=='unstable_macro_rules')].stability.level" '"unstable"' | |
| 39 | //@ is "$.index[?(@.name=='unstable_macro_rules')].stability.feature" '"unstable_macro_rules_feature"' | |
| 40 | //@ !has "$.index[?(@.name=='unstable_macro_rules')].stability.since" | |
| 41 | //@ is "$.index[?(@.name=='unstable_macro_rules')].attrs" '["macro_export"]' | |
| 42 | #[unstable(feature = "unstable_macro_rules_feature", issue = "none")] | |
| 43 | #[macro_export] | |
| 44 | macro_rules! unstable_macro_rules { | |
| 45 | () => {}; | |
| 46 | } |
tests/rustdoc-json/attrs/stability/members.rs created+72| ... | ... | @@ -0,0 +1,72 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | // Mirrors standard-library cases where stable parent items have unstable variants or fields. | |
| 4 | ||
| 5 | #[stable(feature = "stable_enum_feature", since = "1.0.0")] | |
| 6 | pub enum StableEnumWithUnstableVariant { | |
| 7 | StableVariant, | |
| 8 | ||
| 9 | //@ is "$.index[?(@.name=='UnstableVariant')].stability.level" '"unstable"' | |
| 10 | //@ is "$.index[?(@.name=='UnstableVariant')].stability.feature" '"unstable_variant_feature"' | |
| 11 | //@ !has "$.index[?(@.name=='UnstableVariant')].stability.since" | |
| 12 | #[unstable(feature = "unstable_variant_feature", issue = "none")] | |
| 13 | UnstableVariant, | |
| 14 | } | |
| 15 | ||
| 16 | #[stable(feature = "stable_struct_feature", since = "2.0.0")] | |
| 17 | pub struct StableStructWithUnstableField { | |
| 18 | pub stable_field: usize, | |
| 19 | ||
| 20 | //@ is "$.index[?(@.name=='unstable_field')].stability.level" '"unstable"' | |
| 21 | //@ is "$.index[?(@.name=='unstable_field')].stability.feature" '"unstable_field_feature"' | |
| 22 | //@ !has "$.index[?(@.name=='unstable_field')].stability.since" | |
| 23 | #[unstable(feature = "unstable_field_feature", issue = "none")] | |
| 24 | pub unstable_field: usize, | |
| 25 | } | |
| 26 | ||
| 27 | #[stable(feature = "stable_union_with_unstable_field", since = "2.5.0")] | |
| 28 | pub union StableUnionWithUnstableField { | |
| 29 | pub stable_union_field: usize, | |
| 30 | ||
| 31 | //@ is "$.index[?(@.name=='unstable_union_field')].stability.level" '"unstable"' | |
| 32 | //@ is "$.index[?(@.name=='unstable_union_field')].stability.feature" '"unstable_union_field_feature"' | |
| 33 | //@ !has "$.index[?(@.name=='unstable_union_field')].stability.since" | |
| 34 | #[unstable(feature = "unstable_union_field_feature", issue = "none")] | |
| 35 | pub unstable_union_field: usize, | |
| 36 | } | |
| 37 | ||
| 38 | #[stable(feature = "stable_tuple_struct_feature", since = "3.0.0")] | |
| 39 | pub struct StableTupleStructWithUnstableField( | |
| 40 | pub usize, | |
| 41 | //@ is "$.index[?(@.docs=='unstable tuple struct field')].stability.level" '"unstable"' | |
| 42 | //@ is "$.index[?(@.docs=='unstable tuple struct field')].stability.feature" '"unstable_tuple_struct_field_feature"' | |
| 43 | //@ !has "$.index[?(@.docs=='unstable tuple struct field')].stability.since" | |
| 44 | /// unstable tuple struct field | |
| 45 | #[unstable(feature = "unstable_tuple_struct_field_feature", issue = "none")] | |
| 46 | pub usize, | |
| 47 | ); | |
| 48 | ||
| 49 | #[stable(feature = "stable_enum_field_variants_feature", since = "4.0.0")] | |
| 50 | pub enum StableEnumWithFieldVariants { | |
| 51 | #[stable(feature = "stable_tuple_variant_feature", since = "4.1.0")] | |
| 52 | TupleVariant( | |
| 53 | usize, | |
| 54 | //@ is "$.index[?(@.docs=='unstable tuple variant field')].stability.level" '"unstable"' | |
| 55 | //@ is "$.index[?(@.docs=='unstable tuple variant field')].stability.feature" '"unstable_tuple_variant_field_feature"' | |
| 56 | //@ !has "$.index[?(@.docs=='unstable tuple variant field')].stability.since" | |
| 57 | /// unstable tuple variant field | |
| 58 | #[unstable(feature = "unstable_tuple_variant_field_feature", issue = "none")] | |
| 59 | usize, | |
| 60 | ), | |
| 61 | ||
| 62 | #[stable(feature = "stable_struct_variant_feature", since = "4.3.0")] | |
| 63 | StructVariant { | |
| 64 | stable_struct_variant_field: usize, | |
| 65 | ||
| 66 | //@ is "$.index[?(@.name=='unstable_struct_variant_field')].stability.level" '"unstable"' | |
| 67 | //@ is "$.index[?(@.name=='unstable_struct_variant_field')].stability.feature" '"unstable_struct_variant_field_feature"' | |
| 68 | //@ !has "$.index[?(@.name=='unstable_struct_variant_field')].stability.since" | |
| 69 | #[unstable(feature = "unstable_struct_variant_field_feature", issue = "none")] | |
| 70 | unstable_struct_variant_field: usize, | |
| 71 | }, | |
| 72 | } |
tests/rustdoc-json/attrs/stability/modules.rs created+49| ... | ... | @@ -0,0 +1,49 @@ |
| 1 | //! Module items, including the crate root and containing-module stability facts that consumers | |
| 2 | //! need when deciding whether a particular path is stable. | |
| 3 | ||
| 4 | #![feature(staged_api)] | |
| 5 | #![stable(feature = "stable_crate_feature", since = "1.0.0")] | |
| 6 | //@ is "$.index[?(@.name=='modules')].stability.level" '"stable"' | |
| 7 | //@ is "$.index[?(@.name=='modules')].stability.feature" '"stable_crate_feature"' | |
| 8 | //@ is "$.index[?(@.name=='modules')].stability.since" '"1.0.0"' | |
| 9 | ||
| 10 | pub mod inner_stable_module { | |
| 11 | #![stable(feature = "inner_stable_module_feature", since = "1.1.0")] | |
| 12 | ||
| 13 | //@ is "$.index[?(@.name=='inner_stable_module')].stability.level" '"stable"' | |
| 14 | //@ is "$.index[?(@.name=='inner_stable_module')].stability.feature" '"inner_stable_module_feature"' | |
| 15 | //@ is "$.index[?(@.name=='inner_stable_module')].stability.since" '"1.1.0"' | |
| 16 | } | |
| 17 | ||
| 18 | #[unstable(feature = "unstable_module_feature", issue = "none")] | |
| 19 | pub mod unstable_module { | |
| 20 | //@ is "$.index[?(@.name=='unstable_module')].stability.level" '"unstable"' | |
| 21 | //@ is "$.index[?(@.name=='unstable_module')].stability.feature" '"unstable_module_feature"' | |
| 22 | //@ !has "$.index[?(@.name=='unstable_module')].stability.since" | |
| 23 | } | |
| 24 | ||
| 25 | #[stable(feature = "stable_parent_feature", since = "2.0.0")] | |
| 26 | pub mod stable_parent { | |
| 27 | //@ is "$.index[?(@.name=='stable_parent')].stability.level" '"stable"' | |
| 28 | //@ is "$.index[?(@.name=='stable_parent')].stability.feature" '"stable_parent_feature"' | |
| 29 | //@ is "$.index[?(@.name=='stable_parent')].stability.since" '"2.0.0"' | |
| 30 | ||
| 31 | //@ is "$.index[?(@.name=='UnstableChildInStable')].stability.level" '"unstable"' | |
| 32 | //@ is "$.index[?(@.name=='UnstableChildInStable')].stability.feature" '"unstable_child_in_stable"' | |
| 33 | //@ !has "$.index[?(@.name=='UnstableChildInStable')].stability.since" | |
| 34 | #[unstable(feature = "unstable_child_in_stable", issue = "none")] | |
| 35 | pub struct UnstableChildInStable; | |
| 36 | } | |
| 37 | ||
| 38 | #[unstable(feature = "unstable_parent_feature", issue = "27")] | |
| 39 | pub mod unstable_parent { | |
| 40 | //@ is "$.index[?(@.name=='unstable_parent')].stability.level" '"unstable"' | |
| 41 | //@ is "$.index[?(@.name=='unstable_parent')].stability.feature" '"unstable_parent_feature"' | |
| 42 | //@ !has "$.index[?(@.name=='unstable_parent')].stability.since" | |
| 43 | ||
| 44 | //@ is "$.index[?(@.name=='StableChildInUnstable')].stability.level" '"stable"' | |
| 45 | //@ is "$.index[?(@.name=='StableChildInUnstable')].stability.feature" '"stable_child_in_unstable"' | |
| 46 | //@ is "$.index[?(@.name=='StableChildInUnstable')].stability.since" '"3.0.0"' | |
| 47 | #[stable(feature = "stable_child_in_unstable", since = "3.0.0")] | |
| 48 | pub struct StableChildInUnstable; | |
| 49 | } |
tests/rustdoc-json/attrs/stability/reexports.rs created+98| ... | ... | @@ -0,0 +1,98 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | // The stability of an item is a function of both the item and the path by which it is used. | |
| 4 | // It's possible for a stable item to be available under both a stable and an unstable path, | |
| 5 | // depending on re-exports and module stability. This file tests such edge cases. | |
| 6 | // | |
| 7 | // To determine if a path is stable, users of rustdoc JSON should walk all path components | |
| 8 | // (including `Use` items' `inner.use.id` value) and check for (in)stability. | |
| 9 | // The path is unstable if any traversed component (modules, re-exports, or the final item) | |
| 10 | // is marked unstable. | |
| 11 | ||
| 12 | #[unstable(feature = "unstable_source_mod", issue = "none")] | |
| 13 | pub mod unstable_source_mod { | |
| 14 | //@ set stable_in_unstable = "$.index[?(@.name=='StableInUnstable')].id" | |
| 15 | //@ is "$.index[?(@.name=='StableInUnstable')].stability.level" '"stable"' | |
| 16 | //@ is "$.index[?(@.name=='StableInUnstable')].stability.feature" '"stable_in_unstable"' | |
| 17 | //@ is "$.index[?(@.name=='StableInUnstable')].stability.since" '"1.0.0"' | |
| 18 | #[stable(feature = "stable_in_unstable", since = "1.0.0")] | |
| 19 | pub struct StableInUnstable; | |
| 20 | ||
| 21 | //@ set second_stable_in_unstable = "$.index[?(@.name=='SecondStableInUnstable')].id" | |
| 22 | #[stable(feature = "second_stable_in_unstable", since = "1.1.0")] | |
| 23 | pub struct SecondStableInUnstable; | |
| 24 | ||
| 25 | #[stable(feature = "glob_stable_in_unstable", since = "1.2.0")] | |
| 26 | pub struct GlobStableInUnstable; | |
| 27 | } | |
| 28 | ||
| 29 | //@ is "$.index[?(@.inner.use.name=='ReexportedStableInUnstable')].inner.use.id" $stable_in_unstable | |
| 30 | //@ is "$.index[?(@.inner.use.name=='ReexportedStableInUnstable')].stability.level" '"stable"' | |
| 31 | //@ is "$.index[?(@.inner.use.name=='ReexportedStableInUnstable')].stability.feature" '"stable_reexport"' | |
| 32 | //@ is "$.index[?(@.inner.use.name=='ReexportedStableInUnstable')].stability.since" '"3.0.0"' | |
| 33 | //@ is "$.index[?(@.inner.use.name=='ReexportedStableInUnstable')].attrs" [] | |
| 34 | #[stable(feature = "stable_reexport", since = "3.0.0")] | |
| 35 | pub use crate::unstable_source_mod::StableInUnstable as ReexportedStableInUnstable; | |
| 36 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_source_mod')].inner.use.is_glob" true | |
| 37 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_source_mod')].stability.level" '"stable"' | |
| 38 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_source_mod')].stability.feature" '"stable_glob_reexport"' | |
| 39 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_source_mod')].stability.since" '"4.0.0"' | |
| 40 | #[stable(feature = "stable_glob_reexport", since = "4.0.0")] | |
| 41 | pub use crate::unstable_source_mod::*; | |
| 42 | //@ is "$.index[?(@.inner.use.name=='GroupedStableReexport')].inner.use.id" $stable_in_unstable | |
| 43 | //@ is "$.index[?(@.inner.use.name=='GroupedStableReexport')].stability.level" '"stable"' | |
| 44 | //@ is "$.index[?(@.inner.use.name=='GroupedStableReexport')].stability.feature" '"stable_grouped_reexport"' | |
| 45 | //@ is "$.index[?(@.inner.use.name=='GroupedStableReexport')].stability.since" '"3.5.0"' | |
| 46 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedStableReexport')].inner.use.id" $second_stable_in_unstable | |
| 47 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedStableReexport')].stability.level" '"stable"' | |
| 48 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedStableReexport')].stability.feature" '"stable_grouped_reexport"' | |
| 49 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedStableReexport')].stability.since" '"3.5.0"' | |
| 50 | #[stable(feature = "stable_grouped_reexport", since = "3.5.0")] | |
| 51 | pub use crate::unstable_source_mod::{ | |
| 52 | SecondStableInUnstable as SecondGroupedStableReexport, | |
| 53 | StableInUnstable as GroupedStableReexport, | |
| 54 | }; | |
| 55 | ||
| 56 | #[unstable(feature = "unstable_reexport_source_mod", issue = "none")] | |
| 57 | pub mod unstable_reexport_source_mod { | |
| 58 | //@ set stable_for_unstable_reexport = "$.index[?(@.name=='StableForUnstableReexport')].id" | |
| 59 | #[stable(feature = "stable_for_unstable_reexport", since = "6.0.0")] | |
| 60 | pub struct StableForUnstableReexport; | |
| 61 | ||
| 62 | //@ set grouped_stable_for_unstable_reexport = "$.index[?(@.name=='GroupedStableForUnstableReexport')].id" | |
| 63 | #[stable(feature = "grouped_stable_for_unstable_reexport", since = "6.1.0")] | |
| 64 | pub struct GroupedStableForUnstableReexport; | |
| 65 | ||
| 66 | //@ set second_grouped_stable_for_unstable_reexport = "$.index[?(@.name=='SecondGroupedStableForUnstableReexport')].id" | |
| 67 | #[stable(feature = "second_grouped_stable_for_unstable_reexport", since = "6.2.0")] | |
| 68 | pub struct SecondGroupedStableForUnstableReexport; | |
| 69 | ||
| 70 | #[stable(feature = "glob_stable_for_unstable_reexport", since = "6.3.0")] | |
| 71 | pub struct GlobStableForUnstableReexport; | |
| 72 | } | |
| 73 | ||
| 74 | //@ is "$.index[?(@.inner.use.name=='UnstableReexportedStable')].inner.use.id" $stable_for_unstable_reexport | |
| 75 | //@ is "$.index[?(@.inner.use.name=='UnstableReexportedStable')].stability.level" '"unstable"' | |
| 76 | //@ is "$.index[?(@.inner.use.name=='UnstableReexportedStable')].stability.feature" '"unstable_reexport"' | |
| 77 | //@ !has "$.index[?(@.inner.use.name=='UnstableReexportedStable')].stability.since" | |
| 78 | #[unstable(feature = "unstable_reexport", issue = "none")] | |
| 79 | pub use crate::unstable_reexport_source_mod::StableForUnstableReexport as UnstableReexportedStable; | |
| 80 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_reexport_source_mod')].inner.use.is_glob" true | |
| 81 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_reexport_source_mod')].stability.level" '"unstable"' | |
| 82 | //@ is "$.index[?(@.inner.use.source=='crate::unstable_reexport_source_mod')].stability.feature" '"unstable_glob_reexport"' | |
| 83 | //@ !has "$.index[?(@.inner.use.source=='crate::unstable_reexport_source_mod')].stability.since" | |
| 84 | #[unstable(feature = "unstable_glob_reexport", issue = "none")] | |
| 85 | pub use crate::unstable_reexport_source_mod::*; | |
| 86 | //@ is "$.index[?(@.inner.use.name=='GroupedUnstableReexport')].inner.use.id" $grouped_stable_for_unstable_reexport | |
| 87 | //@ is "$.index[?(@.inner.use.name=='GroupedUnstableReexport')].stability.level" '"unstable"' | |
| 88 | //@ is "$.index[?(@.inner.use.name=='GroupedUnstableReexport')].stability.feature" '"unstable_grouped_reexport"' | |
| 89 | //@ !has "$.index[?(@.inner.use.name=='GroupedUnstableReexport')].stability.since" | |
| 90 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedUnstableReexport')].inner.use.id" $second_grouped_stable_for_unstable_reexport | |
| 91 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedUnstableReexport')].stability.level" '"unstable"' | |
| 92 | //@ is "$.index[?(@.inner.use.name=='SecondGroupedUnstableReexport')].stability.feature" '"unstable_grouped_reexport"' | |
| 93 | //@ !has "$.index[?(@.inner.use.name=='SecondGroupedUnstableReexport')].stability.since" | |
| 94 | #[unstable(feature = "unstable_grouped_reexport", issue = "none")] | |
| 95 | pub use crate::unstable_reexport_source_mod::{ | |
| 96 | GroupedStableForUnstableReexport as GroupedUnstableReexport, | |
| 97 | SecondGroupedStableForUnstableReexport as SecondGroupedUnstableReexport, | |
| 98 | }; |
tests/rustdoc-json/attrs/stability/stable.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | //@ is "$.index[?(@.name=='foo')].stability.level" '"stable"' | |
| 4 | //@ is "$.index[?(@.name=='foo')].stability.feature" '"eeeee"' | |
| 5 | //@ is "$.index[?(@.name=='foo')].stability.since" '"2.71.8"' | |
| 6 | //@ is "$.index[?(@.name=='foo')].attrs" [] | |
| 7 | #[stable(since = "2.71.8", feature = "eeeee")] | |
| 8 | pub fn foo() {} |
tests/rustdoc-json/attrs/stability/unmarked.rs created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | //@ is "$.index[?(@.name=='foo')].stability" null | |
| 2 | //@ is "$.index[?(@.name=='foo')].attrs" [] | |
| 3 | pub fn foo() {} |
tests/rustdoc-json/attrs/stability/unstable.rs created+8| ... | ... | @@ -0,0 +1,8 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | ||
| 3 | //@ is "$.index[?(@.name=='foo')].stability.level" '"unstable"' | |
| 4 | //@ is "$.index[?(@.name=='foo')].stability.feature" '"delights"' | |
| 5 | //@ !has "$.index[?(@.name=='foo')].stability.since" | |
| 6 | //@ is "$.index[?(@.name=='foo')].attrs" [] | |
| 7 | #[unstable(feature = "delights", issue = "26")] | |
| 8 | pub fn foo() {} |
tests/rustdoc-json/attrs/stability/unstable_crate.rs created+6| ... | ... | @@ -0,0 +1,6 @@ |
| 1 | #![feature(staged_api)] | |
| 2 | #![unstable(feature = "unstable_crate_feature", issue = "none")] | |
| 3 | ||
| 4 | //@ is "$.index[?(@.name=='unstable_crate')].stability.level" '"unstable"' | |
| 5 | //@ is "$.index[?(@.name=='unstable_crate')].stability.feature" '"unstable_crate_feature"' | |
| 6 | //@ !has "$.index[?(@.name=='unstable_crate')].stability.since" |
tests/rustdoc-ui/type-const-associated-const-no-body.rs deleted-16| ... | ... | @@ -1,16 +0,0 @@ |
| 1 | //! Regression test for <https://github.com/rust-lang/rust/issues/149287> | |
| 2 | //! Ensure that rustdoc does not ICE when a body-less type const is used | |
| 3 | //! as an associated const. | |
| 4 | //@ check-pass | |
| 5 | ||
| 6 | #![feature(min_generic_const_args)] | |
| 7 | ||
| 8 | pub trait Tr { | |
| 9 | type const SIZE: usize; | |
| 10 | } | |
| 11 | ||
| 12 | fn mk_array<T: Tr>() -> [(); <T as Tr>::SIZE] { | |
| 13 | [(); T::SIZE] | |
| 14 | } | |
| 15 | ||
| 16 | fn main() {} |
tests/ui/asm/s390x/bad-reg.rs+7-7| ... | ... | @@ -68,13 +68,13 @@ fn f() { |
| 68 | 68 | |
| 69 | 69 | // vreg |
| 70 | 70 | asm!("", out("v0") _); // always ok |
| 71 | asm!("", in("v0") v); // requires vector & asm_experimental_reg | |
| 71 | asm!("", in("v0") v); | |
| 72 | 72 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 73 | asm!("", out("v0") v); // requires vector & asm_experimental_reg | |
| 73 | asm!("", out("v0") v); | |
| 74 | 74 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 75 | asm!("", in("v0") x); // requires vector & asm_experimental_reg | |
| 75 | asm!("", in("v0") x); | |
| 76 | 76 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 77 | asm!("", out("v0") x); // requires vector & asm_experimental_reg | |
| 77 | asm!("", out("v0") x); | |
| 78 | 78 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 79 | 79 | asm!("", in("v0") b); |
| 80 | 80 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| ... | ... | @@ -82,14 +82,14 @@ fn f() { |
| 82 | 82 | asm!("", out("v0") b); |
| 83 | 83 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 84 | 84 | //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class |
| 85 | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | |
| 85 | asm!("/* {} */", in(vreg) v); | |
| 86 | 86 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 87 | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | |
| 87 | asm!("/* {} */", in(vreg) x); | |
| 88 | 88 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 89 | 89 | asm!("/* {} */", in(vreg) b); |
| 90 | 90 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 91 | 91 | //[s390x_vector]~^^ ERROR type `u8` cannot be used with this register class |
| 92 | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | |
| 92 | asm!("/* {} */", out(vreg) _); | |
| 93 | 93 | //[s390x]~^ ERROR register class `vreg` requires the `vector` target feature |
| 94 | 94 | |
| 95 | 95 | // Clobber-only registers |
tests/ui/asm/s390x/bad-reg.s390x.stderr+7-7| ... | ... | @@ -279,25 +279,25 @@ LL | asm!("", out("v16") _, out("f16") _); |
| 279 | 279 | error: register class `vreg` requires the `vector` target feature |
| 280 | 280 | --> $DIR/bad-reg.rs:71:18 |
| 281 | 281 | | |
| 282 | LL | asm!("", in("v0") v); // requires vector & asm_experimental_reg | |
| 282 | LL | asm!("", in("v0") v); | |
| 283 | 283 | | ^^^^^^^^^^ |
| 284 | 284 | |
| 285 | 285 | error: register class `vreg` requires the `vector` target feature |
| 286 | 286 | --> $DIR/bad-reg.rs:73:18 |
| 287 | 287 | | |
| 288 | LL | asm!("", out("v0") v); // requires vector & asm_experimental_reg | |
| 288 | LL | asm!("", out("v0") v); | |
| 289 | 289 | | ^^^^^^^^^^^ |
| 290 | 290 | |
| 291 | 291 | error: register class `vreg` requires the `vector` target feature |
| 292 | 292 | --> $DIR/bad-reg.rs:75:18 |
| 293 | 293 | | |
| 294 | LL | asm!("", in("v0") x); // requires vector & asm_experimental_reg | |
| 294 | LL | asm!("", in("v0") x); | |
| 295 | 295 | | ^^^^^^^^^^ |
| 296 | 296 | |
| 297 | 297 | error: register class `vreg` requires the `vector` target feature |
| 298 | 298 | --> $DIR/bad-reg.rs:77:18 |
| 299 | 299 | | |
| 300 | LL | asm!("", out("v0") x); // requires vector & asm_experimental_reg | |
| 300 | LL | asm!("", out("v0") x); | |
| 301 | 301 | | ^^^^^^^^^^^ |
| 302 | 302 | |
| 303 | 303 | error: register class `vreg` requires the `vector` target feature |
| ... | ... | @@ -315,13 +315,13 @@ LL | asm!("", out("v0") b); |
| 315 | 315 | error: register class `vreg` requires the `vector` target feature |
| 316 | 316 | --> $DIR/bad-reg.rs:85:26 |
| 317 | 317 | | |
| 318 | LL | asm!("/* {} */", in(vreg) v); // requires vector & asm_experimental_reg | |
| 318 | LL | asm!("/* {} */", in(vreg) v); | |
| 319 | 319 | | ^^^^^^^^^^ |
| 320 | 320 | |
| 321 | 321 | error: register class `vreg` requires the `vector` target feature |
| 322 | 322 | --> $DIR/bad-reg.rs:87:26 |
| 323 | 323 | | |
| 324 | LL | asm!("/* {} */", in(vreg) x); // requires vector & asm_experimental_reg | |
| 324 | LL | asm!("/* {} */", in(vreg) x); | |
| 325 | 325 | | ^^^^^^^^^^ |
| 326 | 326 | |
| 327 | 327 | error: register class `vreg` requires the `vector` target feature |
| ... | ... | @@ -333,7 +333,7 @@ LL | asm!("/* {} */", in(vreg) b); |
| 333 | 333 | error: register class `vreg` requires the `vector` target feature |
| 334 | 334 | --> $DIR/bad-reg.rs:92:26 |
| 335 | 335 | | |
| 336 | LL | asm!("/* {} */", out(vreg) _); // requires vector & asm_experimental_reg | |
| 336 | LL | asm!("/* {} */", out(vreg) _); | |
| 337 | 337 | | ^^^^^^^^^^^ |
| 338 | 338 | |
| 339 | 339 | error: type `i32` cannot be used with this register class |
tests/ui/const-generics/unused-type-param-suggestion.rs+1-2| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | #![crate_type="lib"] | |
| 1 | #![crate_type = "lib"] | |
| 2 | 2 | |
| 3 | 3 | struct S<N>; |
| 4 | 4 | //~^ ERROR type parameter `N` is never used |
| ... | ... | @@ -25,4 +25,3 @@ type C<N: Sized> = (); |
| 25 | 25 | type D<N: ?Sized> = (); |
| 26 | 26 | //~^ ERROR type parameter `N` is never used |
| 27 | 27 | //~| HELP consider removing `N` |
| 28 | //~| HELP if you intended `N` to be a const parameter |
tests/ui/const-generics/unused-type-param-suggestion.stderr-1| ... | ... | @@ -47,7 +47,6 @@ LL | type D<N: ?Sized> = (); |
| 47 | 47 | | ^ unused type parameter |
| 48 | 48 | | |
| 49 | 49 | = help: consider removing `N` or referring to it in the body of the type alias |
| 50 | = help: if you intended `N` to be a const parameter, use `const N: /* Type */` instead | |
| 51 | 50 | |
| 52 | 51 | error: aborting due to 6 previous errors |
| 53 | 52 |
tests/ui/extern/extern-types-unsized.stderr+4-4| ... | ... | @@ -67,10 +67,10 @@ LL | assert_sized::<Bar<A>>(); |
| 67 | 67 | | |
| 68 | 68 | = help: the nightly-only, unstable trait `MetaSized` is not implemented for `A` |
| 69 | 69 | note: required by a bound in `Bar` |
| 70 | --> $DIR/extern-types-unsized.rs:14:12 | |
| 70 | --> $DIR/extern-types-unsized.rs:14:15 | |
| 71 | 71 | | |
| 72 | 72 | LL | struct Bar<T: ?Sized> { |
| 73 | | ^ required by this bound in `Bar` | |
| 73 | | ^^^^^^ required by this bound in `Bar` | |
| 74 | 74 | |
| 75 | 75 | error[E0277]: the size for values of type `A` cannot be known at compilation time |
| 76 | 76 | --> $DIR/extern-types-unsized.rs:32:20 |
| ... | ... | @@ -102,10 +102,10 @@ LL | assert_sized::<Bar<Bar<A>>>(); |
| 102 | 102 | | |
| 103 | 103 | = help: the nightly-only, unstable trait `MetaSized` is not implemented for `A` |
| 104 | 104 | note: required by a bound in `Bar` |
| 105 | --> $DIR/extern-types-unsized.rs:14:12 | |
| 105 | --> $DIR/extern-types-unsized.rs:14:15 | |
| 106 | 106 | | |
| 107 | 107 | LL | struct Bar<T: ?Sized> { |
| 108 | | ^ required by this bound in `Bar` | |
| 108 | | ^^^^^^ required by this bound in `Bar` | |
| 109 | 109 | |
| 110 | 110 | error: aborting due to 6 previous errors |
| 111 | 111 |
tests/ui/parser/recover/raw-no-const-mut-trailing-comma.rs created+7| ... | ... | @@ -0,0 +1,7 @@ |
| 1 | // Regression test for https://github.com/rust-lang/rust/issues/157950. | |
| 2 | ||
| 3 | fn main() { | |
| 4 | takes_raw_ptr_args(&raw x,) | |
| 5 | //~^ ERROR expected one of | |
| 6 | //~| ERROR cannot find function `takes_raw_ptr_args` in this scope | |
| 7 | } |
tests/ui/parser/recover/raw-no-const-mut-trailing-comma.stderr created+22| ... | ... | @@ -0,0 +1,22 @@ |
| 1 | error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `const`, `mut`, `{`, or an operator, found `x` | |
| 2 | --> $DIR/raw-no-const-mut-trailing-comma.rs:4:29 | |
| 3 | | | |
| 4 | LL | takes_raw_ptr_args(&raw x,) | |
| 5 | | ^ expected one of 10 possible tokens | |
| 6 | | | |
| 7 | help: `&raw` must be followed by `const` or `mut` to be a raw reference expression | |
| 8 | | | |
| 9 | LL | takes_raw_ptr_args(&raw const x,) | |
| 10 | | +++++ | |
| 11 | LL | takes_raw_ptr_args(&raw mut x,) | |
| 12 | | +++ | |
| 13 | ||
| 14 | error[E0425]: cannot find function `takes_raw_ptr_args` in this scope | |
| 15 | --> $DIR/raw-no-const-mut-trailing-comma.rs:4:5 | |
| 16 | | | |
| 17 | LL | takes_raw_ptr_args(&raw x,) | |
| 18 | | ^^^^^^^^^^^^^^^^^^ not found in this scope | |
| 19 | ||
| 20 | error: aborting due to 2 previous errors | |
| 21 | ||
| 22 | For more information about this error, try `rustc --explain E0425`. |
tests/ui/sized-hierarchy/overflow.current.stderr+3-3| ... | ... | @@ -8,9 +8,9 @@ note: required for `Box<Element>` to implement `ParseTokens` |
| 8 | 8 | --> $DIR/overflow.rs:13:31 |
| 9 | 9 | | |
| 10 | 10 | LL | impl<T: ParseTokens + ?Sized> ParseTokens for Box<T> { |
| 11 | | - ^^^^^^^^^^^ ^^^^^^ | |
| 12 | | | | |
| 13 | | unsatisfied trait bound introduced here | |
| 11 | | ------ ^^^^^^^^^^^ ^^^^^^ | |
| 12 | | | | |
| 13 | | unsatisfied trait bound introduced here | |
| 14 | 14 | = note: 1 redundant requirement hidden |
| 15 | 15 | = note: required for `Box<Box<Element>>` to implement `ParseTokens` |
| 16 | 16 |
triagebot.toml+2-2| ... | ... | @@ -1270,7 +1270,7 @@ message = "`src/tools/x` was changed. Bump version of Cargo.toml in `src/tools/x |
| 1270 | 1270 | |
| 1271 | 1271 | [mentions."src/tools/tidy/src/deps.rs"] |
| 1272 | 1272 | message = "The list of allowed third-party dependencies may have been modified! You must ensure that any new dependencies have compatible licenses before merging." |
| 1273 | cc = ["@davidtwco", "@wesleywiser"] | |
| 1273 | cc = ["@davidtwco", "@boxyuwu"] | |
| 1274 | 1274 | |
| 1275 | 1275 | [mentions."src/tools/tidy/src/extra_checks"] |
| 1276 | 1276 | message = "`tidy` extra checks were modified." |
| ... | ... | @@ -1517,7 +1517,7 @@ branch = "stable" |
| 1517 | 1517 | [assign.adhoc_groups] |
| 1518 | 1518 | compiler_leads = [ |
| 1519 | 1519 | "@davidtwco", |
| 1520 | "@wesleywiser", | |
| 1520 | "@boxyuwu", | |
| 1521 | 1521 | ] |
| 1522 | 1522 | libs = [ |
| 1523 | 1523 | "@Mark-Simulacrum", |