diff options
372 files changed, 4945 insertions, 3120 deletions
diff --git a/Cargo.lock b/Cargo.lock index 856d293d610..65189571432 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1925,7 +1925,7 @@ version = "0.1.0" dependencies = [ "fs-err", "getopts", - "jsonpath_lib", + "jsonpath-rust", "regex", "serde_json", "shlex", @@ -1945,14 +1945,16 @@ dependencies = [ ] [[package]] -name = "jsonpath_lib" -version = "0.3.0" +name = "jsonpath-rust" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaa63191d68230cccb81c5aa23abd53ed64d83337cacbb25a7b8c7979523774f" +checksum = "9b0231bb404a6cd6c8f0ab41b907049063a089fc02aa7636cc5cd9a4d87364c9" dependencies = [ - "log", - "serde", + "pest", + "pest_derive", + "regex", "serde_json", + "thiserror 2.0.11", ] [[package]] @@ -2646,6 +2648,51 @@ dependencies = [ ] [[package]] +name = "pest" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +dependencies = [ + "memchr", + "thiserror 2.0.11", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "pest_meta" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] name = "phf" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4259,6 +4306,7 @@ dependencies = [ name = "rustc_query_system" version = "0.0.0" dependencies = [ + "hashbrown 0.15.2", "parking_lot", "rustc-rayon-core", "rustc_abi", @@ -4780,7 +4828,6 @@ version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ - "indexmap", "itoa", "memchr", "ryu", @@ -5487,6 +5534,12 @@ dependencies = [ ] [[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] name = "ui_test" version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/RELEASES.md b/RELEASES.md index 381b9ebc952..755e73a34c6 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,14 @@ +Version 1.85.1 (2025-03-18) +========================== + +<a id="1.85.1"></a> + +- [Fix the doctest-merging feature of the 2024 Edition.](https://github.com/rust-lang/rust/pull/137899/) +- [Relax some `target_feature` checks when generating docs.](https://github.com/rust-lang/rust/pull/137632/) +- [Fix errors in `std::fs::rename` on Windows 10, version 1607.](https://github.com/rust-lang/rust/pull/137528/) +- [Downgrade bootstrap `cc` to fix custom targets.](https://github.com/rust-lang/rust/pull/137460/) +- [Skip submodule updates when building Rust from a source tarball.](https://github.com/rust-lang/rust/pull/137338/) + Version 1.85.0 (2025-02-20) ========================== diff --git a/bootstrap.example.toml b/bootstrap.example.toml index 294d9780716..caffe1a9371 100644 --- a/bootstrap.example.toml +++ b/bootstrap.example.toml @@ -1,7 +1,7 @@ # Sample TOML configuration file for building Rust. # # To configure bootstrap, run `./configure` or `./x.py setup`. -# See https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#create-a-configtoml for more information. +# See https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#create-a-bootstraptoml for more information. # # All options are commented out by default in this file, and they're commented # out with their default values. The build system by default looks for @@ -446,7 +446,7 @@ # a specific version. #ccache = false -# List of paths to exclude from the build and test processes. +# List of paths to exclude from the build and test processes. # For example, exclude = ["tests/ui", "src/tools/tidy"]. #exclude = [] diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 7f3d060bb8a..52291fdfb30 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -2150,11 +2150,6 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr_uint(sp, ast::UintTy::U16, value as u128) } - pub(super) fn expr_char(&mut self, sp: Span, value: char) -> hir::Expr<'hir> { - let lit = self.arena.alloc(hir::Lit { span: sp, node: ast::LitKind::Char(value) }); - self.expr(sp, hir::ExprKind::Lit(lit)) - } - pub(super) fn expr_str(&mut self, sp: Span, value: Symbol) -> hir::Expr<'hir> { let lit = self .arena diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index faa47274f96..343895984ca 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -361,24 +361,26 @@ fn make_format_spec<'hir>( zero_pad, debug_hex, } = &placeholder.format_options; - let fill = ctx.expr_char(sp, fill.unwrap_or(' ')); - let align = ctx.expr_lang_item_type_relative( - sp, - hir::LangItem::FormatAlignment, - match alignment { - Some(FormatAlignment::Left) => sym::Left, - Some(FormatAlignment::Right) => sym::Right, - Some(FormatAlignment::Center) => sym::Center, - None => sym::Unknown, - }, - ); - // This needs to match `Flag` in library/core/src/fmt/rt.rs. - let flags: u32 = ((sign == Some(FormatSign::Plus)) as u32) - | ((sign == Some(FormatSign::Minus)) as u32) << 1 - | (alternate as u32) << 2 - | (zero_pad as u32) << 3 - | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 4 - | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 5; + let fill = fill.unwrap_or(' '); + // These need to match the constants in library/core/src/fmt/rt.rs. + let align = match alignment { + Some(FormatAlignment::Left) => 0, + Some(FormatAlignment::Right) => 1, + Some(FormatAlignment::Center) => 2, + None => 3, + }; + // This needs to match the constants in library/core/src/fmt/rt.rs. + let flags: u32 = fill as u32 + | ((sign == Some(FormatSign::Plus)) as u32) << 21 + | ((sign == Some(FormatSign::Minus)) as u32) << 22 + | (alternate as u32) << 23 + | (zero_pad as u32) << 24 + | ((debug_hex == Some(FormatDebugHex::Lower)) as u32) << 25 + | ((debug_hex == Some(FormatDebugHex::Upper)) as u32) << 26 + | (width.is_some() as u32) << 27 + | (precision.is_some() as u32) << 28 + | align << 29 + | 1 << 31; // Highest bit always set. let flags = ctx.expr_u32(sp, flags); let precision = make_count(ctx, sp, precision, argmap); let width = make_count(ctx, sp, width, argmap); @@ -387,7 +389,7 @@ fn make_format_spec<'hir>( hir::LangItem::FormatPlaceholder, sym::new, )); - let args = ctx.arena.alloc_from_iter([position, fill, align, flags, precision, width]); + let args = ctx.arena.alloc_from_iter([position, flags, precision, width]); ctx.expr_call_mut(sp, format_placeholder_new, args) } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index bd011d59aaa..518349343b3 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1724,8 +1724,8 @@ impl<'hir> LoweringContext<'_, 'hir> { return; }; let define_opaque = define_opaque.iter().filter_map(|(id, path)| { - let res = self.resolver.get_partial_res(*id).unwrap(); - let Some(did) = res.expect_full_res().opt_def_id() else { + let res = self.resolver.get_partial_res(*id); + let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) else { self.dcx().span_delayed_bug(path.span, "should have errored in resolve"); return None; }; diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ed95545dea4..84b7b8c6a2d 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -73,6 +73,7 @@ mod def_use; mod diagnostics; mod member_constraints; mod nll; +mod opaque_types; mod path_utils; mod place_ext; mod places_conflict; @@ -192,7 +193,7 @@ fn do_mir_borrowck<'tcx>( // Compute non-lexical lifetimes. let nll::NllOutput { regioncx, - opaque_type_values, + concrete_opaque_types, polonius_input, polonius_output, opt_closure_req, @@ -222,7 +223,7 @@ fn do_mir_borrowck<'tcx>( body, ®ioncx, &opt_closure_req, - &opaque_type_values, + &concrete_opaque_types, diags_buffer, ); @@ -357,7 +358,7 @@ fn do_mir_borrowck<'tcx>( let tainted_by_errors = mbcx.emit_errors(); let result = BorrowCheckResult { - concrete_opaque_types: opaque_type_values, + concrete_opaque_types: concrete_opaque_types.into_inner(), closure_requirements: opt_closure_req, used_mut_upvars: mbcx.used_mut_upvars, tainted_by_errors, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 2031579dfd5..d0bd364425a 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -6,8 +6,6 @@ use std::str::FromStr; use std::{env, io}; use polonius_engine::{Algorithm, Output}; -use rustc_data_structures::fx::FxIndexMap; -use rustc_hir::def_id::LocalDefId; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::{PrettyPrintMirOptions, dump_mir_with_options}; use rustc_middle::mir::{ @@ -15,7 +13,7 @@ use rustc_middle::mir::{ dump_enabled, dump_mir, }; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, OpaqueHiddenType, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use rustc_mir_dataflow::ResultsCursor; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::MoveData; @@ -27,6 +25,7 @@ use tracing::{debug, instrument}; use crate::borrow_set::BorrowSet; use crate::consumers::ConsumerOptions; use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors}; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::polonius::PoloniusDiagnosticsContext; use crate::polonius::legacy::{ PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput, @@ -40,7 +39,7 @@ use crate::{BorrowckInferCtxt, polonius, renumber}; /// closure requirements to propagate, and any generated errors. pub(crate) struct NllOutput<'tcx> { pub regioncx: RegionInferenceContext<'tcx>, - pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, + pub concrete_opaque_types: ConcreteOpaqueTypes<'tcx>, pub polonius_input: Option<Box<PoloniusFacts>>, pub polonius_output: Option<Box<PoloniusOutput>>, pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>, @@ -99,6 +98,8 @@ pub(crate) fn compute_regions<'a, 'tcx>( let location_map = Rc::new(DenseLocationMap::new(body)); + let mut concrete_opaque_types = ConcreteOpaqueTypes::default(); + // Run the MIR type-checker. let MirTypeckResults { constraints, @@ -116,6 +117,7 @@ pub(crate) fn compute_regions<'a, 'tcx>( flow_inits, move_data, Rc::clone(&location_map), + &mut concrete_opaque_types, ); // Create the region inference context, taking ownership of the @@ -180,11 +182,11 @@ pub(crate) fn compute_regions<'a, 'tcx>( infcx.set_tainted_by_errors(guar); } - let remapped_opaque_tys = regioncx.infer_opaque_types(infcx, opaque_type_values); + regioncx.infer_opaque_types(infcx, opaque_type_values, &mut concrete_opaque_types); NllOutput { regioncx, - opaque_type_values: remapped_opaque_tys, + concrete_opaque_types, polonius_input: polonius_facts.map(Box::new), polonius_output, opt_closure_req: closure_region_requirements, @@ -300,7 +302,7 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>, - opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, + concrete_opaque_types: &ConcreteOpaqueTypes<'tcx>, diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>, ) { let tcx = infcx.tcx; @@ -343,8 +345,8 @@ pub(super) fn dump_annotation<'tcx, 'infcx>( err }; - if !opaque_type_values.is_empty() { - err.note(format!("Inferred opaque type values:\n{opaque_type_values:#?}")); + if !concrete_opaque_types.is_empty() { + err.note(format!("Inferred opaque type values:\n{concrete_opaque_types:#?}")); } diagnostics_buffer.buffer_non_error(err); diff --git a/compiler/rustc_borrowck/src/opaque_types.rs b/compiler/rustc_borrowck/src/opaque_types.rs new file mode 100644 index 00000000000..5c78814abdd --- /dev/null +++ b/compiler/rustc_borrowck/src/opaque_types.rs @@ -0,0 +1,55 @@ +use rustc_data_structures::fx::FxIndexMap; +use rustc_hir::def_id::LocalDefId; +use rustc_middle::ty::{OpaqueHiddenType, Ty, TyCtxt}; + +#[derive(Debug, Default)] +pub(super) struct ConcreteOpaqueTypes<'tcx> { + concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, +} + +impl<'tcx> ConcreteOpaqueTypes<'tcx> { + pub(super) fn is_empty(&self) -> bool { + self.concrete_opaque_types.is_empty() + } + + pub(super) fn into_inner(self) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> { + self.concrete_opaque_types + } + + /// Insert an opaque type into the list of opaque types defined by this function + /// after mapping the hidden type to the generic parameters of the opaque type + /// definition. + pub(super) fn insert( + &mut self, + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, + hidden_ty: OpaqueHiddenType<'tcx>, + ) { + // Sometimes two opaque types are the same only after we remap the generic parameters + // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to + // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we + // only know that once we convert the generic parameters to those of the opaque type. + if let Some(prev) = self.concrete_opaque_types.get_mut(&def_id) { + if prev.ty != hidden_ty.ty { + let (Ok(guar) | Err(guar)) = + prev.build_mismatch_error(&hidden_ty, tcx).map(|d| d.emit()); + prev.ty = Ty::new_error(tcx, guar); + } + // Pick a better span if there is one. + // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. + prev.span = prev.span.substitute_dummy(hidden_ty.span); + } else { + self.concrete_opaque_types.insert(def_id, hidden_ty); + } + } + + pub(super) fn extend_from_nested_body( + &mut self, + tcx: TyCtxt<'tcx>, + nested_body: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>, + ) { + for (&def_id, &hidden_ty) in nested_body { + self.insert(tcx, def_id, hidden_ty); + } + } +} diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 04839448596..ca8b9fb4e9d 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -15,6 +15,7 @@ use rustc_trait_selection::traits::ObligationCtxt; use tracing::{debug, instrument}; use super::RegionInferenceContext; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::session_diagnostics::{LifetimeMismatchOpaqueParam, NonGenericOpaqueTypeParam}; use crate::universal_regions::RegionClassification; @@ -67,8 +68,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, infcx: &InferCtxt<'tcx>, opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>, - ) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> { - let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default(); + concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, + ) { let mut decls_modulo_regions: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueTypeKey<'tcx>, Span)> = FxIndexMap::default(); @@ -143,33 +144,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { continue; } } - // Sometimes two opaque types are the same only after we remap the generic parameters - // back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to - // `(X, Y)` and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we - // only know that once we convert the generic parameters to those of the opaque type. - if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { - if prev.ty != ty { - let guar = ty.error_reported().err().unwrap_or_else(|| { - let (Ok(e) | Err(e)) = prev - .build_mismatch_error( - &OpaqueHiddenType { ty, span: concrete_type.span }, - infcx.tcx, - ) - .map(|d| d.emit()); - e - }); - prev.ty = Ty::new_error(infcx.tcx, guar); - } - // Pick a better span if there is one. - // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. - prev.span = prev.span.substitute_dummy(concrete_type.span); - } else { - result.insert( - opaque_type_key.def_id, - OpaqueHiddenType { ty, span: concrete_type.span }, - ); - } + concrete_opaque_types.insert( + infcx.tcx, + opaque_type_key.def_id, + OpaqueHiddenType { ty, span: concrete_type.span }, + ); // Check that all opaque types have the same region parameters if they have the same // non-region parameters. This is necessary because within the new solver we perform // various query operations modulo regions, and thus could unsoundly select some impls @@ -193,7 +173,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } } - result } /// Map the regions in the type to named regions. This is similar to what diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 0fda3e31690..f6144a25938 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -45,6 +45,7 @@ use crate::borrow_set::BorrowSet; use crate::constraints::{OutlivesConstraint, OutlivesConstraintSet}; use crate::diagnostics::UniverseInfo; use crate::member_constraints::MemberConstraintSet; +use crate::opaque_types::ConcreteOpaqueTypes; use crate::polonius::legacy::{PoloniusFacts, PoloniusLocationTable}; use crate::polonius::{PoloniusContext, PoloniusLivenessContext}; use crate::region_infer::TypeTest; @@ -111,6 +112,7 @@ pub(crate) fn type_check<'a, 'tcx>( flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, location_map: Rc<DenseLocationMap>, + concrete_opaque_types: &mut ConcreteOpaqueTypes<'tcx>, ) -> MirTypeckResults<'tcx> { let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body); let mut constraints = MirTypeckRegionConstraints { @@ -165,6 +167,7 @@ pub(crate) fn type_check<'a, 'tcx>( polonius_facts, borrow_set, constraints: &mut constraints, + concrete_opaque_types, polonius_liveness, }; @@ -230,6 +233,7 @@ struct TypeChecker<'a, 'tcx> { polonius_facts: &'a mut Option<PoloniusFacts>, borrow_set: &'a BorrowSet<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, + concrete_opaque_types: &'a mut ConcreteOpaqueTypes<'tcx>, /// When using `-Zpolonius=next`, the liveness helper data used to create polonius constraints. polonius_liveness: Option<PoloniusLivenessContext>, } @@ -2499,7 +2503,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { args: GenericArgsRef<'tcx>, locations: Locations, ) -> ty::InstantiatedPredicates<'tcx> { - if let Some(closure_requirements) = &tcx.mir_borrowck(def_id).closure_requirements { + let closure_borrowck_results = tcx.mir_borrowck(def_id); + self.concrete_opaque_types + .extend_from_nested_body(tcx, &closure_borrowck_results.concrete_opaque_types); + + if let Some(closure_requirements) = &closure_borrowck_results.closure_requirements { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch index 754025ff49d..34249ea4834 100644 --- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch +++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch @@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644 [dependencies] core = { path = "../core", public = true } --compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } -+compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] } +-compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std'] } ++compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std', 'no-f16-f128'] } [features] compiler-builtins-mem = ['compiler_builtins/mem'] diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index a52b18573b1..fb7864ae612 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs @@ -103,12 +103,14 @@ impl OngoingCodegen { ("o", &module_regular.object.as_ref().unwrap()), ("asm.o", &module_global_asm.object.as_ref().unwrap()), ], + &[], ) } else { rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( sess, &module_regular.name, &[("o", &module_regular.object.as_ref().unwrap())], + &[], ) }; if let Some((work_product_id, work_product)) = work_product { @@ -381,6 +383,7 @@ fn emit_cgu( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: Vec::new(), }), existing_work_product: None, }) @@ -437,6 +440,7 @@ fn emit_module( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: Vec::new(), }) } @@ -460,22 +464,23 @@ fn reuse_workproduct_for_cgu( err )); } + let obj_out_global_asm = crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm"); - let has_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") { + let source_file_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") { let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o); if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm) { return Err(format!( "unable to copy {} to {}: {}", - source_file_regular.display(), - obj_out_regular.display(), + source_file_global_asm.display(), + obj_out_global_asm.display(), err )); } - true + Some(source_file_global_asm) } else { - false + None }; Ok(ModuleCodegenResult { @@ -487,8 +492,9 @@ fn reuse_workproduct_for_cgu( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: vec![source_file_regular], }, - module_global_asm: has_global_asm.then(|| CompiledModule { + module_global_asm: source_file_global_asm.map(|source_file| CompiledModule { name: cgu.name().to_string(), kind: ModuleKind::Regular, object: Some(obj_out_global_asm), @@ -496,6 +502,7 @@ fn reuse_workproduct_for_cgu( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: vec![source_file], }), existing_work_product: Some((cgu.work_product_id(), work_product)), }) @@ -637,6 +644,7 @@ fn emit_metadata_module(tcx: TyCtxt<'_>, metadata: &EncodedMetadata) -> Compiled bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: Vec::new(), } } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e2a59c6efb8..3f5e0c1bce9 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1782,7 +1782,10 @@ fn exported_symbols_for_non_proc_macro(tcx: TyCtxt<'_>, crate_type: CrateType) - let mut symbols = Vec::new(); let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { - if info.level.is_below_threshold(export_threshold) { + // Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins + // from any cdylib. The latter doesn't work anyway as we use hidden visibility for + // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning. + if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) { symbols.push(symbol_export::exporting_symbol_name_for_instance_in_crate( tcx, symbol, cnum, )); @@ -1821,7 +1824,9 @@ pub(crate) fn linked_symbols( let export_threshold = symbol_export::crates_export_threshold(&[crate_type]); for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| { - if info.level.is_below_threshold(export_threshold) || info.used { + if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) + || info.used + { symbols.push(( symbol_export::linking_symbol_name_for_instance_in_crate(tcx, symbol, cnum), info.kind, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2ec203458a3..216a18e72ed 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -546,9 +546,12 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir( if let Some(path) = &module.bytecode { files.push((OutputType::Bitcode.extension(), path.as_path())); } - if let Some((id, product)) = - copy_cgu_workproduct_to_incr_comp_cache_dir(sess, &module.name, files.as_slice()) - { + if let Some((id, product)) = copy_cgu_workproduct_to_incr_comp_cache_dir( + sess, + &module.name, + files.as_slice(), + &module.links_from_incr_cache, + ) { work_products.insert(id, product); } } @@ -934,7 +937,9 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( ) -> WorkItemResult<B> { let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); - let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { + let mut links_from_incr_cache = Vec::new(); + + let mut load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { let source_file = in_incr_comp_dir(incr_comp_session_dir, saved_path); debug!( "copying preexisting module `{}` from {:?} to {}", @@ -943,7 +948,10 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( output_path.display() ); match link_or_copy(&source_file, &output_path) { - Ok(_) => Some(output_path), + Ok(_) => { + links_from_incr_cache.push(source_file); + Some(output_path) + } Err(error) => { cgcx.create_dcx().handle().emit_err(errors::CopyPathBuf { source_file, @@ -966,7 +974,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( load_from_incr_comp_dir(dwarf_obj_out, saved_dwarf_object_file) }); - let load_from_incr_cache = |perform, output_type: OutputType| { + let mut load_from_incr_cache = |perform, output_type: OutputType| { if perform { let saved_file = module.source.saved_files.get(output_type.extension())?; let output_path = cgcx.output_filenames.temp_path(output_type, Some(&module.name)); @@ -986,6 +994,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>( } WorkItemResult::Finished(CompiledModule { + links_from_incr_cache, name: module.name, kind: ModuleKind::Regular, object, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 396febcc637..1985b3b7170 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -658,6 +658,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>( bytecode: None, assembly: None, llvm_ir: None, + links_from_incr_cache: Vec::new(), } }) }); @@ -1104,11 +1105,12 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> // know that later). If we are not doing LTO, there is only one optimized // version of each module, so we re-use that. let dep_node = cgu.codegen_dep_node(tcx); - assert!( - !tcx.dep_graph.dep_node_exists(&dep_node), - "CompileCodegenUnit dep-node for CGU `{}` already exists before marking.", - cgu.name() - ); + tcx.dep_graph.assert_dep_node_not_yet_allocated_in_current_session(&dep_node, || { + format!( + "CompileCodegenUnit dep-node for CGU `{}` already exists before marking.", + cgu.name() + ) + }); if tcx.try_mark_green(&dep_node) { // We can re-use either the pre- or the post-thinlto state. If no LTO is diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 44b8cc459cf..93c34a2f576 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -122,6 +122,7 @@ impl<M> ModuleCodegen<M> { bytecode, assembly, llvm_ir, + links_from_incr_cache: Vec::new(), } } } @@ -135,6 +136,7 @@ pub struct CompiledModule { pub bytecode: Option<PathBuf>, pub assembly: Option<PathBuf>, // --emit=asm pub llvm_ir: Option<PathBuf>, // --emit=llvm-ir, llvm-bc is in bytecode + pub links_from_incr_cache: Vec<PathBuf>, } impl CompiledModule { diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 49cafcb17a0..5de9413cf15 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -256,7 +256,7 @@ impl<K: Eq + Hash + Copy + IntoPointer> ShardedHashMap<K, ()> { } #[inline] -fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 { +pub fn make_hash<K: Hash + ?Sized>(val: &K) -> u64 { let mut state = FxHasher::default(); val.hash(&mut state); state.finish() diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl index 05e11c4527f..2c6a0291ac2 100644 --- a/compiler/rustc_driver_impl/messages.ftl +++ b/compiler/rustc_driver_impl/messages.ftl @@ -1,3 +1,5 @@ +driver_impl_cant_emit_mir = could not emit MIR: {$error} + driver_impl_ice = the compiler unexpectedly panicked. this is a bug. driver_impl_ice_bug_report = we would appreciate a bug report: {$bug_report_url} driver_impl_ice_bug_report_internal_feature = using internal features is not supported and expected to cause internal compiler errors when used incorrectly diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 8ede6e41336..37755e7d61d 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -20,7 +20,7 @@ // tidy-alphabetical-end use std::cmp::max; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; use std::ffi::OsString; use std::fmt::Write as _; use std::fs::{self, File}; @@ -61,7 +61,7 @@ use rustc_session::config::{ }; use rustc_session::getopts::{self, Matches}; use rustc_session::lint::{Lint, LintId}; -use rustc_session::output::collect_crate_types; +use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target}; use rustc_session::{EarlyDiagCtxt, Session, config, filesearch}; use rustc_span::FileName; use rustc_target::json::ToJson; @@ -108,7 +108,7 @@ mod signal_handler { } use crate::session_diagnostics::{ - RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch, + CantEmitMIR, RLinkEmptyVersionNumber, RLinkEncodingVersionMismatch, RLinkRustcVersionMismatch, RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage, }; @@ -243,12 +243,17 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) return; } + let input = make_input(&default_early_dcx, &matches.free); + let has_input = input.is_some(); let (odir, ofile) = make_output(&matches); + + drop(default_early_dcx); + let mut config = interface::Config { opts: sopts, crate_cfg: matches.opt_strs("cfg"), crate_check_cfg: matches.opt_strs("check-cfg"), - input: Input::File(PathBuf::new()), + input: input.unwrap_or(Input::File(PathBuf::new())), output_file: ofile, output_dir: odir, ice_file, @@ -265,16 +270,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) expanded_args: args, }; - let has_input = match make_input(&default_early_dcx, &matches.free) { - Some(input) => { - config.input = input; - true // has input: normal compilation - } - None => false, // no input: we will exit early - }; - - drop(default_early_dcx); - callbacks.config(&mut config); let registered_lints = config.register_lints.is_some(); @@ -379,6 +374,12 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) return early_exit(); } + if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { + if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) { + tcx.dcx().emit_fatal(CantEmitMIR { error }); + } + } + Some(Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend)) }); @@ -407,7 +408,7 @@ fn dump_feature_usage_metrics(tcxt: TyCtxt<'_>, metrics_dir: &Path) { } } -// Extract output directory and file from matches. +/// Extract output directory and file from matches. fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<OutFileName>) { let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o)); let ofile = matches.opt_str("o").map(|o| match o.as_str() { @@ -789,6 +790,16 @@ fn print_crate_info( sess.dcx().fatal("only Apple targets currently support deployment version info") } } + SupportedCrateTypes => { + let supported_crate_types = CRATE_TYPES + .iter() + .filter(|(_, crate_type)| !invalid_output_for_target(&sess, *crate_type)) + .map(|(crate_type_sym, _)| *crate_type_sym) + .collect::<BTreeSet<_>>(); + for supported_crate_type in supported_crate_types { + println_info!("{}", supported_crate_type.as_str()); + } + } } req.out.overwrite(&crate_info, sess); diff --git a/compiler/rustc_driver_impl/src/session_diagnostics.rs b/compiler/rustc_driver_impl/src/session_diagnostics.rs index e06c56539d1..774221fd396 100644 --- a/compiler/rustc_driver_impl/src/session_diagnostics.rs +++ b/compiler/rustc_driver_impl/src/session_diagnostics.rs @@ -3,6 +3,12 @@ use std::error::Error; use rustc_macros::{Diagnostic, Subdiagnostic}; #[derive(Diagnostic)] +#[diag(driver_impl_cant_emit_mir)] +pub struct CantEmitMIR { + pub error: std::io::Error, +} + +#[derive(Diagnostic)] #[diag(driver_impl_rlink_unable_to_read)] pub(crate) struct RlinkUnableToRead { pub err: std::io::Error, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 87f01be26c2..e2a55752850 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1941,7 +1941,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { let attr_name = attr.ident().unwrap().name; // `#[cfg]` and `#[cfg_attr]` are special - they are // eagerly evaluated. - if attr_name != sym::cfg && attr_name != sym::cfg_attr { + if attr_name != sym::cfg && attr_name != sym::cfg_attr_trace { self.cx.sess.psess.buffer_lint( UNUSED_ATTRIBUTES, attr.span, diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs index 4e9d21c900d..0df1b243d69 100644 --- a/compiler/rustc_fs_util/src/lib.rs +++ b/compiler/rustc_fs_util/src/lib.rs @@ -55,25 +55,31 @@ pub enum LinkOrCopy { Copy, } -/// Copies `p` into `q`, preferring to use hard-linking if possible. If -/// `q` already exists, it is removed first. +/// Copies `p` into `q`, preferring to use hard-linking if possible. /// The result indicates which of the two operations has been performed. pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<LinkOrCopy> { + // Creating a hard-link will fail if the destination path already exists. We could defensively + // call remove_file in this function, but that pessimizes callers who can avoid such calls. + // Incremental compilation calls this function a lot, and is able to avoid calls that + // would fail the first hard_link attempt. + let p = p.as_ref(); let q = q.as_ref(); - match fs::remove_file(q) { - Ok(()) => (), - Err(err) if err.kind() == io::ErrorKind::NotFound => (), - Err(err) => return Err(err), - } - match fs::hard_link(p, q) { - Ok(()) => Ok(LinkOrCopy::Link), - Err(_) => match fs::copy(p, q) { - Ok(_) => Ok(LinkOrCopy::Copy), - Err(e) => Err(e), - }, + let err = match fs::hard_link(p, q) { + Ok(()) => return Ok(LinkOrCopy::Link), + Err(err) => err, + }; + + if err.kind() == io::ErrorKind::AlreadyExists { + fs::remove_file(q)?; + if fs::hard_link(p, q).is_ok() { + return Ok(LinkOrCopy::Link); + } } + + // Hard linking failed, fall back to copying. + fs::copy(p, q).map(|_| LinkOrCopy::Copy) } #[cfg(any(unix, all(target_os = "wasi", target_env = "p1")))] diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 29f4d5b8076..e625514e9ff 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -322,7 +322,6 @@ language_item_table! { BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None; // Lang items needed for `format_args!()`. - FormatAlignment, sym::format_alignment, format_alignment, Target::Enum, GenericRequirement::None; FormatArgument, sym::format_argument, format_argument, Target::Struct, GenericRequirement::None; FormatArguments, sym::format_arguments, format_arguments, Target::Struct, GenericRequirement::None; FormatCount, sym::format_count, format_count, Target::Enum, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs index 142078900f0..3dec1e286b4 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs @@ -258,9 +258,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for TaitConstraintLocator<'tcx> { self.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } intravisit::walk_expr(self, ex); } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { @@ -371,14 +368,8 @@ impl RpitConstraintChecker<'_> { // Use borrowck to get the type with unerased regions. let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types; debug!(?concrete_opaque_types); - for (&def_id, &concrete_type) in concrete_opaque_types { - if def_id != self.def_id { - // Ignore constraints for other opaque types. - continue; - } - + if let Some(&concrete_type) = concrete_opaque_types.get(&self.def_id) { debug!(?concrete_type, "found constraint"); - if concrete_type.ty != self.found.ty { if let Ok(d) = self.found.build_mismatch_error(&concrete_type, self.tcx) { d.emit(); @@ -395,9 +386,6 @@ impl<'tcx> intravisit::Visitor<'tcx> for RpitConstraintChecker<'tcx> { self.tcx } fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) { - if let hir::ExprKind::Closure(closure) = ex.kind { - self.check(closure.def_id); - } intravisit::walk_expr(self, ex); } fn visit_item(&mut self, it: &'tcx Item<'tcx>) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs index 95b9cb3be62..e068e607902 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/inspect_obligations.rs @@ -1,7 +1,7 @@ //! A utility module to inspect currently ambiguous obligations in the current context. use rustc_infer::traits::{self, ObligationCause, PredicateObligations}; -use rustc_middle::traits::solve::{Goal, GoalSource}; +use rustc_middle::traits::solve::GoalSource; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::solve::inspect::{ @@ -85,7 +85,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { root_cause: &obligation.cause, }; - let goal = Goal::new(self.tcx, obligation.param_env, obligation.predicate); + let goal = obligation.as_goal(); self.visit_proof_tree(goal, &mut visitor); } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6a3417ae5d6..b63c0b6ab7e 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -548,7 +548,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_typeck_results = self.fcx.typeck_results.borrow(); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); for (predicate, cause) in &fcx_typeck_results.coroutine_stalled_predicates { - let (predicate, cause) = self.resolve((*predicate, cause.clone()), &cause.span); + let (predicate, cause) = + self.resolve_coroutine_predicate((*predicate, cause.clone()), &cause.span); self.typeck_results.coroutine_stalled_predicates.insert((predicate, cause)); } } @@ -730,7 +731,25 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { T: TypeFoldable<TyCtxt<'tcx>>, { let value = self.fcx.resolve_vars_if_possible(value); - let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body)); + let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body, true)); + assert!(!value.has_infer()); + + // We may have introduced e.g. `ty::Error`, if inference failed, make sure + // to mark the `TypeckResults` as tainted in that case, so that downstream + // users of the typeck results don't produce extra errors, or worse, ICEs. + if let Err(guar) = value.error_reported() { + self.typeck_results.tainted_by_errors = Some(guar); + } + + value + } + + fn resolve_coroutine_predicate<T>(&mut self, value: T, span: &dyn Locatable) -> T + where + T: TypeFoldable<TyCtxt<'tcx>>, + { + let value = self.fcx.resolve_vars_if_possible(value); + let value = value.fold_with(&mut Resolver::new(self.fcx, span, self.body, false)); assert!(!value.has_infer()); // We may have introduced e.g. `ty::Error`, if inference failed, make sure @@ -774,8 +793,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { fcx: &'cx FnCtxt<'cx, 'tcx>, span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, + should_normalize: bool, ) -> Resolver<'cx, 'tcx> { - Resolver { fcx, span, body, should_normalize: fcx.next_trait_solver() } + Resolver { fcx, span, body, should_normalize } } fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed { @@ -805,10 +825,9 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { T: Into<ty::GenericArg<'tcx>> + TypeSuperFoldable<TyCtxt<'tcx>> + Copy, { let tcx = self.fcx.tcx; - // We must deeply normalize in the new solver, since later lints - // expect that types that show up in the typeck are fully - // normalized. - let mut value = if self.should_normalize { + // We must deeply normalize in the new solver, since later lints expect + // that types that show up in the typeck are fully normalized. + let mut value = if self.should_normalize && self.fcx.next_trait_solver() { let body_id = tcx.hir_body_owner_def_id(self.body.id()); let cause = ObligationCause::misc(self.span.to_span(tcx), body_id); let at = self.fcx.at(&cause, self.fcx.param_env); @@ -864,20 +883,15 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - self.handle_term(ct, ty::Const::outer_exclusive_binder, |tcx, guar| { - ty::Const::new_error(tcx, guar) - }) - .super_fold_with(self) + self.handle_term(ct, ty::Const::outer_exclusive_binder, ty::Const::new_error) } fn fold_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - // Do not normalize predicates in the new solver. The new solver is - // supposed to handle unnormalized predicates and incorrectly normalizing - // them can be unsound, e.g. for `WellFormed` predicates. - let prev = mem::replace(&mut self.should_normalize, false); - let predicate = predicate.super_fold_with(self); - self.should_normalize = prev; - predicate + assert!( + !self.should_normalize, + "normalizing predicates in writeback is not generally sound" + ); + predicate.super_fold_with(self) } } diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 50e47533ab6..0e646b136c4 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -91,7 +91,10 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) { work_product::delete_workproduct_files(sess, &swp.work_product); } -fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkProductMap)> { +fn load_dep_graph( + sess: &Session, + deps: &DepsType, +) -> LoadResult<(Arc<SerializedDepGraph>, WorkProductMap)> { let prof = sess.prof.clone(); if sess.opts.incremental.is_none() { @@ -171,7 +174,7 @@ fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkPr return LoadResult::DataOutOfDate; } - let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder); + let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder, deps); LoadResult::Ok { data: (dep_graph, prev_work_products) } } @@ -205,11 +208,11 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache> { /// Setups the dependency graph by loading an existing graph from disk and set up streaming of a /// new graph to an incremental session directory. -pub fn setup_dep_graph(sess: &Session, crate_name: Symbol) -> DepGraph { +pub fn setup_dep_graph(sess: &Session, crate_name: Symbol, deps: &DepsType) -> DepGraph { // `load_dep_graph` can only be called after `prepare_session_directory`. prepare_session_directory(sess, crate_name); - let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess)); + let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess, deps)); if sess.opts.incremental.is_some() { sess.time("incr_comp_garbage_collect_session_directories", || { diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 8fc50ca1b43..94ce6d9fa81 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -173,7 +173,7 @@ pub(crate) fn build_dep_graph( sess.opts.dep_tracking_hash(false).encode(&mut encoder); Some(DepGraph::new( - &sess.prof, + sess, prev_graph, prev_work_products, encoder, diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 048981f0d5c..7b1eb0a82e3 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -3,7 +3,7 @@ //! [work products]: WorkProduct use std::fs as std_fs; -use std::path::Path; +use std::path::{Path, PathBuf}; use rustc_data_structures::unord::UnordMap; use rustc_fs_util::link_or_copy; @@ -20,6 +20,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, cgu_name: &str, files: &[(&'static str, &Path)], + known_links: &[PathBuf], ) -> Option<(WorkProductId, WorkProduct)> { debug!(?cgu_name, ?files); sess.opts.incremental.as_ref()?; @@ -28,6 +29,10 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( for (ext, path) in files { let file_name = format!("{cgu_name}.{ext}"); let path_in_incr_dir = in_incr_comp_dir_sess(sess, &file_name); + if known_links.contains(&path_in_incr_dir) { + let _ = saved_files.insert(ext.to_string(), file_name); + continue; + } match link_or_copy(path, &path_in_incr_dir) { Ok(_) => { let _ = saved_files.insert(ext.to_string(), file_name); diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index 3fa1923121a..215b1333726 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -246,8 +246,7 @@ impl<'tcx> InferCtxt<'tcx> { .eq(DefineOpaqueTypes::Yes, prev, hidden_ty)? .obligations .into_iter() - // FIXME: Shuttling between obligations and goals is awkward. - .map(Goal::from), + .map(|obligation| obligation.as_goal()), ); } } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index ac641ef5652..b537750f1b5 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -54,6 +54,12 @@ pub struct Obligation<'tcx, T> { pub recursion_depth: usize, } +impl<'tcx, T: Copy> Obligation<'tcx, T> { + pub fn as_goal(&self) -> solve::Goal<'tcx, T> { + solve::Goal { param_env: self.param_env, predicate: self.predicate } + } +} + impl<'tcx, T: PartialEq> PartialEq<Obligation<'tcx, T>> for Obligation<'tcx, T> { #[inline] fn eq(&self, other: &Obligation<'tcx, T>) -> bool { @@ -75,12 +81,6 @@ impl<T: Hash> Hash for Obligation<'_, T> { } } -impl<'tcx, P> From<Obligation<'tcx, P>> for solve::Goal<'tcx, P> { - fn from(value: Obligation<'tcx, P>) -> Self { - solve::Goal { param_env: value.param_env, predicate: value.predicate } - } -} - pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>; pub type TraitObligation<'tcx> = Obligation<'tcx, ty::TraitPredicate<'tcx>>; pub type PolyTraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>; diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl index adc7ed54e14..ffbe708ba8d 100644 --- a/compiler/rustc_interface/messages.ftl +++ b/compiler/rustc_interface/messages.ftl @@ -3,9 +3,6 @@ interface_abi_required_feature = .note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! interface_abi_required_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344> -interface_cant_emit_mir = - could not emit MIR: {$error} - interface_crate_name_does_not_match = `--crate-name` and `#[crate_name]` are required to match, but `{$crate_name}` != `{$attr_crate_name}` interface_crate_name_invalid = crate names cannot start with a `-`, but `{$crate_name}` has a leading hyphen diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index eed729a1777..ef0235b5577 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -74,12 +74,6 @@ pub struct TempsDirError; pub struct OutDirError; #[derive(Diagnostic)] -#[diag(interface_cant_emit_mir)] -pub struct CantEmitMIR { - pub error: io::Error, -} - -#[derive(Diagnostic)] #[diag(interface_rustc_error_fatal)] pub struct RustcErrorFatal { #[primary_span] diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index e47385d0899..8be7ba7455e 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -19,6 +19,7 @@ use rustc_incremental::setup_dep_graph; use rustc_lint::{BufferedEarlyLint, EarlyCheckNode, LintStore, unerased_lint_store}; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; +use rustc_middle::dep_graph::DepsType; use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt}; use rustc_middle::util::Providers; use rustc_parse::{ @@ -774,7 +775,9 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>( sess.cfg_version, ); let outputs = util::build_output_filenames(&pre_configured_attrs, sess); - let dep_graph = setup_dep_graph(sess, crate_name); + + let dep_type = DepsType { dep_names: rustc_query_impl::dep_kind_names() }; + let dep_graph = setup_dep_graph(sess, crate_name, &dep_type); let cstore = FreezeLock::new(Box::new(CStore::new(compiler.codegen_backend.metadata_loader())) as _); @@ -1078,6 +1081,15 @@ pub(crate) fn start_codegen<'tcx>( codegen_backend: &dyn CodegenBackend, tcx: TyCtxt<'tcx>, ) -> Box<dyn Any> { + // Hook for UI tests. + check_for_rustc_errors_attr(tcx); + + // Don't run this test assertions when not doing codegen. Compiletest tries to build + // build-fail tests in check mode first and expects it to not give an error in that case. + if tcx.sess.opts.output_types.should_codegen() { + rustc_symbol_mangling::test::report_symbol_names(tcx); + } + // Don't do code generation if there were any errors. Likewise if // there were any delayed bugs, because codegen will likely cause // more ICEs, obscuring the original problem. @@ -1085,9 +1097,6 @@ pub(crate) fn start_codegen<'tcx>( guar.raise_fatal(); } - // Hook for UI tests. - check_for_rustc_errors_attr(tcx); - info!("Pre-codegen\n{:?}", tcx.debug_stats()); let (metadata, need_metadata_module) = rustc_metadata::fs::encode_and_write_metadata(tcx); @@ -1096,20 +1105,8 @@ pub(crate) fn start_codegen<'tcx>( codegen_backend.codegen_crate(tcx, metadata, need_metadata_module) }); - // Don't run this test assertions when not doing codegen. Compiletest tries to build - // build-fail tests in check mode first and expects it to not give an error in that case. - if tcx.sess.opts.output_types.should_codegen() { - rustc_symbol_mangling::test::report_symbol_names(tcx); - } - info!("Post-codegen\n{:?}", tcx.debug_stats()); - if tcx.sess.opts.output_types.contains_key(&OutputType::Mir) { - if let Err(error) = rustc_mir_transform::dump_mir::emit_mir(tcx) { - tcx.dcx().emit_fatal(errors::CantEmitMIR { error }); - } - } - // This must run after monomorphization so that all generic types // have been instantiated. if tcx.sess.opts.unstable_opts.print_type_sizes { diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index f967d8b92c7..be34c7ef4bd 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -21,6 +21,15 @@ macro_rules! define_dep_nodes { ($mod:ident) => {[ $($mod::$variant()),* ]}; } + #[macro_export] + macro_rules! make_dep_kind_name_array { + ($mod:ident) => { + vec! { + $(*$mod::$variant().name),* + } + }; + } + /// This enum serves as an index into arrays built by `make_dep_kind_array`. // This enum has more than u8::MAX variants so we need some kind of multi-byte // encoding. The derived Encodable/Decodable uses leb128 encoding which is diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index c927538b4cf..739c0be1a91 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -20,7 +20,9 @@ pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepsType>; pub type DepKindStruct<'tcx> = rustc_query_system::dep_graph::DepKindStruct<TyCtxt<'tcx>>; #[derive(Clone)] -pub struct DepsType; +pub struct DepsType { + pub dep_names: Vec<&'static str>, +} impl Deps for DepsType { fn with_deps<OP, R>(task_deps: TaskDepsRef<'_>, op: OP) -> R @@ -44,6 +46,10 @@ impl Deps for DepsType { }) } + fn name(&self, dep_kind: DepKind) -> &'static str { + self.dep_names[dep_kind.as_usize()] + } + const DEP_KIND_NULL: DepKind = dep_kinds::Null; const DEP_KIND_RED: DepKind = dep_kinds::Red; const DEP_KIND_SIDE_EFFECT: DepKind = dep_kinds::SideEffect; diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs index f17efab81ec..52f155a16b8 100644 --- a/compiler/rustc_middle/src/hir/map.rs +++ b/compiler/rustc_middle/src/hir/map.rs @@ -1176,15 +1176,14 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { debugger_visualizers.hash_stable(&mut hcx, &mut stable_hasher); if tcx.sess.opts.incremental.is_some() { let definitions = tcx.untracked().definitions.freeze(); - let mut owner_spans: Vec<_> = krate - .owners - .iter_enumerated() - .filter_map(|(def_id, info)| { - let _ = info.as_owner()?; + let mut owner_spans: Vec<_> = tcx + .hir_crate_items(()) + .definitions() + .map(|def_id| { let def_path_hash = definitions.def_path_hash(def_id); let span = tcx.source_span(def_id); debug_assert_eq!(span.parent(), None); - Some((def_path_hash, span)) + (def_path_hash, span) }) .collect(); owner_spans.sort_unstable_by_key(|bn| bn.0); diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 0b8f0e8cd41..b0c442d28f0 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -101,63 +101,13 @@ impl FlagComputation { &ty::Param(_) => { self.add_flags(TypeFlags::HAS_TY_PARAM); - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } - ty::Coroutine(_, args) => { - let args = args.as_coroutine(); - let should_remove_further_specializable = - !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - self.add_args(args.parent_args()); - if should_remove_further_specializable { - self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; - } - - self.add_ty(args.resume_ty()); - self.add_ty(args.return_ty()); - self.add_ty(args.witness()); - self.add_ty(args.yield_ty()); - self.add_ty(args.tupled_upvars_ty()); - } - - ty::CoroutineWitness(_, args) => { - let should_remove_further_specializable = - !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); + &ty::Closure(_, args) + | &ty::Coroutine(_, args) + | &ty::CoroutineClosure(_, args) + | &ty::CoroutineWitness(_, args) => { self.add_args(args); - if should_remove_further_specializable { - self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; - } - self.add_flags(TypeFlags::HAS_TY_COROUTINE); - } - - &ty::Closure(_, args) => { - let args = args.as_closure(); - let should_remove_further_specializable = - !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - self.add_args(args.parent_args()); - if should_remove_further_specializable { - self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; - } - - self.add_ty(args.sig_as_fn_ptr_ty()); - self.add_ty(args.kind_ty()); - self.add_ty(args.tupled_upvars_ty()); - } - - &ty::CoroutineClosure(_, args) => { - let args = args.as_coroutine_closure(); - let should_remove_further_specializable = - !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - self.add_args(args.parent_args()); - if should_remove_further_specializable { - self.flags -= TypeFlags::STILL_FURTHER_SPECIALIZABLE; - } - - self.add_ty(args.kind_ty()); - self.add_ty(args.signature_parts_ty()); - self.add_ty(args.tupled_upvars_ty()); - self.add_ty(args.coroutine_captures_by_ref_ty()); - self.add_ty(args.coroutine_witness_ty()); } &ty::Bound(debruijn, _) => { @@ -167,21 +117,17 @@ impl FlagComputation { &ty::Placeholder(..) => { self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER); - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } - &ty::Infer(infer) => { - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - match infer { - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { - self.add_flags(TypeFlags::HAS_TY_FRESH) - } + &ty::Infer(infer) => match infer { + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { + self.add_flags(TypeFlags::HAS_TY_FRESH) + } - ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { - self.add_flags(TypeFlags::HAS_TY_INFER) - } + ty::TyVar(_) | ty::IntVar(_) | ty::FloatVar(_) => { + self.add_flags(TypeFlags::HAS_TY_INFER) } - } + }, &ty::Adt(_, args) => { self.add_args(args); @@ -358,24 +304,19 @@ impl FlagComputation { self.add_args(uv.args); self.add_flags(TypeFlags::HAS_CT_PROJECTION); } - ty::ConstKind::Infer(infer) => { - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); - match infer { - InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH), - InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER), - } - } + ty::ConstKind::Infer(infer) => match infer { + InferConst::Fresh(_) => self.add_flags(TypeFlags::HAS_CT_FRESH), + InferConst::Var(_) => self.add_flags(TypeFlags::HAS_CT_INFER), + }, ty::ConstKind::Bound(debruijn, _) => { self.add_bound_var(debruijn); self.add_flags(TypeFlags::HAS_CT_BOUND); } ty::ConstKind::Param(_) => { self.add_flags(TypeFlags::HAS_CT_PARAM); - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Placeholder(_) => { self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER); - self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(cv) => self.add_ty(cv.ty), ty::ConstKind::Expr(e) => self.add_args(e.args()), diff --git a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs index f743ea60a45..64d092e0354 100644 --- a/compiler/rustc_mir_build/src/builder/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/builder/expr/as_constant.rs @@ -105,23 +105,19 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx> return Const::Ty(Ty::new_error(tcx, guar), ty::Const::new_error(tcx, guar)); } - let trunc = |n, width: ty::UintTy| { - let width = width - .normalize(tcx.data_layout.pointer_size.bits().try_into().unwrap()) - .bit_width() - .unwrap(); - let width = Size::from_bits(width); + let lit_ty = match *ty.kind() { + ty::Pat(base, _) => base, + _ => ty, + }; + + let trunc = |n| { + let width = lit_ty.primitive_size(tcx); trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits()); let result = width.truncate(n); trace!("trunc result: {}", result); ConstValue::Scalar(Scalar::from_uint(result, width)) }; - let lit_ty = match *ty.kind() { - ty::Pat(base, _) => base, - _ => ty, - }; - let value = match (lit, lit_ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let s = s.as_str(); @@ -149,11 +145,10 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx> (ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => { ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1))) } - (ast::LitKind::Int(n, _), ty::Uint(ui)) if !neg => trunc(n.get(), *ui), - (ast::LitKind::Int(n, _), ty::Int(i)) => trunc( - if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() }, - i.to_unsigned(), - ), + (ast::LitKind::Int(n, _), ty::Uint(_)) if !neg => trunc(n.get()), + (ast::LitKind::Int(n, _), ty::Int(_)) => { + trunc(if neg { (n.get() as i128).overflowing_neg().0 as u128 } else { n.get() }) + } (ast::LitKind::Float(n, _), ty::Float(fty)) => { parse_float_into_constval(*n, *fty, neg).unwrap() } diff --git a/compiler/rustc_mir_build/src/builder/scope.rs b/compiler/rustc_mir_build/src/builder/scope.rs index 27ff01b4803..e56c0ae92ca 100644 --- a/compiler/rustc_mir_build/src/builder/scope.rs +++ b/compiler/rustc_mir_build/src/builder/scope.rs @@ -305,27 +305,25 @@ impl DropTree { } /// Builds the MIR for a given drop tree. - /// - /// `blocks` should have the same length as `self.drops`, and may have its - /// first value set to some already existing block. fn build_mir<'tcx, T: DropTreeBuilder<'tcx>>( &mut self, cfg: &mut CFG<'tcx>, - blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>, - ) { + root_node: Option<BasicBlock>, + ) -> IndexVec<DropIdx, Option<BasicBlock>> { debug!("DropTree::build_mir(drops = {:#?})", self); - assert_eq!(blocks.len(), self.drops.len()); - self.assign_blocks::<T>(cfg, blocks); - self.link_blocks(cfg, blocks) + let mut blocks = self.assign_blocks::<T>(cfg, root_node); + self.link_blocks(cfg, &mut blocks); + + blocks } /// Assign blocks for all of the drops in the drop tree that need them. fn assign_blocks<'tcx, T: DropTreeBuilder<'tcx>>( &mut self, cfg: &mut CFG<'tcx>, - blocks: &mut IndexVec<DropIdx, Option<BasicBlock>>, - ) { + root_node: Option<BasicBlock>, + ) -> IndexVec<DropIdx, Option<BasicBlock>> { // StorageDead statements can share blocks with each other and also with // a Drop terminator. We iterate through the drops to find which drops // need their own block. @@ -342,8 +340,11 @@ impl DropTree { Own, } + let mut blocks = IndexVec::from_elem(None, &self.drops); + blocks[ROOT_NODE] = root_node; + let mut needs_block = IndexVec::from_elem(Block::None, &self.drops); - if blocks[ROOT_NODE].is_some() { + if root_node.is_some() { // In some cases (such as drops for `continue`) the root node // already has a block. In this case, make sure that we don't // override it. @@ -385,6 +386,8 @@ impl DropTree { debug!("assign_blocks: blocks = {:#?}", blocks); assert!(entry_points.is_empty()); + + blocks } fn link_blocks<'tcx>( @@ -1574,10 +1577,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { span: Span, continue_block: Option<BasicBlock>, ) -> Option<BlockAnd<()>> { - let mut blocks = IndexVec::from_elem(None, &drops.drops); - blocks[ROOT_NODE] = continue_block; - - drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks); + let blocks = drops.build_mir::<ExitScopes>(&mut self.cfg, continue_block); let is_coroutine = self.coroutine.is_some(); // Link the exit drop tree to unwind drop tree. @@ -1633,8 +1633,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { let drops = &mut self.scopes.coroutine_drops; let cfg = &mut self.cfg; let fn_span = self.fn_span; - let mut blocks = IndexVec::from_elem(None, &drops.drops); - drops.build_mir::<CoroutineDrop>(cfg, &mut blocks); + let blocks = drops.build_mir::<CoroutineDrop>(cfg, None); if let Some(root_block) = blocks[ROOT_NODE] { cfg.terminate( root_block, @@ -1670,9 +1669,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> { fn_span: Span, resume_block: &mut Option<BasicBlock>, ) { - let mut blocks = IndexVec::from_elem(None, &drops.drops); - blocks[ROOT_NODE] = *resume_block; - drops.build_mir::<Unwind>(cfg, &mut blocks); + let blocks = drops.build_mir::<Unwind>(cfg, *resume_block); if let (None, Some(resume)) = (*resume_block, blocks[ROOT_NODE]) { cfg.terminate(resume, SourceInfo::outermost(fn_span), TerminatorKind::UnwindResume); diff --git a/compiler/rustc_parse_format/Cargo.toml b/compiler/rustc_parse_format/Cargo.toml index d6c3bd9877c..289e062fb5e 100644 --- a/compiler/rustc_parse_format/Cargo.toml +++ b/compiler/rustc_parse_format/Cargo.toml @@ -8,5 +8,7 @@ edition = "2024" rustc_lexer = { path = "../rustc_lexer" } # tidy-alphabetical-end -[target.'cfg(target_pointer_width = "64")'.dependencies] +[target.'cfg(target_pointer_width = "64")'.dev-dependencies] +# tidy-alphabetical-start rustc_index = { path = "../rustc_index", default-features = false } +# tidy-alphabetical-end diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 5b8a2fe52d3..97931742985 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -1105,7 +1105,7 @@ fn unescape_string(string: &str) -> Option<String> { } // Assert a reasonable size for `Piece` -#[cfg(target_pointer_width = "64")] +#[cfg(all(test, target_pointer_width = "64"))] rustc_index::static_assert_size!(Piece<'_>, 16); #[cfg(test)] diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index ed498d9d344..06398dd4f72 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -811,8 +811,8 @@ passes_unused_duplicate = passes_unused_empty_lints_note = attribute `{$name}` with an empty list has no effect -passes_unused_linker_warnings_note = - the `linker_warnings` lint can only be controlled at the root of a crate that needs to be linked +passes_unused_linker_messages_note = + the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked passes_unused_multiple = multiple `{$name}` attributes diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 1ace98c91e6..9238c73cdb1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2402,7 +2402,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { .iter() .all(|kind| matches!(kind, CrateType::Rlib | CrateType::Staticlib)); if never_needs_link { - errors::UnusedNote::LinkerWarningsBinaryCrateOnly + errors::UnusedNote::LinkerMessagesBinaryCrateOnly } else { return; } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b8359c27e53..a72f40cd843 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -770,8 +770,8 @@ pub(crate) enum UnusedNote { NoLints { name: Symbol }, #[note(passes_unused_default_method_body_const_note)] DefaultMethodBodyConst, - #[note(passes_unused_linker_warnings_note)] - LinkerWarningsBinaryCrateOnly, + #[note(passes_unused_linker_messages_note)] + LinkerMessagesBinaryCrateOnly, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 2b8457ace8e..6fc7f023cf0 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -863,5 +863,9 @@ macro_rules! define_queries { pub fn query_callbacks<'tcx>(arena: &'tcx Arena<'tcx>) -> &'tcx [DepKindStruct<'tcx>] { arena.alloc_from_iter(rustc_middle::make_dep_kind_array!(query_callbacks)) } + + pub fn dep_kind_names() -> Vec<&'static str> { + rustc_middle::make_dep_kind_name_array!(query_callbacks) + } } } diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 78710efb7a9..7db06953aeb 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -24,3 +24,8 @@ rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" # tidy-alphabetical-end + +[dependencies.hashbrown] +version = "0.15.2" +default-features = false +features = ["nightly"] # for may_dangle diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index bfd8b320715..de5bbacf274 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -7,7 +7,8 @@ use std::sync::atomic::{AtomicU32, Ordering}; use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::profiling::{QueryInvocationId, SelfProfilerRef}; +use rustc_data_structures::outline; +use rustc_data_structures::profiling::QueryInvocationId; use rustc_data_structures::sharded::{self, ShardedHashMap}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::{AtomicU64, Lock}; @@ -16,6 +17,7 @@ use rustc_errors::DiagInner; use rustc_index::IndexVec; use rustc_macros::{Decodable, Encodable}; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; +use rustc_session::Session; use tracing::{debug, instrument}; #[cfg(debug_assertions)] use {super::debug::EdgeFilter, std::env}; @@ -117,7 +119,7 @@ where impl<D: Deps> DepGraph<D> { pub fn new( - profiler: &SelfProfilerRef, + session: &Session, prev_graph: Arc<SerializedDepGraph>, prev_work_products: WorkProductMap, encoder: FileEncoder, @@ -127,7 +129,7 @@ impl<D: Deps> DepGraph<D> { let prev_graph_node_count = prev_graph.node_count(); let current = CurrentDepGraph::new( - profiler, + session, prev_graph_node_count, encoder, record_graph, @@ -138,7 +140,7 @@ impl<D: Deps> DepGraph<D> { let colors = DepNodeColorMap::new(prev_graph_node_count); // Instantiate a dependy-less node only once for anonymous queries. - let _green_node_index = current.intern_new_node( + let _green_node_index = current.alloc_new_node( DepNode { kind: D::DEP_KIND_NULL, hash: current.anon_id_seed.into() }, EdgesVec::new(), Fingerprint::ZERO, @@ -351,12 +353,13 @@ impl<D: Deps> DepGraphData<D> { // in `DepGraph::try_mark_green()`. // 2. Two distinct query keys get mapped to the same `DepNode` // (see for example #48923). - assert!( - !self.dep_node_exists(&key), - "forcing query with already existing `DepNode`\n\ + self.assert_dep_node_not_yet_allocated_in_current_session(&key, || { + format!( + "forcing query with already existing `DepNode`\n\ - query-key: {arg:?}\n\ - dep-node: {key:?}" - ); + ) + }); let with_deps = |task_deps| D::with_deps(task_deps, || task(cx, arg)); let (result, edges) = if cx.dep_context().is_eval_always(key.kind) { @@ -436,7 +439,16 @@ impl<D: Deps> DepGraphData<D> { hash: self.current.anon_id_seed.combine(hasher.finish()).into(), }; - self.current.intern_new_node(target_dep_node, task_deps, Fingerprint::ZERO) + // The DepNodes generated by the process above are not unique. 2 queries could + // have exactly the same dependencies. However, deserialization does not handle + // duplicated nodes, so we do the deduplication here directly. + // + // As anonymous nodes are a small quantity compared to the full dep-graph, the + // memory impact of this `anon_node_to_index` map remains tolerable, and helps + // us avoid useless growth of the graph with almost-equivalent nodes. + self.current.anon_node_to_index.get_or_insert_with(target_dep_node, || { + self.current.alloc_new_node(target_dep_node, task_deps, Fingerprint::ZERO) + }) } }; @@ -637,20 +649,24 @@ impl<D: Deps> DepGraph<D> { } impl<D: Deps> DepGraphData<D> { - #[inline] - fn dep_node_index_of_opt(&self, dep_node: &DepNode) -> Option<DepNodeIndex> { + fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>( + &self, + dep_node: &DepNode, + msg: impl FnOnce() -> S, + ) { if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) { - self.current.prev_index_to_index.lock()[prev_index] - } else { - self.current.new_node_to_index.get(dep_node) + let current = self.current.prev_index_to_index.lock()[prev_index]; + assert!(current.is_none(), "{}", msg()) + } else if let Some(nodes_newly_allocated_in_current_session) = + &self.current.nodes_newly_allocated_in_current_session + { + outline(|| { + let seen = nodes_newly_allocated_in_current_session.lock().contains_key(dep_node); + assert!(!seen, "{}", msg()); + }); } } - #[inline] - fn dep_node_exists(&self, dep_node: &DepNode) -> bool { - self.dep_node_index_of_opt(dep_node).is_some() - } - fn node_color(&self, dep_node: &DepNode) -> Option<DepNodeColor> { if let Some(prev_index) = self.previous.node_to_index_opt(dep_node) { self.colors.get(prev_index) @@ -734,11 +750,6 @@ impl<D: Deps> DepGraphData<D> { } impl<D: Deps> DepGraph<D> { - #[inline] - pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool { - self.data.as_ref().is_some_and(|data| data.dep_node_exists(dep_node)) - } - /// Checks whether a previous work product exists for `v` and, if /// so, return the path that leads to it. Used to skip doing work. pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> { @@ -964,6 +975,16 @@ impl<D: Deps> DepGraph<D> { self.node_color(dep_node).is_some_and(|c| c.is_green()) } + pub fn assert_dep_node_not_yet_allocated_in_current_session<S: std::fmt::Display>( + &self, + dep_node: &DepNode, + msg: impl FnOnce() -> S, + ) { + if let Some(data) = &self.data { + data.assert_dep_node_not_yet_allocated_in_current_session(dep_node, msg) + } + } + /// This method loads all on-disk cacheable query results into memory, so /// they can be written out to the new cache file again. Most query results /// will already be in memory but in the case where we marked something as @@ -1069,24 +1090,24 @@ rustc_index::newtype_index! { /// largest in the compiler. /// /// For this reason, we avoid storing `DepNode`s more than once as map -/// keys. The `new_node_to_index` map only contains nodes not in the previous +/// keys. The `anon_node_to_index` map only contains nodes of anonymous queries not in the previous /// graph, and we map nodes in the previous graph to indices via a two-step /// mapping. `SerializedDepGraph` maps from `DepNode` to `SerializedDepNodeIndex`, /// and the `prev_index_to_index` vector (which is more compact and faster than /// using a map) maps from `SerializedDepNodeIndex` to `DepNodeIndex`. /// -/// This struct uses three locks internally. The `data`, `new_node_to_index`, +/// This struct uses three locks internally. The `data`, `anon_node_to_index`, /// and `prev_index_to_index` fields are locked separately. Operations that take /// a `DepNodeIndex` typically just access the `data` field. /// /// We only need to manipulate at most two locks simultaneously: -/// `new_node_to_index` and `data`, or `prev_index_to_index` and `data`. When -/// manipulating both, we acquire `new_node_to_index` or `prev_index_to_index` +/// `anon_node_to_index` and `data`, or `prev_index_to_index` and `data`. When +/// manipulating both, we acquire `anon_node_to_index` or `prev_index_to_index` /// first, and `data` second. pub(super) struct CurrentDepGraph<D: Deps> { encoder: GraphEncoder<D>, - new_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>, prev_index_to_index: Lock<IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>>, + anon_node_to_index: ShardedHashMap<DepNode, DepNodeIndex>, /// This is used to verify that fingerprints do not change between the creation of a node /// and its recomputation. @@ -1098,6 +1119,14 @@ pub(super) struct CurrentDepGraph<D: Deps> { #[cfg(debug_assertions)] forbidden_edge: Option<EdgeFilter>, + /// Used to verify the absence of hash collisions among DepNodes. + /// This field is only `Some` if the `-Z incremental_verify_ich` option is present + /// or if `debug_assertions` are enabled. + /// + /// The map contains all DepNodes that have been allocated in the current session so far and + /// for which there is no equivalent in the previous session. + nodes_newly_allocated_in_current_session: Option<Lock<FxHashMap<DepNode, DepNodeIndex>>>, + /// Anonymous `DepNode`s are nodes whose IDs we compute from the list of /// their edges. This has the beneficial side-effect that multiple anonymous /// nodes can be coalesced into one without changing the semantics of the @@ -1119,7 +1148,7 @@ pub(super) struct CurrentDepGraph<D: Deps> { impl<D: Deps> CurrentDepGraph<D> { fn new( - profiler: &SelfProfilerRef, + session: &Session, prev_graph_node_count: usize, encoder: FileEncoder, record_graph: bool, @@ -1145,16 +1174,20 @@ impl<D: Deps> CurrentDepGraph<D> { let new_node_count_estimate = 102 * prev_graph_node_count / 100 + 200; + let new_node_dbg = + session.opts.unstable_opts.incremental_verify_ich || cfg!(debug_assertions); + CurrentDepGraph { encoder: GraphEncoder::new( encoder, prev_graph_node_count, record_graph, record_stats, - profiler, + &session.prof, previous, ), - new_node_to_index: ShardedHashMap::with_capacity( + anon_node_to_index: ShardedHashMap::with_capacity( + // FIXME: The count estimate is off as anon nodes are only a portion of the nodes. new_node_count_estimate / sharded::shards(), ), prev_index_to_index: Lock::new(IndexVec::from_elem_n(None, prev_graph_node_count)), @@ -1163,6 +1196,12 @@ impl<D: Deps> CurrentDepGraph<D> { forbidden_edge, #[cfg(debug_assertions)] fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)), + nodes_newly_allocated_in_current_session: new_node_dbg.then(|| { + Lock::new(FxHashMap::with_capacity_and_hasher( + new_node_count_estimate, + Default::default(), + )) + }), total_read_count: AtomicU64::new(0), total_duplicate_read_count: AtomicU64::new(0), } @@ -1180,19 +1219,31 @@ impl<D: Deps> CurrentDepGraph<D> { /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it. /// Assumes that this is a node that has no equivalent in the previous dep-graph. #[inline(always)] - fn intern_new_node( + fn alloc_new_node( &self, key: DepNode, edges: EdgesVec, current_fingerprint: Fingerprint, ) -> DepNodeIndex { - let dep_node_index = self - .new_node_to_index - .get_or_insert_with(key, || self.encoder.send(key, current_fingerprint, edges)); + let dep_node_index = self.encoder.send(key, current_fingerprint, edges); #[cfg(debug_assertions)] self.record_edge(dep_node_index, key, current_fingerprint); + if let Some(ref nodes_newly_allocated_in_current_session) = + self.nodes_newly_allocated_in_current_session + { + outline(|| { + if nodes_newly_allocated_in_current_session + .lock() + .insert(key, dep_node_index) + .is_some() + { + panic!("Found duplicate dep-node {key:?}"); + } + }); + } + dep_node_index } @@ -1247,7 +1298,7 @@ impl<D: Deps> CurrentDepGraph<D> { let fingerprint = fingerprint.unwrap_or(Fingerprint::ZERO); // This is a new node: it didn't exist in the previous compilation session. - let dep_node_index = self.intern_new_node(key, edges, fingerprint); + let dep_node_index = self.alloc_new_node(key, edges, fingerprint); (dep_node_index, None) } @@ -1286,7 +1337,10 @@ impl<D: Deps> CurrentDepGraph<D> { ) { let node = &prev_graph.index_to_node(prev_index); debug_assert!( - !self.new_node_to_index.get(node).is_some(), + !self + .nodes_newly_allocated_in_current_session + .as_ref() + .map_or(false, |set| set.lock().contains_key(node)), "node from previous graph present in new node collection" ); } @@ -1408,13 +1462,12 @@ fn panic_on_forbidden_read<D: Deps>(data: &DepGraphData<D>, dep_node_index: DepN } } - if dep_node.is_none() { - // Try to find it among the new nodes - for shard in data.current.new_node_to_index.lock_shards() { - if let Some((node, _)) = shard.iter().find(|(_, index)| *index == dep_node_index) { - dep_node = Some(*node); - break; - } + if dep_node.is_none() + && let Some(nodes) = &data.current.nodes_newly_allocated_in_current_session + { + // Try to find it among the nodes allocated so far in this session + if let Some((node, _)) = nodes.lock().iter().find(|&(_, index)| *index == dep_node_index) { + dep_node = Some(*node); } } diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index e3d64d1c0f8..4eeb6078d14 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -100,6 +100,8 @@ pub trait Deps { where OP: for<'a> FnOnce(TaskDepsRef<'a>); + fn name(&self, dep_kind: DepKind) -> &'static str; + /// We use this for most things when incr. comp. is turned off. const DEP_KIND_NULL: DepKind; @@ -154,7 +156,7 @@ pub enum FingerprintStyle { impl FingerprintStyle { #[inline] - pub fn reconstructible(self) -> bool { + pub const fn reconstructible(self) -> bool { match self { FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => { true diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 2c6fd7d494f..f4b2cf631ed 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -179,8 +179,8 @@ fn mask(bits: usize) -> usize { } impl SerializedDepGraph { - #[instrument(level = "debug", skip(d))] - pub fn decode<D: Deps>(d: &mut MemDecoder<'_>) -> Arc<SerializedDepGraph> { + #[instrument(level = "debug", skip(d, deps))] + pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGraph> { // The last 16 bytes are the node count and edge count. debug!("position: {:?}", d.position()); let (node_count, edge_count) = @@ -252,7 +252,18 @@ impl SerializedDepGraph { .collect(); for (idx, node) in nodes.iter_enumerated() { - index[node.kind.as_usize()].insert(node.hash, idx); + if index[node.kind.as_usize()].insert(node.hash, idx).is_some() { + // Side effect nodes can have duplicates + if node.kind != D::DEP_KIND_SIDE_EFFECT { + let name = deps.name(node.kind); + panic!( + "Error: A dep graph node ({name}) does not have an unique index. \ + Running a clean build on a nightly compiler with `-Z incremental-verify-ich` \ + can help narrow down the issue for reporting. A clean build may also work around the issue.\n + DepNode: {node:?}" + ) + } + } } Arc::new(SerializedDepGraph { diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 7578cb5e2ae..d6b90fbc09f 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -3,14 +3,13 @@ //! manage the caches, and so forth. use std::cell::Cell; -use std::collections::hash_map::Entry; use std::fmt::Debug; use std::hash::Hash; use std::mem; +use hashbrown::hash_table::Entry; use rustc_data_structures::fingerprint::Fingerprint; -use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::sharded::Sharded; +use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::{outline, sync}; use rustc_errors::{Diag, FatalError, StashKey}; @@ -25,8 +24,13 @@ use crate::query::caches::QueryCache; use crate::query::job::{QueryInfo, QueryJob, QueryJobId, QueryJobInfo, QueryLatch, report_cycle}; use crate::query::{QueryContext, QueryMap, QueryStackFrame, SerializedDepNodeIndex}; +#[inline] +fn equivalent_key<K: Eq, V>(k: &K) -> impl Fn(&(K, V)) -> bool + '_ { + move |x| x.0 == *k +} + pub struct QueryState<K> { - active: Sharded<FxHashMap<K, QueryResult>>, + active: Sharded<hashbrown::HashTable<(K, QueryResult)>>, } /// Indicates the state of a query for a given key in a query map. @@ -159,7 +163,7 @@ where { /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query - fn complete<C>(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) + fn complete<C>(self, cache: &C, key_hash: u64, result: C::Value, dep_node_index: DepNodeIndex) where C: QueryCache<Key = K>, { @@ -174,16 +178,17 @@ where cache.complete(key, result, dep_node_index); let job = { - let val = { - // don't keep the lock during the `unwrap()` of the retrieved value, or we taint the - // underlying shard. - // since unwinding also wants to look at this map, this can also prevent a double - // panic. - let mut lock = state.active.lock_shard_by_value(&key); - lock.remove(&key) - }; - val.unwrap().expect_job() + // don't keep the lock during the `unwrap()` of the retrieved value, or we taint the + // underlying shard. + // since unwinding also wants to look at this map, this can also prevent a double + // panic. + let mut shard = state.active.lock_shard_by_hash(key_hash); + match shard.find_entry(key_hash, equivalent_key(&key)) { + Err(_) => None, + Ok(occupied) => Some(occupied.remove().0.1), + } }; + let job = job.expect("active query job entry").expect_job(); job.signal_complete(); } @@ -199,11 +204,16 @@ where // Poison the query so jobs waiting on it panic. let state = self.state; let job = { - let mut shard = state.active.lock_shard_by_value(&self.key); - let job = shard.remove(&self.key).unwrap().expect_job(); - - shard.insert(self.key, QueryResult::Poisoned); - job + let key_hash = sharded::make_hash(&self.key); + let mut shard = state.active.lock_shard_by_hash(key_hash); + match shard.find_entry(key_hash, equivalent_key(&self.key)) { + Err(_) => panic!(), + Ok(occupied) => { + let ((key, value), vacant) = occupied.remove(); + vacant.insert((key, QueryResult::Poisoned)); + value.expect_job() + } + } }; // Also signal the completion of the job, so waiters // will continue execution. @@ -283,11 +293,11 @@ where outline(|| { // We didn't find the query result in the query cache. Check if it was // poisoned due to a panic instead. - let lock = query.query_state(qcx).active.get_shard_by_value(&key).lock(); - - match lock.get(&key) { + let key_hash = sharded::make_hash(&key); + let shard = query.query_state(qcx).active.lock_shard_by_hash(key_hash); + match shard.find(key_hash, equivalent_key(&key)) { // The query we waited on panicked. Continue unwinding here. - Some(QueryResult::Poisoned) => FatalError.raise(), + Some((_, QueryResult::Poisoned)) => FatalError.raise(), _ => panic!( "query '{}' result must be in the cache or the query must be poisoned after a wait", query.name() @@ -318,7 +328,8 @@ where Qcx: QueryContext, { let state = query.query_state(qcx); - let mut state_lock = state.active.lock_shard_by_value(&key); + let key_hash = sharded::make_hash(&key); + let mut state_lock = state.active.lock_shard_by_hash(key_hash); // For the parallel compiler we need to check both the query cache and query state structures // while holding the state lock to ensure that 1) the query has not yet completed and 2) the @@ -335,21 +346,21 @@ where let current_job_id = qcx.current_query_job(); - match state_lock.entry(key) { + match state_lock.entry(key_hash, equivalent_key(&key), |(k, _)| sharded::make_hash(k)) { Entry::Vacant(entry) => { // Nothing has computed or is computing the query, so we start a new job and insert it in the // state map. let id = qcx.next_job_id(); let job = QueryJob::new(id, span, current_job_id); - entry.insert(QueryResult::Started(job)); + entry.insert((key, QueryResult::Started(job))); // Drop the lock before we start executing the query drop(state_lock); - execute_job::<_, _, INCR>(query, qcx, state, key, id, dep_node) + execute_job::<_, _, INCR>(query, qcx, state, key, key_hash, id, dep_node) } Entry::Occupied(mut entry) => { - match entry.get_mut() { + match &mut entry.get_mut().1 { QueryResult::Started(job) => { if sync::is_dyn_thread_safe() { // Get the latch out @@ -380,6 +391,7 @@ fn execute_job<Q, Qcx, const INCR: bool>( qcx: Qcx, state: &QueryState<Q::Key>, key: Q::Key, + key_hash: u64, id: QueryJobId, dep_node: Option<DepNode>, ) -> (Q::Value, Option<DepNodeIndex>) @@ -440,7 +452,7 @@ where } } } - job_owner.complete(cache, result, dep_node_index); + job_owner.complete(cache, key_hash, result, dep_node_index); (result, Some(dep_node_index)) } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 43b78423c72..ed336cc5596 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -58,6 +58,7 @@ pub const PRINT_KINDS: &[(&str, PrintKind)] = &[ ("relocation-models", PrintKind::RelocationModels), ("split-debuginfo", PrintKind::SplitDebuginfo), ("stack-protector-strategies", PrintKind::StackProtectorStrategies), + ("supported-crate-types", PrintKind::SupportedCrateTypes), ("sysroot", PrintKind::Sysroot), ("target-cpus", PrintKind::TargetCPUs), ("target-features", PrintKind::TargetFeatures), @@ -888,6 +889,7 @@ pub enum PrintKind { RelocationModels, SplitDebuginfo, StackProtectorStrategies, + SupportedCrateTypes, Sysroot, TargetCPUs, TargetFeatures, @@ -2063,7 +2065,10 @@ fn check_print_request_stability( (print_name, print_kind): (&str, PrintKind), ) { match print_kind { - PrintKind::AllTargetSpecsJson | PrintKind::CheckCfg | PrintKind::TargetSpecJson + PrintKind::AllTargetSpecsJson + | PrintKind::CheckCfg + | PrintKind::SupportedCrateTypes + | PrintKind::TargetSpecJson if !unstable_opts.unstable_options => { early_dcx.early_fatal(format!( diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 50f09c57107..bdeca91eb64 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -60,66 +60,76 @@ pub fn make_target_bin_path(sysroot: &Path, target_triple: &str) -> PathBuf { #[cfg(unix)] fn current_dll_path() -> Result<PathBuf, String> { - use std::ffi::{CStr, OsStr}; - use std::os::unix::prelude::*; - - #[cfg(not(target_os = "aix"))] - unsafe { - let addr = current_dll_path as usize as *mut _; - let mut info = std::mem::zeroed(); - if libc::dladdr(addr, &mut info) == 0 { - return Err("dladdr failed".into()); - } - if info.dli_fname.is_null() { - return Err("dladdr returned null pointer".into()); - } - let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); - let os = OsStr::from_bytes(bytes); - Ok(PathBuf::from(os)) - } - - #[cfg(target_os = "aix")] - unsafe { - // On AIX, the symbol `current_dll_path` references a function descriptor. - // A function descriptor is consisted of (See https://reviews.llvm.org/D62532) - // * The address of the entry point of the function. - // * The TOC base address for the function. - // * The environment pointer. - // The function descriptor is in the data section. - let addr = current_dll_path as u64; - let mut buffer = vec![std::mem::zeroed::<libc::ld_info>(); 64]; - loop { - if libc::loadquery( - libc::L_GETINFO, - buffer.as_mut_ptr() as *mut u8, - (size_of::<libc::ld_info>() * buffer.len()) as u32, - ) >= 0 - { - break; - } else { - if std::io::Error::last_os_error().raw_os_error().unwrap() != libc::ENOMEM { - return Err("loadquery failed".into()); + use std::sync::OnceLock; + + // This is somewhat expensive relative to other work when compiling `fn main() {}` as `dladdr` + // needs to iterate over the symbol table of librustc_driver.so until it finds a match. + // As such cache this to avoid recomputing if we try to get the sysroot in multiple places. + static CURRENT_DLL_PATH: OnceLock<Result<PathBuf, String>> = OnceLock::new(); + CURRENT_DLL_PATH + .get_or_init(|| { + use std::ffi::{CStr, OsStr}; + use std::os::unix::prelude::*; + + #[cfg(not(target_os = "aix"))] + unsafe { + let addr = current_dll_path as usize as *mut _; + let mut info = std::mem::zeroed(); + if libc::dladdr(addr, &mut info) == 0 { + return Err("dladdr failed".into()); } - buffer.resize(buffer.len() * 2, std::mem::zeroed::<libc::ld_info>()); - } - } - let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; - loop { - let data_base = (*current).ldinfo_dataorg as u64; - let data_end = data_base + (*current).ldinfo_datasize; - if (data_base..data_end).contains(&addr) { - let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); + if info.dli_fname.is_null() { + return Err("dladdr returned null pointer".into()); + } + let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); let os = OsStr::from_bytes(bytes); - return Ok(PathBuf::from(os)); + Ok(PathBuf::from(os)) } - if (*current).ldinfo_next == 0 { - break; + + #[cfg(target_os = "aix")] + unsafe { + // On AIX, the symbol `current_dll_path` references a function descriptor. + // A function descriptor is consisted of (See https://reviews.llvm.org/D62532) + // * The address of the entry point of the function. + // * The TOC base address for the function. + // * The environment pointer. + // The function descriptor is in the data section. + let addr = current_dll_path as u64; + let mut buffer = vec![std::mem::zeroed::<libc::ld_info>(); 64]; + loop { + if libc::loadquery( + libc::L_GETINFO, + buffer.as_mut_ptr() as *mut u8, + (size_of::<libc::ld_info>() * buffer.len()) as u32, + ) >= 0 + { + break; + } else { + if std::io::Error::last_os_error().raw_os_error().unwrap() != libc::ENOMEM { + return Err("loadquery failed".into()); + } + buffer.resize(buffer.len() * 2, std::mem::zeroed::<libc::ld_info>()); + } + } + let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; + loop { + let data_base = (*current).ldinfo_dataorg as u64; + let data_end = data_base + (*current).ldinfo_datasize; + if (data_base..data_end).contains(&addr) { + let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); + let os = OsStr::from_bytes(bytes); + return Ok(PathBuf::from(os)); + } + if (*current).ldinfo_next == 0 { + break; + } + current = (current as *mut i8).offset((*current).ldinfo_next as isize) + as *mut libc::ld_info; + } + return Err(format!("current dll's address {} is not in the load map", addr)); } - current = - (current as *mut i8).offset((*current).ldinfo_next as isize) as *mut libc::ld_info; - } - return Err(format!("current dll's address {} is not in the load map", addr)); - } + }) + .clone() } #[cfg(windows)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index b3be4b611f0..d2f202eb24e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2227,7 +2227,8 @@ options! { incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED], "verify extended properties for incr. comp. (default: no): - hashes of green query instances - - hash collisions of query keys"), + - hash collisions of query keys + - hash collisions when creating dep-nodes"), inline_llvm: bool = (true, parse_bool, [TRACKED], "enable LLVM inlining (default: yes)"), inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED], diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 015ddc6e273..210966bed62 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1003,7 +1003,6 @@ symbols! { forbid, forget, format, - format_alignment, format_args, format_args_capture, format_args_macro, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 1887134c575..263646d8347 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3342,7 +3342,10 @@ impl Target { ); } "arm" => { - check!(self.llvm_floatabi.is_some(), "ARM targets must specify their float ABI",) + check!( + self.llvm_floatabi.is_some(), + "ARM targets must set `llvm-floatabi` to `hard` or `soft`", + ) } _ => {} } diff --git a/compiler/rustc_trait_selection/src/solve/delegate.rs b/compiler/rustc_trait_selection/src/solve/delegate.rs index af5a60027ba..3d9a90eb74e 100644 --- a/compiler/rustc_trait_selection/src/solve/delegate.rs +++ b/compiler/rustc_trait_selection/src/solve/delegate.rs @@ -96,7 +96,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate< ) -> Option<Vec<Goal<'tcx, ty::Predicate<'tcx>>>> { crate::traits::wf::unnormalized_obligations(&self.0, param_env, arg, DUMMY_SP, CRATE_DEF_ID) .map(|obligations| { - obligations.into_iter().map(|obligation| obligation.into()).collect() + obligations.into_iter().map(|obligation| obligation.as_goal()).collect() }) } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index 704ba6e501d..192e632a2d5 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -80,7 +80,7 @@ impl<'tcx> ObligationStorage<'tcx> { // change. // FIXME: <https://github.com/Gankra/thin-vec/pull/66> is merged, this can be removed. self.overflowed.extend(ExtractIf::new(&mut self.pending, |o| { - let goal = o.clone().into(); + let goal = o.as_goal(); let result = <&SolverDelegate<'tcx>>::from(infcx) .evaluate_root_goal(goal, GenerateProofTree::No, o.cause.span) .0; @@ -161,7 +161,7 @@ where let mut has_changed = false; for obligation in self.obligations.unstalled_for_select() { - let goal = obligation.clone().into(); + let goal = obligation.as_goal(); let result = <&SolverDelegate<'tcx>>::from(infcx) .evaluate_root_goal(goal, GenerateProofTree::No, obligation.cause.span) .0; diff --git a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs index 352ac7c1a4e..3a939df25e0 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_next_trait_solver::solve::{GenerateProofTree, SolverDelegateEvalExt as _}; -use rustc_type_ir::solve::{Goal, NoSolution}; +use rustc_type_ir::solve::NoSolution; use tracing::{instrument, trace}; use crate::solve::Certainty; @@ -89,7 +89,7 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>( let (code, refine_obligation) = infcx.probe(|_| { match <&SolverDelegate<'tcx>>::from(infcx) .evaluate_root_goal( - root_obligation.clone().into(), + root_obligation.as_goal(), GenerateProofTree::No, root_obligation.cause.span, ) @@ -155,7 +155,7 @@ fn find_best_leaf_obligation<'tcx>( .fudge_inference_if_ok(|| { infcx .visit_proof_tree( - obligation.clone().into(), + obligation.as_goal(), &mut BestObligation { obligation: obligation.clone(), consider_ambiguities }, ) .break_value() @@ -245,7 +245,7 @@ impl<'tcx> BestObligation<'tcx> { { let nested_goal = candidate.instantiate_proof_tree_for_nested_goal( GoalSource::Misc, - Goal::new(infcx.tcx, obligation.param_env, obligation.predicate), + obligation.as_goal(), self.span(), ); // Skip nested goals that aren't the *reason* for our goal's failure. diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 4c7172c3278..bcc247ba53c 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -625,7 +625,7 @@ fn compute_intercrate_ambiguity_causes<'tcx>( let mut causes: FxIndexSet<IntercrateAmbiguityCause<'tcx>> = Default::default(); for obligation in obligations { - search_ambiguity_causes(infcx, obligation.clone().into(), &mut causes); + search_ambiguity_causes(infcx, obligation.as_goal(), &mut causes); } causes diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index 81aa4a1f19e..6a2498242fe 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -111,18 +111,20 @@ bitflags::bitflags! { /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? - const STILL_FURTHER_SPECIALIZABLE = 1 << 21; + const STILL_FURTHER_SPECIALIZABLE = TypeFlags::HAS_TY_PARAM.bits() + | TypeFlags::HAS_TY_PLACEHOLDER.bits() + | TypeFlags::HAS_TY_INFER.bits() + | TypeFlags::HAS_CT_PARAM.bits() + | TypeFlags::HAS_CT_PLACEHOLDER.bits() + | TypeFlags::HAS_CT_INFER.bits(); /// Does this value have `InferTy::FreshTy/FreshIntTy/FreshFloatTy`? - const HAS_TY_FRESH = 1 << 22; + const HAS_TY_FRESH = 1 << 21; /// Does this value have `InferConst::Fresh`? - const HAS_CT_FRESH = 1 << 23; - - /// Does this have `Coroutine` or `CoroutineWitness`? - const HAS_TY_COROUTINE = 1 << 24; + const HAS_CT_FRESH = 1 << 22; /// Does this have any binders with bound vars (e.g. that need to be anonymized)? - const HAS_BINDER_VARS = 1 << 25; + const HAS_BINDER_VARS = 1 << 23; } } diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 119b658a2bf..2285e0e75de 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -269,10 +269,6 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> { self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) } - fn has_coroutines(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_COROUTINE) - } - fn references_error(&self) -> bool { self.has_type_flags(TypeFlags::HAS_ERROR) } diff --git a/compiler/stable_mir/src/mir.rs b/compiler/stable_mir/src/mir.rs index 82555461d64..413b5152bb3 100644 --- a/compiler/stable_mir/src/mir.rs +++ b/compiler/stable_mir/src/mir.rs @@ -5,4 +5,4 @@ pub mod pretty; pub mod visit; pub use body::*; -pub use visit::MirVisitor; +pub use visit::{MirVisitor, MutMirVisitor}; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index f8b46f50a52..b1bf7bce828 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -77,6 +77,22 @@ impl Body { &self.locals[self.arg_count + 1..] } + /// Returns a mutable reference to the local that holds this function's return value. + pub(crate) fn ret_local_mut(&mut self) -> &mut LocalDecl { + &mut self.locals[RETURN_LOCAL] + } + + /// Returns a mutable slice of locals corresponding to this function's arguments. + pub(crate) fn arg_locals_mut(&mut self) -> &mut [LocalDecl] { + &mut self.locals[1..][..self.arg_count] + } + + /// Returns a mutable slice of inner locals for this function. + /// Inner locals are those that are neither the return local nor the argument locals. + pub(crate) fn inner_locals_mut(&mut self) -> &mut [LocalDecl] { + &mut self.locals[self.arg_count + 1..] + } + /// Convenience function to get all the locals in this function. /// /// Locals are typically accessed via the more specific methods `ret_local`, diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index d985a98fcbf..09447e70dfb 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -39,406 +39,486 @@ use crate::mir::*; use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst}; use crate::{Error, Opaque, Span}; -pub trait MirVisitor { - fn visit_body(&mut self, body: &Body) { - self.super_body(body) - } - - fn visit_basic_block(&mut self, bb: &BasicBlock) { - self.super_basic_block(bb) - } - - fn visit_ret_decl(&mut self, local: Local, decl: &LocalDecl) { - self.super_ret_decl(local, decl) - } - - fn visit_arg_decl(&mut self, local: Local, decl: &LocalDecl) { - self.super_arg_decl(local, decl) - } - - fn visit_local_decl(&mut self, local: Local, decl: &LocalDecl) { - self.super_local_decl(local, decl) - } - - fn visit_statement(&mut self, stmt: &Statement, location: Location) { - self.super_statement(stmt, location) - } - - fn visit_terminator(&mut self, term: &Terminator, location: Location) { - self.super_terminator(term, location) - } - - fn visit_span(&mut self, span: &Span) { - self.super_span(span) - } +macro_rules! make_mir_visitor { + ($visitor_trait_name:ident, $($mutability:ident)?) => { + pub trait $visitor_trait_name { + fn visit_body(&mut self, body: &$($mutability)? Body) { + self.super_body(body) + } - fn visit_place(&mut self, place: &Place, ptx: PlaceContext, location: Location) { - self.super_place(place, ptx, location) - } + fn visit_basic_block(&mut self, bb: &$($mutability)? BasicBlock) { + self.super_basic_block(bb) + } - fn visit_projection_elem( - &mut self, - place_ref: PlaceRef<'_>, - elem: &ProjectionElem, - ptx: PlaceContext, - location: Location, - ) { - let _ = place_ref; - self.super_projection_elem(elem, ptx, location); - } + fn visit_ret_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + self.super_ret_decl(local, decl) + } - fn visit_local(&mut self, local: &Local, ptx: PlaceContext, location: Location) { - let _ = (local, ptx, location); - } + fn visit_arg_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + self.super_arg_decl(local, decl) + } - fn visit_rvalue(&mut self, rvalue: &Rvalue, location: Location) { - self.super_rvalue(rvalue, location) - } + fn visit_local_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + self.super_local_decl(local, decl) + } - fn visit_operand(&mut self, operand: &Operand, location: Location) { - self.super_operand(operand, location) - } + fn visit_statement(&mut self, stmt: &$($mutability)? Statement, location: Location) { + self.super_statement(stmt, location) + } - fn visit_user_type_projection(&mut self, projection: &UserTypeProjection) { - self.super_user_type_projection(projection) - } + fn visit_terminator(&mut self, term: &$($mutability)? Terminator, location: Location) { + self.super_terminator(term, location) + } - fn visit_ty(&mut self, ty: &Ty, location: Location) { - let _ = location; - self.super_ty(ty) - } + fn visit_span(&mut self, span: &$($mutability)? Span) { + self.super_span(span) + } - fn visit_const_operand(&mut self, constant: &ConstOperand, location: Location) { - self.super_const_operand(constant, location) - } + fn visit_place(&mut self, place: &$($mutability)? Place, ptx: PlaceContext, location: Location) { + self.super_place(place, ptx, location) + } - fn visit_mir_const(&mut self, constant: &MirConst, location: Location) { - self.super_mir_const(constant, location) - } + visit_place_fns!($($mutability)?); - fn visit_ty_const(&mut self, constant: &TyConst, location: Location) { - let _ = location; - self.super_ty_const(constant) - } + fn visit_local(&mut self, local: &$($mutability)? Local, ptx: PlaceContext, location: Location) { + let _ = (local, ptx, location); + } - fn visit_region(&mut self, region: &Region, location: Location) { - let _ = location; - self.super_region(region) - } + fn visit_rvalue(&mut self, rvalue: &$($mutability)? Rvalue, location: Location) { + self.super_rvalue(rvalue, location) + } - fn visit_args(&mut self, args: &GenericArgs, location: Location) { - let _ = location; - self.super_args(args) - } + fn visit_operand(&mut self, operand: &$($mutability)? Operand, location: Location) { + self.super_operand(operand, location) + } - fn visit_assert_msg(&mut self, msg: &AssertMessage, location: Location) { - self.super_assert_msg(msg, location) - } + fn visit_user_type_projection(&mut self, projection: &$($mutability)? UserTypeProjection) { + self.super_user_type_projection(projection) + } - fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) { - self.super_var_debug_info(var_debug_info); - } + fn visit_ty(&mut self, ty: &$($mutability)? Ty, location: Location) { + let _ = location; + self.super_ty(ty) + } - fn super_body(&mut self, body: &Body) { - let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _, span } = body; + fn visit_const_operand(&mut self, constant: &$($mutability)? ConstOperand, location: Location) { + self.super_const_operand(constant, location) + } - for bb in blocks { - self.visit_basic_block(bb); - } + fn visit_mir_const(&mut self, constant: &$($mutability)? MirConst, location: Location) { + self.super_mir_const(constant, location) + } - self.visit_ret_decl(RETURN_LOCAL, body.ret_local()); + fn visit_ty_const(&mut self, constant: &$($mutability)? TyConst, location: Location) { + let _ = location; + self.super_ty_const(constant) + } - for (idx, arg) in body.arg_locals().iter().enumerate() { - self.visit_arg_decl(idx + 1, arg) - } + fn visit_region(&mut self, region: &$($mutability)? Region, location: Location) { + let _ = location; + self.super_region(region) + } - let local_start = arg_count + 1; - for (idx, arg) in body.inner_locals().iter().enumerate() { - self.visit_local_decl(idx + local_start, arg) - } + fn visit_args(&mut self, args: &$($mutability)? GenericArgs, location: Location) { + let _ = location; + self.super_args(args) + } - for info in var_debug_info.iter() { - self.visit_var_debug_info(info); - } + fn visit_assert_msg(&mut self, msg: &$($mutability)? AssertMessage, location: Location) { + self.super_assert_msg(msg, location) + } - self.visit_span(span) - } + fn visit_var_debug_info(&mut self, var_debug_info: &$($mutability)? VarDebugInfo) { + self.super_var_debug_info(var_debug_info); + } - fn super_basic_block(&mut self, bb: &BasicBlock) { - let BasicBlock { statements, terminator } = bb; - for stmt in statements { - self.visit_statement(stmt, Location(stmt.span)); - } - self.visit_terminator(terminator, Location(terminator.span)); - } + fn super_body(&mut self, body: &$($mutability)? Body) { + super_body!(self, body, $($mutability)?); + } - fn super_local_decl(&mut self, local: Local, decl: &LocalDecl) { - let _ = local; - let LocalDecl { ty, span, .. } = decl; - self.visit_ty(ty, Location(*span)); - } + fn super_basic_block(&mut self, bb: &$($mutability)? BasicBlock) { + let BasicBlock { statements, terminator } = bb; + for stmt in statements { + self.visit_statement(stmt, Location(stmt.span)); + } + self.visit_terminator(terminator, Location(terminator.span)); + } - fn super_ret_decl(&mut self, local: Local, decl: &LocalDecl) { - self.super_local_decl(local, decl) - } + fn super_local_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + let _ = local; + let LocalDecl { ty, span, .. } = decl; + self.visit_ty(ty, Location(*span)); + } - fn super_arg_decl(&mut self, local: Local, decl: &LocalDecl) { - self.super_local_decl(local, decl) - } + fn super_ret_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + self.super_local_decl(local, decl) + } - fn super_statement(&mut self, stmt: &Statement, location: Location) { - let Statement { kind, span } = stmt; - self.visit_span(span); - match kind { - StatementKind::Assign(place, rvalue) => { - self.visit_place(place, PlaceContext::MUTATING, location); - self.visit_rvalue(rvalue, location); - } - StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => { - self.visit_place(place, PlaceContext::NON_MUTATING, location); - } - StatementKind::SetDiscriminant { place, .. } - | StatementKind::Deinit(place) - | StatementKind::Retag(_, place) => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { - self.visit_local(local, PlaceContext::NON_USE, location); - } - StatementKind::AscribeUserType { place, projections, variance: _ } => { - self.visit_place(place, PlaceContext::NON_USE, location); - self.visit_user_type_projection(projections); - } - StatementKind::Coverage(coverage) => visit_opaque(coverage), - StatementKind::Intrinsic(intrisic) => match intrisic { - NonDivergingIntrinsic::Assume(operand) => { - self.visit_operand(operand, location); - } - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { - src, - dst, - count, - }) => { - self.visit_operand(src, location); - self.visit_operand(dst, location); - self.visit_operand(count, location); - } - }, - StatementKind::ConstEvalCounter | StatementKind::Nop => {} - } - } + fn super_arg_decl(&mut self, local: Local, decl: &$($mutability)? LocalDecl) { + self.super_local_decl(local, decl) + } - fn super_terminator(&mut self, term: &Terminator, location: Location) { - let Terminator { kind, span } = term; - self.visit_span(span); - match kind { - TerminatorKind::Goto { .. } - | TerminatorKind::Resume - | TerminatorKind::Abort - | TerminatorKind::Unreachable => {} - TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { - self.visit_operand(cond, location); - self.visit_assert_msg(msg, location); - } - TerminatorKind::Drop { place, target: _, unwind: _ } => { - self.visit_place(place, PlaceContext::MUTATING, location); - } - TerminatorKind::Call { func, args, destination, target: _, unwind: _ } => { - self.visit_operand(func, location); - for arg in args { - self.visit_operand(arg, location); + fn super_statement(&mut self, stmt: &$($mutability)? Statement, location: Location) { + let Statement { kind, span } = stmt; + self.visit_span(span); + match kind { + StatementKind::Assign(place, rvalue) => { + self.visit_place(place, PlaceContext::MUTATING, location); + self.visit_rvalue(rvalue, location); + } + StatementKind::FakeRead(_, place) | StatementKind::PlaceMention(place) => { + self.visit_place(place, PlaceContext::NON_MUTATING, location); + } + StatementKind::SetDiscriminant { place, .. } + | StatementKind::Deinit(place) + | StatementKind::Retag(_, place) => { + self.visit_place(place, PlaceContext::MUTATING, location); + } + StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { + self.visit_local(local, PlaceContext::NON_USE, location); + } + StatementKind::AscribeUserType { place, projections, variance: _ } => { + self.visit_place(place, PlaceContext::NON_USE, location); + self.visit_user_type_projection(projections); + } + StatementKind::Coverage(coverage) => visit_opaque(coverage), + StatementKind::Intrinsic(intrisic) => match intrisic { + NonDivergingIntrinsic::Assume(operand) => { + self.visit_operand(operand, location); + } + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src, + dst, + count, + }) => { + self.visit_operand(src, location); + self.visit_operand(dst, location); + self.visit_operand(count, location); + } + }, + StatementKind::ConstEvalCounter | StatementKind::Nop => {} } - self.visit_place(destination, PlaceContext::MUTATING, location); } - TerminatorKind::InlineAsm { operands, .. } => { - for op in operands { - let InlineAsmOperand { in_value, out_place, raw_rpr: _ } = op; - if let Some(input) = in_value { - self.visit_operand(input, location); + + fn super_terminator(&mut self, term: &$($mutability)? Terminator, location: Location) { + let Terminator { kind, span } = term; + self.visit_span(span); + match kind { + TerminatorKind::Goto { .. } + | TerminatorKind::Resume + | TerminatorKind::Abort + | TerminatorKind::Unreachable => {} + TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { + self.visit_operand(cond, location); + self.visit_assert_msg(msg, location); + } + TerminatorKind::Drop { place, target: _, unwind: _ } => { + self.visit_place(place, PlaceContext::MUTATING, location); + } + TerminatorKind::Call { func, args, destination, target: _, unwind: _ } => { + self.visit_operand(func, location); + for arg in args { + self.visit_operand(arg, location); + } + self.visit_place(destination, PlaceContext::MUTATING, location); + } + TerminatorKind::InlineAsm { operands, .. } => { + for op in operands { + let InlineAsmOperand { in_value, out_place, raw_rpr: _ } = op; + if let Some(input) = in_value { + self.visit_operand(input, location); + } + if let Some(output) = out_place { + self.visit_place(output, PlaceContext::MUTATING, location); + } + } } - if let Some(output) = out_place { - self.visit_place(output, PlaceContext::MUTATING, location); + TerminatorKind::Return => { + let $($mutability)? local = RETURN_LOCAL; + self.visit_local(&$($mutability)? local, PlaceContext::NON_MUTATING, location); + } + TerminatorKind::SwitchInt { discr, targets: _ } => { + self.visit_operand(discr, location); } } } - TerminatorKind::Return => { - let local = RETURN_LOCAL; - self.visit_local(&local, PlaceContext::NON_MUTATING, location); - } - TerminatorKind::SwitchInt { discr, targets: _ } => { - self.visit_operand(discr, location); - } - } - } - fn super_span(&mut self, span: &Span) { - let _ = span; - } - - fn super_place(&mut self, place: &Place, ptx: PlaceContext, location: Location) { - let _ = location; - let _ = ptx; - self.visit_local(&place.local, ptx, location); + fn super_span(&mut self, span: &$($mutability)? Span) { + let _ = span; + } - for (idx, elem) in place.projection.iter().enumerate() { - let place_ref = PlaceRef { local: place.local, projection: &place.projection[..idx] }; - self.visit_projection_elem(place_ref, elem, ptx, location); - } - } + fn super_rvalue(&mut self, rvalue: &$($mutability)? Rvalue, location: Location) { + match rvalue { + Rvalue::AddressOf(mutability, place) => { + let pcx = PlaceContext { is_mut: *mutability == RawPtrKind::Mut }; + self.visit_place(place, pcx, location); + } + Rvalue::Aggregate(_, operands) => { + for op in operands { + self.visit_operand(op, location); + } + } + Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { + self.visit_operand(lhs, location); + self.visit_operand(rhs, location); + } + Rvalue::Cast(_, op, ty) => { + self.visit_operand(op, location); + self.visit_ty(ty, location); + } + Rvalue::CopyForDeref(place) | Rvalue::Discriminant(place) | Rvalue::Len(place) => { + self.visit_place(place, PlaceContext::NON_MUTATING, location); + } + Rvalue::Ref(region, kind, place) => { + self.visit_region(region, location); + let pcx = PlaceContext { is_mut: matches!(kind, BorrowKind::Mut { .. }) }; + self.visit_place(place, pcx, location); + } + Rvalue::Repeat(op, constant) => { + self.visit_operand(op, location); + self.visit_ty_const(constant, location); + } + Rvalue::ShallowInitBox(op, ty) => { + self.visit_ty(ty, location); + self.visit_operand(op, location) + } + Rvalue::ThreadLocalRef(_) => {} + Rvalue::NullaryOp(_, ty) => { + self.visit_ty(ty, location); + } + Rvalue::UnaryOp(_, op) | Rvalue::Use(op) => { + self.visit_operand(op, location); + } + } + } - fn super_projection_elem( - &mut self, - elem: &ProjectionElem, - ptx: PlaceContext, - location: Location, - ) { - match elem { - ProjectionElem::Downcast(_idx) => {} - ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } - | ProjectionElem::Deref - | ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} - ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), - ProjectionElem::Index(local) => self.visit_local(local, ptx, location), - ProjectionElem::OpaqueCast(ty) | ProjectionElem::Subtype(ty) => { - self.visit_ty(ty, location) + fn super_operand(&mut self, operand: &$($mutability)? Operand, location: Location) { + match operand { + Operand::Copy(place) | Operand::Move(place) => { + self.visit_place(place, PlaceContext::NON_MUTATING, location) + } + Operand::Constant(constant) => { + self.visit_const_operand(constant, location); + } + } } - } - } - fn super_rvalue(&mut self, rvalue: &Rvalue, location: Location) { - match rvalue { - Rvalue::AddressOf(mutability, place) => { - let pcx = PlaceContext { is_mut: *mutability == RawPtrKind::Mut }; - self.visit_place(place, pcx, location); + fn super_user_type_projection(&mut self, projection: &$($mutability)? UserTypeProjection) { + // This is a no-op on mir::Visitor. + let _ = projection; } - Rvalue::Aggregate(_, operands) => { - for op in operands { - self.visit_operand(op, location); - } + + fn super_ty(&mut self, ty: &$($mutability)? Ty) { + let _ = ty; } - Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => { - self.visit_operand(lhs, location); - self.visit_operand(rhs, location); + + fn super_const_operand(&mut self, constant: &$($mutability)? ConstOperand, location: Location) { + let ConstOperand { span, user_ty: _, const_ } = constant; + self.visit_span(span); + self.visit_mir_const(const_, location); } - Rvalue::Cast(_, op, ty) => { - self.visit_operand(op, location); + + fn super_mir_const(&mut self, constant: &$($mutability)? MirConst, location: Location) { + let MirConst { kind: _, ty, id: _ } = constant; self.visit_ty(ty, location); } - Rvalue::CopyForDeref(place) | Rvalue::Discriminant(place) | Rvalue::Len(place) => { - self.visit_place(place, PlaceContext::NON_MUTATING, location); - } - Rvalue::Ref(region, kind, place) => { - self.visit_region(region, location); - let pcx = PlaceContext { is_mut: matches!(kind, BorrowKind::Mut { .. }) }; - self.visit_place(place, pcx, location); + + fn super_ty_const(&mut self, constant: &$($mutability)? TyConst) { + let _ = constant; } - Rvalue::Repeat(op, constant) => { - self.visit_operand(op, location); - self.visit_ty_const(constant, location); + + fn super_region(&mut self, region: &$($mutability)? Region) { + let _ = region; } - Rvalue::ShallowInitBox(op, ty) => { - self.visit_ty(ty, location); - self.visit_operand(op, location) + + fn super_args(&mut self, args: &$($mutability)? GenericArgs) { + let _ = args; } - Rvalue::ThreadLocalRef(_) => {} - Rvalue::NullaryOp(_, ty) => { - self.visit_ty(ty, location); + + fn super_var_debug_info(&mut self, var_debug_info: &$($mutability)? VarDebugInfo) { + let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } = + var_debug_info; + self.visit_span(&$($mutability)? source_info.span); + let location = Location(source_info.span); + if let Some(composite) = composite { + self.visit_ty(&$($mutability)? composite.ty, location); + } + match value { + VarDebugInfoContents::Place(place) => { + self.visit_place(place, PlaceContext::NON_USE, location); + } + VarDebugInfoContents::Const(constant) => { + self.visit_mir_const(&$($mutability)? constant.const_, location); + } + } } - Rvalue::UnaryOp(_, op) | Rvalue::Use(op) => { - self.visit_operand(op, location); + + fn super_assert_msg(&mut self, msg: &$($mutability)? AssertMessage, location: Location) { + match msg { + AssertMessage::BoundsCheck { len, index } => { + self.visit_operand(len, location); + self.visit_operand(index, location); + } + AssertMessage::Overflow(_, left, right) => { + self.visit_operand(left, location); + self.visit_operand(right, location); + } + AssertMessage::OverflowNeg(op) + | AssertMessage::DivisionByZero(op) + | AssertMessage::RemainderByZero(op) => { + self.visit_operand(op, location); + } + AssertMessage::ResumedAfterReturn(_) + | AssertMessage::ResumedAfterPanic(_) + | AssertMessage::NullPointerDereference => { + //nothing to visit + } + AssertMessage::MisalignedPointerDereference { required, found } => { + self.visit_operand(required, location); + self.visit_operand(found, location); + } + } } } - } + }; +} - fn super_operand(&mut self, operand: &Operand, location: Location) { - match operand { - Operand::Copy(place) | Operand::Move(place) => { - self.visit_place(place, PlaceContext::NON_MUTATING, location) - } - Operand::Constant(constant) => { - self.visit_const_operand(constant, location); - } +macro_rules! super_body { + ($self:ident, $body:ident, mut) => { + for bb in $body.blocks.iter_mut() { + $self.visit_basic_block(bb); } - } - fn super_user_type_projection(&mut self, projection: &UserTypeProjection) { - // This is a no-op on mir::Visitor. - let _ = projection; - } + $self.visit_ret_decl(RETURN_LOCAL, $body.ret_local_mut()); - fn super_ty(&mut self, ty: &Ty) { - let _ = ty; - } + for (idx, arg) in $body.arg_locals_mut().iter_mut().enumerate() { + $self.visit_arg_decl(idx + 1, arg) + } - fn super_const_operand(&mut self, constant: &ConstOperand, location: Location) { - let ConstOperand { span, user_ty: _, const_ } = constant; - self.visit_span(span); - self.visit_mir_const(const_, location); - } + let local_start = $body.arg_count + 1; + for (idx, arg) in $body.inner_locals_mut().iter_mut().enumerate() { + $self.visit_local_decl(idx + local_start, arg) + } - fn super_mir_const(&mut self, constant: &MirConst, location: Location) { - let MirConst { kind: _, ty, id: _ } = constant; - self.visit_ty(ty, location); - } + for info in $body.var_debug_info.iter_mut() { + $self.visit_var_debug_info(info); + } - fn super_ty_const(&mut self, constant: &TyConst) { - let _ = constant; - } + $self.visit_span(&mut $body.span) + }; - fn super_region(&mut self, region: &Region) { - let _ = region; - } + ($self:ident, $body:ident, ) => { + let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _, span } = $body; - fn super_args(&mut self, args: &GenericArgs) { - let _ = args; - } + for bb in blocks { + $self.visit_basic_block(bb); + } - fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) { - let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } = - var_debug_info; - self.visit_span(&source_info.span); - let location = Location(source_info.span); - if let Some(composite) = composite { - self.visit_ty(&composite.ty, location); + $self.visit_ret_decl(RETURN_LOCAL, $body.ret_local()); + + for (idx, arg) in $body.arg_locals().iter().enumerate() { + $self.visit_arg_decl(idx + 1, arg) } - match value { - VarDebugInfoContents::Place(place) => { - self.visit_place(place, PlaceContext::NON_USE, location); - } - VarDebugInfoContents::Const(constant) => { - self.visit_mir_const(&constant.const_, location); - } + + let local_start = arg_count + 1; + for (idx, arg) in $body.inner_locals().iter().enumerate() { + $self.visit_local_decl(idx + local_start, arg) } - } - fn super_assert_msg(&mut self, msg: &AssertMessage, location: Location) { - match msg { - AssertMessage::BoundsCheck { len, index } => { - self.visit_operand(len, location); - self.visit_operand(index, location); - } - AssertMessage::Overflow(_, left, right) => { - self.visit_operand(left, location); - self.visit_operand(right, location); + for info in var_debug_info.iter() { + $self.visit_var_debug_info(info); + } + + $self.visit_span(span) + }; +} + +macro_rules! visit_place_fns { + (mut) => { + fn super_place(&mut self, place: &mut Place, ptx: PlaceContext, location: Location) { + self.visit_local(&mut place.local, ptx, location); + + for elem in place.projection.iter_mut() { + self.visit_projection_elem(elem, ptx, location); } - AssertMessage::OverflowNeg(op) - | AssertMessage::DivisionByZero(op) - | AssertMessage::RemainderByZero(op) => { - self.visit_operand(op, location); + } + + // We don't have to replicate the `process_projection()` like we did in + // `rustc_middle::mir::visit.rs` here because the `projection` field in `Place` + // of Stable-MIR is not an immutable borrow, unlike in `Place` of MIR. + fn visit_projection_elem( + &mut self, + elem: &mut ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + self.super_projection_elem(elem, ptx, location) + } + + fn super_projection_elem( + &mut self, + elem: &mut ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + match elem { + ProjectionElem::Deref => {} + ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), + ProjectionElem::Index(local) => self.visit_local(local, ptx, location), + ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {} + ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} + ProjectionElem::Downcast(_idx) => {} + ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), + ProjectionElem::Subtype(ty) => self.visit_ty(ty, location), } - AssertMessage::ResumedAfterReturn(_) - | AssertMessage::ResumedAfterPanic(_) - | AssertMessage::NullPointerDereference => { - //nothing to visit + } + }; + + () => { + fn super_place(&mut self, place: &Place, ptx: PlaceContext, location: Location) { + self.visit_local(&place.local, ptx, location); + + for (idx, elem) in place.projection.iter().enumerate() { + let place_ref = + PlaceRef { local: place.local, projection: &place.projection[..idx] }; + self.visit_projection_elem(place_ref, elem, ptx, location); } - AssertMessage::MisalignedPointerDereference { required, found } => { - self.visit_operand(required, location); - self.visit_operand(found, location); + } + + fn visit_projection_elem<'a>( + &mut self, + place_ref: PlaceRef<'a>, + elem: &ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + let _ = place_ref; + self.super_projection_elem(elem, ptx, location); + } + + fn super_projection_elem( + &mut self, + elem: &ProjectionElem, + ptx: PlaceContext, + location: Location, + ) { + match elem { + ProjectionElem::Deref => {} + ProjectionElem::Field(_idx, ty) => self.visit_ty(ty, location), + ProjectionElem::Index(local) => self.visit_local(local, ptx, location), + ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ } => {} + ProjectionElem::Subslice { from: _, to: _, from_end: _ } => {} + ProjectionElem::Downcast(_idx) => {} + ProjectionElem::OpaqueCast(ty) => self.visit_ty(ty, location), + ProjectionElem::Subtype(ty) => self.visit_ty(ty, location), } } - } + }; } +make_mir_visitor!(MirVisitor,); +make_mir_visitor!(MutMirVisitor, mut); + /// This function is a no-op that gets used to ensure this visitor is kept up-to-date. /// /// The idea is that whenever we replace an Opaque type by a real type, the compiler will fail diff --git a/library/Cargo.lock b/library/Cargo.lock index 104e0a3d010..6b1a0a08055 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -67,9 +67,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.151" +version = "0.1.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abc30f1766d387c35f2405e586d3e7a88230dc728ff78cd1d0bc59ae0b63154b" +checksum = "2153cf213eb259361567720ce55f6446f17acd0ccca87fb6dc05360578228a58" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 8d0253bd29a..b729d5e116d 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -16,7 +16,7 @@ bench = false [dependencies] core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] } +compiler_builtins = { version = "=0.1.152", features = ['rustc-dep-of-std'] } [features] compiler-builtins-mem = ['compiler_builtins/mem'] diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index e77caad6540..4644e37f809 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1149,9 +1149,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { Box(unsafe { Unique::new_unchecked(raw) }, alloc) } @@ -1203,9 +1202,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// [memory layout]: self#memory-layout #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self { + pub unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self { // SAFETY: guaranteed by the caller. unsafe { Box::from_raw_in(raw.as_ptr(), alloc) } } @@ -1550,9 +1548,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// to call it as `Box::allocator(&b)` instead of `b.allocator()`. This /// is so that there is no conflict with a method on the inner type. #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn allocator(b: &Self) -> &A { + pub fn allocator(b: &Self) -> &A { &b.1 } @@ -1639,8 +1636,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> { /// let bar = Pin::from(foo); /// ``` #[stable(feature = "box_into_pin", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn into_pin(boxed: Self) -> Pin<Self> + pub fn into_pin(boxed: Self) -> Pin<Self> where A: 'static, { diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 25bd17d5802..0b0dbf723b6 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -29,6 +29,7 @@ mod bytewise; pub(crate) use bytewise::BytewiseEq; use self::Ordering::*; +use crate::ops::ControlFlow; /// Trait for comparisons using the equality operator. /// @@ -1435,6 +1436,67 @@ pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> { fn ge(&self, other: &Rhs) -> bool { self.partial_cmp(other).is_some_and(Ordering::is_ge) } + + /// If `self == other`, returns `ControlFlow::Continue(())`. + /// Otherwise, returns `ControlFlow::Break(self < other)`. + /// + /// This is useful for chaining together calls when implementing a lexical + /// `PartialOrd::lt`, as it allows types (like primitives) which can cheaply + /// check `==` and `<` separately to do rather than needing to calculate + /// (then optimize out) the three-way `Ordering` result. + #[inline] + #[must_use] + // Added to improve the behaviour of tuples; not necessarily stabilization-track. + #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] + #[doc(hidden)] + fn __chaining_lt(&self, other: &Rhs) -> ControlFlow<bool> { + default_chaining_impl(self, other, Ordering::is_lt) + } + + /// Same as `__chaining_lt`, but for `<=` instead of `<`. + #[inline] + #[must_use] + #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] + #[doc(hidden)] + fn __chaining_le(&self, other: &Rhs) -> ControlFlow<bool> { + default_chaining_impl(self, other, Ordering::is_le) + } + + /// Same as `__chaining_lt`, but for `>` instead of `<`. + #[inline] + #[must_use] + #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] + #[doc(hidden)] + fn __chaining_gt(&self, other: &Rhs) -> ControlFlow<bool> { + default_chaining_impl(self, other, Ordering::is_gt) + } + + /// Same as `__chaining_lt`, but for `>=` instead of `<`. + #[inline] + #[must_use] + #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] + #[doc(hidden)] + fn __chaining_ge(&self, other: &Rhs) -> ControlFlow<bool> { + default_chaining_impl(self, other, Ordering::is_ge) + } +} + +fn default_chaining_impl<T: ?Sized, U: ?Sized>( + lhs: &T, + rhs: &U, + p: impl FnOnce(Ordering) -> bool, +) -> ControlFlow<bool> +where + T: PartialOrd<U>, +{ + // It's important that this only call `partial_cmp` once, not call `eq` then + // one of the relational operators. We don't want to `bcmp`-then-`memcp` a + // `String`, for example, or similarly for other data structures (#108157). + match <T as PartialOrd<U>>::partial_cmp(lhs, rhs) { + Some(Equal) => ControlFlow::Continue(()), + Some(c) => ControlFlow::Break(p(c)), + None => ControlFlow::Break(false), + } } /// Derive macro generating an impl of the trait [`PartialOrd`]. @@ -1741,6 +1803,7 @@ where mod impls { use crate::cmp::Ordering::{self, Equal, Greater, Less}; use crate::hint::unreachable_unchecked; + use crate::ops::ControlFlow::{self, Break, Continue}; macro_rules! partial_eq_impl { ($($t:ty)*) => ($( @@ -1779,6 +1842,35 @@ mod impls { eq_impl! { () bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 } + macro_rules! chaining_methods_impl { + ($t:ty) => { + // These implementations are the same for `Ord` or `PartialOrd` types + // because if either is NAN the `==` test will fail so we end up in + // the `Break` case and the comparison will correctly return `false`. + + #[inline] + fn __chaining_lt(&self, other: &Self) -> ControlFlow<bool> { + let (lhs, rhs) = (*self, *other); + if lhs == rhs { Continue(()) } else { Break(lhs < rhs) } + } + #[inline] + fn __chaining_le(&self, other: &Self) -> ControlFlow<bool> { + let (lhs, rhs) = (*self, *other); + if lhs == rhs { Continue(()) } else { Break(lhs <= rhs) } + } + #[inline] + fn __chaining_gt(&self, other: &Self) -> ControlFlow<bool> { + let (lhs, rhs) = (*self, *other); + if lhs == rhs { Continue(()) } else { Break(lhs > rhs) } + } + #[inline] + fn __chaining_ge(&self, other: &Self) -> ControlFlow<bool> { + let (lhs, rhs) = (*self, *other); + if lhs == rhs { Continue(()) } else { Break(lhs >= rhs) } + } + }; + } + macro_rules! partial_ord_impl { ($($t:ty)*) => ($( #[stable(feature = "rust1", since = "1.0.0")] @@ -1800,6 +1892,8 @@ mod impls { fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } #[inline(always)] fn gt(&self, other: &$t) -> bool { (*self) > (*other) } + + chaining_methods_impl!($t); } )*) } @@ -1838,6 +1932,8 @@ mod impls { fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } #[inline(always)] fn gt(&self, other: &$t) -> bool { (*self) > (*other) } + + chaining_methods_impl!($t); } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index 4a43c12be9a..870ad9df4fd 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -86,7 +86,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.options.precision { + if let Some(precision) = fmt.options.get_precision() { float_to_decimal_common_exact(fmt, num, sign, precision) } else { let min_precision = 0; @@ -162,7 +162,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.options.precision { + if let Some(precision) = fmt.options.get_precision() { // 1 integral digit + `precision` fractional digits = `precision + 1` total digits float_to_exponential_common_exact(fmt, num, sign, precision + 1, upper) } else { @@ -180,7 +180,7 @@ where true => flt2dec::Sign::MinusPlus, }; - if let Some(precision) = fmt.options.precision { + if let Some(precision) = fmt.options.get_precision() { // this behavior of {:.PREC?} predates exponential formatting for {:?} float_to_decimal_common_exact(fmt, num, sign, precision) } else { diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 48f36044471..30fd2d7815f 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -33,19 +33,6 @@ pub enum Alignment { Center, } -#[doc(hidden)] -#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")] -impl From<rt::Alignment> for Option<Alignment> { - fn from(value: rt::Alignment) -> Self { - match value { - rt::Alignment::Left => Some(Alignment::Left), - rt::Alignment::Right => Some(Alignment::Right), - rt::Alignment::Center => Some(Alignment::Center), - rt::Alignment::Unknown => None, - } - } -} - #[stable(feature = "debug_builders", since = "1.2.0")] pub use self::builders::{DebugList, DebugMap, DebugSet, DebugStruct, DebugTuple}; #[unstable(feature = "debug_closure_helpers", issue = "117729")] @@ -291,11 +278,52 @@ pub enum DebugAsHex { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[unstable(feature = "formatting_options", issue = "118117")] pub struct FormattingOptions { + /// Flags, with the following bit fields: + /// + /// ```text + /// 31 30 29 28 27 26 25 24 23 22 21 20 0 + /// ┌───┬───────┬───┬───┬───┬───┬───┬───┬───┬───┬──────────────────────────────────┐ + /// │ 1 │ align │ p │ w │ X?│ x?│'0'│ # │ - │ + │ fill │ + /// └───┴───────┴───┴───┴───┴───┴───┴───┴───┴───┴──────────────────────────────────┘ + /// │ │ │ │ └─┬───────────────────┘ └─┬──────────────────────────────┘ + /// │ │ │ │ │ └─ The fill character (21 bits char). + /// │ │ │ │ └─ The debug upper/lower hex, zero pad, alternate, and plus/minus flags. + /// │ │ │ └─ Whether a width is set. (The value is stored separately.) + /// │ │ └─ Whether a precision is set. (The value is stored separately.) + /// │ ├─ 0: Align left. (<) + /// │ ├─ 1: Align right. (>) + /// │ ├─ 2: Align center. (^) + /// │ └─ 3: Alignment not set. (default) + /// └─ Always set. + /// This makes it possible to distinguish formatting flags from + /// a &str size when stored in (the upper bits of) the same field. + /// (fmt::Arguments will make use of this property in the future.) + /// ``` + // Note: This could use a special niche type with range 0x8000_0000..=0xfdd0ffff. + // It's unclear if that's useful, though. flags: u32, - fill: char, - align: Option<Alignment>, - width: Option<u16>, - precision: Option<u16>, + /// Width if width flag (bit 27) above is set. Otherwise, always 0. + width: u16, + /// Precision if precision flag (bit 28) above is set. Otherwise, always 0. + precision: u16, +} + +// This needs to match with compiler/rustc_ast_lowering/src/format.rs. +mod flags { + pub(super) const SIGN_PLUS_FLAG: u32 = 1 << 21; + pub(super) const SIGN_MINUS_FLAG: u32 = 1 << 22; + pub(super) const ALTERNATE_FLAG: u32 = 1 << 23; + pub(super) const SIGN_AWARE_ZERO_PAD_FLAG: u32 = 1 << 24; + pub(super) const DEBUG_LOWER_HEX_FLAG: u32 = 1 << 25; + pub(super) const DEBUG_UPPER_HEX_FLAG: u32 = 1 << 26; + pub(super) const WIDTH_FLAG: u32 = 1 << 27; + pub(super) const PRECISION_FLAG: u32 = 1 << 28; + pub(super) const ALIGN_BITS: u32 = 0b11 << 29; + pub(super) const ALIGN_LEFT: u32 = 0 << 29; + pub(super) const ALIGN_RIGHT: u32 = 1 << 29; + pub(super) const ALIGN_CENTER: u32 = 2 << 29; + pub(super) const ALIGN_UNKNOWN: u32 = 3 << 29; + pub(super) const ALWAYS_SET: u32 = 1 << 31; } impl FormattingOptions { @@ -311,7 +339,11 @@ impl FormattingOptions { /// - no [`DebugAsHex`] output mode. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn new() -> Self { - Self { flags: 0, fill: ' ', align: None, width: None, precision: None } + Self { + flags: ' ' as u32 | flags::ALIGN_UNKNOWN | flags::ALWAYS_SET, + width: 0, + precision: 0, + } } /// Sets or removes the sign (the `+` or the `-` flag). @@ -324,13 +356,12 @@ impl FormattingOptions { /// - `-`: Currently not used #[unstable(feature = "formatting_options", issue = "118117")] pub fn sign(&mut self, sign: Option<Sign>) -> &mut Self { - self.flags = - self.flags & !(1 << rt::Flag::SignMinus as u32 | 1 << rt::Flag::SignPlus as u32); - match sign { - None => {} - Some(Sign::Plus) => self.flags |= 1 << rt::Flag::SignPlus as u32, - Some(Sign::Minus) => self.flags |= 1 << rt::Flag::SignMinus as u32, - } + let sign = match sign { + None => 0, + Some(Sign::Plus) => flags::SIGN_PLUS_FLAG, + Some(Sign::Minus) => flags::SIGN_MINUS_FLAG, + }; + self.flags = self.flags & !(flags::SIGN_PLUS_FLAG | flags::SIGN_MINUS_FLAG) | sign; self } /// Sets or unsets the `0` flag. @@ -339,9 +370,9 @@ impl FormattingOptions { #[unstable(feature = "formatting_options", issue = "118117")] pub fn sign_aware_zero_pad(&mut self, sign_aware_zero_pad: bool) -> &mut Self { if sign_aware_zero_pad { - self.flags |= 1 << rt::Flag::SignAwareZeroPad as u32 + self.flags |= flags::SIGN_AWARE_ZERO_PAD_FLAG; } else { - self.flags &= !(1 << rt::Flag::SignAwareZeroPad as u32) + self.flags &= !flags::SIGN_AWARE_ZERO_PAD_FLAG; } self } @@ -356,9 +387,9 @@ impl FormattingOptions { #[unstable(feature = "formatting_options", issue = "118117")] pub fn alternate(&mut self, alternate: bool) -> &mut Self { if alternate { - self.flags |= 1 << rt::Flag::Alternate as u32 + self.flags |= flags::ALTERNATE_FLAG; } else { - self.flags &= !(1 << rt::Flag::Alternate as u32) + self.flags &= !flags::ALTERNATE_FLAG; } self } @@ -370,7 +401,7 @@ impl FormattingOptions { /// printed around it. #[unstable(feature = "formatting_options", issue = "118117")] pub fn fill(&mut self, fill: char) -> &mut Self { - self.fill = fill; + self.flags = self.flags & (u32::MAX << 21) | fill as u32; self } /// Sets or removes the alignment. @@ -379,7 +410,13 @@ impl FormattingOptions { /// positioned if it is smaller than the width of the formatter. #[unstable(feature = "formatting_options", issue = "118117")] pub fn align(&mut self, align: Option<Alignment>) -> &mut Self { - self.align = align; + let align: u32 = match align { + Some(Alignment::Left) => flags::ALIGN_LEFT, + Some(Alignment::Right) => flags::ALIGN_RIGHT, + Some(Alignment::Center) => flags::ALIGN_CENTER, + None => flags::ALIGN_UNKNOWN, + }; + self.flags = self.flags & !flags::ALIGN_BITS | align; self } /// Sets or removes the width. @@ -390,7 +427,13 @@ impl FormattingOptions { /// will be used to take up the required space. #[unstable(feature = "formatting_options", issue = "118117")] pub fn width(&mut self, width: Option<u16>) -> &mut Self { - self.width = width; + if let Some(width) = width { + self.flags |= flags::WIDTH_FLAG; + self.width = width; + } else { + self.flags &= !flags::WIDTH_FLAG; + self.width = 0; + } self } /// Sets or removes the precision. @@ -404,77 +447,85 @@ impl FormattingOptions { /// decimal point should be printed. #[unstable(feature = "formatting_options", issue = "118117")] pub fn precision(&mut self, precision: Option<u16>) -> &mut Self { - self.precision = precision; + if let Some(precision) = precision { + self.flags |= flags::PRECISION_FLAG; + self.precision = precision; + } else { + self.flags &= !flags::PRECISION_FLAG; + self.precision = 0; + } self } /// Specifies whether the [`Debug`] trait should use lower-/upper-case /// hexadecimal or normal integers #[unstable(feature = "formatting_options", issue = "118117")] pub fn debug_as_hex(&mut self, debug_as_hex: Option<DebugAsHex>) -> &mut Self { - self.flags = self.flags - & !(1 << rt::Flag::DebugUpperHex as u32 | 1 << rt::Flag::DebugLowerHex as u32); - match debug_as_hex { - None => {} - Some(DebugAsHex::Upper) => self.flags |= 1 << rt::Flag::DebugUpperHex as u32, - Some(DebugAsHex::Lower) => self.flags |= 1 << rt::Flag::DebugLowerHex as u32, - } + let debug_as_hex = match debug_as_hex { + None => 0, + Some(DebugAsHex::Lower) => flags::DEBUG_LOWER_HEX_FLAG, + Some(DebugAsHex::Upper) => flags::DEBUG_UPPER_HEX_FLAG, + }; + self.flags = self.flags & !(flags::DEBUG_LOWER_HEX_FLAG | flags::DEBUG_UPPER_HEX_FLAG) + | debug_as_hex; self } /// Returns the current sign (the `+` or the `-` flag). #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_sign(&self) -> Option<Sign> { - const SIGN_PLUS_BITFIELD: u32 = 1 << rt::Flag::SignPlus as u32; - const SIGN_MINUS_BITFIELD: u32 = 1 << rt::Flag::SignMinus as u32; - match self.flags & ((1 << rt::Flag::SignPlus as u32) | (1 << rt::Flag::SignMinus as u32)) { - SIGN_PLUS_BITFIELD => Some(Sign::Plus), - SIGN_MINUS_BITFIELD => Some(Sign::Minus), - 0 => None, - _ => panic!("Invalid sign bits set in flags"), + if self.flags & flags::SIGN_PLUS_FLAG != 0 { + Some(Sign::Plus) + } else if self.flags & flags::SIGN_MINUS_FLAG != 0 { + Some(Sign::Minus) + } else { + None } } /// Returns the current `0` flag. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_sign_aware_zero_pad(&self) -> bool { - self.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0 + self.flags & flags::SIGN_AWARE_ZERO_PAD_FLAG != 0 } /// Returns the current `#` flag. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_alternate(&self) -> bool { - self.flags & (1 << rt::Flag::Alternate as u32) != 0 + self.flags & flags::ALTERNATE_FLAG != 0 } /// Returns the current fill character. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_fill(&self) -> char { - self.fill + // SAFETY: We only ever put a valid `char` in the lower 21 bits of the flags field. + unsafe { char::from_u32_unchecked(self.flags & 0x1FFFFF) } } /// Returns the current alignment. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_align(&self) -> Option<Alignment> { - self.align + match self.flags & flags::ALIGN_BITS { + flags::ALIGN_LEFT => Some(Alignment::Left), + flags::ALIGN_RIGHT => Some(Alignment::Right), + flags::ALIGN_CENTER => Some(Alignment::Center), + _ => None, + } } /// Returns the current width. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_width(&self) -> Option<u16> { - self.width + if self.flags & flags::WIDTH_FLAG != 0 { Some(self.width) } else { None } } /// Returns the current precision. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_precision(&self) -> Option<u16> { - self.precision + if self.flags & flags::PRECISION_FLAG != 0 { Some(self.precision) } else { None } } /// Returns the current precision. #[unstable(feature = "formatting_options", issue = "118117")] pub const fn get_debug_as_hex(&self) -> Option<DebugAsHex> { - const DEBUG_UPPER_BITFIELD: u32 = 1 << rt::Flag::DebugUpperHex as u32; - const DEBUG_LOWER_BITFIELD: u32 = 1 << rt::Flag::DebugLowerHex as u32; - match self.flags - & ((1 << rt::Flag::DebugUpperHex as u32) | (1 << rt::Flag::DebugLowerHex as u32)) - { - DEBUG_UPPER_BITFIELD => Some(DebugAsHex::Upper), - DEBUG_LOWER_BITFIELD => Some(DebugAsHex::Lower), - 0 => None, - _ => panic!("Invalid hex debug bits set in flags"), + if self.flags & flags::DEBUG_LOWER_HEX_FLAG != 0 { + Some(DebugAsHex::Lower) + } else if self.flags & flags::DEBUG_UPPER_HEX_FLAG != 0 { + Some(DebugAsHex::Upper) + } else { + None } } @@ -485,27 +536,6 @@ impl FormattingOptions { pub fn create_formatter<'a>(self, write: &'a mut (dyn Write + 'a)) -> Formatter<'a> { Formatter { options: self, buf: write } } - - #[doc(hidden)] - #[unstable( - feature = "fmt_internals", - reason = "internal routines only exposed for testing", - issue = "none" - )] - /// Flags for formatting - pub fn flags(&mut self, flags: u32) { - self.flags = flags - } - #[doc(hidden)] - #[unstable( - feature = "fmt_internals", - reason = "internal routines only exposed for testing", - issue = "none" - )] - /// Flags for formatting - pub fn get_flags(&self) -> u32 { - self.flags - } } #[unstable(feature = "formatting_options", issue = "118117")] @@ -1479,15 +1509,25 @@ pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result { } unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argument<'_>]) -> Result { - fmt.options.fill = arg.fill; - fmt.options.align = arg.align.into(); - fmt.options.flags = arg.flags; - // SAFETY: arg and args come from the same Arguments, - // which guarantees the indexes are always within bounds. - unsafe { - fmt.options.width = getcount(args, &arg.width); - fmt.options.precision = getcount(args, &arg.precision); - } + let (width, precision) = + // SAFETY: arg and args come from the same Arguments, + // which guarantees the indexes are always within bounds. + unsafe { (getcount(args, &arg.width), getcount(args, &arg.precision)) }; + + #[cfg(bootstrap)] + let options = + *FormattingOptions { flags: flags::ALWAYS_SET | arg.flags << 21, width: 0, precision: 0 } + .align(match arg.align { + rt::Alignment::Left => Some(Alignment::Left), + rt::Alignment::Right => Some(Alignment::Right), + rt::Alignment::Center => Some(Alignment::Center), + rt::Alignment::Unknown => None, + }) + .fill(arg.fill) + .width(width) + .precision(precision); + #[cfg(not(bootstrap))] + let options = FormattingOptions { flags: arg.flags, width, precision }; // Extract the correct argument debug_assert!(arg.position < args.len()); @@ -1495,17 +1535,18 @@ unsafe fn run(fmt: &mut Formatter<'_>, arg: &rt::Placeholder, args: &[rt::Argume // which guarantees its index is always within bounds. let value = unsafe { args.get_unchecked(arg.position) }; + // Set all the formatting options. + fmt.options = options; + // Then actually do some printing // SAFETY: this is a placeholder argument. unsafe { value.fmt(fmt) } } +#[cfg(bootstrap)] unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> { match *cnt { - #[cfg(bootstrap)] rt::Count::Is(n) => Some(n as u16), - #[cfg(not(bootstrap))] - rt::Count::Is(n) => Some(n), rt::Count::Implied => None, rt::Count::Param(i) => { debug_assert!(i < args.len()); @@ -1516,6 +1557,20 @@ unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> Option<u16> { } } +#[cfg(not(bootstrap))] +unsafe fn getcount(args: &[rt::Argument<'_>], cnt: &rt::Count) -> u16 { + match *cnt { + rt::Count::Is(n) => n, + rt::Count::Implied => 0, + rt::Count::Param(i) => { + debug_assert!(i < args.len()); + // SAFETY: cnt and args come from the same Arguments, + // which guarantees this index is always within bounds. + unsafe { args.get_unchecked(i).as_u16().unwrap_unchecked() } + } + } +} + /// Padding after the end of something. Returned by `Formatter::padding`. #[must_use = "don't forget to write the post padding"] pub(crate) struct PostPadding { @@ -1629,40 +1684,28 @@ impl<'a> Formatter<'a> { } // The `width` field is more of a `min-width` parameter at this point. - match self.options.width { - // If there's no minimum length requirements then we can just - // write the bytes. - None => { - write_prefix(self, sign, prefix)?; - self.buf.write_str(buf) - } - // Check if we're over the minimum width, if so then we can also - // just write the bytes. - Some(min) if width >= usize::from(min) => { - write_prefix(self, sign, prefix)?; - self.buf.write_str(buf) - } + let min = self.options.width; + if width >= usize::from(min) { + // We're over the minimum width, so then we can just write the bytes. + write_prefix(self, sign, prefix)?; + self.buf.write_str(buf) + } else if self.sign_aware_zero_pad() { // The sign and prefix goes before the padding if the fill character // is zero - Some(min) if self.sign_aware_zero_pad() => { - let old_fill = crate::mem::replace(&mut self.options.fill, '0'); - let old_align = - crate::mem::replace(&mut self.options.align, Some(Alignment::Right)); - write_prefix(self, sign, prefix)?; - let post_padding = self.padding(min - width as u16, Alignment::Right)?; - self.buf.write_str(buf)?; - post_padding.write(self)?; - self.options.fill = old_fill; - self.options.align = old_align; - Ok(()) - } + let old_options = self.options; + self.options.fill('0').align(Some(Alignment::Right)); + write_prefix(self, sign, prefix)?; + let post_padding = self.padding(min - width as u16, Alignment::Right)?; + self.buf.write_str(buf)?; + post_padding.write(self)?; + self.options = old_options; + Ok(()) + } else { // Otherwise, the sign and prefix goes after the padding - Some(min) => { - let post_padding = self.padding(min - width as u16, Alignment::Right)?; - write_prefix(self, sign, prefix)?; - self.buf.write_str(buf)?; - post_padding.write(self) - } + let post_padding = self.padding(min - width as u16, Alignment::Right)?; + write_prefix(self, sign, prefix)?; + self.buf.write_str(buf)?; + post_padding.write(self) } } @@ -1698,13 +1741,13 @@ impl<'a> Formatter<'a> { #[stable(feature = "rust1", since = "1.0.0")] pub fn pad(&mut self, s: &str) -> Result { // Make sure there's a fast path up front. - if self.options.width.is_none() && self.options.precision.is_none() { + if self.options.flags & (flags::WIDTH_FLAG | flags::PRECISION_FLAG) == 0 { return self.buf.write_str(s); } // The `precision` field can be interpreted as a maximum width for the // string being formatted. - let (s, char_count) = if let Some(max_char_count) = self.options.precision { + let (s, char_count) = if let Some(max_char_count) = self.options.get_precision() { let mut iter = s.char_indices(); let remaining = match iter.advance_by(usize::from(max_char_count)) { Ok(()) => 0, @@ -1720,12 +1763,11 @@ impl<'a> Formatter<'a> { }; // The `width` field is more of a minimum width parameter at this point. - if let Some(width) = self.options.width - && char_count < usize::from(width) - { + if char_count < usize::from(self.options.width) { // If we're under the minimum width, then fill up the minimum width // with the specified string + some alignment. - let post_padding = self.padding(width - char_count as u16, Alignment::Left)?; + let post_padding = + self.padding(self.options.width - char_count as u16, Alignment::Left)?; self.buf.write_str(s)?; post_padding.write(self) } else { @@ -1744,19 +1786,20 @@ impl<'a> Formatter<'a> { padding: u16, default: Alignment, ) -> result::Result<PostPadding, Error> { - let align = self.align().unwrap_or(default); + let align = self.options.get_align().unwrap_or(default); + let fill = self.options.get_fill(); - let (pre_pad, post_pad) = match align { - Alignment::Left => (0, padding), - Alignment::Right => (padding, 0), - Alignment::Center => (padding / 2, (padding + 1) / 2), + let padding_left = match align { + Alignment::Left => 0, + Alignment::Right => padding, + Alignment::Center => padding / 2, }; - for _ in 0..pre_pad { - self.buf.write_char(self.options.fill)?; + for _ in 0..padding_left { + self.buf.write_char(fill)?; } - Ok(PostPadding::new(self.options.fill, post_pad)) + Ok(PostPadding::new(fill, padding - padding_left)) } /// Takes the formatted parts and applies the padding. @@ -1768,12 +1811,16 @@ impl<'a> Formatter<'a> { /// /// Any `numfmt::Part::Copy` parts in `formatted` must contain valid UTF-8. unsafe fn pad_formatted_parts(&mut self, formatted: &numfmt::Formatted<'_>) -> Result { - if let Some(mut width) = self.options.width { + if self.options.width == 0 { + // this is the common case and we take a shortcut + // SAFETY: Per the precondition. + unsafe { self.write_formatted_parts(formatted) } + } else { // for the sign-aware zero padding, we render the sign first and // behave as if we had no sign from the beginning. let mut formatted = formatted.clone(); - let old_fill = self.options.fill; - let old_align = self.options.align; + let mut width = self.options.width; + let old_options = self.options; if self.sign_aware_zero_pad() { // a sign always goes first let sign = formatted.sign; @@ -1782,8 +1829,7 @@ impl<'a> Formatter<'a> { // remove the sign from the formatted parts formatted.sign = ""; width = width.saturating_sub(sign.len() as u16); - self.options.fill = '0'; - self.options.align = Some(Alignment::Right); + self.options.fill('0').align(Some(Alignment::Right)); } // remaining parts go through the ordinary padding process. @@ -1800,13 +1846,8 @@ impl<'a> Formatter<'a> { } post_padding.write(self) }; - self.options.fill = old_fill; - self.options.align = old_align; + self.options = old_options; ret - } else { - // this is the common case and we take a shortcut - // SAFETY: Per the precondition. - unsafe { self.write_formatted_parts(formatted) } } } @@ -1927,7 +1968,9 @@ impl<'a> Formatter<'a> { or `sign_aware_zero_pad` methods instead" )] pub fn flags(&self) -> u32 { - self.options.flags + // Extract the debug upper/lower hex, zero pad, alternate, and plus/minus flags + // to stay compatible with older versions of Rust. + self.options.flags >> 21 & 0x3F } /// Returns the character used as 'fill' whenever there is alignment. @@ -1960,7 +2003,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn fill(&self) -> char { - self.options.fill + self.options.get_fill() } /// Returns a flag indicating what form of alignment was requested. @@ -1995,7 +2038,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags_align", since = "1.28.0")] pub fn align(&self) -> Option<Alignment> { - self.options.align + self.options.get_align() } /// Returns the optionally specified integer width that the output should be. @@ -2025,7 +2068,11 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn width(&self) -> Option<usize> { - self.options.width.map(|x| x as usize) + if self.options.flags & flags::WIDTH_FLAG == 0 { + None + } else { + Some(self.options.width as usize) + } } /// Returns the optionally specified precision for numeric types. @@ -2056,7 +2103,11 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn precision(&self) -> Option<usize> { - self.options.precision.map(|x| x as usize) + if self.options.flags & flags::PRECISION_FLAG == 0 { + None + } else { + Some(self.options.precision as usize) + } } /// Determines if the `+` flag was specified. @@ -2088,7 +2139,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_plus(&self) -> bool { - self.options.flags & (1 << rt::Flag::SignPlus as u32) != 0 + self.options.flags & flags::SIGN_PLUS_FLAG != 0 } /// Determines if the `-` flag was specified. @@ -2117,7 +2168,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_minus(&self) -> bool { - self.options.flags & (1 << rt::Flag::SignMinus as u32) != 0 + self.options.flags & flags::SIGN_MINUS_FLAG != 0 } /// Determines if the `#` flag was specified. @@ -2145,7 +2196,7 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn alternate(&self) -> bool { - self.options.flags & (1 << rt::Flag::Alternate as u32) != 0 + self.options.flags & flags::ALTERNATE_FLAG != 0 } /// Determines if the `0` flag was specified. @@ -2171,17 +2222,16 @@ impl<'a> Formatter<'a> { #[must_use] #[stable(feature = "fmt_flags", since = "1.5.0")] pub fn sign_aware_zero_pad(&self) -> bool { - self.options.flags & (1 << rt::Flag::SignAwareZeroPad as u32) != 0 + self.options.flags & flags::SIGN_AWARE_ZERO_PAD_FLAG != 0 } // FIXME: Decide what public API we want for these two flags. // https://github.com/rust-lang/rust/issues/48584 fn debug_lower_hex(&self) -> bool { - self.options.flags & (1 << rt::Flag::DebugLowerHex as u32) != 0 + self.options.flags & flags::DEBUG_LOWER_HEX_FLAG != 0 } - fn debug_upper_hex(&self) -> bool { - self.options.flags & (1 << rt::Flag::DebugUpperHex as u32) != 0 + self.options.flags & flags::DEBUG_UPPER_HEX_FLAG != 0 } /// Creates a [`DebugStruct`] builder designed to assist with creation of @@ -2761,7 +2811,7 @@ impl Debug for char { #[stable(feature = "rust1", since = "1.0.0")] impl Display for char { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - if f.options.width.is_none() && f.options.precision.is_none() { + if f.options.flags & (flags::WIDTH_FLAG | flags::PRECISION_FLAG) == 0 { f.write_char(*self) } else { f.pad(self.encode_utf8(&mut [0; MAX_LEN_UTF8])) @@ -2792,26 +2842,24 @@ impl<T: ?Sized> Pointer for *const T { /// /// [problematic]: https://github.com/rust-lang/rust/issues/95489 pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Result { - let old_width = f.options.width; - let old_flags = f.options.flags; + let old_options = f.options; // The alternate flag is already treated by LowerHex as being special- // it denotes whether to prefix with 0x. We use it to work out whether // or not to zero extend, and then unconditionally set it to get the // prefix. - if f.alternate() { - f.options.flags |= 1 << (rt::Flag::SignAwareZeroPad as u32); + if f.options.get_alternate() { + f.options.sign_aware_zero_pad(true); - if f.options.width.is_none() { - f.options.width = Some((usize::BITS / 4) as u16 + 2); + if f.options.get_width().is_none() { + f.options.width(Some((usize::BITS / 4) as u16 + 2)); } } - f.options.flags |= 1 << (rt::Flag::Alternate as u32); + f.options.alternate(true); let ret = LowerHex::fmt(&ptr_addr, f); - f.options.width = old_width; - f.options.flags = old_flags; + f.options = old_options; ret } diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index 080fc6ddfc9..d27f7e6e0d8 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -11,7 +11,9 @@ use crate::ptr::NonNull; #[derive(Copy, Clone)] pub struct Placeholder { pub position: usize, + #[cfg(bootstrap)] pub fill: char, + #[cfg(bootstrap)] pub align: Alignment, pub flags: u32, pub precision: Count, @@ -19,6 +21,7 @@ pub struct Placeholder { } impl Placeholder { + #[cfg(bootstrap)] #[inline] pub const fn new( position: usize, @@ -30,8 +33,15 @@ impl Placeholder { ) -> Self { Self { position, fill, align, flags, precision, width } } + + #[cfg(not(bootstrap))] + #[inline] + pub const fn new(position: usize, flags: u32, precision: Count, width: Count) -> Self { + Self { position, flags, precision, width } + } } +#[cfg(bootstrap)] #[lang = "format_alignment"] #[derive(Copy, Clone, PartialEq, Eq)] pub enum Alignment { @@ -58,17 +68,6 @@ pub enum Count { Implied, } -// This needs to match the order of flags in compiler/rustc_ast_lowering/src/format.rs. -#[derive(Copy, Clone)] -pub(super) enum Flag { - SignPlus, - SignMinus, - Alternate, - SignAwareZeroPad, - DebugLowerHex, - DebugUpperHex, -} - #[derive(Copy, Clone)] enum ArgumentType<'a> { Placeholder { diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index cf03c07b6a5..81e59a1f349 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3002,6 +3002,7 @@ pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discrimina /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs. +/// Returns `1` if unwinding occurred and `catch_fn` was called; returns `0` otherwise. /// /// `catch_fn` must not unwind. /// diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 9b9353b800a..a820045521b 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -172,61 +172,6 @@ where } } -/// Marker trait for iterators/iterables which have a statically known upper -/// bound of the number of items they can produce. -/// -/// # Safety -/// -/// Implementations must not yield more elements than indicated by UPPER_BOUND if it is `Some`. -/// Used in specializations. Implementations must not be conditional on lifetimes or -/// user-implementable traits. -#[rustc_specialization_trait] -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe trait BoundedSize { - const UPPER_BOUND: Option<NonZero<usize>> = NonZero::new(1); -} - -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T> BoundedSize for Option<T> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T> BoundedSize for option::IntoIter<T> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T, U> BoundedSize for Result<T, U> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T> BoundedSize for result::IntoIter<T> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T> BoundedSize for Once<T> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T> BoundedSize for OnceWith<T> {} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T, const N: usize> BoundedSize for [T; N] { - const UPPER_BOUND: Option<NonZero<usize>> = NonZero::new(N); -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<T, const N: usize> BoundedSize for array::IntoIter<T, N> { - const UPPER_BOUND: Option<NonZero<usize>> = NonZero::new(N); -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: BoundedSize, P> BoundedSize for Filter<I, P> { - const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND; -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: BoundedSize, P> BoundedSize for FilterMap<I, P> { - const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND; -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: BoundedSize, F> BoundedSize for Map<I, F> { - const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND; -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: BoundedSize> BoundedSize for Copied<I> { - const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND; -} -#[unstable(issue = "none", feature = "inplace_iteration")] -unsafe impl<I: BoundedSize> BoundedSize for Cloned<I> { - const UPPER_BOUND: Option<NonZero<usize>> = I::UPPER_BOUND; -} - /// An iterator that flattens one level of nesting in an iterator of things /// that can be turned into iterators. /// diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index cc089c617c0..ada37b9af4c 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -1,7 +1,8 @@ use crate::fmt; use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator}; -use crate::mem::{self, MaybeUninit}; +use crate::mem::MaybeUninit; use crate::num::NonZero; +use crate::ops::{NeverShortCircuit, Try}; /// Creates a new iterator that repeats a single element a given number of times. /// @@ -95,10 +96,10 @@ impl<A> RepeatN<A> { fn take_element(&mut self) -> Option<A> { if self.count > 0 { self.count = 0; - let element = mem::replace(&mut self.element, MaybeUninit::uninit()); // SAFETY: We just set count to zero so it won't be dropped again, // and it used to be non-zero so it hasn't already been dropped. - unsafe { Some(element.assume_init()) } + let element = unsafe { self.element.assume_init_read() }; + Some(element) } else { None } @@ -169,6 +170,39 @@ impl<A: Clone> Iterator for RepeatN<A> { } } + fn try_fold<B, F, R>(&mut self, mut acc: B, mut f: F) -> R + where + F: FnMut(B, A) -> R, + R: Try<Output = B>, + { + if self.count > 0 { + while self.count > 1 { + self.count -= 1; + // SAFETY: the count was larger than 1, so the element is + // initialized and hasn't been dropped. + acc = f(acc, unsafe { self.element.assume_init_ref().clone() })?; + } + + // We could just set the count to zero directly, but doing it this + // way should make it easier for the optimizer to fold this tail + // into the loop when `clone()` is equivalent to copying. + self.count -= 1; + // SAFETY: we just set the count to zero from one, so the element + // is still initialized, has not been dropped yet and will not be + // accessed by future calls. + f(acc, unsafe { self.element.assume_init_read() }) + } else { + try { acc } + } + } + + fn fold<B, F>(mut self, init: B, f: F) -> B + where + F: FnMut(B, A) -> B, + { + self.try_fold(init, NeverShortCircuit::wrap_mut_2(f)).0 + } + #[inline] fn last(mut self) -> Option<A> { self.take_element() @@ -203,6 +237,23 @@ impl<A: Clone> DoubleEndedIterator for RepeatN<A> { fn nth_back(&mut self, n: usize) -> Option<A> { self.nth(n) } + + #[inline] + fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R + where + F: FnMut(B, A) -> R, + R: Try<Output = B>, + { + self.try_fold(init, f) + } + + #[inline] + fn rfold<B, F>(self, init: B, f: F) -> B + where + F: FnMut(B, A) -> B, + { + self.fold(init, f) + } } #[stable(feature = "iter_repeat_n", since = "1.82.0")] @@ -220,7 +271,7 @@ impl<A: Clone> UncheckedIterator for RepeatN<A> { // SAFETY: the check above ensured that the count used to be non-zero, // so element hasn't been dropped yet, and we just lowered the count to // zero so it won't be dropped later, and thus it's okay to take it here. - unsafe { mem::replace(&mut self.element, MaybeUninit::uninit()).assume_init() } + unsafe { self.element.assume_init_read() } } else { // SAFETY: the count is non-zero, so it must have not been dropped yet. let element = unsafe { self.element.assume_init_ref() }; diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index fa0d882181a..5f200b31d1a 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1744,7 +1744,7 @@ pub(crate) mod builtin { } /// Provide a list of type aliases and other opaque-type-containing type definitions. - /// This list will be used in the body of the item it is applied to to define opaque + /// This list will be used in the body of the item it is applied to define opaque /// types' hidden types. /// Can only be applied to things that have bodies. #[unstable( diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 88bee622031..9b1b13e7129 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -469,6 +469,7 @@ impl AtomicBool { /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses + #[inline] #[stable(feature = "atomic_from_ptr", since = "1.75.0")] #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut bool) -> &'a AtomicBool { @@ -1389,6 +1390,7 @@ impl<T> AtomicPtr<T> { /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses + #[inline] #[stable(feature = "atomic_from_ptr", since = "1.75.0")] #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut *mut T) -> &'a AtomicPtr<T> { @@ -2525,6 +2527,7 @@ macro_rules! atomic_int { /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses + #[inline] #[stable(feature = "atomic_from_ptr", since = "1.75.0")] #[rustc_const_stable(feature = "const_atomic_from_ptr", since = "1.84.0")] pub const unsafe fn from_ptr<'a>(ptr: *mut $int_type) -> &'a $atomic_type { diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs index 206b5b9e2c2..d754bb90343 100644 --- a/library/core/src/tuple.rs +++ b/library/core/src/tuple.rs @@ -2,6 +2,7 @@ use crate::cmp::Ordering::{self, *}; use crate::marker::{ConstParamTy_, StructuralPartialEq, UnsizedConstParamTy}; +use crate::ops::ControlFlow::{Break, Continue}; // Recursive macro for implementing n-ary tuple functions and operations // @@ -80,19 +81,19 @@ macro_rules! tuple_impls { } #[inline] fn lt(&self, other: &($($T,)+)) -> bool { - lexical_ord!(lt, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + lexical_ord!(lt, __chaining_lt, $( ${ignore($T)} self.${index()}, other.${index()} ),+) } #[inline] fn le(&self, other: &($($T,)+)) -> bool { - lexical_ord!(le, Less, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + lexical_ord!(le, __chaining_le, $( ${ignore($T)} self.${index()}, other.${index()} ),+) } #[inline] fn ge(&self, other: &($($T,)+)) -> bool { - lexical_ord!(ge, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + lexical_ord!(ge, __chaining_ge, $( ${ignore($T)} self.${index()}, other.${index()} ),+) } #[inline] fn gt(&self, other: &($($T,)+)) -> bool { - lexical_ord!(gt, Greater, $( ${ignore($T)} self.${index()}, other.${index()} ),+) + lexical_ord!(gt, __chaining_gt, $( ${ignore($T)} self.${index()}, other.${index()} ),+) } } } @@ -171,15 +172,16 @@ macro_rules! maybe_tuple_doc { // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, opt_is_lt, a1, b1, // a2, b2, a3, b3)` (and similarly for `lexical_cmp`) // -// `$ne_rel` is only used to determine the result after checking that they're -// not equal, so `lt` and `le` can both just use `Less`. +// `$chain_rel` is the chaining method from `PartialOrd` to use for all but the +// final value, to produce better results for simple primitives. macro_rules! lexical_ord { - ($rel: ident, $ne_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{ - let c = PartialOrd::partial_cmp(&$a, &$b); - if c != Some(Equal) { c == Some($ne_rel) } - else { lexical_ord!($rel, $ne_rel, $($rest_a, $rest_b),+) } + ($rel: ident, $chain_rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {{ + match PartialOrd::$chain_rel(&$a, &$b) { + Break(val) => val, + Continue(()) => lexical_ord!($rel, $chain_rel, $($rest_a, $rest_b),+), + } }}; - ($rel: ident, $ne_rel: ident, $a:expr, $b:expr) => { + ($rel: ident, $chain_rel: ident, $a:expr, $b:expr) => { // Use the specific method for the last element PartialOrd::$rel(&$a, &$b) }; diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 3f082a90770..d9060fe903d 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -81,6 +81,7 @@ fn formatting_options_ctor() { } #[test] +#[allow(deprecated)] fn formatting_options_flags() { use core::fmt::*; for sign in [None, Some(Sign::Plus), Some(Sign::Minus)] { @@ -98,6 +99,25 @@ fn formatting_options_flags() { assert_eq!(formatting_options.get_alternate(), alternate); assert_eq!(formatting_options.get_sign_aware_zero_pad(), sign_aware_zero_pad); assert_eq!(formatting_options.get_debug_as_hex(), debug_as_hex); + + let mut output = String::new(); + let fmt = Formatter::new(&mut output, formatting_options); + assert_eq!(fmt.options(), formatting_options); + + assert_eq!(fmt.sign_minus(), sign == Some(Sign::Minus)); + assert_eq!(fmt.sign_plus(), sign == Some(Sign::Plus)); + assert_eq!(fmt.alternate(), alternate); + assert_eq!(fmt.sign_aware_zero_pad(), sign_aware_zero_pad); + + // The flags method is deprecated. + // This checks compatibility with older versions of Rust. + assert_eq!(fmt.flags() & 1 != 0, sign == Some(Sign::Plus)); + assert_eq!(fmt.flags() & 2 != 0, sign == Some(Sign::Minus)); + assert_eq!(fmt.flags() & 4 != 0, alternate); + assert_eq!(fmt.flags() & 8 != 0, sign_aware_zero_pad); + assert_eq!(fmt.flags() & 16 != 0, debug_as_hex == Some(DebugAsHex::Lower)); + assert_eq!(fmt.flags() & 32 != 0, debug_as_hex == Some(DebugAsHex::Upper)); + assert_eq!(fmt.flags() & 0xFFFF_FFC0, 0); } } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 9d9601b79a7..176da603d58 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core", public = true } -compiler_builtins = { version = "=0.1.151" } +compiler_builtins = { version = "=0.1.152" } unwind = { path = "../unwind" } hashbrown = { version = "0.15", default-features = false, features = [ 'rustc-dep-of-std', diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index f9a360585e8..fa98db69306 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -665,6 +665,7 @@ impl File { /// # Examples /// /// ```no_run + /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -673,7 +674,7 @@ impl File { /// Ok(()) /// } /// ``` - #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] + #[unstable(feature = "file_lock", issue = "130994")] pub fn lock(&self) -> io::Result<()> { self.inner.lock() } @@ -717,6 +718,7 @@ impl File { /// # Examples /// /// ```no_run + /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -725,7 +727,7 @@ impl File { /// Ok(()) /// } /// ``` - #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] + #[unstable(feature = "file_lock", issue = "130994")] pub fn lock_shared(&self) -> io::Result<()> { self.inner.lock_shared() } @@ -774,6 +776,7 @@ impl File { /// # Examples /// /// ```no_run + /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -782,7 +785,7 @@ impl File { /// Ok(()) /// } /// ``` - #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] + #[unstable(feature = "file_lock", issue = "130994")] pub fn try_lock(&self) -> io::Result<bool> { self.inner.try_lock() } @@ -830,6 +833,7 @@ impl File { /// # Examples /// /// ```no_run + /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -838,7 +842,7 @@ impl File { /// Ok(()) /// } /// ``` - #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] + #[unstable(feature = "file_lock", issue = "130994")] pub fn try_lock_shared(&self) -> io::Result<bool> { self.inner.try_lock_shared() } @@ -866,6 +870,7 @@ impl File { /// # Examples /// /// ```no_run + /// #![feature(file_lock)] /// use std::fs::File; /// /// fn main() -> std::io::Result<()> { @@ -875,7 +880,7 @@ impl File { /// Ok(()) /// } /// ``` - #[stable(feature = "file_lock", since = "CURRENT_RUSTC_VERSION")] + #[unstable(feature = "file_lock", issue = "130994")] pub fn unlock(&self) -> io::Result<()> { self.inner.unlock() } @@ -1343,6 +1348,9 @@ impl Seek for Arc<File> { fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (&**self).seek(pos) } + fn stream_position(&mut self) -> io::Result<u64> { + (&**self).stream_position() + } } impl OpenOptions { diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 6dd18e4f4c8..4712e58980c 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1719,6 +1719,23 @@ fn test_eq_direntry_metadata() { } } +/// Test that windows file type equality is not affected by attributes unrelated +/// to the file type. +#[test] +#[cfg(target_os = "windows")] +fn test_eq_windows_file_type() { + let tmpdir = tmpdir(); + let file1 = File::create(tmpdir.join("file1")).unwrap(); + let file2 = File::create(tmpdir.join("file2")).unwrap(); + assert_eq!(file1.metadata().unwrap().file_type(), file2.metadata().unwrap().file_type()); + + // Change the readonly attribute of one file. + let mut perms = file1.metadata().unwrap().permissions(); + perms.set_readonly(true); + file1.set_permissions(perms).unwrap(); + assert_eq!(file1.metadata().unwrap().file_type(), file2.metadata().unwrap().file_type()); +} + /// Regression test for https://github.com/rust-lang/rust/issues/50619. #[test] #[cfg(target_os = "linux")] diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index ce46241f8e8..8fc16331339 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -97,15 +97,15 @@ const fn stderr_raw() -> StderrRaw { impl Read for StdinRaw { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { - handle_ebadf(self.0.read(buf), 0) + handle_ebadf(self.0.read(buf), || Ok(0)) } fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { - handle_ebadf(self.0.read_buf(buf), ()) + handle_ebadf(self.0.read_buf(buf), || Ok(())) } fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - handle_ebadf(self.0.read_vectored(bufs), 0) + handle_ebadf(self.0.read_vectored(bufs), || Ok(0)) } #[inline] @@ -113,23 +113,37 @@ impl Read for StdinRaw { self.0.is_read_vectored() } + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if buf.is_empty() { + return Ok(()); + } + handle_ebadf(self.0.read_exact(buf), || Err(io::Error::READ_EXACT_EOF)) + } + + fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { + if buf.capacity() == 0 { + return Ok(()); + } + handle_ebadf(self.0.read_buf_exact(buf), || Err(io::Error::READ_EXACT_EOF)) + } + fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { - handle_ebadf(self.0.read_to_end(buf), 0) + handle_ebadf(self.0.read_to_end(buf), || Ok(0)) } fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> { - handle_ebadf(self.0.read_to_string(buf), 0) + handle_ebadf(self.0.read_to_string(buf), || Ok(0)) } } impl Write for StdoutRaw { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - handle_ebadf(self.0.write(buf), buf.len()) + handle_ebadf(self.0.write(buf), || Ok(buf.len())) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let total = || bufs.iter().map(|b| b.len()).sum(); - handle_ebadf_lazy(self.0.write_vectored(bufs), total) + let total = || Ok(bufs.iter().map(|b| b.len()).sum()); + handle_ebadf(self.0.write_vectored(bufs), total) } #[inline] @@ -138,30 +152,30 @@ impl Write for StdoutRaw { } fn flush(&mut self) -> io::Result<()> { - handle_ebadf(self.0.flush(), ()) + handle_ebadf(self.0.flush(), || Ok(())) } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - handle_ebadf(self.0.write_all(buf), ()) + handle_ebadf(self.0.write_all(buf), || Ok(())) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - handle_ebadf(self.0.write_all_vectored(bufs), ()) + handle_ebadf(self.0.write_all_vectored(bufs), || Ok(())) } fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - handle_ebadf(self.0.write_fmt(fmt), ()) + handle_ebadf(self.0.write_fmt(fmt), || Ok(())) } } impl Write for StderrRaw { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - handle_ebadf(self.0.write(buf), buf.len()) + handle_ebadf(self.0.write(buf), || Ok(buf.len())) } fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { - let total = || bufs.iter().map(|b| b.len()).sum(); - handle_ebadf_lazy(self.0.write_vectored(bufs), total) + let total = || Ok(bufs.iter().map(|b| b.len()).sum()); + handle_ebadf(self.0.write_vectored(bufs), total) } #[inline] @@ -170,32 +184,25 @@ impl Write for StderrRaw { } fn flush(&mut self) -> io::Result<()> { - handle_ebadf(self.0.flush(), ()) + handle_ebadf(self.0.flush(), || Ok(())) } fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - handle_ebadf(self.0.write_all(buf), ()) + handle_ebadf(self.0.write_all(buf), || Ok(())) } fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> io::Result<()> { - handle_ebadf(self.0.write_all_vectored(bufs), ()) + handle_ebadf(self.0.write_all_vectored(bufs), || Ok(())) } fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - handle_ebadf(self.0.write_fmt(fmt), ()) - } -} - -fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> { - match r { - Err(ref e) if stdio::is_ebadf(e) => Ok(default), - r => r, + handle_ebadf(self.0.write_fmt(fmt), || Ok(())) } } -fn handle_ebadf_lazy<T>(r: io::Result<T>, default: impl FnOnce() -> T) -> io::Result<T> { +fn handle_ebadf<T>(r: io::Result<T>, default: impl FnOnce() -> io::Result<T>) -> io::Result<T> { match r { - Err(ref e) if stdio::is_ebadf(e) => Ok(default()), + Err(ref e) if stdio::is_ebadf(e) => default(), r => r, } } diff --git a/library/std/src/net/tcp/tests.rs b/library/std/src/net/tcp/tests.rs index a7b5cdf4ec0..03003037b29 100644 --- a/library/std/src/net/tcp/tests.rs +++ b/library/std/src/net/tcp/tests.rs @@ -315,12 +315,8 @@ fn read_buf() { let mut buf = BorrowedBuf::from(buf.as_mut_slice()); t!(s.read_buf(buf.unfilled())); assert_eq!(buf.filled(), &[1, 2, 3, 4]); - - // FIXME: sgx uses default_read_buf that initializes the buffer. - if cfg!(not(target_env = "sgx")) { - // TcpStream::read_buf should omit buffer initialization. - assert_eq!(buf.init_len(), 4); - } + // TcpStream::read_buf should omit buffer initialization. + assert_eq!(buf.init_len(), 4); t.join().ok().expect("thread panicked"); }) diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index defc1681d38..d6ae86bd3d2 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -1,3 +1,5 @@ +use r_efi::protocols::file; + use crate::ffi::OsString; use crate::fmt; use crate::hash::Hash; @@ -22,7 +24,12 @@ pub struct ReadDir(!); pub struct DirEntry(!); #[derive(Clone, Debug)] -pub struct OpenOptions {} +pub struct OpenOptions { + mode: u64, + append: bool, + truncate: bool, + create_new: bool, +} #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes {} @@ -36,7 +43,7 @@ pub struct FilePermissions(bool); pub struct FileType(bool); #[derive(Debug)] -pub struct DirBuilder {} +pub struct DirBuilder; impl FileAttr { pub fn size(&self) -> u64 { @@ -141,15 +148,58 @@ impl DirEntry { impl OpenOptions { pub fn new() -> OpenOptions { - OpenOptions {} + OpenOptions { mode: 0, append: false, create_new: false, truncate: false } + } + + pub fn read(&mut self, read: bool) { + if read { + self.mode |= file::MODE_READ; + } else { + self.mode &= !file::MODE_READ; + } + } + + pub fn write(&mut self, write: bool) { + if write { + // Valid Combinations: Read, Read/Write, Read/Write/Create + self.read(true); + self.mode |= file::MODE_WRITE; + } else { + self.mode &= !file::MODE_WRITE; + } + } + + pub fn append(&mut self, append: bool) { + // Docs state that `.write(true).append(true)` has the same effect as `.append(true)` + if append { + self.write(true); + } + self.append = append; + } + + pub fn truncate(&mut self, truncate: bool) { + self.truncate = truncate; + } + + pub fn create(&mut self, create: bool) { + if create { + self.mode |= file::MODE_CREATE; + } else { + self.mode &= !file::MODE_CREATE; + } } - pub fn read(&mut self, _read: bool) {} - pub fn write(&mut self, _write: bool) {} - pub fn append(&mut self, _append: bool) {} - pub fn truncate(&mut self, _truncate: bool) {} - pub fn create(&mut self, _create: bool) {} - pub fn create_new(&mut self, _create_new: bool) {} + pub fn create_new(&mut self, create_new: bool) { + self.create_new = create_new; + } + + #[expect(dead_code)] + const fn is_mode_valid(&self) -> bool { + // Valid Combinations: Read, Read/Write, Read/Write/Create + self.mode == file::MODE_READ + || self.mode == (file::MODE_READ | file::MODE_WRITE) + || self.mode == (file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE) + } } impl File { @@ -248,11 +298,11 @@ impl File { impl DirBuilder { pub fn new() -> DirBuilder { - DirBuilder {} + DirBuilder } - pub fn mkdir(&self, _p: &Path) -> io::Result<()> { - unsupported() + pub fn mkdir(&self, p: &Path) -> io::Result<()> { + uefi_fs::mkdir(p) } } @@ -311,12 +361,12 @@ pub fn stat(_p: &Path) -> io::Result<FileAttr> { unsupported() } -pub fn lstat(_p: &Path) -> io::Result<FileAttr> { - unsupported() +pub fn lstat(p: &Path) -> io::Result<FileAttr> { + stat(p) } -pub fn canonicalize(_p: &Path) -> io::Result<PathBuf> { - unsupported() +pub fn canonicalize(p: &Path) -> io::Result<PathBuf> { + crate::path::absolute(p) } pub fn copy(_from: &Path, _to: &Path) -> io::Result<u64> { @@ -452,4 +502,30 @@ mod uefi_fs { } } } + + /// An implementation of mkdir to allow creating new directory without having to open the + /// volume twice (once for checking and once for creating) + pub(crate) fn mkdir(path: &Path) -> io::Result<()> { + let absolute = crate::path::absolute(path)?; + + let p = helpers::OwnedDevicePath::from_text(absolute.as_os_str())?; + let (vol, mut path_remaining) = File::open_volume_from_device_path(p.borrow())?; + + // Check if file exists + match vol.open(&mut path_remaining, file::MODE_READ, 0) { + Ok(_) => { + return Err(io::Error::new(io::ErrorKind::AlreadyExists, "Path already exists")); + } + Err(e) if e.kind() == io::ErrorKind::NotFound => {} + Err(e) => return Err(e), + } + + let _ = vol.open( + &mut path_remaining, + file::MODE_READ | file::MODE_WRITE | file::MODE_CREATE, + file::DIRECTORY, + )?; + + Ok(()) + } } diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index 362e64abf1a..06bba019393 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -41,8 +41,8 @@ pub struct FileAttr { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType { - attributes: u32, - reparse_tag: u32, + is_directory: bool, + is_symlink: bool, } pub struct ReadDir { @@ -1111,32 +1111,29 @@ impl FileTimes { } impl FileType { - fn new(attrs: u32, reparse_tag: u32) -> FileType { - FileType { attributes: attrs, reparse_tag } + fn new(attributes: u32, reparse_tag: u32) -> FileType { + let is_directory = attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0; + let is_symlink = { + let is_reparse_point = attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0; + let is_reparse_tag_name_surrogate = reparse_tag & 0x20000000 != 0; + is_reparse_point && is_reparse_tag_name_surrogate + }; + FileType { is_directory, is_symlink } } pub fn is_dir(&self) -> bool { - !self.is_symlink() && self.is_directory() + !self.is_symlink && self.is_directory } pub fn is_file(&self) -> bool { - !self.is_symlink() && !self.is_directory() + !self.is_symlink && !self.is_directory } pub fn is_symlink(&self) -> bool { - self.is_reparse_point() && self.is_reparse_tag_name_surrogate() + self.is_symlink } pub fn is_symlink_dir(&self) -> bool { - self.is_symlink() && self.is_directory() + self.is_symlink && self.is_directory } pub fn is_symlink_file(&self) -> bool { - self.is_symlink() && !self.is_directory() - } - fn is_directory(&self) -> bool { - self.attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0 - } - fn is_reparse_point(&self) -> bool { - self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 - } - fn is_reparse_tag_name_surrogate(&self) -> bool { - self.reparse_tag & 0x20000000 != 0 + self.is_symlink && !self.is_directory } } diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 09677b9d642..f0cfb9b2773 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -17,6 +17,7 @@ pub mod io; pub mod net; pub mod os_str; pub mod path; +pub mod process; pub mod random; pub mod stdio; pub mod sync; diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index 608245bd430..67eab96fa40 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -25,8 +25,6 @@ pub mod futex; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index bb419c2530e..fe43cfd2caf 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -16,8 +16,6 @@ mod libunwind_integration; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub mod thread; pub mod thread_parking; pub mod time; diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index e4a61fdcfe3..22052a168fd 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -25,8 +25,6 @@ pub(crate) mod error; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub use self::itron::{thread, thread_parking}; pub mod time; diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 41b25121592..c1921a2f40d 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -14,8 +14,6 @@ pub mod env; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub mod thread; #[allow(non_upper_case_globals)] #[path = "../unix/time.rs"] diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 2faa733f23f..309022bcccf 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -120,39 +120,6 @@ pub(crate) fn open_protocol<T>( } } -pub(crate) fn create_event( - signal: u32, - tpl: efi::Tpl, - handler: Option<efi::EventNotify>, - context: *mut crate::ffi::c_void, -) -> io::Result<NonNull<crate::ffi::c_void>> { - let boot_services: NonNull<efi::BootServices> = - boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast(); - let mut event: r_efi::efi::Event = crate::ptr::null_mut(); - let r = unsafe { - let create_event = (*boot_services.as_ptr()).create_event; - (create_event)(signal, tpl, handler, context, &mut event) - }; - if r.is_error() { - Err(crate::io::Error::from_raw_os_error(r.as_usize())) - } else { - NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol")) - } -} - -/// # SAFETY -/// - The supplied event must be valid -pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> { - let boot_services: NonNull<efi::BootServices> = - boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast(); - let r = unsafe { - let close_event = (*boot_services.as_ptr()).close_event; - (close_event)(evt.as_ptr()) - }; - - if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } -} - /// Gets the Protocol for current system handle. /// /// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so. @@ -735,3 +702,56 @@ impl Drop for ServiceProtocol { } } } + +#[repr(transparent)] +pub(crate) struct OwnedEvent(NonNull<crate::ffi::c_void>); + +impl OwnedEvent { + pub(crate) fn new( + signal: u32, + tpl: efi::Tpl, + handler: Option<efi::EventNotify>, + context: Option<NonNull<crate::ffi::c_void>>, + ) -> io::Result<Self> { + let boot_services: NonNull<efi::BootServices> = + boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast(); + let mut event: r_efi::efi::Event = crate::ptr::null_mut(); + let context = context.map(NonNull::as_ptr).unwrap_or(crate::ptr::null_mut()); + + let r = unsafe { + let create_event = (*boot_services.as_ptr()).create_event; + (create_event)(signal, tpl, handler, context, &mut event) + }; + + if r.is_error() { + Err(crate::io::Error::from_raw_os_error(r.as_usize())) + } else { + NonNull::new(event) + .ok_or(const_error!(io::ErrorKind::Other, "failed to create event")) + .map(Self) + } + } + + pub(crate) fn into_raw(self) -> *mut crate::ffi::c_void { + let r = self.0.as_ptr(); + crate::mem::forget(self); + r + } + + /// SAFETY: Assumes that ptr is a non-null valid UEFI event + pub(crate) unsafe fn from_raw(ptr: *mut crate::ffi::c_void) -> Self { + Self(unsafe { NonNull::new_unchecked(ptr) }) + } +} + +impl Drop for OwnedEvent { + fn drop(&mut self) { + if let Some(boot_services) = boot_services() { + let bt: NonNull<r_efi::efi::BootServices> = boot_services.cast(); + unsafe { + let close_event = (*bt.as_ptr()).close_event; + (close_event)(self.0.as_ptr()) + }; + } + } +} diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 714dc392688..9760a23084a 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -19,7 +19,6 @@ pub mod helpers; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -pub mod process; pub mod thread; pub mod time; @@ -47,17 +46,17 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { unsafe { uefi::env::init_globals(image_handle, system_table) }; // Register exit boot services handler - match helpers::create_event( + match helpers::OwnedEvent::new( r_efi::efi::EVT_SIGNAL_EXIT_BOOT_SERVICES, r_efi::efi::TPL_NOTIFY, Some(exit_boot_service_handler), - crate::ptr::null_mut(), + None, ) { Ok(x) => { if EXIT_BOOT_SERVICE_EVENT .compare_exchange( crate::ptr::null_mut(), - x.as_ptr(), + x.into_raw(), Ordering::Release, Ordering::Acquire, ) @@ -77,7 +76,7 @@ pub unsafe fn cleanup() { if let Some(exit_boot_service_event) = NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire)) { - let _ = unsafe { helpers::close_event(exit_boot_service_event) }; + let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) }; } } @@ -143,7 +142,7 @@ pub fn abort_internal() -> ! { if let Some(exit_boot_service_event) = NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire)) { - let _ = unsafe { helpers::close_event(exit_boot_service_event) }; + let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) }; } if let (Some(boot_services), Some(handle)) = diff --git a/library/std/src/sys/pal/unix/process/zircon.rs b/library/std/src/sys/pal/unix/fuchsia.rs index 7932bd26d76..7932bd26d76 100644 --- a/library/std/src/sys/pal/unix/process/zircon.rs +++ b/library/std/src/sys/pal/unix/fuchsia.rs diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index e2e537b7bd3..413fda1d8d8 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -9,6 +9,8 @@ pub mod weak; pub mod args; pub mod env; pub mod fd; +#[cfg(target_os = "fuchsia")] +pub mod fuchsia; pub mod futex; #[cfg(any(target_os = "linux", target_os = "android"))] pub mod kernel_copy; @@ -16,7 +18,6 @@ pub mod kernel_copy; pub mod linux; pub mod os; pub mod pipe; -pub mod process; pub mod stack_overflow; pub mod sync; pub mod thread; @@ -419,7 +420,7 @@ cfg_if::cfg_if! { } #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] -mod unsupported { +pub mod unsupported { use crate::io; pub fn unsupported<T>() -> io::Result<T> { diff --git a/library/std/src/sys/pal/unix/process/mod.rs b/library/std/src/sys/pal/unix/process/mod.rs deleted file mode 100644 index 2751d51c44d..00000000000 --- a/library/std/src/sys/pal/unix/process/mod.rs +++ /dev/null @@ -1,27 +0,0 @@ -pub use self::process_common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes}; -pub use self::process_inner::{ExitStatus, ExitStatusError, Process}; -pub use crate::ffi::OsString as EnvKey; - -#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))] -mod process_common; - -#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] -mod process_unsupported; - -cfg_if::cfg_if! { - if #[cfg(target_os = "fuchsia")] { - #[path = "process_fuchsia.rs"] - mod process_inner; - mod zircon; - } else if #[cfg(target_os = "vxworks")] { - #[path = "process_vxworks.rs"] - mod process_inner; - } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] { - mod process_inner { - pub use super::process_unsupported::*; - } - } else { - #[path = "process_unix.rs"] - mod process_inner; - } -} diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs index 0ecccdc8812..4bd0cedd44c 100644 --- a/library/std/src/sys/pal/unix/stack_overflow.rs +++ b/library/std/src/sys/pal/unix/stack_overflow.rs @@ -585,6 +585,7 @@ mod imp { target_os = "openbsd", target_os = "solaris", target_os = "illumos", + target_os = "cygwin", )))] mod imp { pub unsafe fn init() {} @@ -597,3 +598,89 @@ mod imp { pub unsafe fn drop_handler(_data: *mut libc::c_void) {} } + +#[cfg(target_os = "cygwin")] +mod imp { + mod c { + pub type PVECTORED_EXCEPTION_HANDLER = + Option<unsafe extern "system" fn(exceptioninfo: *mut EXCEPTION_POINTERS) -> i32>; + pub type NTSTATUS = i32; + pub type BOOL = i32; + + unsafe extern "system" { + pub fn AddVectoredExceptionHandler( + first: u32, + handler: PVECTORED_EXCEPTION_HANDLER, + ) -> *mut core::ffi::c_void; + pub fn SetThreadStackGuarantee(stacksizeinbytes: *mut u32) -> BOOL; + } + + pub const EXCEPTION_STACK_OVERFLOW: NTSTATUS = 0xC00000FD_u32 as _; + pub const EXCEPTION_CONTINUE_SEARCH: i32 = 1i32; + + #[repr(C)] + #[derive(Clone, Copy)] + pub struct EXCEPTION_POINTERS { + pub ExceptionRecord: *mut EXCEPTION_RECORD, + // We don't need this field here + // pub Context: *mut CONTEXT, + } + #[repr(C)] + #[derive(Clone, Copy)] + pub struct EXCEPTION_RECORD { + pub ExceptionCode: NTSTATUS, + pub ExceptionFlags: u32, + pub ExceptionRecord: *mut EXCEPTION_RECORD, + pub ExceptionAddress: *mut core::ffi::c_void, + pub NumberParameters: u32, + pub ExceptionInformation: [usize; 15], + } + } + + /// Reserve stack space for use in stack overflow exceptions. + fn reserve_stack() { + let result = unsafe { c::SetThreadStackGuarantee(&mut 0x5000) }; + // Reserving stack space is not critical so we allow it to fail in the released build of libstd. + // We still use debug assert here so that CI will test that we haven't made a mistake calling the function. + debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling"); + } + + unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 { + // SAFETY: It's up to the caller (which in this case is the OS) to ensure that `ExceptionInfo` is valid. + unsafe { + let rec = &(*(*ExceptionInfo).ExceptionRecord); + let code = rec.ExceptionCode; + + if code == c::EXCEPTION_STACK_OVERFLOW { + crate::thread::with_current_name(|name| { + let name = name.unwrap_or("<unknown>"); + rtprintpanic!("\nthread '{name}' has overflowed its stack\n"); + }); + } + c::EXCEPTION_CONTINUE_SEARCH + } + } + + pub unsafe fn init() { + // SAFETY: `vectored_handler` has the correct ABI and is safe to call during exception handling. + unsafe { + let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler)); + // Similar to the above, adding the stack overflow handler is allowed to fail + // but a debug assert is used so CI will still test that it normally works. + debug_assert!(!result.is_null(), "failed to install exception handler"); + } + // Set the thread stack guarantee for the main thread. + reserve_stack(); + } + + pub unsafe fn cleanup() {} + + pub unsafe fn make_handler(main_thread: bool) -> super::Handler { + if !main_thread { + reserve_stack(); + } + super::Handler::null() + } + + pub unsafe fn drop_handler(_data: *mut libc::c_void) {} +} diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index bffe2536299..bb34c2fabe5 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -143,8 +143,8 @@ impl Thread { pub fn set_name(name: &CStr) { unsafe { cfg_if::cfg_if! { - if #[cfg(target_os = "linux")] { - // Linux limits the allowed length of the name. + if #[cfg(any(target_os = "linux", target_os = "cygwin"))] { + // Linux and Cygwin limits the allowed length of the name. const TASK_COMM_LEN: usize = 16; let name = truncate_cstr::<{ TASK_COMM_LEN }>(name); } else { @@ -346,6 +346,7 @@ impl Drop for Thread { target_os = "solaris", target_os = "illumos", target_os = "vxworks", + target_os = "cygwin", target_vendor = "apple", ))] fn truncate_cstr<const MAX_WITH_NUL: usize>(cstr: &CStr) -> [libc::c_char; MAX_WITH_NUL] { diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs index bcea699f3b2..38838b915b5 100644 --- a/library/std/src/sys/pal/unsupported/mod.rs +++ b/library/std/src/sys/pal/unsupported/mod.rs @@ -4,7 +4,6 @@ pub mod args; pub mod env; pub mod os; pub mod pipe; -pub mod process; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs index c89832857dd..cdd613f76b6 100644 --- a/library/std/src/sys/pal/wasi/mod.rs +++ b/library/std/src/sys/pal/wasi/mod.rs @@ -23,8 +23,6 @@ pub mod futex; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs index 3008ba88753..6ac28f1bf4f 100644 --- a/library/std/src/sys/pal/wasip2/mod.rs +++ b/library/std/src/sys/pal/wasip2/mod.rs @@ -20,8 +20,6 @@ pub mod futex; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; #[path = "../wasi/thread.rs"] pub mod thread; #[path = "../wasi/time.rs"] diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs index 175fe75357f..8d39b70d039 100644 --- a/library/std/src/sys/pal/wasm/mod.rs +++ b/library/std/src/sys/pal/wasm/mod.rs @@ -23,8 +23,6 @@ pub mod env; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; #[path = "../unsupported/time.rs"] pub mod time; diff --git a/library/std/src/sys/pal/windows/args.rs b/library/std/src/sys/pal/windows/args.rs index 3447a0157e4..d973743639a 100644 --- a/library/std/src/sys/pal/windows/args.rs +++ b/library/std/src/sys/pal/windows/args.rs @@ -6,13 +6,13 @@ #[cfg(test)] mod tests; +use super::ensure_no_nuls; use super::os::current_exe; use crate::ffi::{OsStr, OsString}; use crate::num::NonZero; use crate::os::windows::prelude::*; use crate::path::{Path, PathBuf}; use crate::sys::path::get_long_path; -use crate::sys::process::ensure_no_nuls; use crate::sys::{c, to_u16s}; use crate::sys_common::AsInner; use crate::sys_common::wstr::WStrUnits; diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 6eb68f3a3bc..bdf0cc2c59c 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -22,7 +22,6 @@ pub mod futex; pub mod handle; pub mod os; pub mod pipe; -pub mod process; pub mod thread; pub mod time; cfg_if::cfg_if! { @@ -287,6 +286,14 @@ pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { } } +pub fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> crate::io::Result<T> { + if s.as_ref().encode_wide().any(|b| b == 0) { + Err(crate::io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) + } else { + Ok(s) + } +} + pub trait IsZero { fn is_zero(&self) -> bool; } diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs index 7d823012ad1..58926e2beb1 100644 --- a/library/std/src/sys/pal/xous/mod.rs +++ b/library/std/src/sys/pal/xous/mod.rs @@ -6,8 +6,6 @@ pub mod env; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; pub mod thread; pub mod time; diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs index 499e2787201..4659dad16e8 100644 --- a/library/std/src/sys/pal/zkvm/mod.rs +++ b/library/std/src/sys/pal/zkvm/mod.rs @@ -17,8 +17,6 @@ pub mod env; pub mod os; #[path = "../unsupported/pipe.rs"] pub mod pipe; -#[path = "../unsupported/process.rs"] -pub mod process; #[path = "../unsupported/thread.rs"] pub mod thread; #[path = "../unsupported/time.rs"] diff --git a/library/std/src/sys/process/mod.rs b/library/std/src/sys/process/mod.rs new file mode 100644 index 00000000000..92cfac7f47c --- /dev/null +++ b/library/std/src/sys/process/mod.rs @@ -0,0 +1,19 @@ +cfg_if::cfg_if! { + if #[cfg(target_family = "unix")] { + mod unix; + use unix as imp; + } else if #[cfg(target_os = "windows")] { + mod windows; + use windows as imp; + } else if #[cfg(target_os = "uefi")] { + mod uefi; + use uefi as imp; + } else { + mod unsupported; + use unsupported as imp; + } +} + +pub use imp::{ + Command, CommandArgs, EnvKey, ExitCode, ExitStatus, ExitStatusError, Process, Stdio, StdioPipes, +}; diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/process/uefi.rs index 1203d51e531..b46418ae9bb 100644 --- a/library/std/src/sys/pal/uefi/process.rs +++ b/library/std/src/sys/process/uefi.rs @@ -1,12 +1,13 @@ use r_efi::protocols::simple_text_output; -use super::helpers; use crate::collections::BTreeMap; pub use crate::ffi::OsString as EnvKey; use crate::ffi::{OsStr, OsString}; use crate::num::{NonZero, NonZeroI32}; use crate::path::Path; use crate::sys::fs::File; +use crate::sys::pal::helpers; +use crate::sys::pal::os::error_string; use crate::sys::pipe::AnonPipe; use crate::sys::unsupported; use crate::sys_common::process::{CommandEnv, CommandEnvs}; @@ -225,7 +226,7 @@ impl ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = super::os::error_string(self.0.as_usize()); + let err_str = error_string(self.0.as_usize()); write!(f, "{}", err_str) } } @@ -241,7 +242,7 @@ pub struct ExitStatusError(r_efi::efi::Status); impl fmt::Debug for ExitStatusError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let err_str = super::os::error_string(self.0.as_usize()); + let err_str = error_string(self.0.as_usize()); write!(f, "{}", err_str) } } @@ -335,7 +336,6 @@ impl<'a> fmt::Debug for CommandArgs<'a> { mod uefi_command_internal { use r_efi::protocols::{loaded_image, simple_text_output}; - use super::super::helpers; use crate::ffi::{OsStr, OsString}; use crate::io::{self, const_error}; use crate::mem::MaybeUninit; @@ -343,7 +343,7 @@ mod uefi_command_internal { use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::ptr::NonNull; use crate::slice; - use crate::sys::pal::uefi::helpers::OwnedTable; + use crate::sys::pal::helpers::{self, OwnedTable}; use crate::sys_common::wstr::WStrUnits; pub struct Image { diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/process/unix/common.rs index a1c747c8df4..8bc17f31491 100644 --- a/library/std/src/sys/pal/unix/process/process_common.rs +++ b/library/std/src/sys/process/unix/common.rs @@ -54,7 +54,7 @@ cfg_if::cfg_if! { let bit = (signum - 1) as usize; if set.is_null() || bit >= (8 * size_of::<sigset_t>()) { - crate::sys::pal::unix::os::set_errno(libc::EINVAL); + crate::sys::pal::os::set_errno(libc::EINVAL); return -1; } let raw = slice::from_raw_parts_mut( diff --git a/library/std/src/sys/pal/unix/process/process_common/tests.rs b/library/std/src/sys/process/unix/common/tests.rs index e5c8dd6e341..e5c8dd6e341 100644 --- a/library/std/src/sys/pal/unix/process/process_common/tests.rs +++ b/library/std/src/sys/process/unix/common/tests.rs diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/process/unix/fuchsia.rs index 05c9ace470e..0de32ecffd4 100644 --- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs +++ b/library/std/src/sys/process/unix/fuchsia.rs @@ -1,8 +1,8 @@ use libc::{c_int, size_t}; +use super::common::*; use crate::num::NonZero; -use crate::sys::process::process_common::*; -use crate::sys::process::zircon::{Handle, zx_handle_t}; +use crate::sys::pal::fuchsia::*; use crate::{fmt, io, mem, ptr}; //////////////////////////////////////////////////////////////////////////////// @@ -58,8 +58,6 @@ impl Command { stdio: ChildPipes, maybe_envp: Option<&CStringArray>, ) -> io::Result<zx_handle_t> { - use crate::sys::process::zircon::*; - let envp = match maybe_envp { // None means to clone the current environment, which is done in the // flags below. @@ -152,8 +150,6 @@ impl Process { } pub fn kill(&mut self) -> io::Result<()> { - use crate::sys::process::zircon::*; - unsafe { zx_cvt(zx_task_kill(self.handle.raw()))?; } @@ -162,8 +158,6 @@ impl Process { } pub fn wait(&mut self) -> io::Result<ExitStatus> { - use crate::sys::process::zircon::*; - let mut proc_info: zx_info_process_t = Default::default(); let mut actual: size_t = 0; let mut avail: size_t = 0; @@ -194,8 +188,6 @@ impl Process { } pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { - use crate::sys::process::zircon::*; - let mut proc_info: zx_info_process_t = Default::default(); let mut actual: size_t = 0; let mut avail: size_t = 0; @@ -251,7 +243,7 @@ impl ExitStatus { None } - // FIXME: The actually-Unix implementation in process_unix.rs uses WSTOPSIG, WCOREDUMP et al. + // FIXME: The actually-Unix implementation in unix.rs uses WSTOPSIG, WCOREDUMP et al. // I infer from the implementation of `success`, `code` and `signal` above that these are not // available on Fuchsia. // diff --git a/library/std/src/sys/process/unix/mod.rs b/library/std/src/sys/process/unix/mod.rs new file mode 100644 index 00000000000..2e8b38f7de1 --- /dev/null +++ b/library/std/src/sys/process/unix/mod.rs @@ -0,0 +1,23 @@ +#[cfg_attr(any(target_os = "espidf", target_os = "horizon", target_os = "nuttx"), allow(unused))] +mod common; + +cfg_if::cfg_if! { + if #[cfg(target_os = "fuchsia")] { + mod fuchsia; + use fuchsia as imp; + } else if #[cfg(target_os = "vxworks")] { + mod vxworks; + use vxworks as imp; + } else if #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "vita", target_os = "nuttx"))] { + mod unsupported; + use unsupported as imp; + } else { + mod unix; + use unix as imp; + } +} + +pub use imp::{ExitStatus, ExitStatusError, Process}; + +pub use self::common::{Command, CommandArgs, ExitCode, Stdio, StdioPipes}; +pub use crate::ffi::OsString as EnvKey; diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/process/unix/unix.rs index f19512233d8..42542f81b65 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/process/unix/unix.rs @@ -10,12 +10,12 @@ use libc::{c_int, pid_t}; )))] use libc::{gid_t, uid_t}; +use super::common::*; use crate::io::{self, Error, ErrorKind}; use crate::num::NonZero; use crate::sys::cvt; #[cfg(target_os = "linux")] -use crate::sys::pal::unix::linux::pidfd::PidFd; -use crate::sys::process::process_common::*; +use crate::sys::pal::linux::pidfd::PidFd; use crate::{fmt, mem, sys}; cfg_if::cfg_if! { @@ -1051,7 +1051,7 @@ impl ExitStatus { // true on all actual versions of Unix, is widely assumed, and is specified in SuS // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not // true for a platform pretending to be Unix, the tests (our doctests, and also - // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. + // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. match NonZero::try_from(self.0) { /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), /* was zero, couldn't convert */ Err(_) => Ok(()), @@ -1232,10 +1232,9 @@ impl ExitStatusError { #[cfg(target_os = "linux")] mod linux_child_ext { - + use crate::io::ErrorKind; use crate::os::linux::process as os; - use crate::sys::pal::unix::ErrorKind; - use crate::sys::pal::unix::linux::pidfd as imp; + use crate::sys::pal::linux::pidfd as imp; use crate::sys_common::FromInner; use crate::{io, mem}; @@ -1261,10 +1260,9 @@ mod linux_child_ext { } #[cfg(test)] -#[path = "process_unix/tests.rs"] mod tests; -// See [`process_unsupported_wait_status::compare_with_linux`]; +// See [`unsupported_wait_status::compare_with_linux`]; #[cfg(all(test, target_os = "linux"))] -#[path = "process_unsupported/wait_status.rs"] -mod process_unsupported_wait_status; +#[path = "unsupported/wait_status.rs"] +mod unsupported_wait_status; diff --git a/library/std/src/sys/pal/unix/process/process_unix/tests.rs b/library/std/src/sys/process/unix/unix/tests.rs index f4d6ac6b4e3..f4d6ac6b4e3 100644 --- a/library/std/src/sys/pal/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/process/unix/unix/tests.rs diff --git a/library/std/src/sys/pal/unix/process/process_unsupported.rs b/library/std/src/sys/process/unix/unsupported.rs index c58548835ff..78d270923cf 100644 --- a/library/std/src/sys/pal/unix/process/process_unsupported.rs +++ b/library/std/src/sys/process/unix/unsupported.rs @@ -1,9 +1,9 @@ use libc::{c_int, pid_t}; +use super::common::*; use crate::io; use crate::num::NonZero; -use crate::sys::pal::unix::unsupported::*; -use crate::sys::process::process_common::*; +use crate::sys::pal::unsupported::*; //////////////////////////////////////////////////////////////////////////////// // Command diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs b/library/std/src/sys/process/unix/unsupported/wait_status.rs index f04036bde49..f348d557e4b 100644 --- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status.rs +++ b/library/std/src/sys/process/unix/unsupported/wait_status.rs @@ -7,7 +7,7 @@ use crate::ffi::c_int; use crate::fmt; use crate::num::NonZero; -/// Emulated wait status for use by `process_unsupported.rs` +/// Emulated wait status for use by `unsupported.rs` /// /// Uses the "traditional unix" encoding. For use on platfors which are `#[cfg(unix)]` /// but do not actually support subprocesses at all. @@ -48,7 +48,7 @@ impl ExitStatus { // true on all actual versions of Unix, is widely assumed, and is specified in SuS // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not // true for a platform pretending to be Unix, the tests (our doctests, and also - // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. + // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. match NonZero::try_from(self.wait_status) { /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), /* was zero, couldn't convert */ Err(_) => Ok(()), @@ -79,5 +79,6 @@ impl ExitStatus { } #[cfg(test)] -#[path = "wait_status/tests.rs"] // needed because of strange layout of process_unsupported +#[path = "wait_status/tests.rs"] +// needed because this module is also imported through #[path] for testing purposes mod tests; diff --git a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status/tests.rs b/library/std/src/sys/process/unix/unsupported/wait_status/tests.rs index 5132eab10a1..0d9232fac5e 100644 --- a/library/std/src/sys/pal/unix/process/process_unsupported/wait_status/tests.rs +++ b/library/std/src/sys/process/unix/unsupported/wait_status/tests.rs @@ -1,4 +1,4 @@ -// Note that tests in this file are run on Linux as well as on platforms using process_unsupported +// Note that tests in this file are run on Linux as well as on platforms using unsupported // Test that our emulation exactly matches Linux // diff --git a/library/std/src/sys/pal/unix/process/process_vxworks.rs b/library/std/src/sys/process/unix/vxworks.rs index e2c1b6a0326..5f1727789a1 100644 --- a/library/std/src/sys/pal/unix/process/process_vxworks.rs +++ b/library/std/src/sys/process/unix/vxworks.rs @@ -1,11 +1,11 @@ #![forbid(unsafe_op_in_unsafe_fn)] use libc::{self, RTP_ID, c_char, c_int}; +use super::common::*; use crate::io::{self, ErrorKind}; use crate::num::NonZero; use crate::sys::cvt; -use crate::sys::pal::unix::thread; -use crate::sys::process::process_common::*; +use crate::sys::pal::thread; use crate::{fmt, sys}; //////////////////////////////////////////////////////////////////////////////// @@ -200,7 +200,7 @@ impl ExitStatus { // true on all actual versions of Unix, is widely assumed, and is specified in SuS // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html. If it is not // true for a platform pretending to be Unix, the tests (our doctests, and also - // process_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. + // unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. match NonZero::try_from(self.0) { Ok(failure) => Err(ExitStatusError(failure)), Err(_) => Ok(()), diff --git a/library/std/src/sys/pal/unsupported/process.rs b/library/std/src/sys/process/unsupported.rs index fee81744f09..fee81744f09 100644 --- a/library/std/src/sys/pal/unsupported/process.rs +++ b/library/std/src/sys/process/unsupported.rs diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/process/windows.rs index 50e4baba607..06c15e08f3f 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/process/windows.rs @@ -5,11 +5,10 @@ mod tests; use core::ffi::c_void; -use super::api::{self, WinError}; use crate::collections::BTreeMap; use crate::env::consts::{EXE_EXTENSION, EXE_SUFFIX}; use crate::ffi::{OsStr, OsString}; -use crate::io::{self, Error, ErrorKind}; +use crate::io::{self, Error}; use crate::num::NonZero; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle}; @@ -20,6 +19,8 @@ use crate::sys::args::{self, Arg}; use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS}; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; +use crate::sys::pal::api::{self, WinError}; +use crate::sys::pal::{ensure_no_nuls, fill_utf16_buf}; use crate::sys::pipe::{self, AnonPipe}; use crate::sys::{cvt, path, stdio}; use crate::sys_common::IntoInner; @@ -142,14 +143,6 @@ impl AsRef<OsStr> for EnvKey { } } -pub(crate) fn ensure_no_nuls<T: AsRef<OsStr>>(s: T) -> io::Result<T> { - if s.as_ref().encode_wide().any(|b| b == 0) { - Err(io::const_error!(ErrorKind::InvalidInput, "nul byte found in provided data")) - } else { - Ok(s) - } -} - pub struct Command { program: OsString, args: Vec<Arg>, @@ -279,7 +272,7 @@ impl Command { let is_batch_file = if path::is_verbatim(&program) { has_bat_extension(&program[..program.len() - 1]) } else { - super::fill_utf16_buf( + fill_utf16_buf( |buffer, size| unsafe { // resolve the path so we can test the final file name. c::GetFullPathNameW(program.as_ptr(), size, buffer, ptr::null_mut()) @@ -521,7 +514,7 @@ where // 3 & 4. System paths // SAFETY: This uses `fill_utf16_buf` to safely call the OS functions. unsafe { - if let Ok(Some(path)) = super::fill_utf16_buf( + if let Ok(Some(path)) = fill_utf16_buf( |buf, size| c::GetSystemDirectoryW(buf, size), |buf| exists(PathBuf::from(OsString::from_wide(buf))), ) { @@ -529,7 +522,7 @@ where } #[cfg(not(target_vendor = "uwp"))] { - if let Ok(Some(path)) = super::fill_utf16_buf( + if let Ok(Some(path)) = fill_utf16_buf( |buf, size| c::GetWindowsDirectoryW(buf, size), |buf| exists(PathBuf::from(OsString::from_wide(buf))), ) { @@ -851,10 +844,8 @@ fn make_command_line(argv0: &OsStr, args: &[Arg], force_quotes: bool) -> io::Res // Get `cmd.exe` for use with bat scripts, encoded as a UTF-16 string. fn command_prompt() -> io::Result<Vec<u16>> { - let mut system: Vec<u16> = super::fill_utf16_buf( - |buf, size| unsafe { c::GetSystemDirectoryW(buf, size) }, - |buf| buf.into(), - )?; + let mut system: Vec<u16> = + fill_utf16_buf(|buf, size| unsafe { c::GetSystemDirectoryW(buf, size) }, |buf| buf.into())?; system.extend("\\cmd.exe".encode_utf16().chain([0])); Ok(system) } diff --git a/library/std/src/sys/pal/windows/process/tests.rs b/library/std/src/sys/process/windows/tests.rs index 1377e12162f..1377e12162f 100644 --- a/library/std/src/sys/pal/windows/process/tests.rs +++ b/library/std/src/sys/process/windows/tests.rs diff --git a/library/std/src/sys/random/trusty.rs b/library/std/src/sys/random/trusty.rs index da6ca3eea24..e4db24695f8 100644 --- a/library/std/src/sys/random/trusty.rs +++ b/library/std/src/sys/random/trusty.rs @@ -1,4 +1,4 @@ -extern "C" { +unsafe extern "C" { fn trusty_rng_secure_rand(randomBuffer: *mut core::ffi::c_void, randomBufferLen: libc::size_t); } diff --git a/library/std/src/sys/stdio/sgx.rs b/library/std/src/sys/stdio/sgx.rs index 1894c098d18..2cf47f49192 100644 --- a/library/std/src/sys/stdio/sgx.rs +++ b/library/std/src/sys/stdio/sgx.rs @@ -3,9 +3,9 @@ use fortanix_sgx_abi as abi; use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; use crate::sys::fd::FileDesc; -pub struct Stdin(()); -pub struct Stdout(()); -pub struct Stderr(()); +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R { let fd = FileDesc::new(fd); @@ -16,7 +16,7 @@ fn with_std_fd<F: FnOnce(&FileDesc) -> R, R>(fd: abi::Fd, f: F) -> R { impl Stdin { pub const fn new() -> Stdin { - Stdin(()) + Stdin } } @@ -41,7 +41,7 @@ impl io::Read for Stdin { impl Stdout { pub const fn new() -> Stdout { - Stdout(()) + Stdout } } @@ -66,7 +66,7 @@ impl io::Write for Stdout { impl Stderr { pub const fn new() -> Stderr { - Stderr(()) + Stderr } } diff --git a/library/std/src/sys/stdio/solid.rs b/library/std/src/sys/stdio/solid.rs index a2ff4bb212f..55daf0b54b9 100644 --- a/library/std/src/sys/stdio/solid.rs +++ b/library/std/src/sys/stdio/solid.rs @@ -1,22 +1,13 @@ +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; + use crate::io; use crate::sys::pal::abi; -pub struct Stdin; +pub type Stdin = unsupported_stdio::Stdin; pub struct Stdout; -pub struct Stderr; -struct PanicOutput; - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} +pub type Stderr = Stdout; impl Stdout { pub const fn new() -> Stdout { @@ -35,46 +26,12 @@ impl io::Write for Stdout { } } -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) }; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -impl PanicOutput { - pub const fn new() -> PanicOutput { - PanicOutput - } -} - -impl io::Write for PanicOutput { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - unsafe { abi::SOLID_LOG_write(buf.as_ptr(), buf.len()) }; - Ok(buf.len()) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} - -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(_err: &io::Error) -> bool { true } pub fn panic_output() -> Option<impl io::Write> { - Some(PanicOutput::new()) + Some(Stderr::new()) } diff --git a/library/std/src/sys/stdio/teeos.rs b/library/std/src/sys/stdio/teeos.rs index 67e251812da..27b3292bf8f 100644 --- a/library/std/src/sys/stdio/teeos.rs +++ b/library/std/src/sys/stdio/teeos.rs @@ -1,12 +1,16 @@ #![deny(unsafe_op_in_unsafe_fn)] +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; + use core::arch::asm; use crate::io; -pub struct Stdin; +pub type Stdin = unsupported_stdio::Stdin; pub struct Stdout; -pub struct Stderr; +pub type Stderr = Stdout; const KCALL_DEBUG_CMD_PUT_BYTES: i64 = 2; @@ -25,27 +29,6 @@ unsafe fn debug_call(cap_ref: u64, call_no: i64, arg1: u64, arg2: u64) -> i32 { ret as i32 } -fn print_buf(s: &[u8]) -> io::Result<usize> { - // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`. - const MAX_LEN: usize = 512; - let len = if s.len() > MAX_LEN { MAX_LEN } else { s.len() }; - let result = unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, s.as_ptr() as u64, len as u64) }; - - if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) } -} - -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} - impl Stdout { pub const fn new() -> Stdout { Stdout @@ -54,23 +37,13 @@ impl Stdout { impl io::Write for Stdout { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - print_buf(buf) - } - - fn flush(&mut self) -> io::Result<()> { - Ok(()) - } -} + // Corresponds to `HM_DEBUG_PUT_BYTES_LIMIT`. + const MAX_LEN: usize = 512; + let len = buf.len().min(MAX_LEN); + let result = + unsafe { debug_call(0, KCALL_DEBUG_CMD_PUT_BYTES, buf.as_ptr() as u64, len as u64) }; -impl Stderr { - pub const fn new() -> Stderr { - Stderr - } -} - -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - print_buf(buf) + if result == 0 { Ok(len) } else { Err(io::Error::from(io::ErrorKind::InvalidInput)) } } fn flush(&mut self) -> io::Result<()> { @@ -78,7 +51,7 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(err: &io::Error) -> bool { err.raw_os_error() == Some(libc::EBADF as i32) diff --git a/library/std/src/sys/stdio/unix.rs b/library/std/src/sys/stdio/unix.rs index 08a06e0da9f..8535e3539e9 100644 --- a/library/std/src/sys/stdio/unix.rs +++ b/library/std/src/sys/stdio/unix.rs @@ -11,13 +11,13 @@ use crate::os::hermit::io::FromRawFd; use crate::os::unix::io::FromRawFd; use crate::sys::fd::FileDesc; -pub struct Stdin(()); -pub struct Stdout(()); -pub struct Stderr(()); +pub struct Stdin; +pub struct Stdout; +pub struct Stderr; impl Stdin { pub const fn new() -> Stdin { - Stdin(()) + Stdin } } @@ -42,7 +42,7 @@ impl io::Read for Stdin { impl Stdout { pub const fn new() -> Stdout { - Stdout(()) + Stdout } } @@ -68,7 +68,7 @@ impl io::Write for Stdout { impl Stderr { pub const fn new() -> Stderr { - Stderr(()) + Stderr } } diff --git a/library/std/src/sys/stdio/unsupported.rs b/library/std/src/sys/stdio/unsupported.rs index b5e3f5be988..177264f5c10 100644 --- a/library/std/src/sys/stdio/unsupported.rs +++ b/library/std/src/sys/stdio/unsupported.rs @@ -1,8 +1,8 @@ -use crate::io; +use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; pub struct Stdin; pub struct Stdout; -pub struct Stderr; +pub type Stderr = Stdout; impl Stdin { pub const fn new() -> Stdin { @@ -11,9 +11,47 @@ impl Stdin { } impl io::Read for Stdin { + #[inline] fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) } + + #[inline] + fn read_buf(&mut self, _cursor: BorrowedCursor<'_>) -> io::Result<()> { + Ok(()) + } + + #[inline] + fn read_vectored(&mut self, _bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn is_read_vectored(&self) -> bool { + // Do not force `Chain<Empty, T>` or `Chain<T, Empty>` to use vectored + // reads, unless the other reader is vectored. + false + } + + #[inline] + fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { + if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> io::Result<()> { + if cursor.capacity() != 0 { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) } + } + + #[inline] + fn read_to_end(&mut self, _buf: &mut Vec<u8>) -> io::Result<usize> { + Ok(0) + } + + #[inline] + fn read_to_string(&mut self, _buf: &mut String) -> io::Result<usize> { + Ok(0) + } } impl Stdout { @@ -23,26 +61,35 @@ impl Stdout { } impl io::Write for Stdout { + #[inline] fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) } - fn flush(&mut self) -> io::Result<()> { - Ok(()) + #[inline] + fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let total_len = bufs.iter().map(|b| b.len()).sum(); + Ok(total_len) } -} -impl Stderr { - pub const fn new() -> Stderr { - Stderr + #[inline] + fn is_write_vectored(&self) -> bool { + true } -} -impl io::Write for Stderr { - fn write(&mut self, buf: &[u8]) -> io::Result<usize> { - Ok(buf.len()) + #[inline] + fn write_all(&mut self, _buf: &[u8]) -> io::Result<()> { + Ok(()) } + #[inline] + fn write_all_vectored(&mut self, _bufs: &mut [IoSlice<'_>]) -> io::Result<()> { + Ok(()) + } + + // Keep the default write_fmt so the `fmt::Arguments` are still evaluated. + + #[inline] fn flush(&mut self) -> io::Result<()> { Ok(()) } diff --git a/library/std/src/sys/stdio/xous.rs b/library/std/src/sys/stdio/xous.rs index 71736145221..a92167642b7 100644 --- a/library/std/src/sys/stdio/xous.rs +++ b/library/std/src/sys/stdio/xous.rs @@ -1,27 +1,18 @@ -use crate::io; - -pub struct Stdin; -pub struct Stdout {} -pub struct Stderr; +#[expect(dead_code)] +#[path = "unsupported.rs"] +mod unsupported_stdio; +use crate::io; use crate::os::xous::ffi::{Connection, lend, try_lend, try_scalar}; use crate::os::xous::services::{LogLend, LogScalar, log_server, try_connect}; -impl Stdin { - pub const fn new() -> Stdin { - Stdin - } -} - -impl io::Read for Stdin { - fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { - Ok(0) - } -} +pub type Stdin = unsupported_stdio::Stdin; +pub struct Stdout; +pub struct Stderr; impl Stdout { pub const fn new() -> Stdout { - Stdout {} + Stdout } } @@ -73,7 +64,7 @@ impl io::Write for Stderr { } } -pub const STDIN_BUF_SIZE: usize = 0; +pub const STDIN_BUF_SIZE: usize = unsupported_stdio::STDIN_BUF_SIZE; pub fn is_ebadf(_err: &io::Error) -> bool { true diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs index 06c347af181..59ec48a57d1 100644 --- a/library/std/src/thread/tests.rs +++ b/library/std/src/thread/tests.rs @@ -108,6 +108,7 @@ fn test_is_finished() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_join_panic() { match thread::spawn(move || panic!()).join() { result::Result::Err(_) => (), @@ -210,6 +211,7 @@ fn test_simple_newsched_spawn() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_try_panic_message_string_literal() { match thread::spawn(move || { panic!("static string"); @@ -226,6 +228,7 @@ fn test_try_panic_message_string_literal() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_try_panic_any_message_owned_str() { match thread::spawn(move || { panic_any("owned string".to_string()); @@ -242,6 +245,7 @@ fn test_try_panic_any_message_owned_str() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_try_panic_any_message_any() { match thread::spawn(move || { panic_any(Box::new(413u16) as Box<dyn Any + Send>); @@ -260,6 +264,7 @@ fn test_try_panic_any_message_any() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_try_panic_any_message_unit_struct() { struct Juju; diff --git a/library/std/tests/sync/mutex.rs b/library/std/tests/sync/mutex.rs index 74c62720107..88fb448d1eb 100644 --- a/library/std/tests/sync/mutex.rs +++ b/library/std/tests/sync/mutex.rs @@ -118,6 +118,7 @@ fn test_into_inner_drop() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_inner_poison() { let m = new_poisoned_mutex(NonCopy(10)); @@ -135,6 +136,7 @@ fn test_get_cloned() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_get_cloned_poison() { let m = new_poisoned_mutex(Cloneable(10)); @@ -152,6 +154,7 @@ fn test_get_mut() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_get_mut_poison() { let mut m = new_poisoned_mutex(NonCopy(10)); @@ -179,6 +182,7 @@ fn test_set() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_set_poison() { fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) where @@ -217,6 +221,7 @@ fn test_replace() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_replace_poison() { fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) where @@ -261,6 +266,7 @@ fn test_mutex_arc_condvar() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_arc_condvar_poison() { let packet = Packet(Arc::new((Mutex::new(1), Condvar::new()))); let packet2 = Packet(packet.0.clone()); @@ -290,6 +296,7 @@ fn test_arc_condvar_poison() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_mutex_arc_poison() { let arc = Arc::new(Mutex::new(1)); assert!(!arc.is_poisoned()); @@ -304,6 +311,7 @@ fn test_mutex_arc_poison() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_mutex_arc_poison_mapped() { let arc = Arc::new(Mutex::new(1)); assert!(!arc.is_poisoned()); @@ -335,6 +343,7 @@ fn test_mutex_arc_nested() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_mutex_arc_access_in_unwind() { let arc = Arc::new(Mutex::new(1)); let arc2 = arc.clone(); @@ -381,6 +390,7 @@ fn test_mapping_mapped_guard() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_while_mapping_unlocked_poison() { let lock = Mutex::new(()); diff --git a/library/std/tests/sync/once.rs b/library/std/tests/sync/once.rs index a3ffc73fe06..1b43831df3a 100644 --- a/library/std/tests/sync/once.rs +++ b/library/std/tests/sync/once.rs @@ -52,6 +52,7 @@ fn stampede_once() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn poison_bad() { static O: Once = Once::new(); @@ -80,6 +81,7 @@ fn poison_bad() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn wait_for_force_to_finish() { static O: Once = Once::new(); @@ -137,6 +139,7 @@ fn wait() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn wait_on_poisoned() { let once = Once::new(); @@ -145,6 +148,7 @@ fn wait_on_poisoned() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn wait_force_on_poisoned() { let once = Once::new(); diff --git a/library/std/tests/sync/once_lock.rs b/library/std/tests/sync/once_lock.rs index ac9aaa8892e..922fd7da3d4 100644 --- a/library/std/tests/sync/once_lock.rs +++ b/library/std/tests/sync/once_lock.rs @@ -77,8 +77,10 @@ fn get_or_try_init() { let cell: OnceLock<String> = OnceLock::new(); assert!(cell.get().is_none()); - let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); - assert!(res.is_err()); + if cfg!(panic = "unwind") { + let res = panic::catch_unwind(|| cell.get_or_try_init(|| -> Result<_, ()> { panic!() })); + assert!(res.is_err()); + } assert!(cell.get().is_none()); assert_eq!(cell.get_or_try_init(|| Err(())), Err(())); diff --git a/library/std/tests/sync/rwlock.rs b/library/std/tests/sync/rwlock.rs index 49f260648c6..d2c784aefcf 100644 --- a/library/std/tests/sync/rwlock.rs +++ b/library/std/tests/sync/rwlock.rs @@ -73,6 +73,7 @@ fn frob() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_poison_wr() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -85,6 +86,7 @@ fn test_rw_arc_poison_wr() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_poison_mapped_w_r() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -98,6 +100,7 @@ fn test_rw_arc_poison_mapped_w_r() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_poison_ww() { let arc = Arc::new(RwLock::new(1)); assert!(!arc.is_poisoned()); @@ -112,6 +115,7 @@ fn test_rw_arc_poison_ww() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_poison_mapped_w_w() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -126,6 +130,7 @@ fn test_rw_arc_poison_mapped_w_w() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_no_poison_rr() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -139,6 +144,7 @@ fn test_rw_arc_no_poison_rr() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_no_poison_mapped_r_r() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -153,6 +159,7 @@ fn test_rw_arc_no_poison_mapped_r_r() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_no_poison_rw() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -166,6 +173,7 @@ fn test_rw_arc_no_poison_rw() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_no_poison_mapped_r_w() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -218,6 +226,7 @@ fn test_rw_arc() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_rw_arc_access_in_unwind() { let arc = Arc::new(RwLock::new(1)); let arc2 = arc.clone(); @@ -316,6 +325,7 @@ fn test_into_inner_drop() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_into_inner_poison() { let m = new_poisoned_rwlock(NonCopy(10)); @@ -333,6 +343,7 @@ fn test_get_cloned() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_get_cloned_poison() { let m = new_poisoned_rwlock(Cloneable(10)); @@ -350,6 +361,7 @@ fn test_get_mut() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_get_mut_poison() { let mut m = new_poisoned_rwlock(NonCopy(10)); @@ -377,6 +389,7 @@ fn test_set() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_set_poison() { fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) where @@ -415,6 +428,7 @@ fn test_replace() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn test_replace_poison() { fn inner<T>(mut init: impl FnMut() -> T, mut value: impl FnMut() -> T) where @@ -482,6 +496,7 @@ fn test_mapping_mapped_guard() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_while_mapping_read_unlocked_no_poison() { let lock = RwLock::new(()); @@ -551,6 +566,7 @@ fn panic_while_mapping_read_unlocked_no_poison() { } #[test] +#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")] fn panic_while_mapping_write_unlocked_poison() { let lock = RwLock::new(()); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 846b4de8142..18b5d4426b1 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -33,7 +33,7 @@ use crate::utils::exec::command; use crate::utils::helpers::{ exe, get_clang_cl_resource_dir, is_debug_info, is_dylib, symlink_dir, t, up_to_date, }; -use crate::{CLang, Compiler, DependencyType, GitRepo, LLVM_TOOLS, Mode, debug, trace}; +use crate::{CLang, Compiler, DependencyType, FileType, GitRepo, LLVM_TOOLS, Mode, debug, trace}; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Std { @@ -321,7 +321,7 @@ fn copy_and_stamp( dependency_type: DependencyType, ) { let target = libdir.join(name); - builder.copy_link(&sourcedir.join(name), &target); + builder.copy_link(&sourcedir.join(name), &target, FileType::Regular); target_deps.push((target, dependency_type)); } @@ -330,7 +330,7 @@ fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: & let libunwind_path = builder.ensure(llvm::Libunwind { target }); let libunwind_source = libunwind_path.join("libunwind.a"); let libunwind_target = libdir.join("libunwind.a"); - builder.copy_link(&libunwind_source, &libunwind_target); + builder.copy_link(&libunwind_source, &libunwind_target, FileType::NativeLibrary); libunwind_target } @@ -401,7 +401,7 @@ fn copy_self_contained_objects( for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { let src = crt_path.join(obj); let target = libdir_self_contained.join(obj); - builder.copy_link(&src, &target); + builder.copy_link(&src, &target, FileType::NativeLibrary); target_deps.push((target, DependencyType::TargetSelfContained)); } } else { @@ -443,9 +443,9 @@ fn copy_self_contained_objects( } else if target.is_windows_gnu() { for obj in ["crt2.o", "dllcrt2.o"].iter() { let src = compiler_file(builder, &builder.cc(target), target, CLang::C, obj); - let target = libdir_self_contained.join(obj); - builder.copy_link(&src, &target); - target_deps.push((target, DependencyType::TargetSelfContained)); + let dst = libdir_self_contained.join(obj); + builder.copy_link(&src, &dst, FileType::NativeLibrary); + target_deps.push((dst, DependencyType::TargetSelfContained)); } } @@ -790,8 +790,11 @@ impl Step for StdLink { let file = t!(file); let path = file.path(); if path.is_file() { - builder - .copy_link(&path, &sysroot.join("lib").join(path.file_name().unwrap())); + builder.copy_link( + &path, + &sysroot.join("lib").join(path.file_name().unwrap()), + FileType::Regular, + ); } } } @@ -829,7 +832,7 @@ fn copy_sanitizers( for runtime in &runtimes { let dst = libdir.join(&runtime.name); - builder.copy_link(&runtime.path, &dst); + builder.copy_link(&runtime.path, &dst, FileType::NativeLibrary); // The `aarch64-apple-ios-macabi` and `x86_64-apple-ios-macabi` are also supported for // sanitizers, but they share a sanitizer runtime with `${arch}-apple-darwin`, so we do @@ -934,9 +937,9 @@ impl Step for StartupObjects { .run(builder); } - let target = sysroot_dir.join((*file).to_string() + ".o"); - builder.copy_link(dst_file, &target); - target_deps.push((target, DependencyType::Target)); + let obj = sysroot_dir.join((*file).to_string() + ".o"); + builder.copy_link(dst_file, &obj, FileType::NativeLibrary); + target_deps.push((obj, DependencyType::Target)); } target_deps @@ -952,7 +955,7 @@ fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, conte if src.is_dir() { t!(fs::create_dir_all(dst)); } else { - builder.copy_link(&src, &dst); + builder.copy_link(&src, &dst, FileType::Regular); } } } @@ -1707,7 +1710,7 @@ fn copy_codegen_backends_to_sysroot( let dot = filename.find('.').unwrap(); format!("{}-{}{}", &filename[..dash], builder.rust_release(), &filename[dot..]) }; - builder.copy_link(file, &dst.join(target_filename)); + builder.copy_link(file, &dst.join(target_filename), FileType::NativeLibrary); } } @@ -2011,7 +2014,11 @@ impl Step for Assemble { extra_features: vec![], }); let tool_exe = exe("llvm-bitcode-linker", target_compiler.host); - builder.copy_link(&llvm_bitcode_linker.tool_path, &libdir_bin.join(tool_exe)); + builder.copy_link( + &llvm_bitcode_linker.tool_path, + &libdir_bin.join(tool_exe), + FileType::Executable, + ); } }; @@ -2072,8 +2079,8 @@ impl Step for Assemble { builder.sysroot_target_libdir(target_compiler, target_compiler.host); let dst_lib = libdir.join(&libenzyme).with_extension(lib_ext); let target_dst_lib = target_libdir.join(&libenzyme).with_extension(lib_ext); - builder.copy_link(&src_lib, &dst_lib); - builder.copy_link(&src_lib, &target_dst_lib); + builder.copy_link(&src_lib, &dst_lib, FileType::NativeLibrary); + builder.copy_link(&src_lib, &target_dst_lib, FileType::NativeLibrary); } // Build the libraries for this compiler to link to (i.e., the libraries @@ -2168,7 +2175,7 @@ impl Step for Assemble { }; if is_dylib_or_debug && can_be_rustc_dynamic_dep && !is_proc_macro { - builder.copy_link(&f.path(), &rustc_libdir.join(&filename)); + builder.copy_link(&f.path(), &rustc_libdir.join(&filename), FileType::Regular); } } @@ -2196,7 +2203,11 @@ impl Step for Assemble { // See <https://github.com/rust-lang/rust/issues/132719>. let src_exe = exe("llvm-objcopy", target_compiler.host); let dst_exe = exe("rust-objcopy", target_compiler.host); - builder.copy_link(&libdir_bin.join(src_exe), &libdir_bin.join(dst_exe)); + builder.copy_link( + &libdir_bin.join(src_exe), + &libdir_bin.join(dst_exe), + FileType::Executable, + ); } // In addition to `rust-lld` also install `wasm-component-ld` when @@ -2212,6 +2223,7 @@ impl Step for Assemble { builder.copy_link( &wasm_component.tool_path, &libdir_bin.join(wasm_component.tool_path.file_name().unwrap()), + FileType::Executable, ); } @@ -2234,7 +2246,7 @@ impl Step for Assemble { t!(fs::create_dir_all(bindir)); let compiler = builder.rustc(target_compiler); debug!(src = ?rustc, dst = ?compiler, "linking compiler binary itself"); - builder.copy_link(&rustc, &compiler); + builder.copy_link(&rustc, &compiler, FileType::Executable); target_compiler } @@ -2260,7 +2272,7 @@ pub fn add_to_sysroot( DependencyType::Target => sysroot_dst, DependencyType::TargetSelfContained => self_contained_dst, }; - builder.copy_link(&path, &dst.join(path.file_name().unwrap())); + builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::Regular); } } diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 39f9680cb2f..83f71aeed72 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -32,7 +32,7 @@ use crate::utils::helpers::{ exe, is_dylib, move_file, t, target_supports_cranelift_backend, timeit, }; use crate::utils::tarball::{GeneratedTarball, OverlayKind, Tarball}; -use crate::{Compiler, DependencyType, LLVM_TOOLS, Mode, trace}; +use crate::{Compiler, DependencyType, FileType, LLVM_TOOLS, Mode, trace}; pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { format!("{}-{}", component, builder.rust_package_vers()) @@ -81,7 +81,7 @@ impl Step for Docs { let mut tarball = Tarball::new(builder, "rust-docs", &host.triple); tarball.set_product_name("Rust Documentation"); tarball.add_bulk_dir(builder.doc_out(host), dest); - tarball.add_file(builder.src.join("src/doc/robots.txt"), dest, 0o644); + tarball.add_file(builder.src.join("src/doc/robots.txt"), dest, FileType::Regular); Some(tarball.generate()) } } @@ -418,7 +418,7 @@ impl Step for Rustc { .is_none_or(|tools| tools.iter().any(|tool| tool == "rustdoc")) { let rustdoc = builder.rustdoc(compiler); - builder.install(&rustdoc, &image.join("bin"), 0o755); + builder.install(&rustdoc, &image.join("bin"), FileType::Executable); } if let Some(ra_proc_macro_srv) = builder.ensure_if_default( @@ -432,7 +432,8 @@ impl Step for Rustc { }, builder.kind, ) { - builder.install(&ra_proc_macro_srv.tool_path, &image.join("libexec"), 0o755); + let dst = image.join("libexec"); + builder.install(&ra_proc_macro_srv.tool_path, &dst, FileType::Executable); } let libdir_relative = builder.libdir_relative(compiler); @@ -444,7 +445,7 @@ impl Step for Rustc { if is_dylib(&entry.path()) { // Don't use custom libdir here because ^lib/ will be resolved again // with installer - builder.install(&entry.path(), &image.join("lib"), 0o644); + builder.install(&entry.path(), &image.join("lib"), FileType::NativeLibrary); } } } @@ -463,7 +464,11 @@ impl Step for Rustc { if builder.config.lld_enabled { let src_dir = builder.sysroot_target_bindir(compiler, host); let rust_lld = exe("rust-lld", compiler.host); - builder.copy_link(&src_dir.join(&rust_lld), &dst_dir.join(&rust_lld)); + builder.copy_link( + &src_dir.join(&rust_lld), + &dst_dir.join(&rust_lld), + FileType::Executable, + ); let self_contained_lld_src_dir = src_dir.join("gcc-ld"); let self_contained_lld_dst_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&self_contained_lld_dst_dir)); @@ -472,6 +477,7 @@ impl Step for Rustc { builder.copy_link( &self_contained_lld_src_dir.join(&exe_name), &self_contained_lld_dst_dir.join(&exe_name), + FileType::Executable, ); } } @@ -480,13 +486,17 @@ impl Step for Rustc { let src_dir = builder.sysroot_target_bindir(compiler, host); let llvm_objcopy = exe("llvm-objcopy", compiler.host); let rust_objcopy = exe("rust-objcopy", compiler.host); - builder.copy_link(&src_dir.join(&llvm_objcopy), &dst_dir.join(&rust_objcopy)); + builder.copy_link( + &src_dir.join(&llvm_objcopy), + &dst_dir.join(&rust_objcopy), + FileType::Executable, + ); } if builder.tool_enabled("wasm-component-ld") { let src_dir = builder.sysroot_target_bindir(compiler, host); let ld = exe("wasm-component-ld", compiler.host); - builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld)); + builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld), FileType::Executable); } // Man pages @@ -511,15 +521,19 @@ impl Step for Rustc { // HTML copyright files let file_list = builder.ensure(super::run::GenerateCopyright); for file in file_list { - builder.install(&file, &image.join("share/doc/rust"), 0o644); + builder.install(&file, &image.join("share/doc/rust"), FileType::Regular); } // README - builder.install(&builder.src.join("README.md"), &image.join("share/doc/rust"), 0o644); + builder.install( + &builder.src.join("README.md"), + &image.join("share/doc/rust"), + FileType::Regular, + ); // The REUSE-managed license files let license = |path: &Path| { - builder.install(path, &image.join("share/doc/rust/licenses"), 0o644); + builder.install(path, &image.join("share/doc/rust/licenses"), FileType::Regular); }; for entry in t!(std::fs::read_dir(builder.src.join("LICENSES"))).flatten() { license(&entry.path()); @@ -548,14 +562,14 @@ impl Step for DebuggerScripts { let dst = sysroot.join("lib/rustlib/etc"); t!(fs::create_dir_all(&dst)); let cp_debugger_script = |file: &str| { - builder.install(&builder.src.join("src/etc/").join(file), &dst, 0o644); + builder.install(&builder.src.join("src/etc/").join(file), &dst, FileType::Regular); }; if host.contains("windows-msvc") { // windbg debugger scripts builder.install( &builder.src.join("src/etc/rust-windbg.cmd"), &sysroot.join("bin"), - 0o755, + FileType::Script, ); cp_debugger_script("natvis/intrinsic.natvis"); @@ -567,15 +581,27 @@ impl Step for DebuggerScripts { cp_debugger_script("rust_types.py"); // gdb debugger scripts - builder.install(&builder.src.join("src/etc/rust-gdb"), &sysroot.join("bin"), 0o755); - builder.install(&builder.src.join("src/etc/rust-gdbgui"), &sysroot.join("bin"), 0o755); + builder.install( + &builder.src.join("src/etc/rust-gdb"), + &sysroot.join("bin"), + FileType::Script, + ); + builder.install( + &builder.src.join("src/etc/rust-gdbgui"), + &sysroot.join("bin"), + FileType::Script, + ); cp_debugger_script("gdb_load_rust_pretty_printers.py"); cp_debugger_script("gdb_lookup.py"); cp_debugger_script("gdb_providers.py"); // lldb debugger scripts - builder.install(&builder.src.join("src/etc/rust-lldb"), &sysroot.join("bin"), 0o755); + builder.install( + &builder.src.join("src/etc/rust-lldb"), + &sysroot.join("bin"), + FileType::Script, + ); cp_debugger_script("lldb_lookup.py"); cp_debugger_script("lldb_providers.py"); @@ -640,9 +666,13 @@ fn copy_target_libs( t!(fs::create_dir_all(&self_contained_dst)); for (path, dependency_type) in builder.read_stamp_file(stamp) { if dependency_type == DependencyType::TargetSelfContained { - builder.copy_link(&path, &self_contained_dst.join(path.file_name().unwrap())); + builder.copy_link( + &path, + &self_contained_dst.join(path.file_name().unwrap()), + FileType::NativeLibrary, + ); } else if dependency_type == DependencyType::Target || builder.is_builder_target(target) { - builder.copy_link(&path, &dst.join(path.file_name().unwrap())); + builder.copy_link(&path, &dst.join(path.file_name().unwrap()), FileType::NativeLibrary); } } } @@ -750,7 +780,11 @@ impl Step for RustcDev { &tarball.image_dir().join("lib/rustlib/rustc-src/rust"), ); for file in src_files { - tarball.add_file(builder.src.join(file), "lib/rustlib/rustc-src/rust", 0o644); + tarball.add_file( + builder.src.join(file), + "lib/rustlib/rustc-src/rust", + FileType::Regular, + ); } Some(tarball.generate()) @@ -1045,7 +1079,11 @@ impl Step for PlainSourceTarball { // Copy the files normally for item in &src_files { - builder.copy_link(&builder.src.join(item), &plain_dst_src.join(item)); + builder.copy_link( + &builder.src.join(item), + &plain_dst_src.join(item), + FileType::Regular, + ); } // Create the version file @@ -1147,9 +1185,14 @@ impl Step for Cargo { let mut tarball = Tarball::new(builder, "cargo", &target.triple); tarball.set_overlay(OverlayKind::Cargo); - tarball.add_file(cargo.tool_path, "bin", 0o755); - tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", 0o644); - tarball.add_renamed_file(etc.join("cargo.bashcomp.sh"), "etc/bash_completion.d", "cargo"); + tarball.add_file(&cargo.tool_path, "bin", FileType::Executable); + tarball.add_file(etc.join("_cargo"), "share/zsh/site-functions", FileType::Regular); + tarball.add_renamed_file( + etc.join("cargo.bashcomp.sh"), + "etc/bash_completion.d", + "cargo", + FileType::Regular, + ); tarball.add_dir(etc.join("man"), "share/man/man1"); tarball.add_legal_and_readme_to("share/doc/cargo"); @@ -1193,7 +1236,7 @@ impl Step for RustAnalyzer { let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); tarball.set_overlay(OverlayKind::RustAnalyzer); tarball.is_preview(true); - tarball.add_file(rust_analyzer.tool_path, "bin", 0o755); + tarball.add_file(&rust_analyzer.tool_path, "bin", FileType::Executable); tarball.add_legal_and_readme_to("share/doc/rust-analyzer"); Some(tarball.generate()) } @@ -1239,8 +1282,8 @@ impl Step for Clippy { let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); tarball.is_preview(true); - tarball.add_file(clippy.tool_path, "bin", 0o755); - tarball.add_file(cargoclippy.tool_path, "bin", 0o755); + tarball.add_file(&clippy.tool_path, "bin", FileType::Executable); + tarball.add_file(&cargoclippy.tool_path, "bin", FileType::Executable); tarball.add_legal_and_readme_to("share/doc/clippy"); Some(tarball.generate()) } @@ -1289,8 +1332,8 @@ impl Step for Miri { let mut tarball = Tarball::new(builder, "miri", &target.triple); tarball.set_overlay(OverlayKind::Miri); tarball.is_preview(true); - tarball.add_file(miri.tool_path, "bin", 0o755); - tarball.add_file(cargomiri.tool_path, "bin", 0o755); + tarball.add_file(&miri.tool_path, "bin", FileType::Executable); + tarball.add_file(&cargomiri.tool_path, "bin", FileType::Executable); tarball.add_legal_and_readme_to("share/doc/miri"); Some(tarball.generate()) } @@ -1374,7 +1417,11 @@ impl Step for CodegenBackend { for backend in fs::read_dir(&backends_src).unwrap() { let file_name = backend.unwrap().file_name(); if file_name.to_str().unwrap().contains(&backend_name) { - tarball.add_file(backends_src.join(file_name), &backends_dst, 0o644); + tarball.add_file( + backends_src.join(file_name), + &backends_dst, + FileType::NativeLibrary, + ); found_backend = true; } } @@ -1420,8 +1467,8 @@ impl Step for Rustfmt { let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); tarball.set_overlay(OverlayKind::Rustfmt); tarball.is_preview(true); - tarball.add_file(rustfmt.tool_path, "bin", 0o755); - tarball.add_file(cargofmt.tool_path, "bin", 0o755); + tarball.add_file(&rustfmt.tool_path, "bin", FileType::Executable); + tarball.add_file(&cargofmt.tool_path, "bin", FileType::Executable); tarball.add_legal_and_readme_to("share/doc/rustfmt"); Some(tarball.generate()) } @@ -1578,27 +1625,33 @@ impl Step for Extended { &work.join(format!("{}-{}", pkgname(builder, name), target.triple)), &pkg.join(name), ); - builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), 0o755); + builder.install(&etc.join("pkg/postinstall"), &pkg.join(name), FileType::Script); pkgbuild(name); }; prepare("rustc"); prepare("cargo"); prepare("rust-std"); prepare("rust-analysis"); - prepare("clippy"); - prepare("rust-analyzer"); - for tool in &["rust-docs", "miri", "rustc-codegen-cranelift"] { + + for tool in &[ + "clippy", + "rustfmt", + "rust-analyzer", + "rust-docs", + "miri", + "rustc-codegen-cranelift", + ] { if built_tools.contains(tool) { prepare(tool); } } // create an 'uninstall' package - builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), 0o755); + builder.install(&etc.join("pkg/postinstall"), &pkg.join("uninstall"), FileType::Script); pkgbuild("uninstall"); builder.create_dir(&pkg.join("res")); builder.create(&pkg.join("res/LICENSE.txt"), &license); - builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), 0o644); + builder.install(&etc.join("gfx/rust-logo.png"), &pkg.join("res"), FileType::Regular); let mut cmd = command("productbuild"); cmd.arg("--distribution") .arg(xform(&etc.join("pkg/Distribution.xml"))) @@ -1627,6 +1680,8 @@ impl Step for Extended { "rust-analyzer-preview".to_string() } else if name == "clippy" { "clippy-preview".to_string() + } else if name == "rustfmt" { + "rustfmt-preview".to_string() } else if name == "miri" { "miri-preview".to_string() } else if name == "rustc-codegen-cranelift" { @@ -1646,7 +1701,7 @@ impl Step for Extended { prepare("cargo"); prepare("rust-analysis"); prepare("rust-std"); - for tool in &["clippy", "rust-analyzer", "rust-docs", "miri"] { + for tool in &["clippy", "rustfmt", "rust-analyzer", "rust-docs", "miri"] { if built_tools.contains(tool) { prepare(tool); } @@ -1655,7 +1710,7 @@ impl Step for Extended { prepare("rust-mingw"); } - builder.install(&etc.join("gfx/rust-logo.ico"), &exe, 0o644); + builder.install(&etc.join("gfx/rust-logo.ico"), &exe, FileType::Regular); // Generate msi installer let wix_path = env::var_os("WIX") @@ -1764,6 +1819,24 @@ impl Step for Extended { .arg(etc.join("msi/remove-duplicates.xsl")) .run(builder); } + if built_tools.contains("rustfmt") { + command(&heat) + .current_dir(&exe) + .arg("dir") + .arg("rustfmt") + .args(heat_flags) + .arg("-cg") + .arg("RustFmtGroup") + .arg("-dr") + .arg("RustFmt") + .arg("-var") + .arg("var.RustFmtDir") + .arg("-out") + .arg(exe.join("RustFmtGroup.wxs")) + .arg("-t") + .arg(etc.join("msi/remove-duplicates.xsl")) + .run(builder); + } if built_tools.contains("miri") { command(&heat) .current_dir(&exe) @@ -1830,11 +1903,14 @@ impl Step for Extended { .arg("-out") .arg(&output) .arg(input); - add_env(builder, &mut cmd, target); + add_env(builder, &mut cmd, target, &built_tools); if built_tools.contains("clippy") { cmd.arg("-dClippyDir=clippy"); } + if built_tools.contains("rustfmt") { + cmd.arg("-dRustFmtDir=rustfmt"); + } if built_tools.contains("rust-docs") { cmd.arg("-dDocsDir=rust-docs"); } @@ -1861,6 +1937,9 @@ impl Step for Extended { if built_tools.contains("clippy") { candle("ClippyGroup.wxs".as_ref()); } + if built_tools.contains("rustfmt") { + candle("RustFmtGroup.wxs".as_ref()); + } if built_tools.contains("miri") { candle("MiriGroup.wxs".as_ref()); } @@ -1874,8 +1953,8 @@ impl Step for Extended { } builder.create(&exe.join("LICENSE.rtf"), &rtf); - builder.install(&etc.join("gfx/banner.bmp"), &exe, 0o644); - builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, 0o644); + builder.install(&etc.join("gfx/banner.bmp"), &exe, FileType::Regular); + builder.install(&etc.join("gfx/dialogbg.bmp"), &exe, FileType::Regular); builder.info(&format!("building `msi` installer with {light:?}")); let filename = format!("{}-{}.msi", pkgname(builder, "rust"), target.triple); @@ -1899,6 +1978,9 @@ impl Step for Extended { if built_tools.contains("clippy") { cmd.arg("ClippyGroup.wixobj"); } + if built_tools.contains("rustfmt") { + cmd.arg("RustFmtGroup.wixobj"); + } if built_tools.contains("miri") { cmd.arg("MiriGroup.wixobj"); } @@ -1925,7 +2007,12 @@ impl Step for Extended { } } -fn add_env(builder: &Builder<'_>, cmd: &mut BootstrapCommand, target: TargetSelection) { +fn add_env( + builder: &Builder<'_>, + cmd: &mut BootstrapCommand, + target: TargetSelection, + built_tools: &HashSet<&'static str>, +) { let mut parts = builder.version.split('.'); cmd.env("CFG_RELEASE_INFO", builder.rust_version()) .env("CFG_RELEASE_NUM", &builder.version) @@ -1946,6 +2033,15 @@ fn add_env(builder: &Builder<'_>, cmd: &mut BootstrapCommand, target: TargetSele } else { cmd.env("CFG_MINGW", "0").env("CFG_ABI", "MSVC"); } + + // ensure these variables are defined + let mut define_optional_tool = |tool_name: &str, env_name: &str| { + cmd.env(env_name, if built_tools.contains(tool_name) { "1" } else { "0" }); + }; + define_optional_tool("rustfmt", "CFG_RUSTFMT"); + define_optional_tool("clippy", "CFG_CLIPPY"); + define_optional_tool("miri", "CFG_MIRI"); + define_optional_tool("rust-analyzer", "CFG_RA"); } fn install_llvm_file( @@ -1961,13 +2057,13 @@ fn install_llvm_file( if source.is_symlink() { // If we have a symlink like libLLVM-18.so -> libLLVM.so.18.1, install the target of the // symlink, which is what will actually get loaded at runtime. - builder.install(&t!(fs::canonicalize(source)), destination, 0o644); + builder.install(&t!(fs::canonicalize(source)), destination, FileType::NativeLibrary); let full_dest = destination.join(source.file_name().unwrap()); if install_symlink { // For download-ci-llvm, also install the symlink, to match what LLVM does. Using a // symlink is fine here, as this is not a rustup component. - builder.copy_link(source, &full_dest); + builder.copy_link(source, &full_dest, FileType::NativeLibrary); } else { // Otherwise, replace the symlink with an equivalent linker script. This is used when // projects like miri link against librustc_driver.so. We don't use a symlink, as @@ -1984,7 +2080,7 @@ fn install_llvm_file( } } } else { - builder.install(source, destination, 0o644); + builder.install(source, destination, FileType::NativeLibrary); } } @@ -2036,7 +2132,7 @@ fn maybe_install_llvm( let src_libdir = builder.llvm_out(target).join("lib"); let llvm_dylib_path = src_libdir.join("libLLVM.dylib"); if llvm_dylib_path.exists() { - builder.install(&llvm_dylib_path, dst_libdir, 0o644); + builder.install(&llvm_dylib_path, dst_libdir, FileType::NativeLibrary); } !builder.config.dry_run() } else if let llvm::LlvmBuildStatus::AlreadyBuilt(llvm::LlvmResult { llvm_config, .. }) = @@ -2186,7 +2282,7 @@ impl Step for LlvmTools { let dst_bindir = format!("lib/rustlib/{}/bin", target.triple); for tool in tools_to_install(&builder.paths) { let exe = src_bindir.join(exe(tool, target)); - tarball.add_file(&exe, &dst_bindir, 0o755); + tarball.add_file(&exe, &dst_bindir, FileType::Executable); } } @@ -2241,7 +2337,7 @@ impl Step for LlvmBitcodeLinker { tarball.set_overlay(OverlayKind::LlvmBitcodeLinker); tarball.is_preview(true); - tarball.add_file(llbc_linker.tool_path, self_contained_bin_dir, 0o755); + tarball.add_file(&llbc_linker.tool_path, self_contained_bin_dir, FileType::Executable); Some(tarball.generate()) } @@ -2302,7 +2398,7 @@ impl Step for RustDev { let entry = t!(entry); if entry.file_type().is_file() && !entry.path_is_symlink() { let name = entry.file_name().to_str().unwrap(); - tarball.add_file(src_bindir.join(name), "bin", 0o755); + tarball.add_file(src_bindir.join(name), "bin", FileType::Executable); } } } @@ -2314,11 +2410,11 @@ impl Step for RustDev { // We don't build LLD on some platforms, so only add it if it exists let lld_path = lld_out.join("bin").join(exe("lld", target)); if lld_path.exists() { - tarball.add_file(lld_path, "bin", 0o755); + tarball.add_file(&lld_path, "bin", FileType::Executable); } } - tarball.add_file(builder.llvm_filecheck(target), "bin", 0o755); + tarball.add_file(builder.llvm_filecheck(target), "bin", FileType::Executable); // Copy the include directory as well; needed mostly to build // librustc_llvm properly (e.g., llvm-config.h is in here). But also @@ -2379,7 +2475,11 @@ impl Step for Bootstrap { let bootstrap_outdir = &builder.bootstrap_out; for file in &["bootstrap", "rustc", "rustdoc"] { - tarball.add_file(bootstrap_outdir.join(exe(file, target)), "bootstrap/bin", 0o755); + tarball.add_file( + bootstrap_outdir.join(exe(file, target)), + "bootstrap/bin", + FileType::Executable, + ); } Some(tarball.generate()) @@ -2412,7 +2512,7 @@ impl Step for BuildManifest { let build_manifest = builder.tool_exe(Tool::BuildManifest); let tarball = Tarball::new(builder, "build-manifest", &self.target.triple); - tarball.add_file(build_manifest, "bin", 0o755); + tarball.add_file(&build_manifest, "bin", FileType::Executable); tarball.generate() } } @@ -2444,15 +2544,15 @@ impl Step for ReproducibleArtifacts { let mut added_anything = false; let tarball = Tarball::new(builder, "reproducible-artifacts", &self.target.triple); if let Some(path) = builder.config.rust_profile_use.as_ref() { - tarball.add_file(path, ".", 0o644); + tarball.add_file(path, ".", FileType::Regular); added_anything = true; } if let Some(path) = builder.config.llvm_profile_use.as_ref() { - tarball.add_file(path, ".", 0o644); + tarball.add_file(path, ".", FileType::Regular); added_anything = true; } for profile in &builder.config.reproducible_artifacts { - tarball.add_file(profile, ".", 0o644); + tarball.add_file(profile, ".", FileType::Regular); added_anything = true; } if added_anything { Some(tarball.generate()) } else { None } @@ -2481,7 +2581,7 @@ impl Step for Gcc { fn run(self, builder: &Builder<'_>) -> Self::Output { let tarball = Tarball::new(builder, "gcc", &self.target.triple); let output = builder.ensure(super::gcc::Gcc { target: self.target }); - tarball.add_file(output.libgccjit, "lib", 0o644); + tarball.add_file(&output.libgccjit, "lib", FileType::NativeLibrary); tarball.generate() } } diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index a8da4146100..7fccf85a0ea 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -11,7 +11,6 @@ use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::{env, fs, mem}; -use crate::Mode; use crate::core::build_steps::compile; use crate::core::build_steps::tool::{self, SourceType, Tool, prepare_tool_cargo}; use crate::core::builder::{ @@ -19,6 +18,7 @@ use crate::core::builder::{ }; use crate::core::config::{Config, TargetSelection}; use crate::helpers::{submodule_path_of, symlink_dir, t, up_to_date}; +use crate::{FileType, Mode}; macro_rules! book { ($($name:ident, $path:expr, $book_name:expr, $lang:expr ;)+) => { @@ -546,6 +546,7 @@ impl Step for SharedAssets { builder.copy_link( &builder.src.join("src").join("doc").join("rust.css"), &out.join("rust.css"), + FileType::Regular, ); SharedAssetsPaths { version_info } diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index aaf6712102c..cd57e06ae04 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -26,7 +26,7 @@ use crate::core::config::{DebuginfoLevel, RustcLto, TargetSelection}; use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{add_dylib_path, exe, t}; -use crate::{Compiler, Kind, Mode, gha}; +use crate::{Compiler, FileType, Kind, Mode, gha}; #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub enum SourceType { @@ -353,7 +353,7 @@ fn copy_link_tool_bin( ) -> PathBuf { let cargo_out = builder.cargo_out(compiler, mode, target).join(exe(name, target)); let bin = builder.tools_dir(compiler).join(exe(name, target)); - builder.copy_link(&cargo_out, &bin); + builder.copy_link(&cargo_out, &bin, FileType::Executable); bin } @@ -696,7 +696,7 @@ impl Step for Rustdoc { .join(exe("rustdoc", target_compiler.host)); let bin_rustdoc = bin_rustdoc(); - builder.copy_link(&precompiled_rustdoc, &bin_rustdoc); + builder.copy_link(&precompiled_rustdoc, &bin_rustdoc, FileType::Executable); return ToolBuildResult { tool_path: bin_rustdoc, @@ -743,7 +743,7 @@ impl Step for Rustdoc { compile::strip_debug(builder, target, &tool_path); } let bin_rustdoc = bin_rustdoc(); - builder.copy_link(&tool_path, &bin_rustdoc); + builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable); ToolBuildResult { tool_path: bin_rustdoc, build_compiler, target_compiler } } else { ToolBuildResult { tool_path, build_compiler, target_compiler } @@ -846,13 +846,20 @@ impl Step for LldWrapper { let src_exe = exe("lld", target); let dst_exe = exe("rust-lld", target); - builder.copy_link(&lld_install.join("bin").join(src_exe), &libdir_bin.join(dst_exe)); + builder.copy_link( + &lld_install.join("bin").join(src_exe), + &libdir_bin.join(dst_exe), + FileType::Executable, + ); let self_contained_lld_dir = libdir_bin.join("gcc-ld"); t!(fs::create_dir_all(&self_contained_lld_dir)); for name in crate::LLD_FILE_NAMES { - builder - .copy_link(&tool_result.tool_path, &self_contained_lld_dir.join(exe(name, target))); + builder.copy_link( + &tool_result.tool_path, + &self_contained_lld_dir.join(exe(name, target)), + FileType::Executable, + ); } tool_result @@ -949,8 +956,11 @@ impl Step for RustAnalyzerProcMacroSrv { // so that r-a can use it. let libexec_path = builder.sysroot(self.compiler).join("libexec"); t!(fs::create_dir_all(&libexec_path)); - builder - .copy_link(&tool_result.tool_path, &libexec_path.join("rust-analyzer-proc-macro-srv")); + builder.copy_link( + &tool_result.tool_path, + &libexec_path.join("rust-analyzer-proc-macro-srv"), + FileType::Executable, + ); Some(tool_result) } @@ -1007,7 +1017,7 @@ impl Step for LlvmBitcodeLinker { t!(fs::create_dir_all(&bindir_self_contained)); let bin_destination = bindir_self_contained .join(exe("llvm-bitcode-linker", tool_result.target_compiler.host)); - builder.copy_link(&tool_result.tool_path, &bin_destination); + builder.copy_link(&tool_result.tool_path, &bin_destination, FileType::Executable); ToolBuildResult { tool_path: bin_destination, build_compiler: tool_result.build_compiler, @@ -1189,7 +1199,7 @@ fn run_tool_build_step( for add_bin in add_bins_to_sysroot { let bin_destination = bindir.join(exe(add_bin, target_compiler.host)); - builder.copy_link(&tool_path, &bin_destination); + builder.copy_link(&tool_path, &bin_destination, FileType::Executable); } // Return a path into the bin dir. diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index ec5c0c53baa..c47cd8b452f 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -37,7 +37,9 @@ use crate::core::builder; use crate::core::builder::Kind; use crate::core::config::{DryRun, LldMode, LlvmLibunwind, Target, TargetSelection, flags}; use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode, command}; -use crate::utils::helpers::{self, dir_is_empty, exe, libdir, output, set_file_times, symlink_dir}; +use crate::utils::helpers::{ + self, dir_is_empty, exe, libdir, output, set_file_times, split_debuginfo, symlink_dir, +}; mod core; mod utils; @@ -275,6 +277,35 @@ pub enum CLang { Cxx, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FileType { + /// An executable binary file (like a `.exe`). + Executable, + /// A native, binary library file (like a `.so`, `.dll`, `.a`, `.lib` or `.o`). + NativeLibrary, + /// An executable (non-binary) script file (like a `.py` or `.sh`). + Script, + /// Any other regular file that is non-executable. + Regular, +} + +impl FileType { + /// Get Unix permissions appropriate for this file type. + pub fn perms(self) -> u32 { + match self { + FileType::Executable | FileType::Script => 0o755, + FileType::Regular | FileType::NativeLibrary => 0o644, + } + } + + pub fn could_have_split_debuginfo(self) -> bool { + match self { + FileType::Executable | FileType::NativeLibrary => true, + FileType::Script | FileType::Regular => false, + } + } +} + macro_rules! forward { ( $( $fn:ident( $($param:ident: $ty:ty),* ) $( -> $ret:ty)? ),+ $(,)? ) => { impl Build { @@ -1745,8 +1776,18 @@ Executed at: {executed_at}"#, /// Attempts to use hard links if possible, falling back to copying. /// You can neither rely on this being a copy nor it being a link, /// so do not write to dst. - pub fn copy_link(&self, src: &Path, dst: &Path) { + pub fn copy_link(&self, src: &Path, dst: &Path, file_type: FileType) { self.copy_link_internal(src, dst, false); + + if file_type.could_have_split_debuginfo() { + if let Some(dbg_file) = split_debuginfo(src) { + self.copy_link_internal( + &dbg_file, + &dst.with_extension(dbg_file.extension().unwrap()), + false, + ); + } + } } fn copy_link_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) { @@ -1809,7 +1850,7 @@ Executed at: {executed_at}"#, t!(fs::create_dir_all(&dst)); self.cp_link_r(&path, &dst); } else { - self.copy_link(&path, &dst); + self.copy_link(&path, &dst, FileType::Regular); } } } @@ -1845,7 +1886,7 @@ Executed at: {executed_at}"#, self.cp_link_filtered_recurse(&path, &dst, &relative, filter); } else { let _ = fs::remove_file(&dst); - self.copy_link(&path, &dst); + self.copy_link(&path, &dst, FileType::Regular); } } } @@ -1854,10 +1895,10 @@ Executed at: {executed_at}"#, fn copy_link_to_folder(&self, src: &Path, dest_folder: &Path) { let file_name = src.file_name().unwrap(); let dest = dest_folder.join(file_name); - self.copy_link(src, &dest); + self.copy_link(src, &dest, FileType::Regular); } - fn install(&self, src: &Path, dstdir: &Path, perms: u32) { + fn install(&self, src: &Path, dstdir: &Path, file_type: FileType) { if self.config.dry_run() { return; } @@ -1867,8 +1908,16 @@ Executed at: {executed_at}"#, if !src.exists() { panic!("ERROR: File \"{}\" not found!", src.display()); } + self.copy_link_internal(src, &dst, true); - chmod(&dst, perms); + chmod(&dst, file_type.perms()); + + // If this file can have debuginfo, look for split debuginfo and install it too. + if file_type.could_have_split_debuginfo() { + if let Some(dbg_file) = split_debuginfo(src) { + self.install(&dbg_file, dstdir, FileType::Regular); + } + } } fn read(&self, path: &Path) -> String { diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs index 89d93a29acb..f8e4d4e0471 100644 --- a/src/bootstrap/src/utils/helpers.rs +++ b/src/bootstrap/src/utils/helpers.rs @@ -52,6 +52,23 @@ pub fn exe(name: &str, target: TargetSelection) -> String { crate::utils::shared_helpers::exe(name, &target.triple) } +/// Returns the path to the split debug info for the specified file if it exists. +pub fn split_debuginfo(name: impl Into<PathBuf>) -> Option<PathBuf> { + // FIXME: only msvc is currently supported + + let path = name.into(); + let pdb = path.with_extension("pdb"); + if pdb.exists() { + return Some(pdb); + } + + // pdbs get named with '-' replaced by '_' + let file_name = pdb.file_name()?.to_str()?.replace("-", "_"); + + let pdb: PathBuf = [path.parent()?, Path::new(&file_name)].into_iter().collect(); + pdb.exists().then_some(pdb) +} + /// Returns `true` if the file name given looks like a dynamic library. pub fn is_dylib(path: &Path) -> bool { path.extension().and_then(|ext| ext.to_str()).is_some_and(|ext| { diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs index 34bf6bb7013..dbfd6f47dc6 100644 --- a/src/bootstrap/src/utils/proc_macro_deps.rs +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -6,18 +6,25 @@ pub static CRATES: &[&str] = &[ "annotate-snippets", "anstyle", "basic-toml", + "block-buffer", "bumpalo", + "cfg-if", + "cpufeatures", + "crypto-common", "darling", "darling_core", "derive_builder_core", + "digest", "fluent-bundle", "fluent-langneg", "fluent-syntax", "fnv", + "generic-array", "heck", "ident_case", "intl-memoizer", "intl_pluralrules", + "libc", "log", "memchr", "mime", @@ -25,12 +32,17 @@ pub static CRATES: &[&str] = &[ "minimal-lexical", "nom", "num-conv", + "once_cell", + "pest", + "pest_generator", + "pest_meta", "proc-macro2", "quote", "rinja_parser", "rustc-hash", "self_cell", "serde", + "sha2", "smallvec", "stable_deref_trait", "strsim", @@ -40,12 +52,15 @@ pub static CRATES: &[&str] = &[ "time-core", "tinystr", "type-map", + "typenum", + "ucd-trie", "unic-langid", "unic-langid-impl", "unic-langid-macros", "unicase", "unicode-ident", "unicode-width", + "version_check", "wasm-bindgen-backend", "wasm-bindgen-macro-support", "wasm-bindgen-shared", diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index f1678bacc97..7b77b212934 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; +use crate::FileType; use crate::core::build_steps::dist::distdir; use crate::core::builder::{Builder, Kind}; use crate::core::config::BUILDER_CONFIG_FILENAME; @@ -182,7 +183,12 @@ impl<'a> Tarball<'a> { &self.image_dir } - pub(crate) fn add_file(&self, src: impl AsRef<Path>, destdir: impl AsRef<Path>, perms: u32) { + pub(crate) fn add_file( + &self, + src: impl AsRef<Path>, + destdir: impl AsRef<Path>, + file_type: FileType, + ) { // create_dir_all fails to create `foo/bar/.`, so when the destination is "." this simply // uses the base directory as the destination directory. let destdir = if destdir.as_ref() == Path::new(".") { @@ -192,7 +198,7 @@ impl<'a> Tarball<'a> { }; t!(std::fs::create_dir_all(&destdir)); - self.builder.install(src.as_ref(), &destdir, perms); + self.builder.install(src.as_ref(), &destdir, file_type); } pub(crate) fn add_renamed_file( @@ -200,15 +206,16 @@ impl<'a> Tarball<'a> { src: impl AsRef<Path>, destdir: impl AsRef<Path>, new_name: &str, + file_type: FileType, ) { let destdir = self.image_dir.join(destdir.as_ref()); t!(std::fs::create_dir_all(&destdir)); - self.builder.copy_link(src.as_ref(), &destdir.join(new_name)); + self.builder.copy_link(src.as_ref(), &destdir.join(new_name), file_type); } pub(crate) fn add_legal_and_readme_to(&self, destdir: impl AsRef<Path>) { for file in self.overlay.legal_and_readme() { - self.add_file(self.builder.src.join(file), destdir.as_ref(), 0o644); + self.add_file(self.builder.src.join(file), destdir.as_ref(), FileType::Regular); } } @@ -318,11 +325,20 @@ impl<'a> Tarball<'a> { // Add config file if present. if let Some(config) = &self.builder.config.config { - self.add_renamed_file(config, &self.overlay_dir, BUILDER_CONFIG_FILENAME); + self.add_renamed_file( + config, + &self.overlay_dir, + BUILDER_CONFIG_FILENAME, + FileType::Regular, + ); } for file in self.overlay.legal_and_readme() { - self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); + self.builder.install( + &self.builder.src.join(file), + &self.overlay_dir, + FileType::Regular, + ); } let mut cmd = self.builder.tool_cmd(crate::core::build_steps::tool::Tool::RustInstaller); diff --git a/src/doc/unstable-book/src/compiler-flags/print-supported-crate-types.md b/src/doc/unstable-book/src/compiler-flags/print-supported-crate-types.md new file mode 100644 index 00000000000..f285d6e7175 --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/print-supported-crate-types.md @@ -0,0 +1,27 @@ +# `print=supported-crate-types` + +The tracking issue for this feature is: [#138640](https://github.com/rust-lang/rust/issues/138640). + +------------------------ + +This option of the `--print` flag produces a list of crate types (delimited by newlines) supported for the given target. + +The crate type strings correspond to the values accepted by the `--crate-type` flag. + +Intended to be used like this: + +```bash +rustc --print=supported-crate-types -Zunstable-options --target=x86_64-unknown-linux-gnu +``` + +Example output for `x86_64-unknown-linux-gnu`: + +```text +bin +cdylib +dylib +lib +proc-macro +rlib +staticlib +``` diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs index f29e1e4d27a..64cceccc975 100644 --- a/src/etc/installer/msi/rust.wxs +++ b/src/etc/installer/msi/rust.wxs @@ -172,6 +172,19 @@ <!-- tool-rust-docs-end --> <Directory Id="Cargo" Name="." /> <Directory Id="Std" Name="." /> + <?if $(env.CFG_RUSTFMT)="1" ?> + <Directory Id="RustFmt" Name="." /> + <?endif?> + <?if $(env.CFG_RA)="1" ?> + <Directory Id="RustAnalyzer" Name="." /> + <?endif?> + <?if $(env.CFG_MIRI)="1" ?> + <Directory Id="Miri" Name="." /> + <?endif?> + <Directory Id="Analysis" Name="." /> + <?if $(env.CFG_CLIPPY)="1" ?> + <Directory Id="Clippy" Name="." /> + <?endif?> </Directory> </Directory> @@ -279,7 +292,49 @@ <ComponentRef Id="PathEnvPerMachine" /> <ComponentRef Id="PathEnvPerUser" /> </Feature> - + <?if $(env.CFG_RUSTFMT)="1" ?> + <Feature Id="RustFmt" + Title="Formatter for rust" + Display="7" + Level="1" + AllowAdvertise="no"> + <ComponentGroupRef Id="RustFmtGroup" /> + </Feature> + <?endif?> + <?if $(env.CFG_CLIPPY)="1" ?> + <Feature Id="Clippy" + Title="Formatter and checker for rust" + Display="8" + Level="1" + AllowAdvertise="no"> + <ComponentGroupRef Id="ClippyGroup" /> + </Feature> + <?endif?> + <?if $(env.CFG_MIRI)="1" ?> + <Feature Id="Miri" + Title="Soundness checker for rust" + Display="9" + Level="1" + AllowAdvertise="no"> + <ComponentGroupRef Id="MiriGroup" /> + </Feature> + <?endif?> + <?if $(env.CFG_RA)="1" ?> + <Feature Id="RustAnalyzer" + Title="Analyzer for rust" + Display="10" + Level="1" + AllowAdvertise="no"> + <ComponentGroupRef Id="RustAnalyzerGroup" /> + </Feature> + <?endif?> + <Feature Id="Analysis" + Title="Analysis for rust" + Display="11" + Level="1" + AllowAdvertise="no"> + <ComponentGroupRef Id="AnalysisGroup" /> + </Feature> <UIRef Id="RustUI" /> </Product> </Wix> diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index ab169f3c2a4..1541e7201ce 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -8,7 +8,6 @@ use std::{mem, ops}; use rustc_ast::{LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit}; use rustc_data_structures::fx::FxHashSet; -use rustc_feature::Features; use rustc_session::parse::ParseSess; use rustc_span::Span; use rustc_span::symbol::{Symbol, sym}; @@ -132,18 +131,13 @@ impl Cfg { /// Checks whether the given configuration can be matched in the current session. /// /// Equivalent to `attr::cfg_matches`. - // FIXME: Actually make use of `features`. - pub(crate) fn matches(&self, psess: &ParseSess, features: Option<&Features>) -> bool { + pub(crate) fn matches(&self, psess: &ParseSess) -> bool { match *self { Cfg::False => false, Cfg::True => true, - Cfg::Not(ref child) => !child.matches(psess, features), - Cfg::All(ref sub_cfgs) => { - sub_cfgs.iter().all(|sub_cfg| sub_cfg.matches(psess, features)) - } - Cfg::Any(ref sub_cfgs) => { - sub_cfgs.iter().any(|sub_cfg| sub_cfg.matches(psess, features)) - } + Cfg::Not(ref child) => !child.matches(psess), + Cfg::All(ref sub_cfgs) => sub_cfgs.iter().all(|sub_cfg| sub_cfg.matches(psess)), + Cfg::Any(ref sub_cfgs) => sub_cfgs.iter().any(|sub_cfg| sub_cfg.matches(psess)), Cfg::Cfg(name, value) => psess.config.contains(&(name, value)), } } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3b2dcb3db81..5f80aded9d0 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -768,12 +768,22 @@ impl Item { .iter() .filter_map(|attr| { if is_json { - if matches!(attr, hir::Attribute::Parsed(AttributeKind::Deprecation { .. })) { - // rustdoc-json stores this in `Item::deprecation`, so we - // don't want it it `Item::attrs`. - None - } else { - Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)) + match attr { + hir::Attribute::Parsed(AttributeKind::Deprecation { .. }) => { + // rustdoc-json stores this in `Item::deprecation`, so we + // don't want it it `Item::attrs`. + None + } + rustc_hir::Attribute::Parsed(rustc_attr_parsing::AttributeKind::Repr( + .., + )) => { + // We have separate pretty-printing logic for `#[repr(..)]` attributes. + // For example, there are circumstances where `#[repr(transparent)]` + // is applied but should not be publicly shown in rustdoc + // because it isn't public API. + None + } + _ => Some(rustc_hir_pretty::attribute_to_string(&tcx, attr)), } } else if ALLOWED_ATTRIBUTES.contains(&attr.name_or_empty()) { Some( @@ -789,8 +799,7 @@ impl Item { .collect(); // Add #[repr(...)] - if !is_json - && let Some(def_id) = self.def_id() + if let Some(def_id) = self.def_id() && let ItemType::Struct | ItemType::Enum | ItemType::Union = self.type_() { let adt = tcx.adt_def(def_id); @@ -1059,6 +1068,13 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute> .meta_item() .and_then(|item| rustc_expand::config::parse_cfg(item, sess)) { + // The result is unused here but we can gate unstable predicates + rustc_attr_parsing::cfg_matches( + cfg_mi, + tcx.sess, + rustc_ast::CRATE_NODE_ID, + Some(tcx.features()), + ); match Cfg::parse(cfg_mi) { Ok(new_cfg) => cfg &= new_cfg, Err(e) => { @@ -1536,6 +1552,10 @@ impl Type { matches!(self, Type::BorrowedRef { .. }) } + fn is_type_alias(&self) -> bool { + matches!(self, Type::Path { path: Path { res: Res::Def(DefKind::TyAlias, _), .. } }) + } + /// Check if two types are "the same" for documentation purposes. /// /// This is different from `Eq`, because it knows that things like @@ -1564,6 +1584,16 @@ impl Type { } else { (self, other) }; + + // FIXME: `Cache` does not have the data required to unwrap type aliases, + // so we just assume they are equal. + // This is only remotely acceptable because we were previously + // assuming all types were equal when used + // as a generic parameter of a type in `Deref::Target`. + if self_cleared.is_type_alias() || other_cleared.is_type_alias() { + return true; + } + match (self_cleared, other_cleared) { // Recursive cases. (Type::Tuple(a), Type::Tuple(b)) => { diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs index d0072256941..12f8b26b1e3 100644 --- a/src/librustdoc/doctest/rust.rs +++ b/src/librustdoc/doctest/rust.rs @@ -98,7 +98,7 @@ impl HirCollector<'_> { let ast_attrs = self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(def_id)); if let Some(ref cfg) = extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default()) - && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) + && !cfg.matches(&self.tcx.sess.psess) { return; } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b067dbf750e..5aab4199d43 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1200,11 +1200,12 @@ impl LangString { data.ignore = Ignore::All; seen_rust_tags = !seen_other_tags; } - LangStringToken::LangToken(x) if x.starts_with("ignore-") => { - if enable_per_target_ignores { - ignores.push(x.trim_start_matches("ignore-").to_owned()); - seen_rust_tags = !seen_other_tags; - } + LangStringToken::LangToken(x) + if let Some(ignore) = x.strip_prefix("ignore-") + && enable_per_target_ignores => + { + ignores.push(ignore.to_owned()); + seen_rust_tags = !seen_other_tags; } LangStringToken::LangToken("rust") => { data.rust = true; @@ -1226,37 +1227,39 @@ impl LangString { data.standalone_crate = true; seen_rust_tags = !seen_other_tags || seen_rust_tags; } - LangStringToken::LangToken(x) if x.starts_with("edition") => { - data.edition = x[7..].parse::<Edition>().ok(); + LangStringToken::LangToken(x) + if let Some(edition) = x.strip_prefix("edition") => + { + data.edition = edition.parse::<Edition>().ok(); } LangStringToken::LangToken(x) - if x.starts_with("rust") && x[4..].parse::<Edition>().is_ok() => + if let Some(edition) = x.strip_prefix("rust") + && edition.parse::<Edition>().is_ok() + && let Some(extra) = extra => { - if let Some(extra) = extra { - extra.error_invalid_codeblock_attr_with_help( - format!("unknown attribute `{x}`"), - |lint| { - lint.help(format!( - "there is an attribute with a similar name: `edition{}`", - &x[4..], - )); - }, - ); - } + extra.error_invalid_codeblock_attr_with_help( + format!("unknown attribute `{x}`"), + |lint| { + lint.help(format!( + "there is an attribute with a similar name: `edition{edition}`" + )); + }, + ); } LangStringToken::LangToken(x) - if allow_error_code_check && x.starts_with('E') && x.len() == 5 => + if allow_error_code_check + && let Some(error_code) = x.strip_prefix('E') + && error_code.len() == 4 => { - if x[1..].parse::<u32>().is_ok() { + if error_code.parse::<u32>().is_ok() { data.error_codes.push(x.to_owned()); seen_rust_tags = !seen_other_tags || seen_rust_tags; } else { seen_other_tags = true; } } - LangStringToken::LangToken(x) if extra.is_some() => { - let s = x.to_lowercase(); - if let Some(help) = match s.as_str() { + LangStringToken::LangToken(x) if let Some(extra) = extra => { + if let Some(help) = match x.to_lowercase().as_str() { "compile-fail" | "compile_fail" | "compilefail" => Some( "use `compile_fail` to invert the results of this test, so that it \ passes if it cannot be compiled and fails if it can", @@ -1273,33 +1276,27 @@ impl LangString { "use `test_harness` to run functions marked `#[test]` instead of a \ potentially-implicit `main` function", ), - "standalone" | "standalone_crate" | "standalone-crate" => { - if let Some(extra) = extra - && extra.sp.at_least_rust_2024() - { - Some( - "use `standalone_crate` to compile this code block \ + "standalone" | "standalone_crate" | "standalone-crate" + if extra.sp.at_least_rust_2024() => + { + Some( + "use `standalone_crate` to compile this code block \ separately", - ) - } else { - None - } + ) } _ => None, } { - if let Some(extra) = extra { - extra.error_invalid_codeblock_attr_with_help( - format!("unknown attribute `{x}`"), - |lint| { - lint.help(help).help( - "this code block may be skipped during testing, \ + extra.error_invalid_codeblock_attr_with_help( + format!("unknown attribute `{x}`"), + |lint| { + lint.help(help).help( + "this code block may be skipped during testing, \ because unknown attributes are treated as markers for \ code samples written in other programming languages, \ unless it is also explicitly marked as `rust`", - ); - }, - ); - } + ); + }, + ); } seen_other_tags = true; data.unknown.push(x.to_owned()); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8dfde1679fe..2237e0f987b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -89,7 +89,7 @@ pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display { /// Specifies whether rendering directly implemented trait items or ones from a certain Deref /// impl. -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub(crate) enum AssocItemRender<'a> { All, DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool }, @@ -1296,7 +1296,8 @@ fn render_assoc_items_inner( info!("Documenting associated items of {:?}", containing_item.name); let cache = &cx.shared.cache; let Some(v) = cache.impls.get(&it) else { return }; - let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none()); + let (mut non_trait, traits): (Vec<_>, _) = + v.iter().partition(|i| i.inner_impl().trait_.is_none()); if !non_trait.is_empty() { let mut close_tags = <Vec<&str>>::with_capacity(1); let mut tmp_buf = String::new(); @@ -1314,6 +1315,16 @@ fn render_assoc_items_inner( AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => { let id = cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx)))); + // the `impls.get` above only looks at the outermost type, + // and the Deref impl may only be implemented for certain + // values of generic parameters. + // for example, if an item impls `Deref<[u8]>`, + // we should not show methods from `[MaybeUninit<u8>]`. + // this `retain` filters out any instances where + // the types do not line up perfectly. + non_trait.retain(|impl_| { + type_.is_doc_subtype_of(&impl_.inner_impl().for_, &cx.shared.cache) + }); let derived_id = cx.derive_id(&id); close_tags.push("</details>"); write_str( @@ -1392,6 +1403,7 @@ fn render_assoc_items_inner( } } +/// `derefs` is the set of all deref targets that have already been handled. fn render_deref_methods( mut w: impl Write, cx: &Context<'_>, diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 3130815af0b..9c78dcdc571 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -533,7 +533,10 @@ fn sidebar_deref_methods<'a>( debug!("found inner_impl: {impls:?}"); let mut ret = impls .iter() - .filter(|i| i.inner_impl().trait_.is_none()) + .filter(|i| { + i.inner_impl().trait_.is_none() + && real_target.is_doc_subtype_of(&i.inner_impl().for_, &c) + }) .flat_map(|i| get_methods(i.inner_impl(), true, used_links, deref_mut, cx.tcx())) .collect::<Vec<_>>(); if !ret.is_empty() { diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts index 4b43c00730d..e94c6beabea 100644 --- a/src/librustdoc/html/static/js/rustdoc.d.ts +++ b/src/librustdoc/html/static/js/rustdoc.d.ts @@ -4,6 +4,10 @@ /* eslint-disable */ declare global { + /** Map from crate name to directory structure, for source view */ + declare var srcIndex: Map<string, rustdoc.Dir>; + /** Defined and documented in `main.js` */ + declare function nonnull(x: T|null, msg: string|undefined); interface Window { /** Make the current theme easy to find */ currentTheme: HTMLLinkElement|null; @@ -41,6 +45,23 @@ declare global { */ rustdocShowSourceSidebar: function(), /** + * Close the sidebar in source code view + */ + rustdocCloseSourceSidebar?: function(), + /** + * Shows the sidebar in source code view + */ + rustdocShowSourceSidebar?: function(), + /** + * Toggles the sidebar in source code view + */ + rustdocToggleSrcSidebar?: function(), + /** + * create's the sidebar in source code view. + * called in generated `src-files.js`. + */ + createSrcSidebar?: function(), + /** * Set up event listeners for a scraped source example. */ updateScrapedExample?: function(HTMLElement, HTMLElement), @@ -438,4 +459,12 @@ declare namespace rustdoc { type TypeImpls = { [cratename: string]: Array<Array<string|0>> } + + /** + * Directory structure for source code view, + * defined in generated `src-files.js`. + * + * is a tuple of (filename, subdirs, filenames). + */ + type Dir = [string, rustdoc.Dir[], string[]] } diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js index fc27241334b..b9ab6e85603 100644 --- a/src/librustdoc/html/static/js/src-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -3,10 +3,8 @@ // Local js definitions: /* global addClass, onEachLazy, removeClass, browserSupportsHistoryApi */ -/* global updateLocalStorage, getVar */ +/* global updateLocalStorage, getVar, nonnull */ -// Eventually fix this. -// @ts-nocheck "use strict"; @@ -29,6 +27,14 @@ function closeSidebarIfMobile() { } } +/** + * @param {rustdoc.Dir} elem + * @param {HTMLElement} parent + * @param {string} fullPath + * @param {boolean} hasFoundFile + * + * @returns {boolean} - new value for hasFoundFile + */ function createDirEntry(elem, parent, fullPath, hasFoundFile) { const dirEntry = document.createElement("details"); const summary = document.createElement("summary"); @@ -95,7 +101,7 @@ window.rustdocToggleSrcSidebar = () => { // This function is called from "src-files.js", generated in `html/render/write_shared.rs`. // eslint-disable-next-line no-unused-vars function createSrcSidebar() { - const container = document.querySelector("nav.sidebar"); + const container = nonnull(document.querySelector("nav.sidebar")); const sidebar = document.createElement("div"); sidebar.id = "src-sidebar"; @@ -111,6 +117,7 @@ function createSrcSidebar() { // Focus on the current file in the source files sidebar. const selected_elem = sidebar.getElementsByClassName("selected")[0]; if (typeof selected_elem !== "undefined") { + // @ts-expect-error selected_elem.focus(); } } @@ -130,11 +137,12 @@ function highlightSrcLines() { to = from; from = tmp; } - let elem = document.getElementById(from); + const from_s = "" + from; + let elem = document.getElementById(from_s); if (!elem) { return; } - const x = document.getElementById(from); + const x = document.getElementById(from_s); if (x) { x.scrollIntoView(); } @@ -142,7 +150,7 @@ function highlightSrcLines() { removeClass(e, "line-highlighted"); }); for (let i = from; i <= to; ++i) { - elem = document.getElementById(i); + elem = document.getElementById("" + i); if (!elem) { break; } @@ -153,11 +161,12 @@ function highlightSrcLines() { const handleSrcHighlight = (function() { let prev_line_id = 0; + /** @type {function(string): void} */ const set_fragment = name => { const x = window.scrollX, y = window.scrollY; if (browserSupportsHistoryApi()) { - history.replaceState(null, null, "#" + name); + history.replaceState(null, "", "#" + name); highlightSrcLines(); } else { location.replace("#" + name); @@ -166,6 +175,7 @@ const handleSrcHighlight = (function() { window.scrollTo(x, y); }; + // @ts-expect-error return ev => { let cur_line_id = parseInt(ev.target.id, 10); // This event handler is attached to the entire line number column, but it should only @@ -191,7 +201,7 @@ const handleSrcHighlight = (function() { } else { prev_line_id = cur_line_id; - set_fragment(cur_line_id); + set_fragment("" + cur_line_id); } }; }()); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 425b915b5f9..748d2ef33c3 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -22,6 +22,28 @@ const settingsDataset = (function() { })(); /** + * Assert that the passed value is nonnull, then return it. + * + * Takes an optional error message argument. + * + * Must be defined in this file, as it is loaded before all others. + * + * @template T + * @param {T|null} x + * @param {string=} msg + * @returns T + */ +// used in other files, not yet used in this one. +// eslint-disable-next-line no-unused-vars +function nonnull(x, msg) { + if (x === null) { + throw (msg || "unexpected null value!"); + } else { + return x; + } +} + +/** * Get a configuration value. If it's not set, get the default. * * @param {string} settingName diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 44e82c7d8b1..137fe4c4c35 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc /// This integer is incremented with every breaking change to the API, /// and is returned along with the JSON blob as [`Crate::format_version`]. /// Consuming code should assert that this value matches the format version(s) that it supports. -pub const FORMAT_VERSION: u32 = 42; +pub const FORMAT_VERSION: u32 = 43; /// The root of the emitted JSON blob. /// @@ -120,9 +120,23 @@ pub struct Item { pub docs: Option<String>, /// This mapping resolves [intra-doc links](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md) from the docstring to their IDs pub links: HashMap<String, Id>, - /// Stringified versions of parsed attributes on this item. - /// Essentially debug printed (e.g. `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`). - /// Equivalent to the hir pretty-printing of attributes. + /// Attributes on this item. + /// + /// Does not include `#[deprecated]` attributes: see the [`Self::deprecation`] field instead. + /// + /// Some attributes appear in pretty-printed Rust form, regardless of their formatting + /// in the original source code. For example: + /// - `#[non_exhaustive]` and `#[must_use]` are represented as themselves. + /// - `#[no_mangle]` and `#[export_name]` are also represented as themselves. + /// - `#[repr(C)]` and other reprs also appear as themselves, + /// though potentially with a different order: e.g. `repr(i8, C)` may become `repr(C, i8)`. + /// Multiple repr attributes on the same item may be combined into an equivalent single attr. + /// + /// Other attributes may appear debug-printed. For example: + /// - `#[inline]` becomes something similar to `#[attr="Inline(Hint)"]`. + /// + /// As an internal implementation detail subject to change, this debug-printing format + /// is currently equivalent to the HIR pretty-printing of parsed attributes. pub attrs: Vec<String>, /// Information about the item’s deprecation, if present. pub deprecation: Option<Deprecation>, diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 6cf8267012570f63d6b86e85a2ae5627de52df9 +Subproject 307cbfda3119f06600e43cd38283f4a746fe1f8 diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 7675e13990d..d7a5f304d23 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -1385,7 +1385,7 @@ pub fn make_test_description<R: Read>( decision!(cfg::handle_ignore(config, ln)); decision!(cfg::handle_only(config, ln)); decision!(needs::handle_needs(&cache.needs, config, ln)); - decision!(ignore_llvm(config, ln)); + decision!(ignore_llvm(config, path, ln)); decision!(ignore_cdb(config, ln)); decision!(ignore_gdb(config, ln)); decision!(ignore_lldb(config, ln)); @@ -1525,7 +1525,7 @@ fn ignore_lldb(config: &Config, line: &str) -> IgnoreDecision { IgnoreDecision::Continue } -fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision { +fn ignore_llvm(config: &Config, path: &Path, line: &str) -> IgnoreDecision { if let Some(needed_components) = config.parse_name_value_directive(line, "needs-llvm-components") { @@ -1536,8 +1536,9 @@ fn ignore_llvm(config: &Config, line: &str) -> IgnoreDecision { { if env::var_os("COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS").is_some() { panic!( - "missing LLVM component {}, and COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS is set", - missing_component + "missing LLVM component {}, and COMPILETEST_REQUIRE_ALL_LLVM_COMPONENTS is set: {}", + missing_component, + path.display() ); } return IgnoreDecision::Ignore { diff --git a/src/tools/jsondocck/Cargo.toml b/src/tools/jsondocck/Cargo.toml index e1eb6d05665..80fc26cbe66 100644 --- a/src/tools/jsondocck/Cargo.toml +++ b/src/tools/jsondocck/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -jsonpath_lib = "0.3" +jsonpath-rust = "1.0.0" getopts = "0.2" regex = "1.4" shlex = "1.0" diff --git a/src/tools/jsondocck/src/cache.rs b/src/tools/jsondocck/src/cache.rs index 47512039740..1369c8ded00 100644 --- a/src/tools/jsondocck/src/cache.rs +++ b/src/tools/jsondocck/src/cache.rs @@ -30,6 +30,6 @@ impl Cache { // FIXME: Make this failible, so jsonpath syntax error has line number. pub fn select(&self, path: &str) -> Vec<&Value> { - jsonpath_lib::select(&self.value, path).unwrap() + jsonpath_rust::query::js_path_vals(path, &self.value).unwrap() } } diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index 2b9ae195478..4a929a376d7 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -2000,7 +2000,6 @@ ui/issues/issue-28586.rs ui/issues/issue-28600.rs ui/issues/issue-28625.rs ui/issues/issue-28776.rs -ui/issues/issue-28777.rs ui/issues/issue-28828.rs ui/issues/issue-28839.rs ui/issues/issue-28936.rs @@ -2063,7 +2062,6 @@ ui/issues/issue-3091.rs ui/issues/issue-31011.rs ui/issues/issue-3109.rs ui/issues/issue-3121.rs -ui/issues/issue-31260.rs ui/issues/issue-31267-additional.rs ui/issues/issue-31267.rs ui/issues/issue-31299.rs @@ -2608,7 +2606,6 @@ ui/issues/issue-9243.rs ui/issues/issue-9249.rs ui/issues/issue-9259.rs ui/issues/issue-92741.rs -ui/issues/issue-9382.rs ui/issues/issue-9446.rs ui/issues/issue-9719.rs ui/issues/issue-9725.rs diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index fe51231c481..61728d0553f 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -17,7 +17,7 @@ use ignore::Walk; const ENTRY_LIMIT: u32 = 901; // FIXME: The following limits should be reduced eventually. -const ISSUES_ENTRY_LIMIT: u32 = 1634; +const ISSUES_ENTRY_LIMIT: u32 = 1631; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/crashes/122904.rs b/tests/crashes/122904.rs deleted file mode 100644 index 2068cd9d239..00000000000 --- a/tests/crashes/122904.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #122904 -trait T {} - -type Alias<'a> = impl T; - -struct S; -impl<'a> T for &'a S {} - -#[define_opaque(Alias)] -fn with_positive(fun: impl Fn(Alias<'_>)) { - with_positive(|&n| ()); -} diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff index 45fc7365d8d..6baa902b6f4 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-abort.diff @@ -29,16 +29,10 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: std::option::Option<u16>; - scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) { - let mut _23: isize; - let _24: u16; - let mut _25: usize; - scope 7 { - scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { - } - } - } + let mut _22: u32; + let mut _23: u32; + let mut _24: usize; + let mut _25: u16; } } } @@ -53,7 +47,7 @@ StorageLive(_20); StorageLive(_21); _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _20 = BitAnd(move _21, const 1_u32); + _20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG); StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); @@ -75,12 +69,12 @@ bb3: { StorageLive(_6); - StorageLive(_24); StorageLive(_22); - _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>); StorageLive(_23); - _23 = discriminant(_22); - switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_23); + switchInt(move _22) -> [0: bb10, otherwise: bb11]; } bb4: { @@ -148,30 +142,31 @@ } bb9: { - StorageDead(_23); - StorageDead(_22); - StorageDead(_24); _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb10: { - unreachable; - } - - bb11: { + StorageDead(_22); _6 = const Option::<usize>::None; goto -> bb9; } - bb12: { - _24 = move ((_22 as Some).0: u16); + bb11: { + StorageDead(_22); + StorageLive(_24); StorageLive(_25); - _25 = copy _24 as usize (IntToInt); - _6 = Option::<usize>::Some(move _25); + _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _24 = move _25 as usize (IntToInt); StorageDead(_25); + _6 = Option::<usize>::Some(move _24); + StorageDead(_24); goto -> bb9; } + + bb12: { + unreachable; + } } ALLOC0 (size: 8, align: 4) { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff index 578d2c2194b..36540e03865 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.32bit.panic-unwind.diff @@ -29,16 +29,10 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: std::option::Option<u16>; - scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) { - let mut _23: isize; - let _24: u16; - let mut _25: usize; - scope 7 { - scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { - } - } - } + let mut _22: u32; + let mut _23: u32; + let mut _24: usize; + let mut _25: u16; } } } @@ -53,7 +47,7 @@ StorageLive(_20); StorageLive(_21); _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _20 = BitAnd(move _21, const 1_u32); + _20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG); StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); @@ -75,12 +69,12 @@ bb3: { StorageLive(_6); - StorageLive(_24); StorageLive(_22); - _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>); StorageLive(_23); - _23 = discriminant(_22); - switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_23); + switchInt(move _22) -> [0: bb10, otherwise: bb11]; } bb4: { @@ -148,30 +142,31 @@ } bb9: { - StorageDead(_23); - StorageDead(_22); - StorageDead(_24); _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb10: { - unreachable; - } - - bb11: { + StorageDead(_22); _6 = const Option::<usize>::None; goto -> bb9; } - bb12: { - _24 = move ((_22 as Some).0: u16); + bb11: { + StorageDead(_22); + StorageLive(_24); StorageLive(_25); - _25 = copy _24 as usize (IntToInt); - _6 = Option::<usize>::Some(move _25); + _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _24 = move _25 as usize (IntToInt); StorageDead(_25); + _6 = Option::<usize>::Some(move _24); + StorageDead(_24); goto -> bb9; } + + bb12: { + unreachable; + } } ALLOC0 (size: 8, align: 4) { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff index 5f0f7d6cc74..41c350f3eae 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-abort.diff @@ -29,16 +29,10 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: std::option::Option<u16>; - scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) { - let mut _23: isize; - let _24: u16; - let mut _25: usize; - scope 7 { - scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { - } - } - } + let mut _22: u32; + let mut _23: u32; + let mut _24: usize; + let mut _25: u16; } } } @@ -53,7 +47,7 @@ StorageLive(_20); StorageLive(_21); _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _20 = BitAnd(move _21, const 1_u32); + _20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG); StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); @@ -75,12 +69,12 @@ bb3: { StorageLive(_6); - StorageLive(_24); StorageLive(_22); - _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>); StorageLive(_23); - _23 = discriminant(_22); - switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_23); + switchInt(move _22) -> [0: bb10, otherwise: bb11]; } bb4: { @@ -148,30 +142,31 @@ } bb9: { - StorageDead(_23); - StorageDead(_22); - StorageDead(_24); _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb10: { - unreachable; - } - - bb11: { + StorageDead(_22); _6 = const Option::<usize>::None; goto -> bb9; } - bb12: { - _24 = move ((_22 as Some).0: u16); + bb11: { + StorageDead(_22); + StorageLive(_24); StorageLive(_25); - _25 = copy _24 as usize (IntToInt); - _6 = Option::<usize>::Some(move _25); + _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _24 = move _25 as usize (IntToInt); StorageDead(_25); + _6 = Option::<usize>::Some(move _24); + StorageDead(_24); goto -> bb9; } + + bb12: { + unreachable; + } } ALLOC0 (size: 16, align: 8) { diff --git a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff index 10cc46a8b82..b839bf81eaf 100644 --- a/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff +++ b/tests/mir-opt/funky_arms.float_to_exponential_common.GVN.64bit.panic-unwind.diff @@ -29,16 +29,10 @@ debug precision => _8; let _8: usize; scope 5 (inlined Formatter::<'_>::precision) { - let mut _22: std::option::Option<u16>; - scope 6 (inlined Option::<u16>::map::<usize, {closure@Formatter<'_>::precision::{closure#0}}>) { - let mut _23: isize; - let _24: u16; - let mut _25: usize; - scope 7 { - scope 8 (inlined Formatter::<'_>::precision::{closure#0}) { - } - } - } + let mut _22: u32; + let mut _23: u32; + let mut _24: usize; + let mut _25: u16; } } } @@ -53,7 +47,7 @@ StorageLive(_20); StorageLive(_21); _21 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); - _20 = BitAnd(move _21, const 1_u32); + _20 = BitAnd(move _21, const core::fmt::flags::SIGN_PLUS_FLAG); StorageDead(_21); _4 = Ne(move _20, const 0_u32); StorageDead(_20); @@ -75,12 +69,12 @@ bb3: { StorageLive(_6); - StorageLive(_24); StorageLive(_22); - _22 = copy (((*_1).0: std::fmt::FormattingOptions).4: std::option::Option<u16>); StorageLive(_23); - _23 = discriminant(_22); - switchInt(move _23) -> [0: bb11, 1: bb12, otherwise: bb10]; + _23 = copy (((*_1).0: std::fmt::FormattingOptions).0: u32); + _22 = BitAnd(move _23, const core::fmt::flags::PRECISION_FLAG); + StorageDead(_23); + switchInt(move _22) -> [0: bb10, otherwise: bb11]; } bb4: { @@ -148,30 +142,31 @@ } bb9: { - StorageDead(_23); - StorageDead(_22); - StorageDead(_24); _7 = discriminant(_6); - switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb10]; + switchInt(move _7) -> [1: bb4, 0: bb6, otherwise: bb12]; } bb10: { - unreachable; - } - - bb11: { + StorageDead(_22); _6 = const Option::<usize>::None; goto -> bb9; } - bb12: { - _24 = move ((_22 as Some).0: u16); + bb11: { + StorageDead(_22); + StorageLive(_24); StorageLive(_25); - _25 = copy _24 as usize (IntToInt); - _6 = Option::<usize>::Some(move _25); + _25 = copy (((*_1).0: std::fmt::FormattingOptions).2: u16); + _24 = move _25 as usize (IntToInt); StorageDead(_25); + _6 = Option::<usize>::Some(move _24); + StorageDead(_24); goto -> bb9; } + + bb12: { + unreachable; + } } ALLOC0 (size: 16, align: 8) { diff --git a/tests/mir-opt/pre-codegen/checked_ops.rs b/tests/mir-opt/pre-codegen/checked_ops.rs index 56f8e3f8338..8fd340503f5 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.rs +++ b/tests/mir-opt/pre-codegen/checked_ops.rs @@ -1,4 +1,3 @@ -// skip-filecheck //@ compile-flags: -O -Zmir-opt-level=2 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY @@ -8,10 +7,48 @@ // EMIT_MIR checked_ops.step_forward.PreCodegen.after.mir pub fn step_forward(x: u16, n: usize) -> u16 { // This uses `u16` so that the conversion to usize is always widening. + + // CHECK-LABEL: fn step_forward + // CHECK: inlined{{.+}}forward std::iter::Step::forward(x, n) } // EMIT_MIR checked_ops.checked_shl.PreCodegen.after.mir pub fn checked_shl(x: u32, rhs: u32) -> Option<u32> { + // CHECK-LABEL: fn checked_shl + // CHECK: [[TEMP:_[0-9]+]] = ShlUnchecked(copy _1, copy _2) + // CHECK: _0 = Option::<u32>::Some({{move|copy}} [[TEMP]]) x.checked_shl(rhs) } + +// EMIT_MIR checked_ops.use_checked_sub.PreCodegen.after.mir +pub fn use_checked_sub(x: u32, rhs: u32) { + // We want this to be equivalent to open-coding it, leaving no `Option`s around. + // FIXME(#138544): It's not yet. + + // CHECK-LABEL: fn use_checked_sub + // CHECK: inlined{{.+}}u32{{.+}}checked_sub + // CHECK: [[DELTA:_[0-9]+]] = SubUnchecked(copy _1, copy _2) + // CHECK: [[TEMP1:_.+]] = Option::<u32>::Some(move [[DELTA]]); + // CHECK: [[TEMP2:_.+]] = {{move|copy}} (([[TEMP1]] as Some).0: u32); + // CHECK: do_something({{move|copy}} [[TEMP2]]) + if let Some(delta) = x.checked_sub(rhs) { + do_something(delta); + } +} + +// EMIT_MIR checked_ops.saturating_sub_at_home.PreCodegen.after.mir +pub fn saturating_sub_at_home(lhs: u32, rhs: u32) -> u32 { + // FIXME(#138544): Similarly here, the `Option` ought to optimize away + + // CHECK-LABEL: fn saturating_sub_at_home + // CHECK: [[DELTA:_[0-9]+]] = SubUnchecked(copy _1, copy _2) + // CHECK: [[TEMP1:_.+]] = Option::<u32>::Some({{move|copy}} [[DELTA]]); + // CHECK: [[TEMP2:_.+]] = {{move|copy}} (([[TEMP1]] as Some).0: u32); + // CHECK: _0 = {{move|copy}} [[TEMP2]]; + u32::checked_sub(lhs, rhs).unwrap_or(0) +} + +unsafe extern "Rust" { + safe fn do_something(_: u32); +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir new file mode 100644 index 00000000000..5b4fdeda857 --- /dev/null +++ b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-abort.mir @@ -0,0 +1,48 @@ +// MIR for `saturating_sub_at_home` after PreCodegen + +fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { + debug lhs => _1; + debug rhs => _2; + let mut _0: u32; + let mut _5: std::option::Option<u32>; + scope 1 (inlined core::num::<impl u32>::checked_sub) { + let mut _3: bool; + let mut _4: u32; + } + scope 2 (inlined Option::<u32>::unwrap_or) { + let _6: u32; + scope 3 { + } + } + + bb0: { + StorageLive(_5); + StorageLive(_3); + _3 = Lt(copy _1, copy _2); + switchInt(move _3) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_4); + _4 = SubUnchecked(copy _1, copy _2); + _5 = Option::<u32>::Some(move _4); + StorageDead(_4); + StorageDead(_3); + StorageLive(_6); + _6 = move ((_5 as Some).0: u32); + _0 = move _6; + StorageDead(_6); + goto -> bb3; + } + + bb2: { + StorageDead(_3); + _0 = const 0_u32; + goto -> bb3; + } + + bb3: { + StorageDead(_5); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir new file mode 100644 index 00000000000..5b4fdeda857 --- /dev/null +++ b/tests/mir-opt/pre-codegen/checked_ops.saturating_sub_at_home.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,48 @@ +// MIR for `saturating_sub_at_home` after PreCodegen + +fn saturating_sub_at_home(_1: u32, _2: u32) -> u32 { + debug lhs => _1; + debug rhs => _2; + let mut _0: u32; + let mut _5: std::option::Option<u32>; + scope 1 (inlined core::num::<impl u32>::checked_sub) { + let mut _3: bool; + let mut _4: u32; + } + scope 2 (inlined Option::<u32>::unwrap_or) { + let _6: u32; + scope 3 { + } + } + + bb0: { + StorageLive(_5); + StorageLive(_3); + _3 = Lt(copy _1, copy _2); + switchInt(move _3) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_4); + _4 = SubUnchecked(copy _1, copy _2); + _5 = Option::<u32>::Some(move _4); + StorageDead(_4); + StorageDead(_3); + StorageLive(_6); + _6 = move ((_5 as Some).0: u32); + _0 = move _6; + StorageDead(_6); + goto -> bb3; + } + + bb2: { + StorageDead(_3); + _0 = const 0_u32; + goto -> bb3; + } + + bb3: { + StorageDead(_5); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-abort.mir new file mode 100644 index 00000000000..3c475cd4030 --- /dev/null +++ b/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-abort.mir @@ -0,0 +1,44 @@ +// MIR for `use_checked_sub` after PreCodegen + +fn use_checked_sub(_1: u32, _2: u32) -> () { + debug x => _1; + debug rhs => _2; + let mut _0: (); + let mut _5: std::option::Option<u32>; + let _7: (); + scope 1 { + debug delta => _6; + let _6: u32; + scope 2 (inlined core::num::<impl u32>::checked_sub) { + let mut _3: bool; + let mut _4: u32; + } + } + + bb0: { + StorageLive(_5); + StorageLive(_3); + _3 = Lt(copy _1, copy _2); + switchInt(move _3) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_4); + _4 = SubUnchecked(copy _1, copy _2); + _5 = Option::<u32>::Some(move _4); + StorageDead(_4); + StorageDead(_3); + _6 = copy ((_5 as Some).0: u32); + _7 = do_something(move _6) -> [return: bb3, unwind unreachable]; + } + + bb2: { + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_5); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-unwind.mir new file mode 100644 index 00000000000..3ef09764b1c --- /dev/null +++ b/tests/mir-opt/pre-codegen/checked_ops.use_checked_sub.PreCodegen.after.panic-unwind.mir @@ -0,0 +1,44 @@ +// MIR for `use_checked_sub` after PreCodegen + +fn use_checked_sub(_1: u32, _2: u32) -> () { + debug x => _1; + debug rhs => _2; + let mut _0: (); + let mut _5: std::option::Option<u32>; + let _7: (); + scope 1 { + debug delta => _6; + let _6: u32; + scope 2 (inlined core::num::<impl u32>::checked_sub) { + let mut _3: bool; + let mut _4: u32; + } + } + + bb0: { + StorageLive(_5); + StorageLive(_3); + _3 = Lt(copy _1, copy _2); + switchInt(move _3) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_4); + _4 = SubUnchecked(copy _1, copy _2); + _5 = Option::<u32>::Some(move _4); + StorageDead(_4); + StorageDead(_3); + _6 = copy ((_5 as Some).0: u32); + _7 = do_something(move _6) -> [return: bb3, unwind continue]; + } + + bb2: { + StorageDead(_3); + goto -> bb3; + } + + bb3: { + StorageDead(_5); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir index cbfc58194cc..7595ad88d9d 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/simple_option_map.ezmap.PreCodegen.after.mir @@ -3,7 +3,7 @@ fn ezmap(_1: Option<i32>) -> Option<i32> { debug x => _1; let mut _0: std::option::Option<i32>; - scope 1 (inlined map::<i32, i32, {closure@$DIR/simple_option_map.rs:17:12: 17:15}>) { + scope 1 (inlined map::<i32, i32, {closure@$DIR/simple_option_map.rs:23:12: 23:15}>) { let mut _2: isize; let _3: i32; let mut _4: i32; diff --git a/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir new file mode 100644 index 00000000000..b921b96966b --- /dev/null +++ b/tests/mir-opt/pre-codegen/simple_option_map.map_via_question_mark.PreCodegen.after.mir @@ -0,0 +1,70 @@ +// MIR for `map_via_question_mark` after PreCodegen + +fn map_via_question_mark(_1: Option<i32>) -> Option<i32> { + debug x => _1; + let mut _0: std::option::Option<i32>; + let mut _4: std::ops::ControlFlow<std::option::Option<std::convert::Infallible>, i32>; + let _5: i32; + let mut _6: i32; + scope 1 { + debug residual => const Option::<Infallible>::None; + scope 2 { + scope 7 (inlined <Option<i32> as FromResidual<Option<Infallible>>>::from_residual) { + } + } + } + scope 3 { + debug val => _5; + scope 4 { + } + } + scope 5 (inlined <Option<i32> as Try>::branch) { + let mut _2: isize; + let _3: i32; + scope 6 { + } + } + + bb0: { + StorageLive(_6); + StorageLive(_4); + StorageLive(_2); + StorageLive(_3); + _2 = discriminant(_1); + switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb4]; + } + + bb1: { + StorageDead(_3); + StorageDead(_2); + _0 = const Option::<i32>::None; + StorageDead(_6); + StorageDead(_4); + goto -> bb3; + } + + bb2: { + _3 = copy ((_1 as Some).0: i32); + _4 = ControlFlow::<Option<Infallible>, i32>::Continue(copy _3); + StorageDead(_3); + StorageDead(_2); + _5 = copy ((_4 as Continue).0: i32); + _6 = Add(copy _5, const 1_i32); + _0 = Option::<i32>::Some(move _6); + StorageDead(_6); + StorageDead(_4); + goto -> bb3; + } + + bb3: { + return; + } + + bb4: { + unreachable; + } +} + +ALLOC0 (size: 8, align: 4) { + 00 00 00 00 __ __ __ __ │ ....░░░░ +} diff --git a/tests/mir-opt/pre-codegen/simple_option_map.rs b/tests/mir-opt/pre-codegen/simple_option_map.rs index 0c432be0419..f0d7b51a643 100644 --- a/tests/mir-opt/pre-codegen/simple_option_map.rs +++ b/tests/mir-opt/pre-codegen/simple_option_map.rs @@ -1,7 +1,6 @@ -// skip-filecheck //@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -#[inline(always)] +#[inline] fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U> where F: FnOnce(T) -> U, @@ -14,9 +13,30 @@ where // EMIT_MIR simple_option_map.ezmap.PreCodegen.after.mir pub fn ezmap(x: Option<i32>) -> Option<i32> { + // We expect this to all be inlined, as though it was written without the + // combinator and without the closure, using just a plain match. + + // CHECK-LABEL: fn ezmap + // CHECK: [[INNER:_.+]] = copy ((_1 as Some).0: i32); + // CHECK: [[SUCC:_.+]] = Add({{copy|move}} [[INNER]], const 1_i32); + // CHECK: _0 = Option::<i32>::Some({{copy|move}} [[SUCC]]); map(x, |n| n + 1) } +// EMIT_MIR simple_option_map.map_via_question_mark.PreCodegen.after.mir +pub fn map_via_question_mark(x: Option<i32>) -> Option<i32> { + // FIXME(#138544): Ideally this would optimize out the `ControlFlow` local. + + // CHECK-LABEL: fn map_via_question_mark + // CHECK: [[INNER:_.+]] = copy ((_1 as Some).0: i32); + // CHECK: [[TEMP1:_.+]] = ControlFlow::<Option<Infallible>, i32>::Continue(copy [[INNER]]); + // CHECK: [[TEMP2:_.+]] = copy (([[TEMP1]] as Continue).0: i32); + // CHECK: [[SUCC:_.+]] = Add({{copy|move}} [[TEMP2]], const 1_i32); + // CHECK: _0 = Option::<i32>::Some({{copy|move}} [[SUCC]]); + Some(x? + 1) +} + fn main() { assert_eq!(None, ezmap(None)); + assert_eq!(None, map_via_question_mark(None)); } diff --git a/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir new file mode 100644 index 00000000000..dd2eebc8f4a --- /dev/null +++ b/tests/mir-opt/pre-codegen/tuple_ord.demo_ge_partial.PreCodegen.after.mir @@ -0,0 +1,70 @@ +// MIR for `demo_ge_partial` after PreCodegen + +fn demo_ge_partial(_1: &(f32, f32), _2: &(f32, f32)) -> bool { + debug a => _1; + debug b => _2; + let mut _0: bool; + scope 1 (inlined std::cmp::impls::<impl PartialOrd for &(f32, f32)>::ge) { + scope 2 (inlined core::tuple::<impl PartialOrd for (f32, f32)>::ge) { + let mut _7: std::ops::ControlFlow<bool>; + let _8: bool; + scope 3 { + } + scope 4 (inlined std::cmp::impls::<impl PartialOrd for f32>::__chaining_ge) { + let mut _3: f32; + let mut _4: f32; + let mut _5: bool; + let mut _6: bool; + scope 5 { + } + } + scope 6 (inlined std::cmp::impls::<impl PartialOrd for f32>::ge) { + let mut _9: f32; + let mut _10: f32; + } + } + } + + bb0: { + StorageLive(_7); + StorageLive(_3); + StorageLive(_4); + _3 = copy ((*_1).0: f32); + _4 = copy ((*_2).0: f32); + StorageLive(_5); + _5 = Eq(copy _3, copy _4); + switchInt(move _5) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = Ge(copy _3, copy _4); + _7 = ControlFlow::<bool>::Break(move _6); + StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + _8 = copy ((_7 as Break).0: bool); + _0 = copy _8; + goto -> bb3; + } + + bb2: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageLive(_9); + _9 = copy ((*_1).1: f32); + StorageLive(_10); + _10 = copy ((*_2).1: f32); + _0 = Ge(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + goto -> bb3; + } + + bb3: { + StorageDead(_7); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir new file mode 100644 index 00000000000..ea1d164cefa --- /dev/null +++ b/tests/mir-opt/pre-codegen/tuple_ord.demo_le_total.PreCodegen.after.mir @@ -0,0 +1,70 @@ +// MIR for `demo_le_total` after PreCodegen + +fn demo_le_total(_1: &(u16, i16), _2: &(u16, i16)) -> bool { + debug a => _1; + debug b => _2; + let mut _0: bool; + scope 1 (inlined std::cmp::impls::<impl PartialOrd for &(u16, i16)>::le) { + scope 2 (inlined core::tuple::<impl PartialOrd for (u16, i16)>::le) { + let mut _7: std::ops::ControlFlow<bool>; + let _8: bool; + scope 3 { + } + scope 4 (inlined std::cmp::impls::<impl PartialOrd for u16>::__chaining_le) { + let mut _3: u16; + let mut _4: u16; + let mut _5: bool; + let mut _6: bool; + scope 5 { + } + } + scope 6 (inlined std::cmp::impls::<impl PartialOrd for i16>::le) { + let mut _9: i16; + let mut _10: i16; + } + } + } + + bb0: { + StorageLive(_7); + StorageLive(_3); + StorageLive(_4); + _3 = copy ((*_1).0: u16); + _4 = copy ((*_2).0: u16); + StorageLive(_5); + _5 = Eq(copy _3, copy _4); + switchInt(move _5) -> [0: bb1, otherwise: bb2]; + } + + bb1: { + StorageLive(_6); + _6 = Le(copy _3, copy _4); + _7 = ControlFlow::<bool>::Break(move _6); + StorageDead(_6); + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + _8 = copy ((_7 as Break).0: bool); + _0 = copy _8; + goto -> bb3; + } + + bb2: { + StorageDead(_5); + StorageDead(_4); + StorageDead(_3); + StorageLive(_9); + _9 = copy ((*_1).1: i16); + StorageLive(_10); + _10 = copy ((*_2).1: i16); + _0 = Le(move _9, move _10); + StorageDead(_10); + StorageDead(_9); + goto -> bb3; + } + + bb3: { + StorageDead(_7); + return; + } +} diff --git a/tests/mir-opt/pre-codegen/tuple_ord.rs b/tests/mir-opt/pre-codegen/tuple_ord.rs new file mode 100644 index 00000000000..74a919e5424 --- /dev/null +++ b/tests/mir-opt/pre-codegen/tuple_ord.rs @@ -0,0 +1,16 @@ +//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0 +//@ needs-unwind + +#![crate_type = "lib"] + +// EMIT_MIR tuple_ord.demo_le_total.PreCodegen.after.mir +pub fn demo_le_total(a: &(u16, i16), b: &(u16, i16)) -> bool { + // CHECK-LABEL: demo_le_total + a <= b +} + +// EMIT_MIR tuple_ord.demo_ge_partial.PreCodegen.after.mir +pub fn demo_ge_partial(a: &(f32, f32), b: &(f32, f32)) -> bool { + // CHECK-LABEL: demo_ge_partial + a >= b +} diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout index c8ea09ee2c8..98e56735082 100644 --- a/tests/run-make/rustc-help/help-v.stdout +++ b/tests/run-make/rustc-help/help-v.stdout @@ -29,7 +29,7 @@ Options: --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit - --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout index 434e71e901e..040555f1d04 100644 --- a/tests/run-make/rustc-help/help.stdout +++ b/tests/run-make/rustc-help/help.stdout @@ -29,7 +29,7 @@ Options: --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir] Comma separated list of types of output for the compiler to emit - --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout -g Equivalent to -C debuginfo=2 -O Equivalent to -C opt-level=3 diff --git a/tests/rustdoc-json/assoc_items.rs b/tests/rustdoc-json/assoc_items.rs index f315f37966d..f47a522e81a 100644 --- a/tests/rustdoc-json/assoc_items.rs +++ b/tests/rustdoc-json/assoc_items.rs @@ -3,32 +3,32 @@ pub struct Simple; impl Simple { - //@ has "$.index[*][?(@.name=='CONSTANT')].inner.assoc_const" + //@ has "$.index[?(@.name=='CONSTANT')].inner.assoc_const" pub const CONSTANT: usize = 0; } pub trait EasyToImpl { - //@ has "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type" - //@ is "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type.type" null - //@ is "$.index[*][?(@.docs=='ToDeclare trait')].inner.assoc_type.bounds" [] + //@ has "$.index[?(@.docs=='ToDeclare trait')].inner.assoc_type" + //@ is "$.index[?(@.docs=='ToDeclare trait')].inner.assoc_type.type" null + //@ is "$.index[?(@.docs=='ToDeclare trait')].inner.assoc_type.bounds" [] /// ToDeclare trait type ToDeclare; - //@ has "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const" - //@ is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.value" null - //@ is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.type.primitive" '"usize"' + //@ has "$.index[?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const" + //@ is "$.index[?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.value" null + //@ is "$.index[?(@.docs=='AN_ATTRIBUTE trait')].inner.assoc_const.type.primitive" '"usize"' /// AN_ATTRIBUTE trait const AN_ATTRIBUTE: usize; } impl EasyToImpl for Simple { - //@ has "$.index[*][?(@.docs=='ToDeclare impl')].inner.assoc_type" - //@ is "$.index[*][?(@.docs=='ToDeclare impl')].inner.assoc_type.type.primitive" \"usize\" + //@ has "$.index[?(@.docs=='ToDeclare impl')].inner.assoc_type" + //@ is "$.index[?(@.docs=='ToDeclare impl')].inner.assoc_type.type.primitive" \"usize\" /// ToDeclare impl type ToDeclare = usize; - //@ has "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const" - //@ is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.type.primitive" \"usize\" - //@ is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.value" \"12\" + //@ has "$.index[?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const" + //@ is "$.index[?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.type.primitive" \"usize\" + //@ is "$.index[?(@.docs=='AN_ATTRIBUTE impl')].inner.assoc_const.value" \"12\" /// AN_ATTRIBUTE impl const AN_ATTRIBUTE: usize = 12; } diff --git a/tests/rustdoc-json/assoc_type.rs b/tests/rustdoc-json/assoc_type.rs index 43b4d387d92..816075ca17a 100644 --- a/tests/rustdoc-json/assoc_type.rs +++ b/tests/rustdoc-json/assoc_type.rs @@ -1,9 +1,9 @@ // Regression test for <https://github.com/rust-lang/rust/issues/98547>. -//@ has "$.index[*][?(@.name=='Trait')]" -//@ has "$.index[*][?(@.name=='AssocType')]" -//@ has "$.index[*][?(@.name=='S')]" -//@ has "$.index[*][?(@.name=='S2')]" +//@ has "$.index[?(@.name=='Trait')]" +//@ has "$.index[?(@.name=='AssocType')]" +//@ has "$.index[?(@.name=='S')]" +//@ has "$.index[?(@.name=='S2')]" pub trait Trait { type AssocType; diff --git a/tests/rustdoc-json/attrs/deprecated.rs b/tests/rustdoc-json/attrs/deprecated.rs index 5cde7af841f..0799471fc88 100644 --- a/tests/rustdoc-json/attrs/deprecated.rs +++ b/tests/rustdoc-json/attrs/deprecated.rs @@ -1,38 +1,38 @@ -//@ is "$.index[*][?(@.name=='not')].attrs" [] -//@ is "$.index[*][?(@.name=='not')].deprecation" null +//@ is "$.index[?(@.name=='not')].attrs" [] +//@ is "$.index[?(@.name=='not')].deprecation" null pub fn not() {} -//@ is "$.index[*][?(@.name=='raw')].attrs" [] -//@ is "$.index[*][?(@.name=='raw')].deprecation" '{"since": null, "note": null}' +//@ is "$.index[?(@.name=='raw')].attrs" [] +//@ is "$.index[?(@.name=='raw')].deprecation" '{"since": null, "note": null}' #[deprecated] pub fn raw() {} -//@ is "$.index[*][?(@.name=='equals_string')].attrs" [] -//@ is "$.index[*][?(@.name=='equals_string')].deprecation" '{"since": null, "note": "here is a reason"}' +//@ is "$.index[?(@.name=='equals_string')].attrs" [] +//@ is "$.index[?(@.name=='equals_string')].deprecation" '{"since": null, "note": "here is a reason"}' #[deprecated = "here is a reason"] pub fn equals_string() {} -//@ is "$.index[*][?(@.name=='since')].attrs" [] -//@ is "$.index[*][?(@.name=='since')].deprecation" '{"since": "yoinks ago", "note": null}' +//@ is "$.index[?(@.name=='since')].attrs" [] +//@ is "$.index[?(@.name=='since')].deprecation" '{"since": "yoinks ago", "note": null}' #[deprecated(since = "yoinks ago")] pub fn since() {} -//@ is "$.index[*][?(@.name=='note')].attrs" [] -//@ is "$.index[*][?(@.name=='note')].deprecation" '{"since": null, "note": "7"}' +//@ is "$.index[?(@.name=='note')].attrs" [] +//@ is "$.index[?(@.name=='note')].deprecation" '{"since": null, "note": "7"}' #[deprecated(note = "7")] pub fn note() {} -//@ is "$.index[*][?(@.name=='since_and_note')].attrs" [] -//@ is "$.index[*][?(@.name=='since_and_note')].deprecation" '{"since": "tomorrow", "note": "sorry"}' +//@ is "$.index[?(@.name=='since_and_note')].attrs" [] +//@ is "$.index[?(@.name=='since_and_note')].deprecation" '{"since": "tomorrow", "note": "sorry"}' #[deprecated(since = "tomorrow", note = "sorry")] pub fn since_and_note() {} -//@ is "$.index[*][?(@.name=='note_and_since')].attrs" [] -//@ is "$.index[*][?(@.name=='note_and_since')].deprecation" '{"since": "a year from tomorrow", "note": "your welcome"}' +//@ is "$.index[?(@.name=='note_and_since')].attrs" [] +//@ is "$.index[?(@.name=='note_and_since')].deprecation" '{"since": "a year from tomorrow", "note": "your welcome"}' #[deprecated(note = "your welcome", since = "a year from tomorrow")] pub fn note_and_since() {} -//@ is "$.index[*][?(@.name=='neither_but_parens')].attrs" [] -//@ is "$.index[*][?(@.name=='neither_but_parens')].deprecation" '{"since": null, "note": null}' +//@ is "$.index[?(@.name=='neither_but_parens')].attrs" [] +//@ is "$.index[?(@.name=='neither_but_parens')].deprecation" '{"since": null, "note": null}' #[deprecated()] pub fn neither_but_parens() {} diff --git a/tests/rustdoc-json/attrs/export_name_2021.rs b/tests/rustdoc-json/attrs/export_name_2021.rs index badf124bdde..254e9f6ef5b 100644 --- a/tests/rustdoc-json/attrs/export_name_2021.rs +++ b/tests/rustdoc-json/attrs/export_name_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[*][?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' #[export_name = "altered"] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/export_name_2024.rs b/tests/rustdoc-json/attrs/export_name_2024.rs index c5bb9dcc8f6..8129c109306 100644 --- a/tests/rustdoc-json/attrs/export_name_2024.rs +++ b/tests/rustdoc-json/attrs/export_name_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(export_name = ..)]` in rustdoc in edition 2024 // is still `#[export_name = ..]` without the `unsafe` attribute wrapper. -//@ is "$.index[*][?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[export_name = \"altered\"]"]' #[unsafe(export_name = "altered")] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/must_use.rs b/tests/rustdoc-json/attrs/must_use.rs index dca73abc76a..64df8e5f509 100644 --- a/tests/rustdoc-json/attrs/must_use.rs +++ b/tests/rustdoc-json/attrs/must_use.rs @@ -1,9 +1,9 @@ #![no_std] -//@ is "$.index[*][?(@.name=='example')].attrs" '["#[must_use]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[must_use]"]' #[must_use] pub fn example() -> impl Iterator<Item = i64> {} -//@ is "$.index[*][?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' +//@ is "$.index[?(@.name=='explicit_message')].attrs" '["#[must_use = \"does nothing if you do not use it\"]"]' #[must_use = "does nothing if you do not use it"] pub fn explicit_message() -> impl Iterator<Item = i64> {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2021.rs b/tests/rustdoc-json/attrs/no_mangle_2021.rs index 258542086ec..588be7256db 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2021.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![no_std] -//@ is "$.index[*][?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' #[no_mangle] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/no_mangle_2024.rs b/tests/rustdoc-json/attrs/no_mangle_2024.rs index 4c01082d045..0d500e20e6c 100644 --- a/tests/rustdoc-json/attrs/no_mangle_2024.rs +++ b/tests/rustdoc-json/attrs/no_mangle_2024.rs @@ -4,6 +4,6 @@ // The representation of `#[unsafe(no_mangle)]` in rustdoc in edition 2024 // is still `#[no_mangle]` without the `unsafe` attribute wrapper. -//@ is "$.index[*][?(@.name=='example')].attrs" '["#[no_mangle]"]' +//@ is "$.index[?(@.name=='example')].attrs" '["#[no_mangle]"]' #[unsafe(no_mangle)] pub extern "C" fn example() {} diff --git a/tests/rustdoc-json/attrs/non_exhaustive.rs b/tests/rustdoc-json/attrs/non_exhaustive.rs index 5d738fc0560..b95f1a8171f 100644 --- a/tests/rustdoc-json/attrs/non_exhaustive.rs +++ b/tests/rustdoc-json/attrs/non_exhaustive.rs @@ -1,18 +1,18 @@ #![no_std] -//@ is "$.index[*][?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyEnum')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] pub enum MyEnum { First, } pub enum NonExhaustiveVariant { - //@ is "$.index[*][?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' + //@ is "$.index[?(@.name=='Variant')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] Variant(i64), } -//@ is "$.index[*][?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' +//@ is "$.index[?(@.name=='MyStruct')].attrs" '["#[non_exhaustive]"]' #[non_exhaustive] pub struct MyStruct { pub x: i64, diff --git a/tests/rustdoc-json/attrs/repr_align.rs b/tests/rustdoc-json/attrs/repr_align.rs index bebbe1fea34..c6debda7f1c 100644 --- a/tests/rustdoc-json/attrs/repr_align.rs +++ b/tests/rustdoc-json/attrs/repr_align.rs @@ -1,6 +1,6 @@ #![no_std] -//@ is "$.index[*][?(@.name=='Aligned')].attrs" '["#[attr = Repr([ReprAlign(Align(4 bytes))])]\n"]' +//@ is "$.index[?(@.name=='Aligned')].attrs" '["#[repr(align(4))]"]' #[repr(align(4))] pub struct Aligned { a: i8, diff --git a/tests/rustdoc-json/attrs/repr_c.rs b/tests/rustdoc-json/attrs/repr_c.rs index 609d33d94de..e6219413f30 100644 --- a/tests/rustdoc-json/attrs/repr_c.rs +++ b/tests/rustdoc-json/attrs/repr_c.rs @@ -1,16 +1,16 @@ #![no_std] -//@ is "$.index[*][?(@.name=='ReprCStruct')].attrs" '["#[attr = Repr([ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReprCStruct')].attrs" '["#[repr(C)]"]' #[repr(C)] pub struct ReprCStruct(pub i64); -//@ is "$.index[*][?(@.name=='ReprCEnum')].attrs" '["#[attr = Repr([ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReprCEnum')].attrs" '["#[repr(C)]"]' #[repr(C)] pub enum ReprCEnum { First, } -//@ is "$.index[*][?(@.name=='ReprCUnion')].attrs" '["#[attr = Repr([ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReprCUnion')].attrs" '["#[repr(C)]"]' #[repr(C)] pub union ReprCUnion { pub left: i64, diff --git a/tests/rustdoc-json/attrs/repr_combination.rs b/tests/rustdoc-json/attrs/repr_combination.rs index 662bfef67cb..0e8e2ef0d83 100644 --- a/tests/rustdoc-json/attrs/repr_combination.rs +++ b/tests/rustdoc-json/attrs/repr_combination.rs @@ -1,34 +1,35 @@ #![no_std] // Combinations of `#[repr(..)]` attributes. +// Rustdoc JSON emits normalized output, regardless of the original source. -//@ is "$.index[*][?(@.name=='ReprCI8')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I8))])]\n"]' +//@ is "$.index[?(@.name=='ReprCI8')].attrs" '["#[repr(C, i8)]"]' #[repr(C, i8)] pub enum ReprCI8 { First, } -//@ is "$.index[*][?(@.name=='SeparateReprCI16')].attrs" '["#[attr = Repr([ReprC, ReprInt(SignedInt(I16))])]\n"]' +//@ is "$.index[?(@.name=='SeparateReprCI16')].attrs" '["#[repr(C, i16)]"]' #[repr(C)] #[repr(i16)] pub enum SeparateReprCI16 { First, } -//@ is "$.index[*][?(@.name=='ReversedReprCUsize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize)), ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReversedReprCUsize')].attrs" '["#[repr(C, usize)]"]' #[repr(usize, C)] pub enum ReversedReprCUsize { First, } -//@ is "$.index[*][?(@.name=='ReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(1 bytes))])]\n"]' +//@ is "$.index[?(@.name=='ReprCPacked')].attrs" '["#[repr(C, packed(1))]"]' #[repr(C, packed)] pub struct ReprCPacked { a: i8, b: i64, } -//@ is "$.index[*][?(@.name=='SeparateReprCPacked')].attrs" '["#[attr = Repr([ReprC, ReprPacked(Align(2 bytes))])]\n"]' +//@ is "$.index[?(@.name=='SeparateReprCPacked')].attrs" '["#[repr(C, packed(2))]"]' #[repr(C)] #[repr(packed(2))] pub struct SeparateReprCPacked { @@ -36,21 +37,21 @@ pub struct SeparateReprCPacked { b: i64, } -//@ is "$.index[*][?(@.name=='ReversedReprCPacked')].attrs" '["#[attr = Repr([ReprPacked(Align(2 bytes)), ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReversedReprCPacked')].attrs" '["#[repr(C, packed(2))]"]' #[repr(packed(2), C)] pub struct ReversedReprCPacked { a: i8, b: i64, } -//@ is "$.index[*][?(@.name=='ReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes))])]\n"]' +//@ is "$.index[?(@.name=='ReprCAlign')].attrs" '["#[repr(C, align(16))]"]' #[repr(C, align(16))] pub struct ReprCAlign { a: i8, b: i64, } -//@ is "$.index[*][?(@.name=='SeparateReprCAlign')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(2 bytes))])]\n"]' +//@ is "$.index[?(@.name=='SeparateReprCAlign')].attrs" '["#[repr(C, align(2))]"]' #[repr(C)] #[repr(align(2))] pub struct SeparateReprCAlign { @@ -58,20 +59,20 @@ pub struct SeparateReprCAlign { b: i64, } -//@ is "$.index[*][?(@.name=='ReversedReprCAlign')].attrs" '["#[attr = Repr([ReprAlign(Align(2 bytes)), ReprC])]\n"]' +//@ is "$.index[?(@.name=='ReversedReprCAlign')].attrs" '["#[repr(C, align(2))]"]' #[repr(align(2), C)] pub struct ReversedReprCAlign { a: i8, b: i64, } -//@ is "$.index[*][?(@.name=='AlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprC, ReprAlign(Align(16 bytes)), ReprInt(SignedInt(Isize))])]\n"]' +//@ is "$.index[?(@.name=='AlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]' #[repr(C, align(16), isize)] pub enum AlignedExplicitRepr { First, } -//@ is "$.index[*][?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[attr = Repr([ReprInt(SignedInt(Isize)), ReprC, ReprAlign(Align(16 bytes))])]\n"]' +//@ is "$.index[?(@.name=='ReorderedAlignedExplicitRepr')].attrs" '["#[repr(C, align(16), isize)]"]' #[repr(isize, C, align(16))] pub enum ReorderedAlignedExplicitRepr { First, diff --git a/tests/rustdoc-json/attrs/repr_int_enum.rs b/tests/rustdoc-json/attrs/repr_int_enum.rs index 2ad57de2798..9b09f341d4f 100644 --- a/tests/rustdoc-json/attrs/repr_int_enum.rs +++ b/tests/rustdoc-json/attrs/repr_int_enum.rs @@ -1,18 +1,18 @@ #![no_std] -//@ is "$.index[*][?(@.name=='I8')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I8))])]\n"]' +//@ is "$.index[?(@.name=='I8')].attrs" '["#[repr(i8)]"]' #[repr(i8)] pub enum I8 { First, } -//@ is "$.index[*][?(@.name=='I32')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]' +//@ is "$.index[?(@.name=='I32')].attrs" '["#[repr(i32)]"]' #[repr(i32)] pub enum I32 { First, } -//@ is "$.index[*][?(@.name=='Usize')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(Usize))])]\n"]' +//@ is "$.index[?(@.name=='Usize')].attrs" '["#[repr(usize)]"]' #[repr(usize)] pub enum Usize { First, diff --git a/tests/rustdoc-json/attrs/repr_packed.rs b/tests/rustdoc-json/attrs/repr_packed.rs index 33acc23b7c8..9f3fd86c4b0 100644 --- a/tests/rustdoc-json/attrs/repr_packed.rs +++ b/tests/rustdoc-json/attrs/repr_packed.rs @@ -1,16 +1,16 @@ #![no_std] // Note the normalization: -// `#[repr(packed)]` in has the implict "1" in rustdoc JSON. - -//@ is "$.index[*][?(@.name=='Packed')].attrs" '["#[attr = Repr([ReprPacked(Align(1 bytes))])]\n"]' +// `#[repr(packed)]` in source becomes `#[repr(packed(1))]` in rustdoc JSON. +// +//@ is "$.index[?(@.name=='Packed')].attrs" '["#[repr(packed(1))]"]' #[repr(packed)] pub struct Packed { a: i8, b: i64, } -//@ is "$.index[*][?(@.name=='PackedAligned')].attrs" '["#[attr = Repr([ReprPacked(Align(4 bytes))])]\n"]' +//@ is "$.index[?(@.name=='PackedAligned')].attrs" '["#[repr(packed(4))]"]' #[repr(packed(4))] pub struct PackedAligned { a: i8, diff --git a/tests/rustdoc-json/attrs/repr_transparent.rs b/tests/rustdoc-json/attrs/repr_transparent.rs index ef6e69f8703..1e634ca901d 100644 --- a/tests/rustdoc-json/attrs/repr_transparent.rs +++ b/tests/rustdoc-json/attrs/repr_transparent.rs @@ -1,22 +1,37 @@ #![no_std] -// Rustdoc JSON currently includes `#[repr(transparent)]` -// even if the transparency is not part of the public API +// Rustdoc JSON *only* includes `#[repr(transparent)]` +// if the transparency is public API: +// - if a non-1-ZST field exists, it has to be public +// - otherwise, all fields are 1-ZST and at least one of them is public // -// https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent +// More info: https://doc.rust-lang.org/nomicon/other-reprs.html#reprtransparent -//@ is "$.index[*][?(@.name=='Transparent')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +// Here, the non-1-ZST field is public. +// We expect `#[repr(transparent)]` in the attributes. +// +//@ is "$.index[?(@.name=='Transparent')].attrs" '["#[repr(transparent)]"]' #[repr(transparent)] pub struct Transparent(pub i64); -//@ is "$.index[*][?(@.name=='TransparentNonPub')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +// Here the non-1-ZST field isn't public, so the attribute isn't included. +// +//@ has "$.index[?(@.name=='TransparentNonPub')]" +//@ is "$.index[?(@.name=='TransparentNonPub')].attrs" '[]' #[repr(transparent)] pub struct TransparentNonPub(i64); -//@ is "$.index[*][?(@.name=='AllZst')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +// Only 1-ZST fields here, and one of them is public. +// We expect `#[repr(transparent)]` in the attributes. +// +//@ is "$.index[?(@.name=='AllZst')].attrs" '["#[repr(transparent)]"]' #[repr(transparent)] pub struct AllZst<'a>(pub core::marker::PhantomData<&'a ()>, ()); -//@ is "$.index[*][?(@.name=='AllZstNotPublic')].attrs" '["#[attr = Repr([ReprTransparent])]\n"]' +// Only 1-ZST fields here but none of them are public. +// The attribute isn't included. +// +//@ has "$.index[?(@.name=='AllZstNotPublic')]" +//@ is "$.index[?(@.name=='AllZstNotPublic')].attrs" '[]' #[repr(transparent)] pub struct AllZstNotPublic<'a>(core::marker::PhantomData<&'a ()>, ()); diff --git a/tests/rustdoc-json/blanket_impls.rs b/tests/rustdoc-json/blanket_impls.rs index bf0983e66a1..d500bf5af6b 100644 --- a/tests/rustdoc-json/blanket_impls.rs +++ b/tests/rustdoc-json/blanket_impls.rs @@ -2,7 +2,7 @@ #![no_std] -//@ has "$.index[*][?(@.name=='Error')].inner.assoc_type" -//@ has "$.index[*][?(@.name=='Error')].inner.assoc_type.type.resolved_path" -//@ has "$.index[*][?(@.name=='Error')].inner.assoc_type.type.resolved_path.path" \"Infallible\" +//@ has "$.index[?(@.name=='Error')].inner.assoc_type" +//@ has "$.index[?(@.name=='Error')].inner.assoc_type.type.resolved_path" +//@ has "$.index[?(@.name=='Error')].inner.assoc_type.type.resolved_path.path" \"Infallible\" pub struct ForBlanketTryFromImpl; diff --git a/tests/rustdoc-json/doc_hidden_failure.rs b/tests/rustdoc-json/doc_hidden_failure.rs index 249e35b7243..e68df7e9c61 100644 --- a/tests/rustdoc-json/doc_hidden_failure.rs +++ b/tests/rustdoc-json/doc_hidden_failure.rs @@ -11,8 +11,8 @@ mod auto { } } -//@ count "$.index[*][?(@.name=='builders')]" 1 -//@ has "$.index[*][?(@.name == 'ActionRowBuilder')"] +//@ count "$.index[?(@.name=='builders')]" 1 +//@ has "$.index[?(@.name == 'ActionRowBuilder')"] pub use auto::*; pub mod builders { diff --git a/tests/rustdoc-json/enums/discriminant/basic.rs b/tests/rustdoc-json/enums/discriminant/basic.rs index 06a240404fb..c7f164f3408 100644 --- a/tests/rustdoc-json/enums/discriminant/basic.rs +++ b/tests/rustdoc-json/enums/discriminant/basic.rs @@ -1,12 +1,12 @@ #[repr(i8)] pub enum Ordering { - //@ is "$.index[*][?(@.name=='Less')].inner.variant.discriminant.expr" '"-1"' - //@ is "$.index[*][?(@.name=='Less')].inner.variant.discriminant.value" '"-1"' + //@ is "$.index[?(@.name=='Less')].inner.variant.discriminant.expr" '"-1"' + //@ is "$.index[?(@.name=='Less')].inner.variant.discriminant.value" '"-1"' Less = -1, - //@ is "$.index[*][?(@.name=='Equal')].inner.variant.discriminant.expr" '"0"' - //@ is "$.index[*][?(@.name=='Equal')].inner.variant.discriminant.value" '"0"' + //@ is "$.index[?(@.name=='Equal')].inner.variant.discriminant.expr" '"0"' + //@ is "$.index[?(@.name=='Equal')].inner.variant.discriminant.value" '"0"' Equal = 0, - //@ is "$.index[*][?(@.name=='Greater')].inner.variant.discriminant.expr" '"1"' - //@ is "$.index[*][?(@.name=='Greater')].inner.variant.discriminant.value" '"1"' + //@ is "$.index[?(@.name=='Greater')].inner.variant.discriminant.expr" '"1"' + //@ is "$.index[?(@.name=='Greater')].inner.variant.discriminant.value" '"1"' Greater = 1, } diff --git a/tests/rustdoc-json/enums/discriminant/expr.rs b/tests/rustdoc-json/enums/discriminant/expr.rs index bf2bce85108..3743b13fec8 100644 --- a/tests/rustdoc-json/enums/discriminant/expr.rs +++ b/tests/rustdoc-json/enums/discriminant/expr.rs @@ -1,30 +1,30 @@ pub enum Foo { - //@ is "$.index[*][?(@.name=='Addition')].inner.variant.discriminant.value" '"0"' - //@ is "$.index[*][?(@.name=='Addition')].inner.variant.discriminant.expr" '"{ _ }"' + //@ is "$.index[?(@.name=='Addition')].inner.variant.discriminant.value" '"0"' + //@ is "$.index[?(@.name=='Addition')].inner.variant.discriminant.expr" '"{ _ }"' Addition = 0 + 0, - //@ is "$.index[*][?(@.name=='Bin')].inner.variant.discriminant.value" '"1"' - //@ is "$.index[*][?(@.name=='Bin')].inner.variant.discriminant.expr" '"0b1"' + //@ is "$.index[?(@.name=='Bin')].inner.variant.discriminant.value" '"1"' + //@ is "$.index[?(@.name=='Bin')].inner.variant.discriminant.expr" '"0b1"' Bin = 0b1, - //@ is "$.index[*][?(@.name=='Oct')].inner.variant.discriminant.value" '"2"' - //@ is "$.index[*][?(@.name=='Oct')].inner.variant.discriminant.expr" '"0o2"' + //@ is "$.index[?(@.name=='Oct')].inner.variant.discriminant.value" '"2"' + //@ is "$.index[?(@.name=='Oct')].inner.variant.discriminant.expr" '"0o2"' Oct = 0o2, - //@ is "$.index[*][?(@.name=='PubConst')].inner.variant.discriminant.value" '"3"' - //@ is "$.index[*][?(@.name=='PubConst')].inner.variant.discriminant.expr" '"THREE"' + //@ is "$.index[?(@.name=='PubConst')].inner.variant.discriminant.value" '"3"' + //@ is "$.index[?(@.name=='PubConst')].inner.variant.discriminant.expr" '"THREE"' PubConst = THREE, - //@ is "$.index[*][?(@.name=='Hex')].inner.variant.discriminant.value" '"4"' - //@ is "$.index[*][?(@.name=='Hex')].inner.variant.discriminant.expr" '"0x4"' + //@ is "$.index[?(@.name=='Hex')].inner.variant.discriminant.value" '"4"' + //@ is "$.index[?(@.name=='Hex')].inner.variant.discriminant.expr" '"0x4"' Hex = 0x4, - //@ is "$.index[*][?(@.name=='Cast')].inner.variant.discriminant.value" '"5"' - //@ is "$.index[*][?(@.name=='Cast')].inner.variant.discriminant.expr" '"{ _ }"' + //@ is "$.index[?(@.name=='Cast')].inner.variant.discriminant.value" '"5"' + //@ is "$.index[?(@.name=='Cast')].inner.variant.discriminant.expr" '"{ _ }"' Cast = 5 as isize, - //@ is "$.index[*][?(@.name=='PubCall')].inner.variant.discriminant.value" '"6"' - //@ is "$.index[*][?(@.name=='PubCall')].inner.variant.discriminant.expr" '"{ _ }"' + //@ is "$.index[?(@.name=='PubCall')].inner.variant.discriminant.value" '"6"' + //@ is "$.index[?(@.name=='PubCall')].inner.variant.discriminant.expr" '"{ _ }"' PubCall = six(), - //@ is "$.index[*][?(@.name=='PrivCall')].inner.variant.discriminant.value" '"7"' - //@ is "$.index[*][?(@.name=='PrivCall')].inner.variant.discriminant.expr" '"{ _ }"' + //@ is "$.index[?(@.name=='PrivCall')].inner.variant.discriminant.value" '"7"' + //@ is "$.index[?(@.name=='PrivCall')].inner.variant.discriminant.expr" '"{ _ }"' PrivCall = seven(), - //@ is "$.index[*][?(@.name=='PrivConst')].inner.variant.discriminant.value" '"8"' - //@ is "$.index[*][?(@.name=='PrivConst')].inner.variant.discriminant.expr" '"EIGHT"' + //@ is "$.index[?(@.name=='PrivConst')].inner.variant.discriminant.value" '"8"' + //@ is "$.index[?(@.name=='PrivConst')].inner.variant.discriminant.expr" '"EIGHT"' PrivConst = EIGHT, } diff --git a/tests/rustdoc-json/enums/discriminant/limits.rs b/tests/rustdoc-json/enums/discriminant/limits.rs index 7508490d666..c84181334e3 100644 --- a/tests/rustdoc-json/enums/discriminant/limits.rs +++ b/tests/rustdoc-json/enums/discriminant/limits.rs @@ -3,40 +3,40 @@ #[repr(u64)] pub enum U64 { - //@ is "$.index[*][?(@.name=='U64Min')].inner.variant.discriminant.value" '"0"' - //@ is "$.index[*][?(@.name=='U64Min')].inner.variant.discriminant.expr" '"u64::MIN"' + //@ is "$.index[?(@.name=='U64Min')].inner.variant.discriminant.value" '"0"' + //@ is "$.index[?(@.name=='U64Min')].inner.variant.discriminant.expr" '"u64::MIN"' U64Min = u64::MIN, - //@ is "$.index[*][?(@.name=='U64Max')].inner.variant.discriminant.value" '"18446744073709551615"' - //@ is "$.index[*][?(@.name=='U64Max')].inner.variant.discriminant.expr" '"u64::MAX"' + //@ is "$.index[?(@.name=='U64Max')].inner.variant.discriminant.value" '"18446744073709551615"' + //@ is "$.index[?(@.name=='U64Max')].inner.variant.discriminant.expr" '"u64::MAX"' U64Max = u64::MAX, } #[repr(i64)] pub enum I64 { - //@ is "$.index[*][?(@.name=='I64Min')].inner.variant.discriminant.value" '"-9223372036854775808"' - //@ is "$.index[*][?(@.name=='I64Min')].inner.variant.discriminant.expr" '"i64::MIN"' + //@ is "$.index[?(@.name=='I64Min')].inner.variant.discriminant.value" '"-9223372036854775808"' + //@ is "$.index[?(@.name=='I64Min')].inner.variant.discriminant.expr" '"i64::MIN"' I64Min = i64::MIN, - //@ is "$.index[*][?(@.name=='I64Max')].inner.variant.discriminant.value" '"9223372036854775807"' - //@ is "$.index[*][?(@.name=='I64Max')].inner.variant.discriminant.expr" '"i64::MAX"' + //@ is "$.index[?(@.name=='I64Max')].inner.variant.discriminant.value" '"9223372036854775807"' + //@ is "$.index[?(@.name=='I64Max')].inner.variant.discriminant.expr" '"i64::MAX"' I64Max = i64::MAX, } #[repr(u128)] pub enum U128 { - //@ is "$.index[*][?(@.name=='U128Min')].inner.variant.discriminant.value" '"0"' - //@ is "$.index[*][?(@.name=='U128Min')].inner.variant.discriminant.expr" '"u128::MIN"' + //@ is "$.index[?(@.name=='U128Min')].inner.variant.discriminant.value" '"0"' + //@ is "$.index[?(@.name=='U128Min')].inner.variant.discriminant.expr" '"u128::MIN"' U128Min = u128::MIN, - //@ is "$.index[*][?(@.name=='U128Max')].inner.variant.discriminant.value" '"340282366920938463463374607431768211455"' - //@ is "$.index[*][?(@.name=='U128Max')].inner.variant.discriminant.expr" '"u128::MAX"' + //@ is "$.index[?(@.name=='U128Max')].inner.variant.discriminant.value" '"340282366920938463463374607431768211455"' + //@ is "$.index[?(@.name=='U128Max')].inner.variant.discriminant.expr" '"u128::MAX"' U128Max = u128::MAX, } #[repr(i128)] pub enum I128 { - //@ is "$.index[*][?(@.name=='I128Min')].inner.variant.discriminant.value" '"-170141183460469231731687303715884105728"' - //@ is "$.index[*][?(@.name=='I128Min')].inner.variant.discriminant.expr" '"i128::MIN"' + //@ is "$.index[?(@.name=='I128Min')].inner.variant.discriminant.value" '"-170141183460469231731687303715884105728"' + //@ is "$.index[?(@.name=='I128Min')].inner.variant.discriminant.expr" '"i128::MIN"' I128Min = i128::MIN, - //@ is "$.index[*][?(@.name=='I128Max')].inner.variant.discriminant.value" '"170141183460469231731687303715884105727"' - //@ is "$.index[*][?(@.name=='I128Max')].inner.variant.discriminant.expr" '"i128::MAX"' + //@ is "$.index[?(@.name=='I128Max')].inner.variant.discriminant.value" '"170141183460469231731687303715884105727"' + //@ is "$.index[?(@.name=='I128Max')].inner.variant.discriminant.expr" '"i128::MAX"' I128Max = i128::MAX, } diff --git a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs index 6f66495bed2..acf58048d3a 100644 --- a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs +++ b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs @@ -1,15 +1,15 @@ #[repr(u32)] pub enum Foo { - //@ is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.value" '"0"' - //@ is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.expr" '"0"' + //@ is "$.index[?(@.name=='Basic')].inner.variant.discriminant.value" '"0"' + //@ is "$.index[?(@.name=='Basic')].inner.variant.discriminant.expr" '"0"' Basic = 0, - //@ is "$.index[*][?(@.name=='Suffix')].inner.variant.discriminant.value" '"10"' - //@ is "$.index[*][?(@.name=='Suffix')].inner.variant.discriminant.expr" '"10u32"' + //@ is "$.index[?(@.name=='Suffix')].inner.variant.discriminant.value" '"10"' + //@ is "$.index[?(@.name=='Suffix')].inner.variant.discriminant.expr" '"10u32"' Suffix = 10u32, - //@ is "$.index[*][?(@.name=='Underscore')].inner.variant.discriminant.value" '"100"' - //@ is "$.index[*][?(@.name=='Underscore')].inner.variant.discriminant.expr" '"1_0_0"' + //@ is "$.index[?(@.name=='Underscore')].inner.variant.discriminant.value" '"100"' + //@ is "$.index[?(@.name=='Underscore')].inner.variant.discriminant.expr" '"1_0_0"' Underscore = 1_0_0, - //@ is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant.discriminant.value" '"1000"' - //@ is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant.discriminant.expr" '"1_0_0_0u32"' + //@ is "$.index[?(@.name=='SuffixUnderscore')].inner.variant.discriminant.value" '"1000"' + //@ is "$.index[?(@.name=='SuffixUnderscore')].inner.variant.discriminant.expr" '"1_0_0_0u32"' SuffixUnderscore = 1_0_0_0u32, } diff --git a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs index 8e7985f07f4..d8b92cfabb3 100644 --- a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs +++ b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs @@ -1,10 +1,10 @@ pub enum Foo { - //@ is "$.index[*][?(@.name=='Has')].inner.variant.discriminant" '{"expr":"0", "value":"0"}' + //@ is "$.index[?(@.name=='Has')].inner.variant.discriminant" '{"expr":"0", "value":"0"}' Has = 0, - //@ is "$.index[*][?(@.name=='Doesnt')].inner.variant.discriminant" null + //@ is "$.index[?(@.name=='Doesnt')].inner.variant.discriminant" null Doesnt, - //@ is "$.index[*][?(@.name=='AlsoDoesnt')].inner.variant.discriminant" null + //@ is "$.index[?(@.name=='AlsoDoesnt')].inner.variant.discriminant" null AlsoDoesnt, - //@ is "$.index[*][?(@.name=='AlsoHas')].inner.variant.discriminant" '{"expr":"44", "value":"44"}' + //@ is "$.index[?(@.name=='AlsoHas')].inner.variant.discriminant" '{"expr":"44", "value":"44"}' AlsoHas = 44, } diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs index f2bed77902b..ea669e6a0b3 100644 --- a/tests/rustdoc-json/enums/discriminant/struct.rs +++ b/tests/rustdoc-json/enums/discriminant/struct.rs @@ -1,13 +1,13 @@ #[repr(i32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(SignedInt(I32))])]\n"]' +//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(i32)]"]' pub enum Foo { - //@ is "$.index[*][?(@.name=='Struct')].inner.variant.discriminant" null - //@ count "$.index[*][?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0 + //@ is "$.index[?(@.name=='Struct')].inner.variant.discriminant" null + //@ count "$.index[?(@.name=='Struct')].inner.variant.kind.struct.fields[*]" 0 Struct {}, - //@ is "$.index[*][?(@.name=='StructWithDiscr')].inner.variant.discriminant" '{"expr": "42", "value": "42"}' - //@ count "$.index[*][?(@.name=='StructWithDiscr')].inner.variant.kind.struct.fields[*]" 1 + //@ is "$.index[?(@.name=='StructWithDiscr')].inner.variant.discriminant" '{"expr": "42", "value": "42"}' + //@ count "$.index[?(@.name=='StructWithDiscr')].inner.variant.kind.struct.fields[*]" 1 StructWithDiscr { x: i32 } = 42, - //@ is "$.index[*][?(@.name=='StructWithHexDiscr')].inner.variant.discriminant" '{"expr": "0x42", "value": "66"}' - //@ count "$.index[*][?(@.name=='StructWithHexDiscr')].inner.variant.kind.struct.fields[*]" 2 + //@ is "$.index[?(@.name=='StructWithHexDiscr')].inner.variant.discriminant" '{"expr": "0x42", "value": "66"}' + //@ count "$.index[?(@.name=='StructWithHexDiscr')].inner.variant.kind.struct.fields[*]" 2 StructWithHexDiscr { x: i32, y: bool } = 0x42, } diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs index 201c1cdc88e..1b8e791eb23 100644 --- a/tests/rustdoc-json/enums/discriminant/tuple.rs +++ b/tests/rustdoc-json/enums/discriminant/tuple.rs @@ -1,13 +1,13 @@ #[repr(u32)] -//@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr = Repr([ReprInt(UnsignedInt(U32))])]\n"]' +//@ is "$.index[?(@.name=='Foo')].attrs" '["#[repr(u32)]"]' pub enum Foo { - //@ is "$.index[*][?(@.name=='Tuple')].inner.variant.discriminant" null - //@ count "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0 + //@ is "$.index[?(@.name=='Tuple')].inner.variant.discriminant" null + //@ count "$.index[?(@.name=='Tuple')].inner.variant.kind.tuple[*]" 0 Tuple(), - //@ is "$.index[*][?(@.name=='TupleWithDiscr')].inner.variant.discriminant" '{"expr": "1", "value": "1"}' - //@ count "$.index[*][?(@.name=='TupleWithDiscr')].inner.variant.kind.tuple[*]" 1 + //@ is "$.index[?(@.name=='TupleWithDiscr')].inner.variant.discriminant" '{"expr": "1", "value": "1"}' + //@ count "$.index[?(@.name=='TupleWithDiscr')].inner.variant.kind.tuple[*]" 1 TupleWithDiscr(i32) = 1, - //@ is "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.variant.discriminant" '{"expr": "0b10", "value": "2"}' - //@ count "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.variant.kind.tuple[*]" 2 + //@ is "$.index[?(@.name=='TupleWithBinDiscr')].inner.variant.discriminant" '{"expr": "0b10", "value": "2"}' + //@ count "$.index[?(@.name=='TupleWithBinDiscr')].inner.variant.kind.tuple[*]" 2 TupleWithBinDiscr(i32, i32) = 0b10, } diff --git a/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs b/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs index 6aec6960b5f..6ecd98fadf5 100644 --- a/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs +++ b/tests/rustdoc-json/enums/doc_link_to_foreign_variant.rs @@ -5,7 +5,7 @@ extern crate color; use color::Color::Red; -//@ set red = "$.index[*][?(@.inner.module.is_crate)].links.Red" +//@ set red = "$.index[?(@.inner.module.is_crate)].links.Red" -//@ !has "$.index[*][?(@.name == 'Red')]" -//@ !has "$.index[*][?(@.name == 'Color')]" +//@ !has "$.index[?(@.name == 'Red')]" +//@ !has "$.index[?(@.name == 'Color')]" diff --git a/tests/rustdoc-json/enums/field_hidden.rs b/tests/rustdoc-json/enums/field_hidden.rs index b353678ac92..07ee0e62ea9 100644 --- a/tests/rustdoc-json/enums/field_hidden.rs +++ b/tests/rustdoc-json/enums/field_hidden.rs @@ -1,9 +1,9 @@ // Regression test for <https://github.com/rust-lang/rust/issues/100529>. -//@ has "$.index[*][?(@.name=='ParseError')]" -//@ has "$.index[*][?(@.name=='UnexpectedEndTag')]" -//@ is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant.kind.tuple" [null] -//@ is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant.discriminant" null +//@ has "$.index[?(@.name=='ParseError')]" +//@ has "$.index[?(@.name=='UnexpectedEndTag')]" +//@ is "$.index[?(@.name=='UnexpectedEndTag')].inner.variant.kind.tuple" [null] +//@ is "$.index[?(@.name=='UnexpectedEndTag')].inner.variant.discriminant" null pub enum ParseError { UnexpectedEndTag(#[doc(hidden)] u32), diff --git a/tests/rustdoc-json/enums/field_order.rs b/tests/rustdoc-json/enums/field_order.rs index a78be200b41..e8560687954 100644 --- a/tests/rustdoc-json/enums/field_order.rs +++ b/tests/rustdoc-json/enums/field_order.rs @@ -17,24 +17,24 @@ pub enum Whatever { }, } -//@ set 0 = '$.index[*][?(@.name == "ews_0")].id' -//@ set 1 = '$.index[*][?(@.name == "dik_1")].id' -//@ set 2 = '$.index[*][?(@.name == "hsk_2")].id' -//@ set 3 = '$.index[*][?(@.name == "djt_3")].id' -//@ set 4 = '$.index[*][?(@.name == "jnr_4")].id' -//@ set 5 = '$.index[*][?(@.name == "dfs_5")].id' -//@ set 6 = '$.index[*][?(@.name == "bja_6")].id' -//@ set 7 = '$.index[*][?(@.name == "lyc_7")].id' -//@ set 8 = '$.index[*][?(@.name == "yqd_8")].id' -//@ set 9 = '$.index[*][?(@.name == "vll_9")].id' +//@ set 0 = '$.index[?(@.name == "ews_0")].id' +//@ set 1 = '$.index[?(@.name == "dik_1")].id' +//@ set 2 = '$.index[?(@.name == "hsk_2")].id' +//@ set 3 = '$.index[?(@.name == "djt_3")].id' +//@ set 4 = '$.index[?(@.name == "jnr_4")].id' +//@ set 5 = '$.index[?(@.name == "dfs_5")].id' +//@ set 6 = '$.index[?(@.name == "bja_6")].id' +//@ set 7 = '$.index[?(@.name == "lyc_7")].id' +//@ set 8 = '$.index[?(@.name == "yqd_8")].id' +//@ set 9 = '$.index[?(@.name == "vll_9")].id' -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[0]' $0 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[1]' $1 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[2]' $2 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[3]' $3 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[4]' $4 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[5]' $5 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[6]' $6 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[7]' $7 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[8]' $8 -//@ is '$.index[*][?(@.name == "Foo")].inner.variant.kind.struct.fields[9]' $9 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[0]' $0 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[1]' $1 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[2]' $2 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[3]' $3 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[4]' $4 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[5]' $5 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[6]' $6 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[7]' $7 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[8]' $8 +//@ is '$.index[?(@.name == "Foo")].inner.variant.kind.struct.fields[9]' $9 diff --git a/tests/rustdoc-json/enums/kind.rs b/tests/rustdoc-json/enums/kind.rs index 517a53828b7..3c011858630 100644 --- a/tests/rustdoc-json/enums/kind.rs +++ b/tests/rustdoc-json/enums/kind.rs @@ -1,27 +1,27 @@ pub enum Foo { - //@ set Unit = "$.index[*][?(@.name=='Unit')].id" - //@ is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"' + //@ set Unit = "$.index[?(@.name=='Unit')].id" + //@ is "$.index[?(@.name=='Unit')].inner.variant.kind" '"plain"' Unit, - //@ set Named = "$.index[*][?(@.name=='Named')].id" - //@ is "$.index[*][?(@.name=='Named')].inner.variant.kind.struct" '{"fields": [], "has_stripped_fields": false}' + //@ set Named = "$.index[?(@.name=='Named')].id" + //@ is "$.index[?(@.name=='Named')].inner.variant.kind.struct" '{"fields": [], "has_stripped_fields": false}' Named {}, - //@ set Tuple = "$.index[*][?(@.name=='Tuple')].id" - //@ is "$.index[*][?(@.name=='Tuple')].inner.variant.kind.tuple" [] + //@ set Tuple = "$.index[?(@.name=='Tuple')].id" + //@ is "$.index[?(@.name=='Tuple')].inner.variant.kind.tuple" [] Tuple(), - //@ set NamedField = "$.index[*][?(@.name=='NamedField')].id" - //@ set x = "$.index[*][?(@.name=='x' && @.inner.struct_field)].id" - //@ is "$.index[*][?(@.name=='NamedField')].inner.variant.kind.struct.fields[*]" $x - //@ is "$.index[*][?(@.name=='NamedField')].inner.variant.kind.struct.has_stripped_fields" false + //@ set NamedField = "$.index[?(@.name=='NamedField')].id" + //@ set x = "$.index[?(@.name=='x' && @.inner.struct_field)].id" + //@ is "$.index[?(@.name=='NamedField')].inner.variant.kind.struct.fields[*]" $x + //@ is "$.index[?(@.name=='NamedField')].inner.variant.kind.struct.has_stripped_fields" false NamedField { x: i32 }, - //@ set TupleField = "$.index[*][?(@.name=='TupleField')].id" - //@ set tup_field = "$.index[*][?(@.name=='0' && @.inner.struct_field)].id" - //@ is "$.index[*][?(@.name=='TupleField')].inner.variant.kind.tuple[*]" $tup_field + //@ set TupleField = "$.index[?(@.name=='TupleField')].id" + //@ set tup_field = "$.index[?(@.name=='0' && @.inner.struct_field)].id" + //@ is "$.index[?(@.name=='TupleField')].inner.variant.kind.tuple[*]" $tup_field TupleField(i32), } -//@ is "$.index[*][?(@.name=='Foo')].inner.enum.variants[0]" $Unit -//@ is "$.index[*][?(@.name=='Foo')].inner.enum.variants[1]" $Named -//@ is "$.index[*][?(@.name=='Foo')].inner.enum.variants[2]" $Tuple -//@ is "$.index[*][?(@.name=='Foo')].inner.enum.variants[3]" $NamedField -//@ is "$.index[*][?(@.name=='Foo')].inner.enum.variants[4]" $TupleField -//@ count "$.index[*][?(@.name=='Foo')].inner.enum.variants[*]" 5 +//@ is "$.index[?(@.name=='Foo')].inner.enum.variants[0]" $Unit +//@ is "$.index[?(@.name=='Foo')].inner.enum.variants[1]" $Named +//@ is "$.index[?(@.name=='Foo')].inner.enum.variants[2]" $Tuple +//@ is "$.index[?(@.name=='Foo')].inner.enum.variants[3]" $NamedField +//@ is "$.index[?(@.name=='Foo')].inner.enum.variants[4]" $TupleField +//@ count "$.index[?(@.name=='Foo')].inner.enum.variants[*]" 5 diff --git a/tests/rustdoc-json/enums/struct_field_hidden.rs b/tests/rustdoc-json/enums/struct_field_hidden.rs index 2184f58b1da..cd9d2ce0b8a 100644 --- a/tests/rustdoc-json/enums/struct_field_hidden.rs +++ b/tests/rustdoc-json/enums/struct_field_hidden.rs @@ -2,15 +2,15 @@ pub enum Foo { Variant { #[doc(hidden)] a: i32, - //@ set b = "$.index[*][?(@.name=='b')].id" + //@ set b = "$.index[?(@.name=='b')].id" b: i32, #[doc(hidden)] x: i32, - //@ set y = "$.index[*][?(@.name=='y')].id" + //@ set y = "$.index[?(@.name=='y')].id" y: i32, }, - //@ is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.has_stripped_fields" true - //@ is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[0]" $b - //@ is "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[1]" $y - //@ count "$.index[*][?(@.name=='Variant')].inner.variant.kind.struct.fields[*]" 2 + //@ is "$.index[?(@.name=='Variant')].inner.variant.kind.struct.has_stripped_fields" true + //@ is "$.index[?(@.name=='Variant')].inner.variant.kind.struct.fields[0]" $b + //@ is "$.index[?(@.name=='Variant')].inner.variant.kind.struct.fields[1]" $y + //@ count "$.index[?(@.name=='Variant')].inner.variant.kind.struct.fields[*]" 2 } diff --git a/tests/rustdoc-json/enums/tuple_fields_hidden.rs b/tests/rustdoc-json/enums/tuple_fields_hidden.rs index 3ac7a3ce0fc..aa25625b94c 100644 --- a/tests/rustdoc-json/enums/tuple_fields_hidden.rs +++ b/tests/rustdoc-json/enums/tuple_fields_hidden.rs @@ -1,80 +1,80 @@ -//@ set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id" -//@ set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id" -//@ set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id" -//@ set 2.2.1 = "$.index[*][?(@.docs=='2.2.1')].id" -//@ set 2.3.0 = "$.index[*][?(@.docs=='2.3.0')].id" -//@ set 3.1.1 = "$.index[*][?(@.docs=='3.1.1')].id" -//@ set 3.1.2 = "$.index[*][?(@.docs=='3.1.2')].id" -//@ set 3.2.0 = "$.index[*][?(@.docs=='3.2.0')].id" -//@ set 3.2.2 = "$.index[*][?(@.docs=='3.2.2')].id" -//@ set 3.3.0 = "$.index[*][?(@.docs=='3.3.0')].id" -//@ set 3.3.1 = "$.index[*][?(@.docs=='3.3.1')].id" +//@ set 1.1.0 = "$.index[?(@.docs=='1.1.0')].id" +//@ set 2.1.0 = "$.index[?(@.docs=='2.1.0')].id" +//@ set 2.1.1 = "$.index[?(@.docs=='2.1.1')].id" +//@ set 2.2.1 = "$.index[?(@.docs=='2.2.1')].id" +//@ set 2.3.0 = "$.index[?(@.docs=='2.3.0')].id" +//@ set 3.1.1 = "$.index[?(@.docs=='3.1.1')].id" +//@ set 3.1.2 = "$.index[?(@.docs=='3.1.2')].id" +//@ set 3.2.0 = "$.index[?(@.docs=='3.2.0')].id" +//@ set 3.2.2 = "$.index[?(@.docs=='3.2.2')].id" +//@ set 3.3.0 = "$.index[?(@.docs=='3.3.0')].id" +//@ set 3.3.1 = "$.index[?(@.docs=='3.3.1')].id" pub enum EnumWithStrippedTupleVariants { - //@ count "$.index[*][?(@.name=='None')].inner.variant.kind.tuple[*]" 0 + //@ count "$.index[?(@.name=='None')].inner.variant.kind.tuple[*]" 0 None(), - //@ count "$.index[*][?(@.name=='One')].inner.variant.kind.tuple[*]" 1 - //@ is "$.index[*][?(@.name=='One')].inner.variant.kind.tuple[0]" $1.1.0 + //@ count "$.index[?(@.name=='One')].inner.variant.kind.tuple[*]" 1 + //@ is "$.index[?(@.name=='One')].inner.variant.kind.tuple[0]" $1.1.0 One(/** 1.1.0*/ bool), - //@ count "$.index[*][?(@.name=='OneHidden')].inner.variant.kind.tuple[*]" 1 - //@ is "$.index[*][?(@.name=='OneHidden')].inner.variant.kind.tuple[0]" null + //@ count "$.index[?(@.name=='OneHidden')].inner.variant.kind.tuple[*]" 1 + //@ is "$.index[?(@.name=='OneHidden')].inner.variant.kind.tuple[0]" null OneHidden(#[doc(hidden)] bool), - //@ count "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[*]" 2 - //@ is "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[0]" $2.1.0 - //@ is "$.index[*][?(@.name=='Two')].inner.variant.kind.tuple[1]" $2.1.1 + //@ count "$.index[?(@.name=='Two')].inner.variant.kind.tuple[*]" 2 + //@ is "$.index[?(@.name=='Two')].inner.variant.kind.tuple[0]" $2.1.0 + //@ is "$.index[?(@.name=='Two')].inner.variant.kind.tuple[1]" $2.1.1 Two(/** 2.1.0*/ bool, /** 2.1.1*/ bool), - //@ count "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[*]" 2 - //@ is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[0]" null - //@ is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[1]" $2.2.1 + //@ count "$.index[?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[*]" 2 + //@ is "$.index[?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[0]" null + //@ is "$.index[?(@.name=='TwoLeftHidden')].inner.variant.kind.tuple[1]" $2.2.1 TwoLeftHidden(#[doc(hidden)] bool, /** 2.2.1*/ bool), - //@ count "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[*]" 2 - //@ is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[0]" $2.3.0 - //@ is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[1]" null + //@ count "$.index[?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[*]" 2 + //@ is "$.index[?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[0]" $2.3.0 + //@ is "$.index[?(@.name=='TwoRightHidden')].inner.variant.kind.tuple[1]" null TwoRightHidden(/** 2.3.0*/ bool, #[doc(hidden)] bool), - //@ count "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[*]" 2 - //@ is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[0]" null - //@ is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[1]" null + //@ count "$.index[?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[*]" 2 + //@ is "$.index[?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[0]" null + //@ is "$.index[?(@.name=='TwoBothHidden')].inner.variant.kind.tuple[1]" null TwoBothHidden(#[doc(hidden)] bool, #[doc(hidden)] bool), - //@ count "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[*]" 3 - //@ is "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[0]" null - //@ is "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[1]" $3.1.1 - //@ is "$.index[*][?(@.name=='Three1')].inner.variant.kind.tuple[2]" $3.1.2 + //@ count "$.index[?(@.name=='Three1')].inner.variant.kind.tuple[*]" 3 + //@ is "$.index[?(@.name=='Three1')].inner.variant.kind.tuple[0]" null + //@ is "$.index[?(@.name=='Three1')].inner.variant.kind.tuple[1]" $3.1.1 + //@ is "$.index[?(@.name=='Three1')].inner.variant.kind.tuple[2]" $3.1.2 Three1(#[doc(hidden)] bool, /** 3.1.1*/ bool, /** 3.1.2*/ bool), - //@ count "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[*]" 3 - //@ is "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[0]" $3.2.0 - //@ is "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[1]" null - //@ is "$.index[*][?(@.name=='Three2')].inner.variant.kind.tuple[2]" $3.2.2 + //@ count "$.index[?(@.name=='Three2')].inner.variant.kind.tuple[*]" 3 + //@ is "$.index[?(@.name=='Three2')].inner.variant.kind.tuple[0]" $3.2.0 + //@ is "$.index[?(@.name=='Three2')].inner.variant.kind.tuple[1]" null + //@ is "$.index[?(@.name=='Three2')].inner.variant.kind.tuple[2]" $3.2.2 Three2(/** 3.2.0*/ bool, #[doc(hidden)] bool, /** 3.2.2*/ bool), - //@ count "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[*]" 3 - //@ is "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[0]" $3.3.0 - //@ is "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[1]" $3.3.1 - //@ is "$.index[*][?(@.name=='Three3')].inner.variant.kind.tuple[2]" null + //@ count "$.index[?(@.name=='Three3')].inner.variant.kind.tuple[*]" 3 + //@ is "$.index[?(@.name=='Three3')].inner.variant.kind.tuple[0]" $3.3.0 + //@ is "$.index[?(@.name=='Three3')].inner.variant.kind.tuple[1]" $3.3.1 + //@ is "$.index[?(@.name=='Three3')].inner.variant.kind.tuple[2]" null Three3(/** 3.3.0*/ bool, /** 3.3.1*/ bool, #[doc(hidden)] bool), } -//@ is "$.index[*][?(@.docs=='1.1.0')].name" '"0"' -//@ is "$.index[*][?(@.docs=='2.1.0')].name" '"0"' -//@ is "$.index[*][?(@.docs=='2.1.1')].name" '"1"' -//@ is "$.index[*][?(@.docs=='2.2.1')].name" '"1"' -//@ is "$.index[*][?(@.docs=='2.3.0')].name" '"0"' -//@ is "$.index[*][?(@.docs=='3.1.1')].name" '"1"' -//@ is "$.index[*][?(@.docs=='3.1.2')].name" '"2"' -//@ is "$.index[*][?(@.docs=='3.2.0')].name" '"0"' -//@ is "$.index[*][?(@.docs=='3.2.2')].name" '"2"' -//@ is "$.index[*][?(@.docs=='3.3.0')].name" '"0"' -//@ is "$.index[*][?(@.docs=='3.3.1')].name" '"1"' +//@ is "$.index[?(@.docs=='1.1.0')].name" '"0"' +//@ is "$.index[?(@.docs=='2.1.0')].name" '"0"' +//@ is "$.index[?(@.docs=='2.1.1')].name" '"1"' +//@ is "$.index[?(@.docs=='2.2.1')].name" '"1"' +//@ is "$.index[?(@.docs=='2.3.0')].name" '"0"' +//@ is "$.index[?(@.docs=='3.1.1')].name" '"1"' +//@ is "$.index[?(@.docs=='3.1.2')].name" '"2"' +//@ is "$.index[?(@.docs=='3.2.0')].name" '"0"' +//@ is "$.index[?(@.docs=='3.2.2')].name" '"2"' +//@ is "$.index[?(@.docs=='3.3.0')].name" '"0"' +//@ is "$.index[?(@.docs=='3.3.1')].name" '"1"' -//@ is "$.index[*][?(@.docs=='1.1.0')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='2.1.0')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='2.1.1')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='2.2.1')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='2.3.0')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.1.1')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.1.2')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.2.0')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.2.2')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.3.0')].inner.struct_field" '{"primitive": "bool"}' -//@ is "$.index[*][?(@.docs=='3.3.1')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='1.1.0')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='2.1.0')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='2.1.1')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='2.2.1')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='2.3.0')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.1.1')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.1.2')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.2.0')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.2.2')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.3.0')].inner.struct_field" '{"primitive": "bool"}' +//@ is "$.index[?(@.docs=='3.3.1')].inner.struct_field" '{"primitive": "bool"}' diff --git a/tests/rustdoc-json/enums/use_glob.rs b/tests/rustdoc-json/enums/use_glob.rs index 2631b43da8e..18f21ff0903 100644 --- a/tests/rustdoc-json/enums/use_glob.rs +++ b/tests/rustdoc-json/enums/use_glob.rs @@ -1,15 +1,15 @@ // Regression test for <https://github.com/rust-lang/rust/issues/104942> -//@ set Color = "$.index[*][?(@.name == 'Color')].id" +//@ set Color = "$.index[?(@.name == 'Color')].id" pub enum Color { Red, Green, Blue, } -//@ set use_Color = "$.index[*][?(@.inner.use)].id" -//@ is "$.index[*][?(@.inner.use)].inner.use.id" $Color -//@ is "$.index[*][?(@.inner.use)].inner.use.is_glob" true +//@ set use_Color = "$.index[?(@.inner.use)].id" +//@ is "$.index[?(@.inner.use)].inner.use.id" $Color +//@ is "$.index[?(@.inner.use)].inner.use.is_glob" true pub use Color::*; -//@ ismany "$.index[*][?(@.name == 'use_glob')].inner.module.items[*]" $Color $use_Color +//@ ismany "$.index[?(@.name == 'use_glob')].inner.module.items[*]" $Color $use_Color diff --git a/tests/rustdoc-json/enums/use_variant.rs b/tests/rustdoc-json/enums/use_variant.rs index 6d3322e0ba9..26cca0743d9 100644 --- a/tests/rustdoc-json/enums/use_variant.rs +++ b/tests/rustdoc-json/enums/use_variant.rs @@ -1,12 +1,12 @@ -//@ set AlwaysNone = "$.index[*][?(@.name == 'AlwaysNone')].id" +//@ set AlwaysNone = "$.index[?(@.name == 'AlwaysNone')].id" pub enum AlwaysNone { - //@ set None = "$.index[*][?(@.name == 'None')].id" + //@ set None = "$.index[?(@.name == 'None')].id" None, } -//@ is "$.index[*][?(@.name == 'AlwaysNone')].inner.enum.variants[*]" $None +//@ is "$.index[?(@.name == 'AlwaysNone')].inner.enum.variants[*]" $None -//@ set use_None = "$.index[*][?(@.inner.use)].id" -//@ is "$.index[*][?(@.inner.use)].inner.use.id" $None +//@ set use_None = "$.index[?(@.inner.use)].id" +//@ is "$.index[?(@.inner.use)].inner.use.id" $None pub use AlwaysNone::None; -//@ ismany "$.index[*][?(@.name == 'use_variant')].inner.module.items[*]" $AlwaysNone $use_None +//@ ismany "$.index[?(@.name == 'use_variant')].inner.module.items[*]" $AlwaysNone $use_None diff --git a/tests/rustdoc-json/enums/use_variant_foreign.rs b/tests/rustdoc-json/enums/use_variant_foreign.rs index a9ad61b9fe3..14e07b4123e 100644 --- a/tests/rustdoc-json/enums/use_variant_foreign.rs +++ b/tests/rustdoc-json/enums/use_variant_foreign.rs @@ -2,8 +2,8 @@ extern crate color; -//@ has "$.index[*].inner.use[?(@.name == 'Red')]" +//@ has "$.index[?(@.inner.use.name == 'Red')]" pub use color::Color::Red; -//@ !has "$.index[*][?(@.name == 'Red')]" -//@ !has "$.index[*][?(@.name == 'Color')]" +//@ !has "$.index[?(@.name == 'Red')]" +//@ !has "$.index[?(@.name == 'Color')]" diff --git a/tests/rustdoc-json/enums/variant_order.rs b/tests/rustdoc-json/enums/variant_order.rs index 6ebe28c94ca..dd11c0963ee 100644 --- a/tests/rustdoc-json/enums/variant_order.rs +++ b/tests/rustdoc-json/enums/variant_order.rs @@ -15,24 +15,24 @@ pub enum Foo { Vll9, } -//@ set 0 = '$.index[*][?(@.name == "Ews0")].id' -//@ set 1 = '$.index[*][?(@.name == "Dik1")].id' -//@ set 2 = '$.index[*][?(@.name == "Hsk2")].id' -//@ set 3 = '$.index[*][?(@.name == "Djt3")].id' -//@ set 4 = '$.index[*][?(@.name == "Jnr4")].id' -//@ set 5 = '$.index[*][?(@.name == "Dfs5")].id' -//@ set 6 = '$.index[*][?(@.name == "Bja6")].id' -//@ set 7 = '$.index[*][?(@.name == "Lyc7")].id' -//@ set 8 = '$.index[*][?(@.name == "Yqd8")].id' -//@ set 9 = '$.index[*][?(@.name == "Vll9")].id' +//@ set 0 = '$.index[?(@.name == "Ews0")].id' +//@ set 1 = '$.index[?(@.name == "Dik1")].id' +//@ set 2 = '$.index[?(@.name == "Hsk2")].id' +//@ set 3 = '$.index[?(@.name == "Djt3")].id' +//@ set 4 = '$.index[?(@.name == "Jnr4")].id' +//@ set 5 = '$.index[?(@.name == "Dfs5")].id' +//@ set 6 = '$.index[?(@.name == "Bja6")].id' +//@ set 7 = '$.index[?(@.name == "Lyc7")].id' +//@ set 8 = '$.index[?(@.name == "Yqd8")].id' +//@ set 9 = '$.index[?(@.name == "Vll9")].id' -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[0]' $0 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[1]' $1 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[2]' $2 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[3]' $3 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[4]' $4 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[5]' $5 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[6]' $6 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[7]' $7 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[8]' $8 -//@ is '$.index[*][?(@.name == "Foo")].inner.enum.variants[9]' $9 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[0]' $0 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[1]' $1 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[2]' $2 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[3]' $3 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[4]' $4 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[5]' $5 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[6]' $6 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[7]' $7 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[8]' $8 +//@ is '$.index[?(@.name == "Foo")].inner.enum.variants[9]' $9 diff --git a/tests/rustdoc-json/enums/variant_struct.rs b/tests/rustdoc-json/enums/variant_struct.rs index 44a0c946711..730689c8afa 100644 --- a/tests/rustdoc-json/enums/variant_struct.rs +++ b/tests/rustdoc-json/enums/variant_struct.rs @@ -1,10 +1,10 @@ -//@ is "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='EnumStruct')].inner.enum" +//@ is "$.index[?(@.name=='EnumStruct')].visibility" \"public\" +//@ has "$.index[?(@.name=='EnumStruct')].inner.enum" pub enum EnumStruct { - //@ has "$.index[*][?(@.name=='x')].inner.struct_field" - //@ set x = "$.index[*][?(@.name=='x')].id" - //@ has "$.index[*][?(@.name=='y')].inner.struct_field" - //@ set y = "$.index[*][?(@.name=='y')].id" - //@ ismany "$.index[*][?(@.name=='VariantS')].inner.variant.kind.struct.fields[*]" $x $y + //@ has "$.index[?(@.name=='x')].inner.struct_field" + //@ set x = "$.index[?(@.name=='x')].id" + //@ has "$.index[?(@.name=='y')].inner.struct_field" + //@ set y = "$.index[?(@.name=='y')].id" + //@ ismany "$.index[?(@.name=='VariantS')].inner.variant.kind.struct.fields[*]" $x $y VariantS { x: u32, y: String }, } diff --git a/tests/rustdoc-json/enums/variant_tuple_struct.rs b/tests/rustdoc-json/enums/variant_tuple_struct.rs index 04f0cbb40c4..0fc06920e4b 100644 --- a/tests/rustdoc-json/enums/variant_tuple_struct.rs +++ b/tests/rustdoc-json/enums/variant_tuple_struct.rs @@ -1,10 +1,10 @@ -//@ is "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='EnumTupleStruct')].inner.enum" +//@ is "$.index[?(@.name=='EnumTupleStruct')].visibility" \"public\" +//@ has "$.index[?(@.name=='EnumTupleStruct')].inner.enum" pub enum EnumTupleStruct { - //@ has "$.index[*][?(@.name=='0')].inner.struct_field" - //@ set f0 = "$.index[*][?(@.name=='0')].id" - //@ has "$.index[*][?(@.name=='1')].inner.struct_field" - //@ set f1 = "$.index[*][?(@.name=='1')].id" - //@ ismany "$.index[*][?(@.name=='VariantA')].inner.variant.kind.tuple[*]" $f0 $f1 + //@ has "$.index[?(@.name=='0')].inner.struct_field" + //@ set f0 = "$.index[?(@.name=='0')].id" + //@ has "$.index[?(@.name=='1')].inner.struct_field" + //@ set f1 = "$.index[?(@.name=='1')].id" + //@ ismany "$.index[?(@.name=='VariantA')].inner.variant.kind.tuple[*]" $f0 $f1 VariantA(u32, String), } diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs index 13a967bd35e..34150c0fe89 100644 --- a/tests/rustdoc-json/fn_pointer/abi.rs +++ b/tests/rustdoc-json/fn_pointer/abi.rs @@ -1,22 +1,22 @@ #![feature(abi_vectorcall)] -//@ is "$.index[*][?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\" +//@ is "$.index[?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\" pub type AbiRust = fn(); -//@ is "$.index[*][?(@.name=='AbiC')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": false}}' +//@ is "$.index[?(@.name=='AbiC')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": false}}' pub type AbiC = extern "C" fn(); -//@ is "$.index[*][?(@.name=='AbiSystem')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": false}}' +//@ is "$.index[?(@.name=='AbiSystem')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": false}}' pub type AbiSystem = extern "system" fn(); -//@ is "$.index[*][?(@.name=='AbiCUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": true}}' +//@ is "$.index[?(@.name=='AbiCUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"C": {"unwind": true}}' pub type AbiCUnwind = extern "C-unwind" fn(); -//@ is "$.index[*][?(@.name=='AbiSystemUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": true}}' +//@ is "$.index[?(@.name=='AbiSystemUnwind')].inner.type_alias.type.function_pointer.header.abi" '{"System": {"unwind": true}}' pub type AbiSystemUnwind = extern "system-unwind" fn(); -//@ is "$.index[*][?(@.name=='AbiVecorcall')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall\""' +//@ is "$.index[?(@.name=='AbiVecorcall')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall\""' pub type AbiVecorcall = extern "vectorcall" fn(); -//@ is "$.index[*][?(@.name=='AbiVecorcallUnwind')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""' +//@ is "$.index[?(@.name=='AbiVecorcallUnwind')].inner.type_alias.type.function_pointer.header.abi.Other" '"\"vectorcall-unwind\""' pub type AbiVecorcallUnwind = extern "vectorcall-unwind" fn(); diff --git a/tests/rustdoc-json/fn_pointer/generics.rs b/tests/rustdoc-json/fn_pointer/generics.rs index c974b472297..960b91e7d8e 100644 --- a/tests/rustdoc-json/fn_pointer/generics.rs +++ b/tests/rustdoc-json/fn_pointer/generics.rs @@ -1,8 +1,8 @@ -//@ count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][0]" '"val"' -//@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][1].borrowed_ref.lifetime" \"\'c\" -//@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.output.primitive" \"i32\" -//@ count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[*]" 1 -//@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[0].name" \"\'c\" -//@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' +//@ count "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][0]" '"val"' +//@ is "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][1].borrowed_ref.lifetime" \"\'c\" +//@ is "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.output.primitive" \"i32\" +//@ count "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[*]" 1 +//@ is "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[0].name" \"\'c\" +//@ is "$.index[?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' pub type WithHigherRankTraitBounds = for<'c> fn(val: &'c i32) -> i32; diff --git a/tests/rustdoc-json/fn_pointer/qualifiers.rs b/tests/rustdoc-json/fn_pointer/qualifiers.rs index 398e31f72db..769749d0dd4 100644 --- a/tests/rustdoc-json/fn_pointer/qualifiers.rs +++ b/tests/rustdoc-json/fn_pointer/qualifiers.rs @@ -1,9 +1,9 @@ -//@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_unsafe" false -//@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_const" false -//@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_async" false +//@ is "$.index[?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_unsafe" false +//@ is "$.index[?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_const" false +//@ is "$.index[?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_async" false pub type FnPointer = fn(); -//@ is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_unsafe" true -//@ is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_const" false -//@ is "$.index[*][?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_async" false +//@ is "$.index[?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_unsafe" true +//@ is "$.index[?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_const" false +//@ is "$.index[?(@.name=='UnsafePointer')].inner.type_alias.type.function_pointer.header.is_async" false pub type UnsafePointer = unsafe fn(); diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs index 68957f79952..7277bb1f59a 100644 --- a/tests/rustdoc-json/fns/abi.rs +++ b/tests/rustdoc-json/fns/abi.rs @@ -1,22 +1,22 @@ #![feature(abi_vectorcall)] -//@ is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" +//@ is "$.index[?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" pub fn abi_rust() {} -//@ is "$.index[*][?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' +//@ is "$.index[?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' pub extern "C" fn abi_c() {} -//@ is "$.index[*][?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' +//@ is "$.index[?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' pub extern "system" fn abi_system() {} -//@ is "$.index[*][?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' +//@ is "$.index[?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' pub extern "C-unwind" fn abi_c_unwind() {} -//@ is "$.index[*][?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' +//@ is "$.index[?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' pub extern "system-unwind" fn abi_system_unwind() {} -//@ is "$.index[*][?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' +//@ is "$.index[?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' pub extern "vectorcall" fn abi_vectorcall() {} -//@ is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' +//@ is "$.index[?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {} diff --git a/tests/rustdoc-json/fns/async_return.rs b/tests/rustdoc-json/fns/async_return.rs index ddfd4ccf90d..e7c6a2981ac 100644 --- a/tests/rustdoc-json/fns/async_return.rs +++ b/tests/rustdoc-json/fns/async_return.rs @@ -4,30 +4,30 @@ use std::future::Future; -//@ is "$.index[*][?(@.name=='get_int')].inner.function.sig.output.primitive" \"i32\" -//@ is "$.index[*][?(@.name=='get_int')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='get_int')].inner.function.sig.output.primitive" \"i32\" +//@ is "$.index[?(@.name=='get_int')].inner.function.header.is_async" false pub fn get_int() -> i32 { 42 } -//@ is "$.index[*][?(@.name=='get_int_async')].inner.function.sig.output.primitive" \"i32\" -//@ is "$.index[*][?(@.name=='get_int_async')].inner.function.header.is_async" true +//@ is "$.index[?(@.name=='get_int_async')].inner.function.sig.output.primitive" \"i32\" +//@ is "$.index[?(@.name=='get_int_async')].inner.function.header.is_async" true pub async fn get_int_async() -> i32 { 42 } -//@ is "$.index[*][?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.path" '"Future"' -//@ is "$.index[*][?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name" '"Output"' -//@ is "$.index[*][?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive" \"i32\" -//@ is "$.index[*][?(@.name=='get_int_future')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.path" '"Future"' +//@ is "$.index[?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name" '"Output"' +//@ is "$.index[?(@.name=='get_int_future')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive" \"i32\" +//@ is "$.index[?(@.name=='get_int_future')].inner.function.header.is_async" false pub fn get_int_future() -> impl Future<Output = i32> { async { 42 } } -//@ is "$.index[*][?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.path" '"Future"' -//@ is "$.index[*][?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name" '"Output"' -//@ is "$.index[*][?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive" \"i32\" -//@ is "$.index[*][?(@.name=='get_int_future_async')].inner.function.header.is_async" true +//@ is "$.index[?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.path" '"Future"' +//@ is "$.index[?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name" '"Output"' +//@ is "$.index[?(@.name=='get_int_future_async')].inner.function.sig.output.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive" \"i32\" +//@ is "$.index[?(@.name=='get_int_future_async')].inner.function.header.is_async" true pub async fn get_int_future_async() -> impl Future<Output = i32> { async { 42 } } diff --git a/tests/rustdoc-json/fns/extern_c_variadic.rs b/tests/rustdoc-json/fns/extern_c_variadic.rs index 8e9085640e0..d90bb83d98f 100644 --- a/tests/rustdoc-json/fns/extern_c_variadic.rs +++ b/tests/rustdoc-json/fns/extern_c_variadic.rs @@ -1,6 +1,6 @@ extern "C" { - //@ is "$.index[*][?(@.name == 'not_variadic')].inner.function.sig.is_c_variadic" false + //@ is "$.index[?(@.name == 'not_variadic')].inner.function.sig.is_c_variadic" false pub fn not_variadic(_: i32); - //@ is "$.index[*][?(@.name == 'variadic')].inner.function.sig.is_c_variadic" true + //@ is "$.index[?(@.name == 'variadic')].inner.function.sig.is_c_variadic" true pub fn variadic(_: i32, ...); } diff --git a/tests/rustdoc-json/fns/extern_safe.rs b/tests/rustdoc-json/fns/extern_safe.rs index b00f9f50bd2..bc217ae914c 100644 --- a/tests/rustdoc-json/fns/extern_safe.rs +++ b/tests/rustdoc-json/fns/extern_safe.rs @@ -1,17 +1,17 @@ extern "C" { - //@ is "$.index[*][?(@.name=='f1')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='f1')].inner.function.header.is_unsafe" true pub fn f1(); // items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers } unsafe extern "C" { - //@ is "$.index[*][?(@.name=='f4')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='f4')].inner.function.header.is_unsafe" true pub fn f4(); - //@ is "$.index[*][?(@.name=='f5')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='f5')].inner.function.header.is_unsafe" true pub unsafe fn f5(); - //@ is "$.index[*][?(@.name=='f6')].inner.function.header.is_unsafe" false + //@ is "$.index[?(@.name=='f6')].inner.function.header.is_unsafe" false pub safe fn f6(); } diff --git a/tests/rustdoc-json/fns/generic_args.rs b/tests/rustdoc-json/fns/generic_args.rs index 6a7124976f8..2ea68173d68 100644 --- a/tests/rustdoc-json/fns/generic_args.rs +++ b/tests/rustdoc-json/fns/generic_args.rs @@ -1,58 +1,58 @@ -//@ set foo = "$.index[*][?(@.name=='Foo')].id" +//@ set foo = "$.index[?(@.name=='Foo')].id" pub trait Foo {} -//@ set generic_foo = "$.index[*][?(@.name=='GenericFoo')].id" +//@ set generic_foo = "$.index[?(@.name=='GenericFoo')].id" pub trait GenericFoo<'a> {} -//@ is "$.index[*][?(@.name=='generics')].inner.function.generics.where_predicates" "[]" -//@ count "$.index[*][?(@.name=='generics')].inner.function.generics.params[*]" 1 -//@ is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].name" '"F"' -//@ is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.default" 'null' -//@ count "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo' -//@ count "$.index[*][?(@.name=='generics')].inner.function.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='generics')].inner.function.sig.inputs[0][0]" '"f"' -//@ is "$.index[*][?(@.name=='generics')].inner.function.sig.inputs[0][1].generic" '"F"' +//@ is "$.index[?(@.name=='generics')].inner.function.generics.where_predicates" "[]" +//@ count "$.index[?(@.name=='generics')].inner.function.generics.params[*]" 1 +//@ is "$.index[?(@.name=='generics')].inner.function.generics.params[0].name" '"F"' +//@ is "$.index[?(@.name=='generics')].inner.function.generics.params[0].kind.type.default" 'null' +//@ count "$.index[?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[*]" 1 +//@ is "$.index[?(@.name=='generics')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" '$foo' +//@ count "$.index[?(@.name=='generics')].inner.function.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='generics')].inner.function.sig.inputs[0][0]" '"f"' +//@ is "$.index[?(@.name=='generics')].inner.function.sig.inputs[0][1].generic" '"F"' pub fn generics<F: Foo>(f: F) {} -//@ is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.where_predicates" "[]" -//@ count "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[*]" 1 -//@ is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[0].name" '"impl Foo"' -//@ is "$.index[*][?(@.name=='impl_trait')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo -//@ count "$.index[*][?(@.name=='impl_trait')].inner.function.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='impl_trait')].inner.function.sig.inputs[0][0]" '"f"' -//@ count "$.index[*][?(@.name=='impl_trait')].inner.function.sig.inputs[0][1].impl_trait[*]" 1 -//@ is "$.index[*][?(@.name=='impl_trait')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $foo +//@ is "$.index[?(@.name=='impl_trait')].inner.function.generics.where_predicates" "[]" +//@ count "$.index[?(@.name=='impl_trait')].inner.function.generics.params[*]" 1 +//@ is "$.index[?(@.name=='impl_trait')].inner.function.generics.params[0].name" '"impl Foo"' +//@ is "$.index[?(@.name=='impl_trait')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $foo +//@ count "$.index[?(@.name=='impl_trait')].inner.function.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='impl_trait')].inner.function.sig.inputs[0][0]" '"f"' +//@ count "$.index[?(@.name=='impl_trait')].inner.function.sig.inputs[0][1].impl_trait[*]" 1 +//@ is "$.index[?(@.name=='impl_trait')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $foo pub fn impl_trait(f: impl Foo) {} -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[*]" 3 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[0].name" '"F"' -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "is_synthetic": false}}' -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.sig.inputs[*]" 3 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.sig.inputs[0][0]" '"f"' -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.sig.inputs[0][1].generic" '"F"' -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[*]" 3 +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.params[*]" 3 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.params[0].name" '"F"' +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.params[0].kind" '{"type": {"bounds": [], "default": null, "is_synthetic": false}}' +//@ count "$.index[?(@.name=='where_clase')].inner.function.sig.inputs[*]" 3 +//@ is "$.index[?(@.name=='where_clase')].inner.function.sig.inputs[0][0]" '"f"' +//@ is "$.index[?(@.name=='where_clase')].inner.function.sig.inputs[0][1].generic" '"F"' +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[*]" 3 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.type.generic" \"F\" -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.type.generic" \"F\" +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]" 1 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].trait_bound.trait.id" $foo -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.type.generic" \"G\" -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\" -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind.lifetime.outlives" "[]" -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.generic_params" "[]" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.type.generic" \"G\" +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[*]" 1 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.trait.id" $generic_foo +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[*]" 1 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].name" \"\'a\" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.bounds[0].trait_bound.generic_params[0].kind.lifetime.outlives" "[]" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[1].bound_predicate.generic_params" "[]" -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.lifetime" \"\'b\" -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.type.generic" \"H\" -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]" -//@ count "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[*]" 1 -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\" -//@ is "$.index[*][?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].kind.lifetime.outlives" "[]" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.lifetime" \"\'b\" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.type.borrowed_ref.type.generic" \"H\" +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[*]" 1 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.trait.id" $foo +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.bounds[0].trait_bound.generic_params" "[]" +//@ count "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[*]" 1 +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].name" \"\'b\" +//@ is "$.index[?(@.name=='where_clase')].inner.function.generics.where_predicates[2].bound_predicate.generic_params[0].kind.lifetime.outlives" "[]" pub fn where_clase<F, G, H>(f: F, g: G, h: H) where F: Foo, diff --git a/tests/rustdoc-json/fns/generic_returns.rs b/tests/rustdoc-json/fns/generic_returns.rs index 90e17525c44..a0d4c745599 100644 --- a/tests/rustdoc-json/fns/generic_returns.rs +++ b/tests/rustdoc-json/fns/generic_returns.rs @@ -1,11 +1,11 @@ -//@ count "$.index[*][?(@.name=='generic_returns')].inner.module.items[*]" 2 +//@ count "$.index[?(@.name=='generic_returns')].inner.module.items[*]" 2 -//@ set foo = "$.index[*][?(@.name=='Foo')].id" +//@ set foo = "$.index[?(@.name=='Foo')].id" pub trait Foo {} -//@ is "$.index[*][?(@.name=='get_foo')].inner.function.sig.inputs" [] -//@ count "$.index[*][?(@.name=='get_foo')].inner.function.sig.output.impl_trait[*]" 1 -//@ is "$.index[*][?(@.name=='get_foo')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $foo +//@ is "$.index[?(@.name=='get_foo')].inner.function.sig.inputs" [] +//@ count "$.index[?(@.name=='get_foo')].inner.function.sig.output.impl_trait[*]" 1 +//@ is "$.index[?(@.name=='get_foo')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $foo pub fn get_foo() -> impl Foo { Fooer {} } diff --git a/tests/rustdoc-json/fns/generics.rs b/tests/rustdoc-json/fns/generics.rs index b953094b5de..3efd917309a 100644 --- a/tests/rustdoc-json/fns/generics.rs +++ b/tests/rustdoc-json/fns/generics.rs @@ -1,20 +1,20 @@ -//@ set wham_id = "$.index[*][?(@.name=='Wham')].id" +//@ set wham_id = "$.index[?(@.name=='Wham')].id" pub trait Wham {} -//@ is "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.where_predicates" [] -//@ count "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[*]" 1 -//@ is "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].name" '"T"' -//@ is "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.is_synthetic" false -//@ is "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id -//@ is "$.index[*][?(@.name=='one_generic_param_fn')].inner.function.sig.inputs" '[["w", {"generic": "T"}]]' +//@ is "$.index[?(@.name=='one_generic_param_fn')].inner.function.generics.where_predicates" [] +//@ count "$.index[?(@.name=='one_generic_param_fn')].inner.function.generics.params[*]" 1 +//@ is "$.index[?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].name" '"T"' +//@ is "$.index[?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.is_synthetic" false +//@ is "$.index[?(@.name=='one_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id +//@ is "$.index[?(@.name=='one_generic_param_fn')].inner.function.sig.inputs" '[["w", {"generic": "T"}]]' pub fn one_generic_param_fn<T: Wham>(w: T) {} -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.where_predicates" [] -//@ count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[*]" 1 -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].name" '"impl Wham"' -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.is_synthetic" true -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id -//@ count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[0][0]" '"w"' -//@ is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $wham_id +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.where_predicates" [] +//@ count "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[*]" 1 +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].name" '"impl Wham"' +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.is_synthetic" true +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id +//@ count "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[0][0]" '"w"' +//@ is "$.index[?(@.name=='one_synthetic_generic_param_fn')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $wham_id pub fn one_synthetic_generic_param_fn(w: impl Wham) {} diff --git a/tests/rustdoc-json/fns/pattern_arg.rs b/tests/rustdoc-json/fns/pattern_arg.rs index d2a00f47438..059318a4295 100644 --- a/tests/rustdoc-json/fns/pattern_arg.rs +++ b/tests/rustdoc-json/fns/pattern_arg.rs @@ -1,7 +1,7 @@ -//@ is "$.index[*][?(@.name=='fst')].inner.function.sig.inputs[0][0]" '"(x, _)"' +//@ is "$.index[?(@.name=='fst')].inner.function.sig.inputs[0][0]" '"(x, _)"' pub fn fst<X, Y>((x, _): (X, Y)) -> X { x } -//@ is "$.index[*][?(@.name=='drop_int')].inner.function.sig.inputs[0][0]" '"_"' +//@ is "$.index[?(@.name=='drop_int')].inner.function.sig.inputs[0][0]" '"_"' pub fn drop_int(_: i32) {} diff --git a/tests/rustdoc-json/fns/qualifiers.rs b/tests/rustdoc-json/fns/qualifiers.rs index 67e49f0780a..7d93a3bf243 100644 --- a/tests/rustdoc-json/fns/qualifiers.rs +++ b/tests/rustdoc-json/fns/qualifiers.rs @@ -1,33 +1,33 @@ //@ edition:2018 -//@ is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.is_async" false -//@ is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.is_const" false -//@ is "$.index[*][?(@.name=='nothing_fn')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='nothing_fn')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='nothing_fn')].inner.function.header.is_const" false +//@ is "$.index[?(@.name=='nothing_fn')].inner.function.header.is_unsafe" false pub fn nothing_fn() {} -//@ is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.is_async" false -//@ is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.is_const" false -//@ is "$.index[*][?(@.name=='unsafe_fn')].inner.function.header.is_unsafe" true +//@ is "$.index[?(@.name=='unsafe_fn')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='unsafe_fn')].inner.function.header.is_const" false +//@ is "$.index[?(@.name=='unsafe_fn')].inner.function.header.is_unsafe" true pub unsafe fn unsafe_fn() {} -//@ is "$.index[*][?(@.name=='const_fn')].inner.function.header.is_async" false -//@ is "$.index[*][?(@.name=='const_fn')].inner.function.header.is_const" true -//@ is "$.index[*][?(@.name=='const_fn')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='const_fn')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='const_fn')].inner.function.header.is_const" true +//@ is "$.index[?(@.name=='const_fn')].inner.function.header.is_unsafe" false pub const fn const_fn() {} -//@ is "$.index[*][?(@.name=='async_fn')].inner.function.header.is_async" true -//@ is "$.index[*][?(@.name=='async_fn')].inner.function.header.is_const" false -//@ is "$.index[*][?(@.name=='async_fn')].inner.function.header.is_unsafe" false +//@ is "$.index[?(@.name=='async_fn')].inner.function.header.is_async" true +//@ is "$.index[?(@.name=='async_fn')].inner.function.header.is_const" false +//@ is "$.index[?(@.name=='async_fn')].inner.function.header.is_unsafe" false pub async fn async_fn() {} -//@ is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.is_async" true -//@ is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.is_const" false -//@ is "$.index[*][?(@.name=='async_unsafe_fn')].inner.function.header.is_unsafe" true +//@ is "$.index[?(@.name=='async_unsafe_fn')].inner.function.header.is_async" true +//@ is "$.index[?(@.name=='async_unsafe_fn')].inner.function.header.is_const" false +//@ is "$.index[?(@.name=='async_unsafe_fn')].inner.function.header.is_unsafe" true pub async unsafe fn async_unsafe_fn() {} -//@ is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.is_async" false -//@ is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.is_const" true -//@ is "$.index[*][?(@.name=='const_unsafe_fn')].inner.function.header.is_unsafe" true +//@ is "$.index[?(@.name=='const_unsafe_fn')].inner.function.header.is_async" false +//@ is "$.index[?(@.name=='const_unsafe_fn')].inner.function.header.is_const" true +//@ is "$.index[?(@.name=='const_unsafe_fn')].inner.function.header.is_unsafe" true pub const unsafe fn const_unsafe_fn() {} // It's impossible for a function to be both const and async, so no test for that diff --git a/tests/rustdoc-json/fns/return_type_alias.rs b/tests/rustdoc-json/fns/return_type_alias.rs index d60c4b68258..0aa1db47b7f 100644 --- a/tests/rustdoc-json/fns/return_type_alias.rs +++ b/tests/rustdoc-json/fns/return_type_alias.rs @@ -1,9 +1,9 @@ // Regression test for <https://github.com/rust-lang/rust/issues/104851> -///@ set foo = "$.index[*][?(@.name=='Foo')].id" +///@ set foo = "$.index[?(@.name=='Foo')].id" pub type Foo = i32; -//@ is "$.index[*][?(@.name=='demo')].inner.function.sig.output.resolved_path.id" $foo +//@ is "$.index[?(@.name=='demo')].inner.function.sig.output.resolved_path.id" $foo pub fn demo() -> Foo { 42 } diff --git a/tests/rustdoc-json/generic-associated-types/gats.rs b/tests/rustdoc-json/generic-associated-types/gats.rs index d1172b35fda..5218cc886e3 100644 --- a/tests/rustdoc-json/generic-associated-types/gats.rs +++ b/tests/rustdoc-json/generic-associated-types/gats.rs @@ -1,32 +1,32 @@ pub trait Display {} pub trait LendingIterator { - //@ count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.params[*]" 1 - //@ is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.params[*].name" \"\'a\" - //@ count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*]" 1 - //@ is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.type.generic" \"Self\" - //@ is "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\" - //@ count "$.index[*][?(@.name=='LendingItem')].inner.assoc_type.bounds[*]" 1 + //@ count "$.index[?(@.name=='LendingItem')].inner.assoc_type.generics.params[*]" 1 + //@ is "$.index[?(@.name=='LendingItem')].inner.assoc_type.generics.params[*].name" \"\'a\" + //@ count "$.index[?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*]" 1 + //@ is "$.index[?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.type.generic" \"Self\" + //@ is "$.index[?(@.name=='LendingItem')].inner.assoc_type.generics.where_predicates[*].bound_predicate.bounds[*].outlives" \"\'a\" + //@ count "$.index[?(@.name=='LendingItem')].inner.assoc_type.bounds[*]" 1 type LendingItem<'a>: Display where Self: 'a; - //@ count "$.index[*][?(@.name=='lending_next')].inner.function.sig.output.qualified_path.args.angle_bracketed.args[*]" 1 - //@ count "$.index[*][?(@.name=='lending_next')].inner.function.sig.output.qualified_path.args.angle_bracketed.bindings[*]" 0 - //@ is "$.index[*][?(@.name=='lending_next')].inner.function.sig.output.qualified_path.self_type.generic" \"Self\" - //@ is "$.index[*][?(@.name=='lending_next')].inner.function.sig.output.qualified_path.name" \"LendingItem\" + //@ count "$.index[?(@.name=='lending_next')].inner.function.sig.output.qualified_path.args.angle_bracketed.args[*]" 1 + //@ count "$.index[?(@.name=='lending_next')].inner.function.sig.output.qualified_path.args.angle_bracketed.bindings[*]" 0 + //@ is "$.index[?(@.name=='lending_next')].inner.function.sig.output.qualified_path.self_type.generic" \"Self\" + //@ is "$.index[?(@.name=='lending_next')].inner.function.sig.output.qualified_path.name" \"LendingItem\" fn lending_next<'a>(&'a self) -> Self::LendingItem<'a>; } pub trait Iterator { - //@ count "$.index[*][?(@.name=='Item')].inner.assoc_type.generics.params[*]" 0 - //@ count "$.index[*][?(@.name=='Item')].inner.assoc_type.generics.where_predicates[*]" 0 - //@ count "$.index[*][?(@.name=='Item')].inner.assoc_type.bounds[*]" 1 + //@ count "$.index[?(@.name=='Item')].inner.assoc_type.generics.params[*]" 0 + //@ count "$.index[?(@.name=='Item')].inner.assoc_type.generics.where_predicates[*]" 0 + //@ count "$.index[?(@.name=='Item')].inner.assoc_type.bounds[*]" 1 type Item: Display; - //@ count "$.index[*][?(@.name=='next')].inner.function.sig.output.qualified_path.args.angle_bracketed.args[*]" 0 - //@ count "$.index[*][?(@.name=='next')].inner.function.sig.output.qualified_path.args.angle_bracketed.bindings[*]" 0 - //@ is "$.index[*][?(@.name=='next')].inner.function.sig.output.qualified_path.self_type.generic" \"Self\" - //@ is "$.index[*][?(@.name=='next')].inner.function.sig.output.qualified_path.name" \"Item\" + //@ count "$.index[?(@.name=='next')].inner.function.sig.output.qualified_path.args.angle_bracketed.args[*]" 0 + //@ count "$.index[?(@.name=='next')].inner.function.sig.output.qualified_path.args.angle_bracketed.bindings[*]" 0 + //@ is "$.index[?(@.name=='next')].inner.function.sig.output.qualified_path.self_type.generic" \"Self\" + //@ is "$.index[?(@.name=='next')].inner.function.sig.output.qualified_path.name" \"Item\" fn next<'a>(&'a self) -> Self::Item; } diff --git a/tests/rustdoc-json/generic_impl.rs b/tests/rustdoc-json/generic_impl.rs index e7a5d2a78c1..90bda1644ff 100644 --- a/tests/rustdoc-json/generic_impl.rs +++ b/tests/rustdoc-json/generic_impl.rs @@ -1,8 +1,8 @@ // Regression test for <https://github.com/rust-lang/rust/issues/97986>. -//@ has "$.index[*][?(@.name=='f')]" -//@ has "$.index[*][?(@.name=='AssocTy')]" -//@ has "$.index[*][?(@.name=='AssocConst')]" +//@ has "$.index[?(@.name=='f')]" +//@ has "$.index[?(@.name=='AssocTy')]" +//@ has "$.index[?(@.name=='AssocConst')]" pub mod m { pub struct S; diff --git a/tests/rustdoc-json/glob_import.rs b/tests/rustdoc-json/glob_import.rs index b63e5dadd9e..6887f9ff63d 100644 --- a/tests/rustdoc-json/glob_import.rs +++ b/tests/rustdoc-json/glob_import.rs @@ -2,8 +2,8 @@ #![no_std] -//@ has "$.index[*][?(@.name=='glob')]" -//@ has "$.index[*][?(@.inner.use)].inner.use.name" \"*\" +//@ has "$.index[?(@.name=='glob')]" +//@ has "$.index[?(@.inner.use)].inner.use.name" \"*\" mod m1 { pub fn f() {} diff --git a/tests/rustdoc-json/impl-trait-in-assoc-type.rs b/tests/rustdoc-json/impl-trait-in-assoc-type.rs index fc12fc87e8d..742a46e8967 100644 --- a/tests/rustdoc-json/impl-trait-in-assoc-type.rs +++ b/tests/rustdoc-json/impl-trait-in-assoc-type.rs @@ -4,25 +4,25 @@ pub struct AlwaysTrue; /// impl IntoIterator impl IntoIterator for AlwaysTrue { - //@ set Item = '$.index[*][?(@.docs=="type Item")].id' + //@ set Item = '$.index[?(@.docs=="type Item")].id' /// type Item type Item = bool; - //@ count '$.index[*][?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[*]' 1 - //@ is '$.index[*][?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.path' '"Iterator"' - //@ count '$.index[*][?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[*]' 1 - //@ is '$.index[*][?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name' '"Item"' - //@ is '$.index[*][?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive' '"bool"' + //@ count '$.index[?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[*]' 1 + //@ is '$.index[?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.path' '"Iterator"' + //@ count '$.index[?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[*]' 1 + //@ is '$.index[?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].name' '"Item"' + //@ is '$.index[?(@.docs=="type IntoIter")].inner.assoc_type.type.impl_trait[0].trait_bound.trait.args.angle_bracketed.constraints[0].binding.equality.type.primitive' '"bool"' - //@ set IntoIter = '$.index[*][?(@.docs=="type IntoIter")].id' + //@ set IntoIter = '$.index[?(@.docs=="type IntoIter")].id' /// type IntoIter type IntoIter = impl Iterator<Item = bool>; - //@ set into_iter = '$.index[*][?(@.docs=="fn into_iter")].id' + //@ set into_iter = '$.index[?(@.docs=="fn into_iter")].id' /// fn into_iter fn into_iter(self) -> Self::IntoIter { std::iter::repeat(true) } } -//@ ismany '$.index[*][?(@.docs=="impl IntoIterator")].inner.impl.items[*]' $Item $IntoIter $into_iter +//@ ismany '$.index[?(@.docs=="impl IntoIterator")].inner.impl.items[*]' $Item $IntoIter $into_iter diff --git a/tests/rustdoc-json/impl-trait-precise-capturing.rs b/tests/rustdoc-json/impl-trait-precise-capturing.rs index 06be95099b4..37adb514f55 100644 --- a/tests/rustdoc-json/impl-trait-precise-capturing.rs +++ b/tests/rustdoc-json/impl-trait-precise-capturing.rs @@ -1,4 +1,4 @@ -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0].lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1].param" \"T\" -//@ is "$.index[*][?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2].param" \"N\" +//@ is "$.index[?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[0].lifetime" \"\'a\" +//@ is "$.index[?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[1].param" \"T\" +//@ is "$.index[?(@.name=='hello')].inner.function.sig.output.impl_trait[1].use[2].param" \"N\" pub fn hello<'a, T, const N: usize>() -> impl Sized + use<'a, T, N> {} diff --git a/tests/rustdoc-json/impls/auto.rs b/tests/rustdoc-json/impls/auto.rs index f37dae4c1ed..f94f7338480 100644 --- a/tests/rustdoc-json/impls/auto.rs +++ b/tests/rustdoc-json/impls/auto.rs @@ -15,8 +15,8 @@ impl Foo { } // Testing spans, so all tests below code -//@ is "$.index[*][?(@.docs=='has span')].span.begin" "[13, 0]" -//@ is "$.index[*][?(@.docs=='has span')].span.end" "[15, 1]" +//@ is "$.index[?(@.docs=='has span')].span.begin" "[13, 0]" +//@ is "$.index[?(@.docs=='has span')].span.end" "[15, 1]" // FIXME: this doesn't work due to https://github.com/freestrings/jsonpath/issues/91 -// is "$.index[*][?(@.inner.impl.is_synthetic==true)].span" null +// is "$.index[?(@.inner.impl.is_synthetic==true)].span" null pub struct Foo; diff --git a/tests/rustdoc-json/impls/blanket_with_local.rs b/tests/rustdoc-json/impls/blanket_with_local.rs index de92dafae0b..24ee6cf6670 100644 --- a/tests/rustdoc-json/impls/blanket_with_local.rs +++ b/tests/rustdoc-json/impls/blanket_with_local.rs @@ -1,11 +1,11 @@ // Test for the ICE in rust/83718 // A blanket impl plus a local type together shouldn't result in mismatched ID issues -//@ has "$.index[*][?(@.name=='Load')]" +//@ has "$.index[?(@.name=='Load')]" pub trait Load { - //@ has "$.index[*][?(@.name=='load')]" + //@ has "$.index[?(@.name=='load')]" fn load() {} - //@ has "$.index[*][?(@.name=='write')]" + //@ has "$.index[?(@.name=='write')]" fn write(self) {} } @@ -14,5 +14,5 @@ impl<P> Load for P { fn write(self) {} } -//@ has "$.index[*][?(@.name=='Wrapper')]" +//@ has "$.index[?(@.name=='Wrapper')]" pub struct Wrapper {} diff --git a/tests/rustdoc-json/impls/foreign_for_local.rs b/tests/rustdoc-json/impls/foreign_for_local.rs index 1347f954cad..e46b158d802 100644 --- a/tests/rustdoc-json/impls/foreign_for_local.rs +++ b/tests/rustdoc-json/impls/foreign_for_local.rs @@ -3,16 +3,16 @@ extern crate foreign_trait; /// ForeignTrait id hack pub use foreign_trait::ForeignTrait as _; -//@ set ForeignTrait = "$.index[*][?(@.docs=='ForeignTrait id hack')].inner.use.id" +//@ set ForeignTrait = "$.index[?(@.docs=='ForeignTrait id hack')].inner.use.id" pub struct LocalStruct; -//@ set LocalStruct = "$.index[*][?(@.name=='LocalStruct')].id" +//@ set LocalStruct = "$.index[?(@.name=='LocalStruct')].id" /// foreign for local impl foreign_trait::ForeignTrait for LocalStruct {} -//@ set impl = "$.index[*][?(@.docs=='foreign for local')].id" -//@ is "$.index[*][?(@.docs=='foreign for local')].inner.impl.for.resolved_path.id" $LocalStruct -//@ is "$.index[*][?(@.docs=='foreign for local')].inner.impl.trait.id" $ForeignTrait +//@ set impl = "$.index[?(@.docs=='foreign for local')].id" +//@ is "$.index[?(@.docs=='foreign for local')].inner.impl.for.resolved_path.id" $LocalStruct +//@ is "$.index[?(@.docs=='foreign for local')].inner.impl.trait.id" $ForeignTrait -//@ has "$.index[*][?(@.name=='LocalStruct')].inner.struct.impls[*]" $impl +//@ has "$.index[?(@.name=='LocalStruct')].inner.struct.impls[*]" $impl diff --git a/tests/rustdoc-json/impls/impl_item_visibility.rs b/tests/rustdoc-json/impls/impl_item_visibility.rs index 293dd965804..680ea175d0b 100644 --- a/tests/rustdoc-json/impls/impl_item_visibility.rs +++ b/tests/rustdoc-json/impls/impl_item_visibility.rs @@ -4,13 +4,13 @@ pub struct Foo; impl Foo { fn baz() {} } -//@ !has '$.index[*][?(@.docs=="impl Foo priv")]' +//@ !has '$.index[?(@.docs=="impl Foo priv")]' /// impl Foo pub impl Foo { pub fn qux() {} } -//@ is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo pub")].visibility' '"default"' /// impl Foo hidden impl Foo { @@ -18,4 +18,4 @@ impl Foo { pub fn __quazl() {} } // FIXME(#111564): Is this the right behaviour? -//@ is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs index 77ee717b03a..82d59b97b01 100644 --- a/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs @@ -7,13 +7,13 @@ impl Foo { fn baz() {} } // FIXME(#111564): Is this the right behaviour? -//@ is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo priv")].visibility' '"default"' /// impl Foo pub impl Foo { pub fn qux() {} } -//@ is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo pub")].visibility' '"default"' /// impl Foo hidden impl Foo { @@ -21,4 +21,4 @@ impl Foo { pub fn __quazl() {} } // FIXME(#111564): Is this the right behaviour? -//@ is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs index 80c47eee6cb..a3b145adb86 100644 --- a/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs @@ -6,13 +6,13 @@ pub struct Foo; impl Foo { fn baz() {} } -//@ is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo priv")].visibility' '"default"' /// impl Foo pub impl Foo { pub fn qux() {} } -//@ is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo pub")].visibility' '"default"' /// impl Foo hidden impl Foo { @@ -20,4 +20,4 @@ impl Foo { pub fn __quazl() {} } // FIXME(#111564): Is this the right behaviour? -//@ is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' +//@ is '$.index[?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/import_from_private.rs b/tests/rustdoc-json/impls/import_from_private.rs index 32b9abb0717..02262d9b65f 100644 --- a/tests/rustdoc-json/impls/import_from_private.rs +++ b/tests/rustdoc-json/impls/import_from_private.rs @@ -1,20 +1,20 @@ // https://github.com/rust-lang/rust/issues/100252 mod bar { - //@ set baz = "$.index[*][?(@.name == 'Baz')].id" + //@ set baz = "$.index[?(@.name == 'Baz')].id" pub struct Baz; - //@ set impl = "$.index[*][?(@.docs == 'impl')].id" + //@ set impl = "$.index[?(@.docs == 'impl')].id" /// impl impl Baz { - //@ set doit = "$.index[*][?(@.name == 'doit')].id" + //@ set doit = "$.index[?(@.name == 'doit')].id" pub fn doit() {} } } -//@ set import = "$.index[*][?(@.inner.use)].id" +//@ set import = "$.index[?(@.inner.use)].id" pub use bar::Baz; //@ is "$.index[*].inner.module.items[*]" $import //@ is "$.index[*].inner.use.id" $baz -//@ has "$.index[*][?(@.name == 'Baz')].inner.struct.impls[*]" $impl -//@ is "$.index[*][?(@.docs=='impl')].inner.impl.items[*]" $doit +//@ has "$.index[?(@.name == 'Baz')].inner.struct.impls[*]" $impl +//@ is "$.index[?(@.docs=='impl')].inner.impl.items[*]" $doit diff --git a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-2.rs b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-2.rs index 4a313044920..54ec08135be 100644 --- a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-2.rs +++ b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-2.rs @@ -1,8 +1,8 @@ -//@ has "$.index[*][?(@.docs=='Here')]" -//@ !has "$.index[*][?(@.docs=='Not Here')]" -//@ !has "$.index[*][?(@.name == 'HiddenPubStruct')]" -//@ has "$.index[*][?(@.name == 'NotHiddenPubStruct')]" -//@ has "$.index[*][?(@.name=='PubTrait')]" +//@ has "$.index[?(@.docs=='Here')]" +//@ !has "$.index[?(@.docs=='Not Here')]" +//@ !has "$.index[?(@.name == 'HiddenPubStruct')]" +//@ has "$.index[?(@.name == 'NotHiddenPubStruct')]" +//@ has "$.index[?(@.name=='PubTrait')]" pub trait PubTrait {} #[doc(hidden)] diff --git a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-3.rs b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-3.rs index d3f2180f22c..afb29fd6316 100644 --- a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-3.rs +++ b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id-3.rs @@ -1,8 +1,8 @@ //@ compile-flags: --document-hidden-items -//@ has "$.index[*][?(@.name == 'HiddenPubStruct')]" -//@ has "$.index[*][?(@.inner.impl)]" -//@ has "$.index[*][?(@.name=='PubTrait')]" +//@ has "$.index[?(@.name == 'HiddenPubStruct')]" +//@ has "$.index[?(@.inner.impl)]" +//@ has "$.index[?(@.name=='PubTrait')]" pub trait PubTrait {} #[doc(hidden)] diff --git a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id.rs b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id.rs index a3f05818842..7fc3f70fe5a 100644 --- a/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id.rs +++ b/tests/rustdoc-json/impls/issue-112852-dangling-trait-impl-id.rs @@ -1,21 +1,21 @@ -//@ has "$.index[*][?(@.name=='PubTrait')]" +//@ has "$.index[?(@.name=='PubTrait')]" pub trait PubTrait {} #[doc(hidden)] pub mod hidden { - //@ !has "$.index[*][?(@.name == 'HiddenPubStruct')]" + //@ !has "$.index[?(@.name == 'HiddenPubStruct')]" pub struct HiddenPubStruct; - //@ !has "$.index[*][?(@.docs == 'Not Here')]" + //@ !has "$.index[?(@.docs == 'Not Here')]" /// Not Here impl crate::PubTrait for HiddenPubStruct {} } pub mod not_hidden { - //@ has "$.index[*][?(@.name == 'NotHiddenPubStruct')]" + //@ has "$.index[?(@.name == 'NotHiddenPubStruct')]" pub struct NotHiddenPubStruct; - //@ has "$.index[*][?(@.docs == 'Here')]" + //@ has "$.index[?(@.docs == 'Here')]" /// Here impl crate::PubTrait for NotHiddenPubStruct {} } diff --git a/tests/rustdoc-json/impls/local_for_foreign.rs b/tests/rustdoc-json/impls/local_for_foreign.rs index cd89c475348..86c72a580b2 100644 --- a/tests/rustdoc-json/impls/local_for_foreign.rs +++ b/tests/rustdoc-json/impls/local_for_foreign.rs @@ -3,16 +3,16 @@ extern crate foreign_struct; /// ForeignStruct id hack pub use foreign_struct::ForeignStruct as _; -//@ set ForeignStruct = "$.index[*][?(@.docs=='ForeignStruct id hack')].inner.use.id" +//@ set ForeignStruct = "$.index[?(@.docs=='ForeignStruct id hack')].inner.use.id" pub trait LocalTrait {} -//@ set LocalTrait = "$.index[*][?(@.name=='LocalTrait')].id" +//@ set LocalTrait = "$.index[?(@.name=='LocalTrait')].id" /// local for foreign impl LocalTrait for foreign_struct::ForeignStruct {} -//@ set impl = "$.index[*][?(@.docs=='local for foreign')].id" -//@ is "$.index[*][?(@.docs=='local for foreign')].inner.impl.trait.id" $LocalTrait -//@ is "$.index[*][?(@.docs=='local for foreign')].inner.impl.for.resolved_path.id" $ForeignStruct +//@ set impl = "$.index[?(@.docs=='local for foreign')].id" +//@ is "$.index[?(@.docs=='local for foreign')].inner.impl.trait.id" $LocalTrait +//@ is "$.index[?(@.docs=='local for foreign')].inner.impl.for.resolved_path.id" $ForeignStruct -//@ is "$.index[*][?(@.name=='LocalTrait')].inner.trait.implementations[*]" $impl +//@ is "$.index[?(@.name=='LocalTrait')].inner.trait.implementations[*]" $impl diff --git a/tests/rustdoc-json/impls/local_for_local.rs b/tests/rustdoc-json/impls/local_for_local.rs index 1d141d6e4de..876a7912f09 100644 --- a/tests/rustdoc-json/impls/local_for_local.rs +++ b/tests/rustdoc-json/impls/local_for_local.rs @@ -1,12 +1,12 @@ -//@ set struct = "$.index[*][?(@.name=='Struct')].id" +//@ set struct = "$.index[?(@.name=='Struct')].id" pub struct Struct; -//@ set trait = "$.index[*][?(@.name=='Trait')].id" +//@ set trait = "$.index[?(@.name=='Trait')].id" pub trait Trait {} -//@ set impl = "$.index[*][?(@.docs=='impl')].id" +//@ set impl = "$.index[?(@.docs=='impl')].id" /// impl impl Trait for Struct {} -//@ has "$.index[*][?(@.name=='Struct')].inner.struct.impls[*]" $impl -//@ is "$.index[*][?(@.name=='Trait')].inner.trait.implementations[*]" $impl -//@ is "$.index[*][?(@.docs=='impl')].inner.impl.trait.id" $trait -//@ is "$.index[*][?(@.docs=='impl')].inner.impl.for.resolved_path.id" $struct +//@ has "$.index[?(@.name=='Struct')].inner.struct.impls[*]" $impl +//@ is "$.index[?(@.name=='Trait')].inner.trait.implementations[*]" $impl +//@ is "$.index[?(@.docs=='impl')].inner.impl.trait.id" $trait +//@ is "$.index[?(@.docs=='impl')].inner.impl.for.resolved_path.id" $struct diff --git a/tests/rustdoc-json/impls/local_for_local_primitive.rs b/tests/rustdoc-json/impls/local_for_local_primitive.rs index 8c1eb044eae..859c0cb8ec8 100644 --- a/tests/rustdoc-json/impls/local_for_local_primitive.rs +++ b/tests/rustdoc-json/impls/local_for_local_primitive.rs @@ -1,18 +1,18 @@ #![feature(rustc_attrs)] -//@ set Local = "$.index[*][?(@.name=='Local')].id" +//@ set Local = "$.index[?(@.name=='Local')].id" pub trait Local {} -//@ is "$.index[*][?(@.docs=='Local for bool')].inner.impl.trait.id" $Local -//@ is "$.index[*][?(@.docs=='Local for bool')].inner.impl.for.primitive" '"bool"' +//@ is "$.index[?(@.docs=='Local for bool')].inner.impl.trait.id" $Local +//@ is "$.index[?(@.docs=='Local for bool')].inner.impl.for.primitive" '"bool"' /// Local for bool impl Local for bool {} -//@ set impl = "$.index[*][?(@.docs=='Local for bool')].id" -//@ is "$.index[*][?(@.name=='Local')].inner.trait.implementations[*]" $impl +//@ set impl = "$.index[?(@.docs=='Local for bool')].id" +//@ is "$.index[?(@.name=='Local')].inner.trait.implementations[*]" $impl // FIXME(#101695): Test bool's `impls` include "Local for bool" -//@ has "$.index[*][?(@.name=='bool')]" +//@ has "$.index[?(@.name=='bool')]" #[rustc_doc_primitive = "bool"] /// Boolean docs mod prim_bool {} diff --git a/tests/rustdoc-json/impls/local_for_primitive.rs b/tests/rustdoc-json/impls/local_for_primitive.rs index 56d930ca5c4..a5ab3ec8a1b 100644 --- a/tests/rustdoc-json/impls/local_for_primitive.rs +++ b/tests/rustdoc-json/impls/local_for_primitive.rs @@ -1,7 +1,7 @@ -//@ set local = "$.index[*][?(@.name=='Local')]" +//@ set local = "$.index[?(@.name=='Local')]" pub trait Local {} -//@ set impl = "$.index[*][?(@.docs=='local for bool')].id" -//@ is "$.index[*][?(@.name=='Local')].inner.trait.implementations[*]" $impl +//@ set impl = "$.index[?(@.docs=='local for bool')].id" +//@ is "$.index[?(@.name=='Local')].inner.trait.implementations[*]" $impl /// local for bool impl Local for bool {} diff --git a/tests/rustdoc-json/impls/pub_for_hidden_private.rs b/tests/rustdoc-json/impls/pub_for_hidden_private.rs index 261ffbfeb4a..eb89219022c 100644 --- a/tests/rustdoc-json/impls/pub_for_hidden_private.rs +++ b/tests/rustdoc-json/impls/pub_for_hidden_private.rs @@ -5,6 +5,6 @@ pub trait TheTrait {} #[doc(hidden)] struct Value {} -//@ has '$.index[*][?(@.docs=="THE IMPL")]' +//@ has '$.index[?(@.docs=="THE IMPL")]' /// THE IMPL impl TheTrait for Value {} diff --git a/tests/rustdoc-json/impls/trait-for-dyn-trait.rs b/tests/rustdoc-json/impls/trait-for-dyn-trait.rs index 0fbb4df0028..17cb07f3571 100644 --- a/tests/rustdoc-json/impls/trait-for-dyn-trait.rs +++ b/tests/rustdoc-json/impls/trait-for-dyn-trait.rs @@ -1,15 +1,15 @@ -//@ set t1 = '$.index[*][?(@.name=="T1")].id' +//@ set t1 = '$.index[?(@.name=="T1")].id' pub trait T1 {} -//@ set t2 = '$.index[*][?(@.name=="T2")].id' +//@ set t2 = '$.index[?(@.name=="T2")].id' pub trait T2 {} /// Fun impl impl T1 for dyn T2 {} -//@ set impl = '$.index[*][?(@.docs=="Fun impl")].id' -//@ is '$.index[*][?(@.name=="T1")].inner.trait.implementations[*]' $impl -//@ is '$.index[*][?(@.name=="T2")].inner.trait.implementations' [] +//@ set impl = '$.index[?(@.docs=="Fun impl")].id' +//@ is '$.index[?(@.name=="T1")].inner.trait.implementations[*]' $impl +//@ is '$.index[?(@.name=="T2")].inner.trait.implementations' [] -//@ is '$.index[*][?(@.docs=="Fun impl")].inner.impl.trait.id' $t1 -//@ is '$.index[*][?(@.docs=="Fun impl")].inner.impl.for.dyn_trait.traits[*].trait.id' $t2 +//@ is '$.index[?(@.docs=="Fun impl")].inner.impl.trait.id' $t1 +//@ is '$.index[?(@.docs=="Fun impl")].inner.impl.for.dyn_trait.traits[*].trait.id' $t2 diff --git a/tests/rustdoc-json/intra-doc-links/foreign_variant.rs b/tests/rustdoc-json/intra-doc-links/foreign_variant.rs index 251c4884fbb..b3e6f51d23c 100644 --- a/tests/rustdoc-json/intra-doc-links/foreign_variant.rs +++ b/tests/rustdoc-json/intra-doc-links/foreign_variant.rs @@ -8,6 +8,6 @@ pub struct Local; /// local impl impl enum_variant_in_trait_method::Trait for Local {} -//@ !has "$.index[*][?(@.name == 'Trait')]" -//@ !has "$.index[*][?(@.name == 'method')]" -//@ count "$.index[*][?(@.docs == 'local impl')].inner.items[*]" 0 +//@ !has "$.index[?(@.name == 'Trait')]" +//@ !has "$.index[?(@.name == 'method')]" +//@ count "$.index[?(@.docs == 'local impl')].inner.items[*]" 0 diff --git a/tests/rustdoc-json/intra-doc-links/non_page.rs b/tests/rustdoc-json/intra-doc-links/non_page.rs index 00987d93c1e..e2d00ee64e9 100644 --- a/tests/rustdoc-json/intra-doc-links/non_page.rs +++ b/tests/rustdoc-json/intra-doc-links/non_page.rs @@ -7,17 +7,17 @@ //! [`Trait::ASSOC_CONST`] //! [`Trait::method`] -//@ set struct_field = "$.index[*][?(@.name=='struct_field')].id" -//@ set Variant = "$.index[*][?(@.name=='Variant')].id" -//@ set AssocType = "$.index[*][?(@.name=='AssocType')].id" -//@ set ASSOC_CONST = "$.index[*][?(@.name=='ASSOC_CONST')].id" -//@ set method = "$.index[*][?(@.name=='method')].id" +//@ set struct_field = "$.index[?(@.name=='struct_field')].id" +//@ set Variant = "$.index[?(@.name=='Variant')].id" +//@ set AssocType = "$.index[?(@.name=='AssocType')].id" +//@ set ASSOC_CONST = "$.index[?(@.name=='ASSOC_CONST')].id" +//@ set method = "$.index[?(@.name=='method')].id" -//@ is "$.index[*][?(@.name=='non_page')].links['`Struct::struct_field`']" $struct_field -//@ is "$.index[*][?(@.name=='non_page')].links['`Enum::Variant`']" $Variant -//@ is "$.index[*][?(@.name=='non_page')].links['`Trait::AssocType`']" $AssocType -//@ is "$.index[*][?(@.name=='non_page')].links['`Trait::ASSOC_CONST`']" $ASSOC_CONST -//@ is "$.index[*][?(@.name=='non_page')].links['`Trait::method`']" $method +//@ is "$.index[?(@.name=='non_page')].links['`Struct::struct_field`']" $struct_field +//@ is "$.index[?(@.name=='non_page')].links['`Enum::Variant`']" $Variant +//@ is "$.index[?(@.name=='non_page')].links['`Trait::AssocType`']" $AssocType +//@ is "$.index[?(@.name=='non_page')].links['`Trait::ASSOC_CONST`']" $ASSOC_CONST +//@ is "$.index[?(@.name=='non_page')].links['`Trait::method`']" $method pub struct Struct { pub struct_field: i32, diff --git a/tests/rustdoc-json/intra-doc-links/user_written.rs b/tests/rustdoc-json/intra-doc-links/user_written.rs index c3f9df95a8f..97a643490e6 100644 --- a/tests/rustdoc-json/intra-doc-links/user_written.rs +++ b/tests/rustdoc-json/intra-doc-links/user_written.rs @@ -4,5 +4,5 @@ /// To test rustdoc json pub fn foo() {} -//@ set foo = "$.index[*][?(@.name=='foo')].id" -//@ is "$.index[*][?(@.name=='user_written')].links['foo#reasons']" $foo +//@ set foo = "$.index[?(@.name=='foo')].id" +//@ is "$.index[?(@.name=='user_written')].links['foo#reasons']" $foo diff --git a/tests/rustdoc-json/keyword.rs b/tests/rustdoc-json/keyword.rs index 8a2130f1978..566b2c68bd5 100644 --- a/tests/rustdoc-json/keyword.rs +++ b/tests/rustdoc-json/keyword.rs @@ -6,15 +6,15 @@ #![feature(rustdoc_internals)] #![no_std] -//@ !has "$.index[*][?(@.name=='match')]" -//@ has "$.index[*][?(@.name=='foo')]" +//@ !has "$.index[?(@.name=='match')]" +//@ has "$.index[?(@.name=='foo')]" #[doc(keyword = "match")] /// this is a test! pub mod foo {} -//@ !has "$.index[*][?(@.name=='break')]" -//@ !has "$.index[*][?(@.name=='bar')]" +//@ !has "$.index[?(@.name=='break')]" +//@ !has "$.index[?(@.name=='bar')]" #[doc(keyword = "break")] /// hello mod bar {} diff --git a/tests/rustdoc-json/keyword_private.rs b/tests/rustdoc-json/keyword_private.rs index 2a13bf10d5d..fea546c9fb6 100644 --- a/tests/rustdoc-json/keyword_private.rs +++ b/tests/rustdoc-json/keyword_private.rs @@ -3,18 +3,18 @@ //@ compile-flags: --document-private-items #![feature(rustdoc_internals)] -//@ !has "$.index[*][?(@.name=='match')]" -//@ has "$.index[*][?(@.name=='foo')]" -//@ is "$.index[*][?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]' -//@ is "$.index[*][?(@.name=='foo')].docs" '"this is a test!"' +//@ !has "$.index[?(@.name=='match')]" +//@ has "$.index[?(@.name=='foo')]" +//@ is "$.index[?(@.name=='foo')].attrs" '["#[doc(keyword = \"match\")]"]' +//@ is "$.index[?(@.name=='foo')].docs" '"this is a test!"' #[doc(keyword = "match")] /// this is a test! pub mod foo {} -//@ !has "$.index[*][?(@.name=='break')]" -//@ has "$.index[*][?(@.name=='bar')]" -//@ is "$.index[*][?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]' -//@ is "$.index[*][?(@.name=='bar')].docs" '"hello"' +//@ !has "$.index[?(@.name=='break')]" +//@ has "$.index[?(@.name=='bar')]" +//@ is "$.index[?(@.name=='bar')].attrs" '["#[doc(keyword = \"break\")]"]' +//@ is "$.index[?(@.name=='bar')].docs" '"hello"' #[doc(keyword = "break")] /// hello mod bar {} diff --git a/tests/rustdoc-json/lifetime/longest.rs b/tests/rustdoc-json/lifetime/longest.rs index 2d4e098d696..50cf084c398 100644 --- a/tests/rustdoc-json/lifetime/longest.rs +++ b/tests/rustdoc-json/lifetime/longest.rs @@ -1,24 +1,24 @@ -//@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].name" \"\'a\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' -//@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' -//@ count "$.index[*][?(@.name=='longest')].inner.function.generics.params[*]" 1 -//@ is "$.index[*][?(@.name=='longest')].inner.function.generics.where_predicates" [] +//@ is "$.index[?(@.name=='longest')].inner.function.generics.params[0].name" \"\'a\" +//@ is "$.index[?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' +//@ is "$.index[?(@.name=='longest')].inner.function.generics.params[0].kind" '{"lifetime": {"outlives": []}}' +//@ count "$.index[?(@.name=='longest')].inner.function.generics.params[*]" 1 +//@ is "$.index[?(@.name=='longest')].inner.function.generics.where_predicates" [] -//@ count "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[*]" 2 -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[0][0]" '"l"' -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[1][0]" '"r"' +//@ count "$.index[?(@.name=='longest')].inner.function.sig.inputs[*]" 2 +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[0][0]" '"l"' +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[1][0]" '"r"' -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable" false -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.type.primitive" \"str\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable" false +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[0][1].borrowed_ref.type.primitive" \"str\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.is_mutable" false -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.type.primitive" \"str\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.is_mutable" false +//@ is "$.index[?(@.name=='longest')].inner.function.sig.inputs[1][1].borrowed_ref.type.primitive" \"str\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.output.borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.output.borrowed_ref.is_mutable" false -//@ is "$.index[*][?(@.name=='longest')].inner.function.sig.output.borrowed_ref.type.primitive" \"str\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.output.borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='longest')].inner.function.sig.output.borrowed_ref.is_mutable" false +//@ is "$.index[?(@.name=='longest')].inner.function.sig.output.borrowed_ref.type.primitive" \"str\" pub fn longest<'a>(l: &'a str, r: &'a str) -> &'a str { if l.len() > r.len() { l } else { r } diff --git a/tests/rustdoc-json/lifetime/outlives.rs b/tests/rustdoc-json/lifetime/outlives.rs index 257e43985ac..f191b386c6c 100644 --- a/tests/rustdoc-json/lifetime/outlives.rs +++ b/tests/rustdoc-json/lifetime/outlives.rs @@ -1,16 +1,16 @@ -//@ count "$.index[*][?(@.name=='foo')].inner.function.generics.params[*]" 3 -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates" [] -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].name" \"\'a\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[1].name" \"\'b\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].name" '"T"' -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].kind.lifetime.outlives" [] -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[1].kind.lifetime.outlives" [\"\'a\"] -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.default" null -//@ count "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[0].outlives" \"\'b\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable" false -//@ is "$.index[*][?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.lifetime" \"\'b\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.is_mutable" false -//@ is "$.index[*][?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.type.generic" \"T\" +//@ count "$.index[?(@.name=='foo')].inner.function.generics.params[*]" 3 +//@ is "$.index[?(@.name=='foo')].inner.function.generics.where_predicates" [] +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[0].name" \"\'a\" +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[1].name" \"\'b\" +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[2].name" '"T"' +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[0].kind.lifetime.outlives" [] +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[1].kind.lifetime.outlives" [\"\'a\"] +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[2].kind.type.default" null +//@ count "$.index[?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[*]" 1 +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[2].kind.type.bounds[0].outlives" \"\'b\" +//@ is "$.index[?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable" false +//@ is "$.index[?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.lifetime" \"\'b\" +//@ is "$.index[?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.is_mutable" false +//@ is "$.index[?(@.name=='foo')].inner.function.sig.inputs[0][1].borrowed_ref.type.borrowed_ref.type.generic" \"T\" pub fn foo<'a, 'b: 'a, T: 'b>(_: &'a &'b T) {} diff --git a/tests/rustdoc-json/lifetime/outlives_in_param.rs b/tests/rustdoc-json/lifetime/outlives_in_param.rs index 55ff5250541..dc9f57ff8a1 100644 --- a/tests/rustdoc-json/lifetime/outlives_in_param.rs +++ b/tests/rustdoc-json/lifetime/outlives_in_param.rs @@ -1,6 +1,6 @@ -//@ count '$.index[*][?(@.name=="outlives")].inner.function.generics.params[*]' 2 -//@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\" -//@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' [] -//@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].name' '"T"' -//@ is '$.index[*][?(@.name=="outlives")].inner.function.generics.params[1].kind.type.bounds' '[{"outlives": "'\''a"}]' +//@ count '$.index[?(@.name=="outlives")].inner.function.generics.params[*]' 2 +//@ is '$.index[?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\" +//@ is '$.index[?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' [] +//@ is '$.index[?(@.name=="outlives")].inner.function.generics.params[1].name' '"T"' +//@ is '$.index[?(@.name=="outlives")].inner.function.generics.params[1].kind.type.bounds' '[{"outlives": "'\''a"}]' pub fn outlives<'a, T: 'a>() {} diff --git a/tests/rustdoc-json/lifetime/outlives_in_where.rs b/tests/rustdoc-json/lifetime/outlives_in_where.rs index 5158ff118a0..48faf8ff830 100644 --- a/tests/rustdoc-json/lifetime/outlives_in_where.rs +++ b/tests/rustdoc-json/lifetime/outlives_in_where.rs @@ -1,20 +1,20 @@ -//@ is '$.index[*][?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]' +//@ is '$.index[?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]' pub fn on_lifetimes<'a, 'b, 'c, 'all>() where 'all: 'a + 'b + 'c, { } -//@ count '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[*]' 2 -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].name' \"\'a\" -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[0].kind.lifetime.outlives' [] -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].name' '"T"' -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] -//@ count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[*]' 1 -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.type.generic' '"T"' -//@ count '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]' 1 -//@ is '$.index[*][?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].outlives' \"\'a\" +//@ count '$.index[?(@.name=="on_trait")].inner.function.generics.params[*]' 2 +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.params[0].name' \"\'a\" +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.params[0].kind.lifetime.outlives' [] +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.params[1].name' '"T"' +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.params[1].kind.type.bounds' [] +//@ count '$.index[?(@.name=="on_trait")].inner.function.generics.where_predicates[*]' 1 +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.type.generic' '"T"' +//@ count '$.index[?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[*]' 1 +//@ is '$.index[?(@.name=="on_trait")].inner.function.generics.where_predicates[0].bound_predicate.bounds[0].outlives' \"\'a\" pub fn on_trait<'a, T>() where T: 'a, diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs index dac02a6ce3c..fa2387ddf67 100644 --- a/tests/rustdoc-json/methods/abi.rs +++ b/tests/rustdoc-json/methods/abi.rs @@ -1,50 +1,50 @@ #![feature(abi_vectorcall)] -//@ has "$.index[*][?(@.name=='Foo')]" +//@ has "$.index[?(@.name=='Foo')]" pub struct Foo; impl Foo { - //@ is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" + //@ is "$.index[?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\" pub fn abi_rust() {} - //@ is "$.index[*][?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' + //@ is "$.index[?(@.name=='abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' pub extern "C" fn abi_c() {} - //@ is "$.index[*][?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' + //@ is "$.index[?(@.name=='abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' pub extern "system" fn abi_system() {} - //@ is "$.index[*][?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' + //@ is "$.index[?(@.name=='abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' pub extern "C-unwind" fn abi_c_unwind() {} - //@ is "$.index[*][?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' + //@ is "$.index[?(@.name=='abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' pub extern "system-unwind" fn abi_system_unwind() {} - //@ is "$.index[*][?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' + //@ is "$.index[?(@.name=='abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' pub extern "vectorcall" fn abi_vectorcall() {} - //@ is "$.index[*][?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' + //@ is "$.index[?(@.name=='abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' pub extern "vectorcall-unwind" fn abi_vectorcall_unwind() {} } pub trait Bar { - //@ is "$.index[*][?(@.name=='trait_abi_rust')].inner.function.header.abi" \"Rust\" + //@ is "$.index[?(@.name=='trait_abi_rust')].inner.function.header.abi" \"Rust\" fn trait_abi_rust() {} - //@ is "$.index[*][?(@.name=='trait_abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' + //@ is "$.index[?(@.name=='trait_abi_c')].inner.function.header.abi" '{"C": {"unwind": false}}' extern "C" fn trait_abi_c() {} - //@ is "$.index[*][?(@.name=='trait_abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' + //@ is "$.index[?(@.name=='trait_abi_system')].inner.function.header.abi" '{"System": {"unwind": false}}' extern "system" fn trait_abi_system() {} - //@ is "$.index[*][?(@.name=='trait_abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' + //@ is "$.index[?(@.name=='trait_abi_c_unwind')].inner.function.header.abi" '{"C": {"unwind": true}}' extern "C-unwind" fn trait_abi_c_unwind() {} - //@ is "$.index[*][?(@.name=='trait_abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' + //@ is "$.index[?(@.name=='trait_abi_system_unwind')].inner.function.header.abi" '{"System": {"unwind": true}}' extern "system-unwind" fn trait_abi_system_unwind() {} - //@ is "$.index[*][?(@.name=='trait_abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' + //@ is "$.index[?(@.name=='trait_abi_vectorcall')].inner.function.header.abi.Other" '"\"vectorcall\""' extern "vectorcall" fn trait_abi_vectorcall() {} - //@ is "$.index[*][?(@.name=='trait_abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' + //@ is "$.index[?(@.name=='trait_abi_vectorcall_unwind')].inner.function.header.abi.Other" '"\"vectorcall-unwind\""' extern "vectorcall-unwind" fn trait_abi_vectorcall_unwind() {} } diff --git a/tests/rustdoc-json/methods/qualifiers.rs b/tests/rustdoc-json/methods/qualifiers.rs index ba7c2e60936..b1d9f0c1af3 100644 --- a/tests/rustdoc-json/methods/qualifiers.rs +++ b/tests/rustdoc-json/methods/qualifiers.rs @@ -3,34 +3,34 @@ pub struct Foo; impl Foo { - //@ is "$.index[*][?(@.name=='const_meth')].inner.function.header.is_async" false - //@ is "$.index[*][?(@.name=='const_meth')].inner.function.header.is_const" true - //@ is "$.index[*][?(@.name=='const_meth')].inner.function.header.is_unsafe" false + //@ is "$.index[?(@.name=='const_meth')].inner.function.header.is_async" false + //@ is "$.index[?(@.name=='const_meth')].inner.function.header.is_const" true + //@ is "$.index[?(@.name=='const_meth')].inner.function.header.is_unsafe" false pub const fn const_meth() {} - //@ is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.is_async" false - //@ is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.is_const" false - //@ is "$.index[*][?(@.name=='nothing_meth')].inner.function.header.is_unsafe" false + //@ is "$.index[?(@.name=='nothing_meth')].inner.function.header.is_async" false + //@ is "$.index[?(@.name=='nothing_meth')].inner.function.header.is_const" false + //@ is "$.index[?(@.name=='nothing_meth')].inner.function.header.is_unsafe" false pub fn nothing_meth() {} - //@ is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.is_async" false - //@ is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.is_const" false - //@ is "$.index[*][?(@.name=='unsafe_meth')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='unsafe_meth')].inner.function.header.is_async" false + //@ is "$.index[?(@.name=='unsafe_meth')].inner.function.header.is_const" false + //@ is "$.index[?(@.name=='unsafe_meth')].inner.function.header.is_unsafe" true pub unsafe fn unsafe_meth() {} - //@ is "$.index[*][?(@.name=='async_meth')].inner.function.header.is_async" true - //@ is "$.index[*][?(@.name=='async_meth')].inner.function.header.is_const" false - //@ is "$.index[*][?(@.name=='async_meth')].inner.function.header.is_unsafe" false + //@ is "$.index[?(@.name=='async_meth')].inner.function.header.is_async" true + //@ is "$.index[?(@.name=='async_meth')].inner.function.header.is_const" false + //@ is "$.index[?(@.name=='async_meth')].inner.function.header.is_unsafe" false pub async fn async_meth() {} - //@ is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.is_async" true - //@ is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.is_const" false - //@ is "$.index[*][?(@.name=='async_unsafe_meth')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='async_unsafe_meth')].inner.function.header.is_async" true + //@ is "$.index[?(@.name=='async_unsafe_meth')].inner.function.header.is_const" false + //@ is "$.index[?(@.name=='async_unsafe_meth')].inner.function.header.is_unsafe" true pub async unsafe fn async_unsafe_meth() {} - //@ is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.is_async" false - //@ is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.is_const" true - //@ is "$.index[*][?(@.name=='const_unsafe_meth')].inner.function.header.is_unsafe" true + //@ is "$.index[?(@.name=='const_unsafe_meth')].inner.function.header.is_async" false + //@ is "$.index[?(@.name=='const_unsafe_meth')].inner.function.header.is_const" true + //@ is "$.index[?(@.name=='const_unsafe_meth')].inner.function.header.is_unsafe" true pub const unsafe fn const_unsafe_meth() {} // It's impossible for a method to be both const and async, so no test for that diff --git a/tests/rustdoc-json/nested.rs b/tests/rustdoc-json/nested.rs index 10ec2831c21..8cc564706d6 100644 --- a/tests/rustdoc-json/nested.rs +++ b/tests/rustdoc-json/nested.rs @@ -2,31 +2,31 @@ //@ compile-flags: --crate-version 1.0.0 //@ is "$.crate_version" \"1.0.0\" -//@ has "$.index[*][?(@.name=='nested')].inner.module" -//@ is "$.index[*][?(@.name=='nested')].inner.module.is_crate" true +//@ has "$.index[?(@.name=='nested')].inner.module" +//@ is "$.index[?(@.name=='nested')].inner.module.is_crate" true -//@ set l1_id = "$.index[*][?(@.name=='l1')].id" -//@ ismany "$.index[*][?(@.name=='nested')].inner.module.items[*]" $l1_id +//@ set l1_id = "$.index[?(@.name=='l1')].id" +//@ ismany "$.index[?(@.name=='nested')].inner.module.items[*]" $l1_id -//@ has "$.index[*][?(@.name=='l1')].inner.module" -//@ is "$.index[*][?(@.name=='l1')].inner.module.is_crate" false +//@ has "$.index[?(@.name=='l1')].inner.module" +//@ is "$.index[?(@.name=='l1')].inner.module.is_crate" false pub mod l1 { - //@ has "$.index[*][?(@.name=='l3')].inner.module" - //@ is "$.index[*][?(@.name=='l3')].inner.module.is_crate" false - //@ set l3_id = "$.index[*][?(@.name=='l3')].id" + //@ has "$.index[?(@.name=='l3')].inner.module" + //@ is "$.index[?(@.name=='l3')].inner.module.is_crate" false + //@ set l3_id = "$.index[?(@.name=='l3')].id" pub mod l3 { - //@ has "$.index[*][?(@.name=='L4')].inner.struct" - //@ is "$.index[*][?(@.name=='L4')].inner.struct.kind" '"unit"' - //@ set l4_id = "$.index[*][?(@.name=='L4')].id" - //@ ismany "$.index[*][?(@.name=='l3')].inner.module.items[*]" $l4_id + //@ has "$.index[?(@.name=='L4')].inner.struct" + //@ is "$.index[?(@.name=='L4')].inner.struct.kind" '"unit"' + //@ set l4_id = "$.index[?(@.name=='L4')].id" + //@ ismany "$.index[?(@.name=='l3')].inner.module.items[*]" $l4_id pub struct L4; } - //@ is "$.index[*][?(@.inner.use)].inner.use.is_glob" false - //@ is "$.index[*][?(@.inner.use)].inner.use.source" '"l3::L4"' - //@ is "$.index[*][?(@.inner.use)].inner.use.is_glob" false - //@ is "$.index[*][?(@.inner.use)].inner.use.id" $l4_id - //@ set l4_use_id = "$.index[*][?(@.inner.use)].id" + //@ is "$.index[?(@.inner.use)].inner.use.is_glob" false + //@ is "$.index[?(@.inner.use)].inner.use.source" '"l3::L4"' + //@ is "$.index[?(@.inner.use)].inner.use.is_glob" false + //@ is "$.index[?(@.inner.use)].inner.use.id" $l4_id + //@ set l4_use_id = "$.index[?(@.inner.use)].id" pub use l3::L4; } -//@ ismany "$.index[*][?(@.name=='l1')].inner.module.items[*]" $l3_id $l4_use_id +//@ ismany "$.index[?(@.name=='l1')].inner.module.items[*]" $l3_id $l4_use_id diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs index 7c518a8f5a7..84318821c50 100644 --- a/tests/rustdoc-json/non_lifetime_binders.rs +++ b/tests/rustdoc-json/non_lifetime_binders.rs @@ -5,11 +5,11 @@ pub trait Trait {} pub struct Wrapper<T_>(std::marker::PhantomData<T_>); -//@ count "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[*]" 2 -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\" -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "is_synthetic": false } }' +//@ count "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[*]" 2 +//@ is "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\" +//@ is "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' +//@ is "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\" +//@ is "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "is_synthetic": false } }' pub fn foo() where for<'a, T> &'a Wrapper<T>: Trait, diff --git a/tests/rustdoc-json/output_generics.rs b/tests/rustdoc-json/output_generics.rs index 3454f421636..4d4339ceb23 100644 --- a/tests/rustdoc-json/output_generics.rs +++ b/tests/rustdoc-json/output_generics.rs @@ -2,11 +2,11 @@ // This is a regression test for #98009. -//@ has "$.index[*][?(@.name=='this_compiles')]" -//@ has "$.index[*][?(@.name=='this_does_not')]" -//@ has "$.index[*][?(@.name=='Events')]" -//@ has "$.index[*][?(@.name=='Other')]" -//@ has "$.index[*][?(@.name=='Trait')]" +//@ has "$.index[?(@.name=='this_compiles')]" +//@ has "$.index[?(@.name=='this_does_not')]" +//@ has "$.index[?(@.name=='Events')]" +//@ has "$.index[?(@.name=='Other')]" +//@ has "$.index[?(@.name=='Trait')]" struct Events<R>(R); diff --git a/tests/rustdoc-json/path_name.rs b/tests/rustdoc-json/path_name.rs index a1b3ae294fa..dcfaa0607c4 100644 --- a/tests/rustdoc-json/path_name.rs +++ b/tests/rustdoc-json/path_name.rs @@ -19,49 +19,49 @@ pub use priv_mod::{InPrivMod, InPrivMod as InPrivMod2}; use pub_mod::InPubMod as InPubMod3; pub use pub_mod::{InPubMod, InPubMod as InPubMod2}; -//@ is "$.index[*][?(@.name=='T0')].inner.type_alias.type.resolved_path.path" '"priv_mod::InPrivMod"' +//@ is "$.index[?(@.name=='T0')].inner.type_alias.type.resolved_path.path" '"priv_mod::InPrivMod"' pub type T0 = priv_mod::InPrivMod; -//@ is "$.index[*][?(@.name=='T1')].inner.type_alias.type.resolved_path.path" '"InPrivMod"' +//@ is "$.index[?(@.name=='T1')].inner.type_alias.type.resolved_path.path" '"InPrivMod"' pub type T1 = InPrivMod; -//@ is "$.index[*][?(@.name=='T2')].inner.type_alias.type.resolved_path.path" '"InPrivMod2"' +//@ is "$.index[?(@.name=='T2')].inner.type_alias.type.resolved_path.path" '"InPrivMod2"' pub type T2 = InPrivMod2; -//@ is "$.index[*][?(@.name=='T3')].inner.type_alias.type.resolved_path.path" '"priv_mod::InPrivMod"' +//@ is "$.index[?(@.name=='T3')].inner.type_alias.type.resolved_path.path" '"priv_mod::InPrivMod"' pub type T3 = InPrivMod3; -//@ is "$.index[*][?(@.name=='U0')].inner.type_alias.type.resolved_path.path" '"pub_mod::InPubMod"' +//@ is "$.index[?(@.name=='U0')].inner.type_alias.type.resolved_path.path" '"pub_mod::InPubMod"' pub type U0 = pub_mod::InPubMod; -//@ is "$.index[*][?(@.name=='U1')].inner.type_alias.type.resolved_path.path" '"InPubMod"' +//@ is "$.index[?(@.name=='U1')].inner.type_alias.type.resolved_path.path" '"InPubMod"' pub type U1 = InPubMod; -//@ is "$.index[*][?(@.name=='U2')].inner.type_alias.type.resolved_path.path" '"InPubMod2"' +//@ is "$.index[?(@.name=='U2')].inner.type_alias.type.resolved_path.path" '"InPubMod2"' pub type U2 = InPubMod2; -//@ is "$.index[*][?(@.name=='U3')].inner.type_alias.type.resolved_path.path" '"pub_mod::InPubMod"' +//@ is "$.index[?(@.name=='U3')].inner.type_alias.type.resolved_path.path" '"pub_mod::InPubMod"' pub type U3 = InPubMod3; // Check we only have paths for structs at their original path -//@ ismany "$.paths[*][?(@.crate_id==0 && @.kind=='struct')].path" '["path_name", "priv_mod", "InPrivMod"]' '["path_name", "pub_mod", "InPubMod"]' +//@ ismany "$.paths[?(@.crate_id==0 && @.kind=='struct')].path" '["path_name", "priv_mod", "InPrivMod"]' '["path_name", "pub_mod", "InPubMod"]' pub use defines_and_reexports::{InPrivMod as XPrivMod, InPubMod as XPubMod}; use defines_and_reexports::{InPrivMod as XPrivMod2, InPubMod as XPubMod2}; -//@ is "$.index[*][?(@.name=='X0')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::m1::InPubMod"' +//@ is "$.index[?(@.name=='X0')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::m1::InPubMod"' pub type X0 = defines_and_reexports::m1::InPubMod; -//@ is "$.index[*][?(@.name=='X1')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod"' +//@ is "$.index[?(@.name=='X1')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod"' pub type X1 = defines_and_reexports::InPubMod; -//@ is "$.index[*][?(@.name=='X2')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod2"' +//@ is "$.index[?(@.name=='X2')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod2"' pub type X2 = defines_and_reexports::InPubMod2; -//@ is "$.index[*][?(@.name=='X3')].inner.type_alias.type.resolved_path.path" '"XPubMod"' +//@ is "$.index[?(@.name=='X3')].inner.type_alias.type.resolved_path.path" '"XPubMod"' pub type X3 = XPubMod; // N.B. This isn't the path as used *or* the original path! -//@ is "$.index[*][?(@.name=='X4')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod"' +//@ is "$.index[?(@.name=='X4')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPubMod"' pub type X4 = XPubMod2; -//@ is "$.index[*][?(@.name=='Y1')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod"' +//@ is "$.index[?(@.name=='Y1')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod"' pub type Y1 = defines_and_reexports::InPrivMod; -//@ is "$.index[*][?(@.name=='Y2')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod2"' +//@ is "$.index[?(@.name=='Y2')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod2"' pub type Y2 = defines_and_reexports::InPrivMod2; -//@ is "$.index[*][?(@.name=='Y3')].inner.type_alias.type.resolved_path.path" '"XPrivMod"' +//@ is "$.index[?(@.name=='Y3')].inner.type_alias.type.resolved_path.path" '"XPrivMod"' pub type Y3 = XPrivMod; -//@ is "$.index[*][?(@.name=='Y4')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod"' +//@ is "$.index[?(@.name=='Y4')].inner.type_alias.type.resolved_path.path" '"defines_and_reexports::InPrivMod"' pub type Y4 = XPrivMod2; // For foreign items, $.paths contains the *origional* path, even if it's not publicly @@ -74,9 +74,9 @@ pub type Y4 = XPrivMod2; // Tests for the example in the docs of Path::name. // If these change, chage the docs. -//@ is "$.index[*][?(@.name=='Vec1')].inner.type_alias.type.resolved_path.path" '"std::vec::Vec"' +//@ is "$.index[?(@.name=='Vec1')].inner.type_alias.type.resolved_path.path" '"std::vec::Vec"' pub type Vec1 = std::vec::Vec<i32>; -//@ is "$.index[*][?(@.name=='Vec2')].inner.type_alias.type.resolved_path.path" '"Vec"' +//@ is "$.index[?(@.name=='Vec2')].inner.type_alias.type.resolved_path.path" '"Vec"' pub type Vec2 = Vec<i32>; -//@ is "$.index[*][?(@.name=='Vec3')].inner.type_alias.type.resolved_path.path" '"std::prelude::v1::Vec"' +//@ is "$.index[?(@.name=='Vec3')].inner.type_alias.type.resolved_path.path" '"std::prelude::v1::Vec"' pub type Vec3 = std::prelude::v1::Vec<i32>; diff --git a/tests/rustdoc-json/primitives/local_primitive.rs b/tests/rustdoc-json/primitives/local_primitive.rs index b10ae45f3ec..b58120bae05 100644 --- a/tests/rustdoc-json/primitives/local_primitive.rs +++ b/tests/rustdoc-json/primitives/local_primitive.rs @@ -11,11 +11,11 @@ #[rustc_doc_primitive = "i32"] mod prim_i32 {} -//@ set local_i32 = "$.index[*][?(@.name=='i32')].id" +//@ set local_i32 = "$.index[?(@.name=='i32')].id" -//@ has "$.index[*][?(@.name=='local_primitive')]" -//@ ismany "$.index[*][?(@.name=='local_primitive')].inner.module.items[*]" $local_i32 -//@ is "$.index[*][?(@.name=='local_primitive')].links['prim@i32']" $local_i32 +//@ has "$.index[?(@.name=='local_primitive')]" +//@ ismany "$.index[?(@.name=='local_primitive')].inner.module.items[*]" $local_i32 +//@ is "$.index[?(@.name=='local_primitive')].links['prim@i32']" $local_i32 // Let's ensure the `prim_i32` module isn't present in the output JSON: -//@ !has "$.index[*][?(@.name=='prim_i32')]" +//@ !has "$.index[?(@.name=='prim_i32')]" diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index 58c222ce4f0..a1f0ebd11b6 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -4,26 +4,26 @@ #![no_core] #![rustc_coherence_is_core] -//@ set impl_i32 = "$.index[*][?(@.docs=='Only core can do this')].id" +//@ set impl_i32 = "$.index[?(@.docs=='Only core can do this')].id" #[lang = "sized"] trait Sized {} /// Only core can do this impl i32 { - //@ set identity = "$.index[*][?(@.docs=='Do Nothing')].id" + //@ set identity = "$.index[?(@.docs=='Do Nothing')].id" /// Do Nothing pub fn identity(self) -> Self { self } - //@ is "$.index[*][?(@.docs=='Only core can do this')].inner.impl.items[*]" $identity + //@ is "$.index[?(@.docs=='Only core can do this')].inner.impl.items[*]" $identity } -//@ set Trait = "$.index[*][?(@.name=='Trait')].id" +//@ set Trait = "$.index[?(@.name=='Trait')].id" pub trait Trait {} -//@ set impl_trait_for_i32 = "$.index[*][?(@.docs=='impl Trait for i32')].id" +//@ set impl_trait_for_i32 = "$.index[?(@.docs=='impl Trait for i32')].id" /// impl Trait for i32 impl Trait for i32 {} @@ -31,7 +31,7 @@ impl Trait for i32 {} #[rustc_doc_primitive = "i32"] mod prim_i32 {} -//@ set i32 = "$.index[*][?(@.docs=='i32')].id" -//@ is "$.index[*][?(@.docs=='i32')].name" '"i32"' -//@ is "$.index[*][?(@.docs=='i32')].inner.primitive.name" '"i32"' -//@ ismany "$.index[*][?(@.docs=='i32')].inner.primitive.impls[*]" $impl_i32 $impl_trait_for_i32 +//@ set i32 = "$.index[?(@.docs=='i32')].id" +//@ is "$.index[?(@.docs=='i32')].name" '"i32"' +//@ is "$.index[?(@.docs=='i32')].inner.primitive.name" '"i32"' +//@ ismany "$.index[?(@.docs=='i32')].inner.primitive.impls[*]" $impl_i32 $impl_trait_for_i32 diff --git a/tests/rustdoc-json/primitives/primitive_overloading.rs b/tests/rustdoc-json/primitives/primitive_overloading.rs index 5e5f3974ab3..ae0306843c5 100644 --- a/tests/rustdoc-json/primitives/primitive_overloading.rs +++ b/tests/rustdoc-json/primitives/primitive_overloading.rs @@ -4,8 +4,8 @@ #![feature(rustc_attrs)] -//@ has "$.index[*][?(@.name=='usize')]" -//@ has "$.index[*][?(@.name=='prim')]" +//@ has "$.index[?(@.name=='usize')]" +//@ has "$.index[?(@.name=='prim')]" #[rustc_doc_primitive = "usize"] /// This is the built-in type `usize`. diff --git a/tests/rustdoc-json/primitives/primitive_type.rs b/tests/rustdoc-json/primitives/primitive_type.rs index 21ef5ab7196..a0d34218b80 100644 --- a/tests/rustdoc-json/primitives/primitive_type.rs +++ b/tests/rustdoc-json/primitives/primitive_type.rs @@ -1,17 +1,17 @@ #![feature(never_type)] -//@ is "$.index[*][?(@.name=='PrimNever')].visibility" \"public\" -//@ is "$.index[*][?(@.name=='PrimNever')].inner.type_alias.type.primitive" \"never\" +//@ is "$.index[?(@.name=='PrimNever')].visibility" \"public\" +//@ is "$.index[?(@.name=='PrimNever')].inner.type_alias.type.primitive" \"never\" pub type PrimNever = !; -//@ is "$.index[*][?(@.name=='PrimStr')].inner.type_alias.type.primitive" \"str\" +//@ is "$.index[?(@.name=='PrimStr')].inner.type_alias.type.primitive" \"str\" pub type PrimStr = str; -//@ is "$.index[*][?(@.name=='PrimBool')].inner.type_alias.type.primitive" \"bool\" +//@ is "$.index[?(@.name=='PrimBool')].inner.type_alias.type.primitive" \"bool\" pub type PrimBool = bool; -//@ is "$.index[*][?(@.name=='PrimChar')].inner.type_alias.type.primitive" \"char\" +//@ is "$.index[?(@.name=='PrimChar')].inner.type_alias.type.primitive" \"char\" pub type PrimChar = char; -//@ is "$.index[*][?(@.name=='PrimU8')].inner.type_alias.type.primitive" \"u8\" +//@ is "$.index[?(@.name=='PrimU8')].inner.type_alias.type.primitive" \"u8\" pub type PrimU8 = u8; diff --git a/tests/rustdoc-json/primitives/use_primitive.rs b/tests/rustdoc-json/primitives/use_primitive.rs index d4cdef84de8..2991cc1e47c 100644 --- a/tests/rustdoc-json/primitives/use_primitive.rs +++ b/tests/rustdoc-json/primitives/use_primitive.rs @@ -5,15 +5,15 @@ #[rustc_doc_primitive = "usize"] mod usize {} -//@ set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id" +//@ set local_crate_id = "$.index[?(@.name=='use_primitive')].crate_id" -//@ has "$.index[*][?(@.name=='ilog10')]" -//@ !is "$.index[*][?(@.name=='ilog10')].crate_id" $local_crate_id -//@ has "$.index[*][?(@.name=='checked_add')]" -//@ !is "$.index[*][?(@.name=='checked_add')]" $local_crate_id -//@ !has "$.index[*][?(@.name=='is_ascii_uppercase')]" +//@ has "$.index[?(@.name=='ilog10')]" +//@ !is "$.index[?(@.name=='ilog10')].crate_id" $local_crate_id +//@ has "$.index[?(@.name=='checked_add')]" +//@ !is "$.index[?(@.name=='checked_add')]" $local_crate_id +//@ !has "$.index[?(@.name=='is_ascii_uppercase')]" -//@ is "$.index[*].inner.use[?(@.name=='my_i32')].id" null +//@ is "$.index[?(@.inner.use.name=='my_i32')].inner.use.id" null pub use i32 as my_i32; -//@ is "$.index[*].inner.use[?(@.name=='u32')].id" null +//@ is "$.index[?(@.inner.use.name=='u32')].inner.use.id" null pub use u32; diff --git a/tests/rustdoc-json/pub_mod_in_private_mod.rs b/tests/rustdoc-json/pub_mod_in_private_mod.rs index 112ab9c68f0..8b31ad0bcfe 100644 --- a/tests/rustdoc-json/pub_mod_in_private_mod.rs +++ b/tests/rustdoc-json/pub_mod_in_private_mod.rs @@ -1,6 +1,6 @@ // See https://github.com/rust-lang/rust/issues/101105 -//@ !has "$.index[*][?(@.name=='nucleus')]" +//@ !has "$.index[?(@.name=='nucleus')]" mod corpus { pub mod nucleus {} } diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs index 4debd395496..f7067857ddf 100644 --- a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs +++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs @@ -4,7 +4,7 @@ #[doc(inline)] pub extern crate enum_with_discriminant; -//@ !has '$.index[*][?(@.docs == "Should not be inlined")]' -//@ has '$.index[*][?(@.name == "enum_with_discriminant")].inner.extern_crate' -//@ set enum_with_discriminant = '$.index[*][?(@.name == "enum_with_discriminant")].id' -//@ is '$.index[*][?(@.name == "doc_inline_external_crate")].inner.module.items[*]' $enum_with_discriminant +//@ !has '$.index[?(@.docs == "Should not be inlined")]' +//@ has '$.index[?(@.name == "enum_with_discriminant")].inner.extern_crate' +//@ set enum_with_discriminant = '$.index[?(@.name == "enum_with_discriminant")].id' +//@ is '$.index[?(@.name == "doc_inline_external_crate")].inner.module.items[*]' $enum_with_discriminant diff --git a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs index 4efacd283ef..746749e0204 100644 --- a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs +++ b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs @@ -2,5 +2,5 @@ #![crate_name = "export_extern_crate_as_self"] -//@ is "$.index[*][?(@.inner.module)].name" \"export_extern_crate_as_self\" +//@ is "$.index[?(@.inner.module)].name" \"export_extern_crate_as_self\" pub extern crate self as export_extern_crate_as_self; // Must be the same name as the crate already has diff --git a/tests/rustdoc-json/reexport/extern_crate_glob.rs b/tests/rustdoc-json/reexport/extern_crate_glob.rs index dfe6e7a03b1..8a4388feaca 100644 --- a/tests/rustdoc-json/reexport/extern_crate_glob.rs +++ b/tests/rustdoc-json/reexport/extern_crate_glob.rs @@ -5,7 +5,7 @@ extern crate enum_with_discriminant; #[doc(inline)] pub use enum_with_discriminant::*; -//@ !has '$.index[*][?(@.docs == "Should not be inlined")]' -//@ is '$.index[*][?(@.inner.use)].inner.use.name' \"enum_with_discriminant\" -//@ set use = '$.index[*][?(@.inner.use)].id' -//@ is '$.index[*][?(@.name == "extern_crate_glob")].inner.module.items[*]' $use +//@ !has '$.index[?(@.docs == "Should not be inlined")]' +//@ is '$.index[?(@.inner.use)].inner.use.name' \"enum_with_discriminant\" +//@ set use = '$.index[?(@.inner.use)].id' +//@ is '$.index[?(@.name == "extern_crate_glob")].inner.module.items[*]' $use diff --git a/tests/rustdoc-json/reexport/glob_collision.rs b/tests/rustdoc-json/reexport/glob_collision.rs index 8142c35f4c7..48de1b5e772 100644 --- a/tests/rustdoc-json/reexport/glob_collision.rs +++ b/tests/rustdoc-json/reexport/glob_collision.rs @@ -1,27 +1,27 @@ // Regression test for https://github.com/rust-lang/rust/issues/100973 -//@ set m1 = "$.index[*][?(@.name == 'm1' && @.inner.module)].id" -//@ is "$.index[*][?(@.name == 'm1')].inner.module.items" [] -//@ is "$.index[*][?(@.name == 'm1')].inner.module.is_stripped" true +//@ set m1 = "$.index[?(@.name == 'm1' && @.inner.module)].id" +//@ is "$.index[?(@.name == 'm1')].inner.module.items" [] +//@ is "$.index[?(@.name == 'm1')].inner.module.is_stripped" true mod m1 { pub fn f() {} } -//@ set m2 = "$.index[*][?(@.name == 'm2' && @.inner.module)].id" -//@ is "$.index[*][?(@.name == 'm2')].inner.module.items" [] -//@ is "$.index[*][?(@.name == 'm2')].inner.module.is_stripped" true +//@ set m2 = "$.index[?(@.name == 'm2' && @.inner.module)].id" +//@ is "$.index[?(@.name == 'm2')].inner.module.items" [] +//@ is "$.index[?(@.name == 'm2')].inner.module.is_stripped" true mod m2 { pub fn f(_: u8) {} } -//@ set m1_use = "$.index[*][?(@.docs=='m1 re-export')].id" -//@ is "$.index[*].inner.use[?(@.name=='m1')].id" $m1 -//@ is "$.index[*].inner.use[?(@.name=='m1')].is_glob" true +//@ set m1_use = "$.index[?(@.docs=='m1 re-export')].id" +//@ is "$.index[?(@.inner.use.name=='m1')].inner.use.id" $m1 +//@ is "$.index[?(@.inner.use.name=='m1')].inner.use.is_glob" true /// m1 re-export pub use m1::*; -//@ set m2_use = "$.index[*][?(@.docs=='m2 re-export')].id" -//@ is "$.index[*].inner.use[?(@.name=='m2')].id" $m2 -//@ is "$.index[*].inner.use[?(@.name=='m2')].is_glob" true +//@ set m2_use = "$.index[?(@.docs=='m2 re-export')].id" +//@ is "$.index[?(@.inner.use.name=='m2')].inner.use.id" $m2 +//@ is "$.index[?(@.inner.use.name=='m2')].inner.use.is_glob" true /// m2 re-export pub use m2::*; -//@ ismany "$.index[*].inner.module[?(@.is_crate==true)].items[*]" $m1_use $m2_use +//@ ismany "$.index[?(@.name=='glob_collision')].inner.module.items[*]" $m1_use $m2_use diff --git a/tests/rustdoc-json/reexport/glob_empty_mod.rs b/tests/rustdoc-json/reexport/glob_empty_mod.rs index ee1779407f4..69c0c0e6d5f 100644 --- a/tests/rustdoc-json/reexport/glob_empty_mod.rs +++ b/tests/rustdoc-json/reexport/glob_empty_mod.rs @@ -1,8 +1,8 @@ // Regression test for https://github.com/rust-lang/rust/issues/100973 -//@ is "$.index[*][?(@.name=='m1' && @.inner.module)].inner.module.is_stripped" true -//@ set m1 = "$.index[*][?(@.name=='m1')].id" +//@ is "$.index[?(@.name=='m1' && @.inner.module)].inner.module.is_stripped" true +//@ set m1 = "$.index[?(@.name=='m1')].id" mod m1 {} -//@ is "$.index[*][?(@.inner.use)].inner.use.id" $m1 +//@ is "$.index[?(@.inner.use)].inner.use.id" $m1 pub use m1::*; diff --git a/tests/rustdoc-json/reexport/glob_extern.rs b/tests/rustdoc-json/reexport/glob_extern.rs index 98be4773941..ccc6faffc8e 100644 --- a/tests/rustdoc-json/reexport/glob_extern.rs +++ b/tests/rustdoc-json/reexport/glob_extern.rs @@ -1,19 +1,19 @@ //@ edition:2018 -//@ is "$.index[*][?(@.name=='mod1')].inner.module.is_stripped" "true" +//@ is "$.index[?(@.name=='mod1')].inner.module.is_stripped" "true" mod mod1 { extern "C" { - //@ set public_fn_id = "$.index[*][?(@.name=='public_fn')].id" + //@ set public_fn_id = "$.index[?(@.name=='public_fn')].id" pub fn public_fn(); - //@ !has "$.index[*][?(@.name=='private_fn')]" + //@ !has "$.index[?(@.name=='private_fn')]" fn private_fn(); } - //@ ismany "$.index[*][?(@.name=='mod1')].inner.module.items[*]" $public_fn_id - //@ set mod1_id = "$.index[*][?(@.name=='mod1')].id" + //@ ismany "$.index[?(@.name=='mod1')].inner.module.items[*]" $public_fn_id + //@ set mod1_id = "$.index[?(@.name=='mod1')].id" } -//@ is "$.index[*][?(@.inner.use)].inner.use.is_glob" true -//@ is "$.index[*][?(@.inner.use)].inner.use.id" $mod1_id -//@ set use_id = "$.index[*][?(@.inner.use)].id" -//@ ismany "$.index[*][?(@.name=='glob_extern')].inner.module.items[*]" $use_id +//@ is "$.index[?(@.inner.use)].inner.use.is_glob" true +//@ is "$.index[?(@.inner.use)].inner.use.id" $mod1_id +//@ set use_id = "$.index[?(@.inner.use)].id" +//@ ismany "$.index[?(@.name=='glob_extern')].inner.module.items[*]" $use_id pub use mod1::*; diff --git a/tests/rustdoc-json/reexport/glob_private.rs b/tests/rustdoc-json/reexport/glob_private.rs index 2084ffc356e..f232914787b 100644 --- a/tests/rustdoc-json/reexport/glob_private.rs +++ b/tests/rustdoc-json/reexport/glob_private.rs @@ -1,32 +1,32 @@ //@ edition:2018 -//@ is "$.index[*][?(@.name=='mod1')].inner.module.is_stripped" "true" +//@ is "$.index[?(@.name=='mod1')].inner.module.is_stripped" "true" mod mod1 { - //@ is "$.index[*][?(@.name=='mod2')].inner.module.is_stripped" "true" + //@ is "$.index[?(@.name=='mod2')].inner.module.is_stripped" "true" mod mod2 { - //@ set m2pub_id = "$.index[*][?(@.name=='Mod2Public')].id" + //@ set m2pub_id = "$.index[?(@.name=='Mod2Public')].id" pub struct Mod2Public; - //@ !has "$.index[*][?(@.name=='Mod2Private')]" + //@ !has "$.index[?(@.name=='Mod2Private')]" struct Mod2Private; } - //@ set mod2_use_id = "$.index[*][?(@.docs=='Mod2 re-export')].id" - //@ is "$.index[*][?(@.docs=='Mod2 re-export')].inner.use.name" \"mod2\" + //@ set mod2_use_id = "$.index[?(@.docs=='Mod2 re-export')].id" + //@ is "$.index[?(@.docs=='Mod2 re-export')].inner.use.name" \"mod2\" /// Mod2 re-export pub use self::mod2::*; - //@ set m1pub_id = "$.index[*][?(@.name=='Mod1Public')].id" + //@ set m1pub_id = "$.index[?(@.name=='Mod1Public')].id" pub struct Mod1Public; - //@ !has "$.index[*][?(@.name=='Mod1Private')]" + //@ !has "$.index[?(@.name=='Mod1Private')]" struct Mod1Private; } -//@ set mod1_use_id = "$.index[*][?(@.docs=='Mod1 re-export')].id" -//@ is "$.index[*][?(@.docs=='Mod1 re-export')].inner.use.name" \"mod1\" +//@ set mod1_use_id = "$.index[?(@.docs=='Mod1 re-export')].id" +//@ is "$.index[?(@.docs=='Mod1 re-export')].inner.use.name" \"mod1\" /// Mod1 re-export pub use mod1::*; -//@ ismany "$.index[*][?(@.name=='mod2')].inner.module.items[*]" $m2pub_id -//@ ismany "$.index[*][?(@.name=='mod1')].inner.module.items[*]" $m1pub_id $mod2_use_id -//@ ismany "$.index[*][?(@.name=='glob_private')].inner.module.items[*]" $mod1_use_id +//@ ismany "$.index[?(@.name=='mod2')].inner.module.items[*]" $m2pub_id +//@ ismany "$.index[?(@.name=='mod1')].inner.module.items[*]" $m1pub_id $mod2_use_id +//@ ismany "$.index[?(@.name=='glob_private')].inner.module.items[*]" $mod1_use_id diff --git a/tests/rustdoc-json/reexport/in_root_and_mod.rs b/tests/rustdoc-json/reexport/in_root_and_mod.rs index a1d2080c068..005004e3b86 100644 --- a/tests/rustdoc-json/reexport/in_root_and_mod.rs +++ b/tests/rustdoc-json/reexport/in_root_and_mod.rs @@ -1,13 +1,13 @@ -//@ !has "$.index[*][?(@.name=='foo')]" +//@ !has "$.index[*].name" '"foo"' mod foo { - //@ has "$.index[*][?(@.name=='Foo')]" + //@ has "$.index[*].name" '"Foo"' pub struct Foo; } -//@ has "$.index[*].inner[?(@.use.source=='foo::Foo')]" +//@ has "$.index[*].inner.use.source" '"foo::Foo"' pub use foo::Foo; pub mod bar { - //@ has "$.index[*].inner[?(@.use.source=='crate::foo::Foo')]" + //@ has "$.index[*].inner.use.source" '"crate::foo::Foo"' pub use crate::foo::Foo; } diff --git a/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs b/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs index 7d26d2a970d..54dda2a3cd0 100644 --- a/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs +++ b/tests/rustdoc-json/reexport/in_root_and_mod_pub.rs @@ -1,19 +1,19 @@ pub mod foo { - //@ set bar_id = "$.index[*][?(@.name=='Bar')].id" - //@ ismany "$.index[*][?(@.name=='foo')].inner.module.items[*]" $bar_id + //@ set bar_id = "$.index[?(@.name=='Bar')].id" + //@ ismany "$.index[?(@.name=='foo')].inner.module.items[*]" $bar_id pub struct Bar; } -//@ set root_import_id = "$.index[*][?(@.docs=='Outer re-export')].id" -//@ is "$.index[*].inner[?(@.use.source=='foo::Bar')].use.id" $bar_id -//@ has "$.index[*][?(@.name=='in_root_and_mod_pub')].inner.module.items[*]" $root_import_id +//@ set root_import_id = "$.index[?(@.docs=='Outer re-export')].id" +//@ is "$.index[?(@.inner.use.source=='foo::Bar')].inner.use.id" $bar_id +//@ has "$.index[?(@.name=='in_root_and_mod_pub')].inner.module.items[*]" $root_import_id /// Outer re-export pub use foo::Bar; pub mod baz { - //@ set baz_import_id = "$.index[*][?(@.docs=='Inner re-export')].id" - //@ is "$.index[*].inner[?(@.use.source=='crate::foo::Bar')].use.id" $bar_id - //@ ismany "$.index[*][?(@.name=='baz')].inner.module.items[*]" $baz_import_id + //@ set baz_import_id = "$.index[?(@.docs=='Inner re-export')].id" + //@ is "$.index[?(@.inner.use.source=='crate::foo::Bar')].inner.use.id" $bar_id + //@ ismany "$.index[?(@.name=='baz')].inner.module.items[*]" $baz_import_id /// Inner re-export pub use crate::foo::Bar; } diff --git a/tests/rustdoc-json/reexport/macro.rs b/tests/rustdoc-json/reexport/macro.rs index f182208c341..0bd37768255 100644 --- a/tests/rustdoc-json/reexport/macro.rs +++ b/tests/rustdoc-json/reexport/macro.rs @@ -1,13 +1,13 @@ //@ edition:2018 -//@ set repro_id = "$.index[*][?(@.name=='repro')].id" +//@ set repro_id = "$.index[?(@.name=='repro')].id" #[macro_export] macro_rules! repro { () => {}; } -//@ set repro2_id = "$.index[*][?(@.docs=='Re-export')].id" +//@ set repro2_id = "$.index[?(@.docs=='Re-export')].id" /// Re-export pub use crate::repro as repro2; -//@ ismany "$.index[*][?(@.name=='macro')].inner.module.items[*]" $repro_id $repro2_id +//@ ismany "$.index[?(@.name=='macro')].inner.module.items[*]" $repro_id $repro2_id diff --git a/tests/rustdoc-json/reexport/mod_not_included.rs b/tests/rustdoc-json/reexport/mod_not_included.rs index d0ce95749f1..59e5fff59c9 100644 --- a/tests/rustdoc-json/reexport/mod_not_included.rs +++ b/tests/rustdoc-json/reexport/mod_not_included.rs @@ -6,6 +6,6 @@ mod m1 { pub use m1::x; -//@ has "$.index[*][?(@.name=='x' && @.inner.function)]" -//@ has "$.index[*].inner[?(@.use.name=='x')].use.source" '"m1::x"' -//@ !has "$.index[*][?(@.name=='m1')]" +//@ has "$.index[?(@.name=='x' && @.inner.function)]" +//@ has "$.index[?(@.inner.use.name=='x')].inner.use.source" '"m1::x"' +//@ !has "$.index[?(@.name=='m1')]" diff --git a/tests/rustdoc-json/reexport/private_twice_one_inline.rs b/tests/rustdoc-json/reexport/private_twice_one_inline.rs index fdf8cda103b..6b5d03e207e 100644 --- a/tests/rustdoc-json/reexport/private_twice_one_inline.rs +++ b/tests/rustdoc-json/reexport/private_twice_one_inline.rs @@ -5,19 +5,19 @@ extern crate pub_struct as foo; #[doc(inline)] -//@ set crate_use_id = "$.index[*][?(@.docs=='Hack A')].id" -//@ set foo_id = "$.index[*][?(@.docs=='Hack A')].inner.use.id" +//@ set crate_use_id = "$.index[?(@.docs=='Hack A')].id" +//@ set foo_id = "$.index[?(@.docs=='Hack A')].inner.use.id" /// Hack A pub use foo::Foo; -//@ set bar_id = "$.index[*][?(@.name=='bar')].id" +//@ set bar_id = "$.index[?(@.name=='bar')].id" pub mod bar { - //@ is "$.index[*][?(@.docs=='Hack B')].inner.use.id" $foo_id - //@ set bar_use_id = "$.index[*][?(@.docs=='Hack B')].id" - //@ ismany "$.index[*][?(@.name=='bar')].inner.module.items[*]" $bar_use_id + //@ is "$.index[?(@.docs=='Hack B')].inner.use.id" $foo_id + //@ set bar_use_id = "$.index[?(@.docs=='Hack B')].id" + //@ ismany "$.index[?(@.name=='bar')].inner.module.items[*]" $bar_use_id /// Hack B pub use foo::Foo; } -//@ ismany "$.index[*][?(@.inner.use)].id" $crate_use_id $bar_use_id -//@ ismany "$.index[*][?(@.name=='private_twice_one_inline')].inner.module.items[*]" $bar_id $crate_use_id +//@ ismany "$.index[?(@.inner.use)].id" $crate_use_id $bar_use_id +//@ ismany "$.index[?(@.name=='private_twice_one_inline')].inner.module.items[*]" $bar_id $crate_use_id diff --git a/tests/rustdoc-json/reexport/private_two_names.rs b/tests/rustdoc-json/reexport/private_two_names.rs index 049100d7f49..79af40b83a4 100644 --- a/tests/rustdoc-json/reexport/private_two_names.rs +++ b/tests/rustdoc-json/reexport/private_two_names.rs @@ -1,21 +1,21 @@ // Test for the ICE in https://github.com/rust-lang/rust/issues/83720 // A pub-in-private type re-exported under two different names shouldn't cause an error -//@ !has "$.index[*][?(@.name=='style')]" +//@ !has "$.index[?(@.name=='style')]" mod style { - //@ set color_struct_id = "$.index[*][?(@.inner.struct && @.name=='Color')].id" + //@ set color_struct_id = "$.index[?(@.inner.struct && @.name=='Color')].id" pub struct Color; } -//@ is "$.index[*][?(@.docs=='First re-export')].inner.use.id" $color_struct_id -//@ is "$.index[*][?(@.docs=='First re-export')].inner.use.name" \"Color\" -//@ set color_export_id = "$.index[*][?(@.docs=='First re-export')].id" +//@ is "$.index[?(@.docs=='First re-export')].inner.use.id" $color_struct_id +//@ is "$.index[?(@.docs=='First re-export')].inner.use.name" \"Color\" +//@ set color_export_id = "$.index[?(@.docs=='First re-export')].id" /// First re-export pub use style::Color; -//@ is "$.index[*][?(@.docs=='Second re-export')].inner.use.id" $color_struct_id -//@ is "$.index[*][?(@.docs=='Second re-export')].inner.use.name" \"Colour\" -//@ set colour_export_id = "$.index[*][?(@.docs=='Second re-export')].id" +//@ is "$.index[?(@.docs=='Second re-export')].inner.use.id" $color_struct_id +//@ is "$.index[?(@.docs=='Second re-export')].inner.use.name" \"Colour\" +//@ set colour_export_id = "$.index[?(@.docs=='Second re-export')].id" /// Second re-export pub use style::Color as Colour; -//@ ismany "$.index[*][?(@.name=='private_two_names')].inner.module.items[*]" $color_export_id $colour_export_id +//@ ismany "$.index[?(@.name=='private_two_names')].inner.module.items[*]" $color_export_id $colour_export_id diff --git a/tests/rustdoc-json/reexport/pub_use_doc_hidden.rs b/tests/rustdoc-json/reexport/pub_use_doc_hidden.rs index e021b51ab4b..129ccb7e2eb 100644 --- a/tests/rustdoc-json/reexport/pub_use_doc_hidden.rs +++ b/tests/rustdoc-json/reexport/pub_use_doc_hidden.rs @@ -9,5 +9,5 @@ mod repeat_n { /// not here pub use repeat_n::RepeatN; -//@ count "$.index[*][?(@.name=='pub_use_doc_hidden')].inner.items[*]" 0 -//@ !has "$.index[*][?(@.docs == 'not here')]" +//@ count "$.index[?(@.name=='pub_use_doc_hidden')].inner.items[*]" 0 +//@ !has "$.index[?(@.docs == 'not here')]" diff --git a/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs b/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs index 25edd5dbb28..56922340a6f 100644 --- a/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs +++ b/tests/rustdoc-json/reexport/reexport_method_from_private_module.rs @@ -1,11 +1,11 @@ // Regression test for <https://github.com/rust-lang/rust/issues/102583>. -//@ set impl_S = "$.index[*][?(@.docs=='impl S')].id" -//@ has "$.index[*][?(@.name=='S')].inner.struct.impls[*]" $impl_S -//@ set is_present = "$.index[*][?(@.name=='is_present')].id" -//@ is "$.index[*][?(@.docs=='impl S')].inner.impl.items[*]" $is_present -//@ !has "$.index[*][?(@.name=='hidden_impl')]" -//@ !has "$.index[*][?(@.name=='hidden_fn')]" +//@ set impl_S = "$.index[?(@.docs=='impl S')].id" +//@ has "$.index[?(@.name=='S')].inner.struct.impls[*]" $impl_S +//@ set is_present = "$.index[?(@.name=='is_present')].id" +//@ is "$.index[?(@.docs=='impl S')].inner.impl.items[*]" $is_present +//@ !has "$.index[?(@.name=='hidden_impl')]" +//@ !has "$.index[?(@.name=='hidden_fn')]" #![no_std] diff --git a/tests/rustdoc-json/reexport/reexport_of_hidden.rs b/tests/rustdoc-json/reexport/reexport_of_hidden.rs index 80f171da888..119e699d815 100644 --- a/tests/rustdoc-json/reexport/reexport_of_hidden.rs +++ b/tests/rustdoc-json/reexport/reexport_of_hidden.rs @@ -1,7 +1,7 @@ //@ compile-flags: --document-hidden-items -//@ has "$.index[*].inner[?(@.use.name=='UsedHidden')]" -//@ has "$.index[*][?(@.name=='Hidden')]" +//@ has "$.index[*].inner.use.name" '"UsedHidden"' +//@ has "$.index[*].name" '"Hidden"' pub mod submodule { #[doc(hidden)] pub struct Hidden {} diff --git a/tests/rustdoc-json/reexport/rename_private.rs b/tests/rustdoc-json/reexport/rename_private.rs index 3f13f305d64..0494dff5bca 100644 --- a/tests/rustdoc-json/reexport/rename_private.rs +++ b/tests/rustdoc-json/reexport/rename_private.rs @@ -1,10 +1,10 @@ //@ edition:2018 -//@ !has "$.index[*][?(@.name=='inner')]" +//@ !has "$.index[?(@.name=='inner')]" mod inner { - //@ has "$.index[*][?(@.name=='Public')]" + //@ has "$.index[?(@.name=='Public')]" pub struct Public; } -//@ is "$.index[*][?(@.inner.use)].inner.use.name" \"NewName\" +//@ is "$.index[?(@.inner.use)].inner.use.name" \"NewName\" pub use inner::Public as NewName; diff --git a/tests/rustdoc-json/reexport/rename_public.rs b/tests/rustdoc-json/reexport/rename_public.rs index 81c003a51c4..a3d712358f2 100644 --- a/tests/rustdoc-json/reexport/rename_public.rs +++ b/tests/rustdoc-json/reexport/rename_public.rs @@ -1,15 +1,15 @@ //@ edition:2018 -//@ set inner_id = "$.index[*][?(@.name=='inner')].id" +//@ set inner_id = "$.index[?(@.name=='inner')].id" pub mod inner { - //@ set public_id = "$.index[*][?(@.name=='Public')].id" - //@ ismany "$.index[*][?(@.name=='inner')].inner.module.items[*]" $public_id + //@ set public_id = "$.index[?(@.name=='Public')].id" + //@ ismany "$.index[?(@.name=='inner')].inner.module.items[*]" $public_id pub struct Public; } -//@ set import_id = "$.index[*][?(@.docs=='Re-export')].id" -//@ !has "$.index[*].inner[?(@.use.name=='Public')]" -//@ is "$.index[*].inner[?(@.use.name=='NewName')].use.source" \"inner::Public\" +//@ set import_id = "$.index[?(@.docs=='Re-export')].id" +//@ !has "$.index[?(@.inner.use.name=='Public')]" +//@ is "$.index[?(@.inner.use.name=='NewName')].inner.use.source" \"inner::Public\" /// Re-export pub use inner::Public as NewName; -//@ ismany "$.index[*][?(@.name=='rename_public')].inner.module.items[*]" $inner_id $import_id +//@ ismany "$.index[?(@.name=='rename_public')].inner.module.items[*]" $inner_id $import_id diff --git a/tests/rustdoc-json/reexport/same_name_different_types.rs b/tests/rustdoc-json/reexport/same_name_different_types.rs index 760e2c6f775..6e7ad3393e5 100644 --- a/tests/rustdoc-json/reexport/same_name_different_types.rs +++ b/tests/rustdoc-json/reexport/same_name_different_types.rs @@ -1,22 +1,22 @@ // Regression test for <https://github.com/rust-lang/rust/issues/107677>. pub mod nested { - //@ set foo_struct = "$.index[*][?(@.docs == 'Foo the struct')].id" + //@ set foo_struct = "$.index[?(@.docs == 'Foo the struct')].id" /// Foo the struct pub struct Foo {} - //@ set foo_fn = "$.index[*][?(@.docs == 'Foo the function')].id" + //@ set foo_fn = "$.index[?(@.docs == 'Foo the function')].id" #[allow(non_snake_case)] /// Foo the function pub fn Foo() {} } -//@ ismany "$.index[*].inner[?(@.use.name == 'Foo')].use.id" $foo_fn $foo_struct -//@ ismany "$.index[*].inner[?(@.use.name == 'Bar')].use.id" $foo_fn $foo_struct +//@ ismany "$.index[?(@.inner.use.name == 'Foo')].inner.use.id" $foo_fn $foo_struct +//@ ismany "$.index[?(@.inner.use.name == 'Bar')].inner.use.id" $foo_fn $foo_struct -//@ count "$.index[*].inner[?(@.use.name == 'Foo')]" 2 -//@ count "$.index[*].inner[?(@.use.name == 'Bar')]" 2 +//@ count "$.index[?(@.inner.use.name == 'Foo')]" 2 +//@ count "$.index[?(@.inner.use.name == 'Bar')]" 2 pub use Foo as Bar; pub use nested::Foo; diff --git a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs index f313171afa5..05b55c7b12a 100644 --- a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs +++ b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs @@ -3,17 +3,17 @@ #![no_std] mod inner { - //@ set trait_id = "$.index[*][?(@.name=='Trait')].id" + //@ set trait_id = "$.index[?(@.name=='Trait')].id" pub trait Trait {} } -//@ set export_id = "$.index[*][?(@.docs=='First re-export')].id" -//@ is "$.index[*].inner[?(@.use.name=='Trait')].use.id" $trait_id +//@ set export_id = "$.index[?(@.docs=='First re-export')].id" +//@ is "$.index[?(@.inner.use.name=='Trait')].inner.use.id" $trait_id /// First re-export pub use inner::Trait; -//@ set reexport_id = "$.index[*][?(@.docs=='Second re-export')].id" -//@ is "$.index[*].inner[?(@.use.name=='Reexport')].use.id" $trait_id +//@ set reexport_id = "$.index[?(@.docs=='Second re-export')].id" +//@ is "$.index[?(@.inner.use.name=='Reexport')].inner.use.id" $trait_id /// Second re-export pub use inner::Trait as Reexport; -//@ ismany "$.index[*][?(@.name=='same_type_reexported_more_than_once')].inner.module.items[*]" $reexport_id $export_id +//@ ismany "$.index[?(@.name=='same_type_reexported_more_than_once')].inner.module.items[*]" $reexport_id $export_id diff --git a/tests/rustdoc-json/reexport/simple_private.rs b/tests/rustdoc-json/reexport/simple_private.rs index 405d57d342e..40be1708dc6 100644 --- a/tests/rustdoc-json/reexport/simple_private.rs +++ b/tests/rustdoc-json/reexport/simple_private.rs @@ -1,20 +1,20 @@ //@ edition:2018 -//@ !has "$.index[*][?(@.name=='inner')]" +//@ !has "$.index[?(@.name=='inner')]" mod inner { - //@ set pub_id = "$.index[*][?(@.name=='Public')].id" + //@ set pub_id = "$.index[?(@.name=='Public')].id" pub struct Public; } -//@ is "$.index[*][?(@.inner.use)].inner.use.name" \"Public\" -//@ is "$.index[*][?(@.inner.use)].inner.use.id" $pub_id -//@ set use_id = "$.index[*][?(@.inner.use)].id" +//@ is "$.index[?(@.inner.use)].inner.use.name" \"Public\" +//@ is "$.index[?(@.inner.use)].inner.use.id" $pub_id +//@ set use_id = "$.index[?(@.inner.use)].id" pub use inner::Public; -//@ ismany "$.index[*][?(@.name=='simple_private')].inner.module.items[*]" $use_id +//@ ismany "$.index[?(@.name=='simple_private')].inner.module.items[*]" $use_id // Test for https://github.com/rust-lang/rust/issues/135309 -//@ has "$.paths[*][?(@.kind=='module')].path" '["simple_private"]' +//@ has "$.paths[?(@.kind=='module')].path" '["simple_private"]' //@ !has "$.paths[*].path" '["simple_private", "inner"]' -//@ has "$.paths[*][?(@.kind=='struct')].path" '["simple_private", "inner", "Public"]' +//@ has "$.paths[?(@.kind=='struct')].path" '["simple_private", "inner", "Public"]' //@ !has "$.paths[*].path" '["simple_private", "Public"]' diff --git a/tests/rustdoc-json/reexport/simple_public.rs b/tests/rustdoc-json/reexport/simple_public.rs index f1335828314..cdb6c0dc88a 100644 --- a/tests/rustdoc-json/reexport/simple_public.rs +++ b/tests/rustdoc-json/reexport/simple_public.rs @@ -1,21 +1,21 @@ //@ edition:2018 -//@ set inner_id = "$.index[*][?(@.name=='inner')].id" +//@ set inner_id = "$.index[?(@.name=='inner')].id" pub mod inner { - //@ set public_id = "$.index[*][?(@.name=='Public')].id" - //@ ismany "$.index[*][?(@.name=='inner')].inner.module.items[*]" $public_id + //@ set public_id = "$.index[?(@.name=='Public')].id" + //@ ismany "$.index[?(@.name=='inner')].inner.module.items[*]" $public_id pub struct Public; } -//@ set import_id = "$.index[*][?(@.docs=='Outer')].id" -//@ is "$.index[*][?(@.docs=='Outer')].inner.use.source" \"inner::Public\" +//@ set import_id = "$.index[?(@.docs=='Outer')].id" +//@ is "$.index[?(@.docs=='Outer')].inner.use.source" \"inner::Public\" /// Outer pub use inner::Public; -//@ ismany "$.index[*][?(@.name=='simple_public')].inner.module.items[*]" $import_id $inner_id +//@ ismany "$.index[?(@.name=='simple_public')].inner.module.items[*]" $import_id $inner_id -//@ has "$.paths[*][?(@.kind=='module')].path" '["simple_public"]' -//@ has "$.paths[*][?(@.kind=='module')].path" '["simple_public", "inner"]' -//@ has "$.paths[*][?(@.kind=='struct')].path" '["simple_public", "inner", "Public"]' +//@ has "$.paths[?(@.kind=='module')].path" '["simple_public"]' +//@ has "$.paths[?(@.kind=='module')].path" '["simple_public", "inner"]' +//@ has "$.paths[?(@.kind=='struct')].path" '["simple_public", "inner", "Public"]' //@ !has "$.paths[*].path" '["simple_public", "Public"]' diff --git a/tests/rustdoc-json/reexport/synthesize_trait_with_docs.rs b/tests/rustdoc-json/reexport/synthesize_trait_with_docs.rs index 59699e4861b..89591690bca 100644 --- a/tests/rustdoc-json/reexport/synthesize_trait_with_docs.rs +++ b/tests/rustdoc-json/reexport/synthesize_trait_with_docs.rs @@ -7,4 +7,4 @@ pub struct Local; impl trait_with_docs::HasDocs for Local {} -//@ !has "$.index[*][?(@.name == 'HasDocs')]" +//@ !has "$.index[?(@.name == 'HasDocs')]" diff --git a/tests/rustdoc-json/return-type-notation.rs b/tests/rustdoc-json/return-type-notation.rs index 2219642bfc5..7943991616b 100644 --- a/tests/rustdoc-json/return-type-notation.rs +++ b/tests/rustdoc-json/return-type-notation.rs @@ -8,8 +8,8 @@ pub trait Foo { async fn bar(); } -//@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.args.angle_bracketed.constraints[0].args" '"return_type_notation"' -//@ ismany "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates[*].bound_predicate.type.qualified_path.args" '"return_type_notation"' '"return_type_notation"' +//@ is "$.index[?(@.name=='foo')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.args.angle_bracketed.constraints[0].args" '"return_type_notation"' +//@ ismany "$.index[?(@.name=='foo')].inner.function.generics.where_predicates[*].bound_predicate.type.qualified_path.args" '"return_type_notation"' '"return_type_notation"' pub fn foo<T: Foo<bar(..): Send>>() where <T as Foo>::bar(..): 'static, diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs index 214fda14aca..8fbdb6be5c9 100644 --- a/tests/rustdoc-json/return_private.rs +++ b/tests/rustdoc-json/return_private.rs @@ -1,13 +1,13 @@ // Regression test for <https://github.com/rust-lang/rust/issues/96161>. mod secret { - //@ set struct_secret = "$.index[*][?(@.name == 'Secret' && @.inner.struct)].id" + //@ set struct_secret = "$.index[?(@.name == 'Secret' && @.inner.struct)].id" pub struct Secret; } -//@ has "$.index[*][?(@.name=='get_secret')].inner.function" -//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.path" '"secret::Secret"' -//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.id" $struct_secret +//@ has "$.index[?(@.name=='get_secret')].inner.function" +//@ is "$.index[?(@.name=='get_secret')].inner.function.sig.output.resolved_path.path" '"secret::Secret"' +//@ is "$.index[?(@.name=='get_secret')].inner.function.sig.output.resolved_path.id" $struct_secret pub fn get_secret() -> secret::Secret { secret::Secret } diff --git a/tests/rustdoc-json/statics/extern.rs b/tests/rustdoc-json/statics/extern.rs index 9e0265da8e2..5be13c8b8fc 100644 --- a/tests/rustdoc-json/statics/extern.rs +++ b/tests/rustdoc-json/statics/extern.rs @@ -1,38 +1,38 @@ //@ edition: 2021 extern "C" { - //@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false + //@ is '$.index[?(@.name=="A")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="A")].inner.static.is_mutable' false pub static A: i32; - //@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true + //@ is '$.index[?(@.name=="B")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="B")].inner.static.is_mutable' true pub static mut B: i32; // items in unadorned `extern` blocks cannot have safety qualifiers } unsafe extern "C" { - //@ is '$.index[*][?(@.name=="C")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="C")].inner.static.is_mutable' false + //@ is '$.index[?(@.name=="C")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="C")].inner.static.is_mutable' false pub static C: i32; - //@ is '$.index[*][?(@.name=="D")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="D")].inner.static.is_mutable' true + //@ is '$.index[?(@.name=="D")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="D")].inner.static.is_mutable' true pub static mut D: i32; - //@ is '$.index[*][?(@.name=="E")].inner.static.is_unsafe' false - //@ is '$.index[*][?(@.name=="E")].inner.static.is_mutable' false + //@ is '$.index[?(@.name=="E")].inner.static.is_unsafe' false + //@ is '$.index[?(@.name=="E")].inner.static.is_mutable' false pub safe static E: i32; - //@ is '$.index[*][?(@.name=="F")].inner.static.is_unsafe' false - //@ is '$.index[*][?(@.name=="F")].inner.static.is_mutable' true + //@ is '$.index[?(@.name=="F")].inner.static.is_unsafe' false + //@ is '$.index[?(@.name=="F")].inner.static.is_mutable' true pub safe static mut F: i32; - //@ is '$.index[*][?(@.name=="G")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="G")].inner.static.is_mutable' false + //@ is '$.index[?(@.name=="G")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="G")].inner.static.is_mutable' false pub unsafe static G: i32; - //@ is '$.index[*][?(@.name=="H")].inner.static.is_unsafe' true - //@ is '$.index[*][?(@.name=="H")].inner.static.is_mutable' true + //@ is '$.index[?(@.name=="H")].inner.static.is_unsafe' true + //@ is '$.index[?(@.name=="H")].inner.static.is_mutable' true pub unsafe static mut H: i32; } -//@ ismany '$.index[*][?(@.inner.static)].inner.static.expr' '""' '""' '""' '""' '""' '""' '""' '""' -//@ ismany '$.index[*][?(@.inner.static)].inner.static.type.primitive' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' +//@ ismany '$.index[?(@.inner.static)].inner.static.expr' '""' '""' '""' '""' '""' '""' '""' '""' +//@ ismany '$.index[?(@.inner.static)].inner.static.type.primitive' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' '"i32"' diff --git a/tests/rustdoc-json/statics/statics.rs b/tests/rustdoc-json/statics/statics.rs index a8af23cc87d..497a134c503 100644 --- a/tests/rustdoc-json/statics/statics.rs +++ b/tests/rustdoc-json/statics/statics.rs @@ -1,12 +1,12 @@ -//@ is '$.index[*][?(@.name=="A")].inner.static.type.primitive' '"i32"' -//@ is '$.index[*][?(@.name=="A")].inner.static.is_mutable' false -//@ is '$.index[*][?(@.name=="A")].inner.static.expr' '"5"' -//@ is '$.index[*][?(@.name=="A")].inner.static.is_unsafe' false +//@ is '$.index[?(@.name=="A")].inner.static.type.primitive' '"i32"' +//@ is '$.index[?(@.name=="A")].inner.static.is_mutable' false +//@ is '$.index[?(@.name=="A")].inner.static.expr' '"5"' +//@ is '$.index[?(@.name=="A")].inner.static.is_unsafe' false pub static A: i32 = 5; -//@ is '$.index[*][?(@.name=="B")].inner.static.type.primitive' '"u32"' -//@ is '$.index[*][?(@.name=="B")].inner.static.is_mutable' true +//@ is '$.index[?(@.name=="B")].inner.static.type.primitive' '"u32"' +//@ is '$.index[?(@.name=="B")].inner.static.is_mutable' true // Expr value isn't gaurenteed, it'd be fine to change it. -//@ is '$.index[*][?(@.name=="B")].inner.static.expr' '"_"' -//@ is '$.index[*][?(@.name=="B")].inner.static.is_unsafe' false +//@ is '$.index[?(@.name=="B")].inner.static.expr' '"_"' +//@ is '$.index[?(@.name=="B")].inner.static.is_unsafe' false pub static mut B: u32 = 2 + 3; diff --git a/tests/rustdoc-json/stripped_modules.rs b/tests/rustdoc-json/stripped_modules.rs index d0db9c6588b..ba6644190a2 100644 --- a/tests/rustdoc-json/stripped_modules.rs +++ b/tests/rustdoc-json/stripped_modules.rs @@ -1,17 +1,17 @@ -//@ !has "$.index[*][?(@.name=='no_pub_inner')]" +//@ !has "$.index[?(@.name=='no_pub_inner')]" mod no_pub_inner { fn priv_inner() {} } -//@ !has "$.index[*][?(@.name=='pub_inner_unreachable')]" +//@ !has "$.index[?(@.name=='pub_inner_unreachable')]" mod pub_inner_unreachable { - //@ !has "$.index[*][?(@.name=='pub_inner_1')]" + //@ !has "$.index[?(@.name=='pub_inner_1')]" pub fn pub_inner_1() {} } -//@ !has "$.index[*][?(@.name=='pub_inner_reachable')]" +//@ !has "$.index[?(@.name=='pub_inner_reachable')]" mod pub_inner_reachable { - //@ has "$.index[*][?(@.name=='pub_inner_2')]" + //@ has "$.index[?(@.name=='pub_inner_2')]" pub fn pub_inner_2() {} } diff --git a/tests/rustdoc-json/structs/field_order.rs b/tests/rustdoc-json/structs/field_order.rs index 7e556df777f..eb1740676a6 100644 --- a/tests/rustdoc-json/structs/field_order.rs +++ b/tests/rustdoc-json/structs/field_order.rs @@ -15,24 +15,24 @@ pub struct Foo { pub vll_9: i32, } -//@ set 0 = '$.index[*][?(@.name == "ews_0")].id' -//@ set 1 = '$.index[*][?(@.name == "dik_1")].id' -//@ set 2 = '$.index[*][?(@.name == "hsk_2")].id' -//@ set 3 = '$.index[*][?(@.name == "djt_3")].id' -//@ set 4 = '$.index[*][?(@.name == "jnr_4")].id' -//@ set 5 = '$.index[*][?(@.name == "dfs_5")].id' -//@ set 6 = '$.index[*][?(@.name == "bja_6")].id' -//@ set 7 = '$.index[*][?(@.name == "lyc_7")].id' -//@ set 8 = '$.index[*][?(@.name == "yqd_8")].id' -//@ set 9 = '$.index[*][?(@.name == "vll_9")].id' +//@ set 0 = '$.index[?(@.name == "ews_0")].id' +//@ set 1 = '$.index[?(@.name == "dik_1")].id' +//@ set 2 = '$.index[?(@.name == "hsk_2")].id' +//@ set 3 = '$.index[?(@.name == "djt_3")].id' +//@ set 4 = '$.index[?(@.name == "jnr_4")].id' +//@ set 5 = '$.index[?(@.name == "dfs_5")].id' +//@ set 6 = '$.index[?(@.name == "bja_6")].id' +//@ set 7 = '$.index[?(@.name == "lyc_7")].id' +//@ set 8 = '$.index[?(@.name == "yqd_8")].id' +//@ set 9 = '$.index[?(@.name == "vll_9")].id' -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[0]' $0 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[1]' $1 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[2]' $2 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[3]' $3 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[4]' $4 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[5]' $5 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[6]' $6 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[7]' $7 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[8]' $8 -//@ is '$.index[*][?(@.name == "Foo")].inner.struct.kind.plain.fields[9]' $9 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[0]' $0 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[1]' $1 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[2]' $2 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[3]' $3 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[4]' $4 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[5]' $5 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[6]' $6 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[7]' $7 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[8]' $8 +//@ is '$.index[?(@.name == "Foo")].inner.struct.kind.plain.fields[9]' $9 diff --git a/tests/rustdoc-json/structs/plain_all_pub.rs b/tests/rustdoc-json/structs/plain_all_pub.rs index 67d2a4a7a8c..501044f62cc 100644 --- a/tests/rustdoc-json/structs/plain_all_pub.rs +++ b/tests/rustdoc-json/structs/plain_all_pub.rs @@ -3,9 +3,9 @@ pub struct Demo { pub y: i32, } -//@ set x = "$.index[*][?(@.name=='x')].id" -//@ set y = "$.index[*][?(@.name=='y')].id" -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[1]" $y -//@ count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 2 -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" false +//@ set x = "$.index[?(@.name=='x')].id" +//@ set y = "$.index[?(@.name=='y')].id" +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[1]" $y +//@ count "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 2 +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" false diff --git a/tests/rustdoc-json/structs/plain_doc_hidden.rs b/tests/rustdoc-json/structs/plain_doc_hidden.rs index 4573adc73fa..e62fb27ae86 100644 --- a/tests/rustdoc-json/structs/plain_doc_hidden.rs +++ b/tests/rustdoc-json/structs/plain_doc_hidden.rs @@ -4,8 +4,8 @@ pub struct Demo { pub y: i32, } -//@ set x = "$.index[*][?(@.name=='x')].id" -//@ !has "$.index[*][?(@.name=='y')].id" -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x -//@ count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1 -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" true +//@ set x = "$.index[?(@.name=='x')].id" +//@ !has "$.index[?(@.name=='y')].id" +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x +//@ count "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1 +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" true diff --git a/tests/rustdoc-json/structs/plain_empty.rs b/tests/rustdoc-json/structs/plain_empty.rs index 30013021abe..127f9ed1972 100644 --- a/tests/rustdoc-json/structs/plain_empty.rs +++ b/tests/rustdoc-json/structs/plain_empty.rs @@ -1,5 +1,5 @@ -//@ is "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='PlainEmpty')].inner.struct" -//@ is "$.index[*][?(@.name=='PlainEmpty')].inner.struct.kind.plain.has_stripped_fields" false -//@ is "$.index[*][?(@.name=='PlainEmpty')].inner.struct.kind.plain.fields" [] +//@ is "$.index[?(@.name=='PlainEmpty')].visibility" \"public\" +//@ has "$.index[?(@.name=='PlainEmpty')].inner.struct" +//@ is "$.index[?(@.name=='PlainEmpty')].inner.struct.kind.plain.has_stripped_fields" false +//@ is "$.index[?(@.name=='PlainEmpty')].inner.struct.kind.plain.fields" [] pub struct PlainEmpty {} diff --git a/tests/rustdoc-json/structs/plain_pub_priv.rs b/tests/rustdoc-json/structs/plain_pub_priv.rs index 91079a30d42..181d5ea0de2 100644 --- a/tests/rustdoc-json/structs/plain_pub_priv.rs +++ b/tests/rustdoc-json/structs/plain_pub_priv.rs @@ -3,7 +3,7 @@ pub struct Demo { y: i32, } -//@ set x = "$.index[*][?(@.name=='x')].id" -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x -//@ count "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1 -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" true +//@ set x = "$.index[?(@.name=='x')].id" +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[0]" $x +//@ count "$.index[?(@.name=='Demo')].inner.struct.kind.plain.fields[*]" 1 +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.plain.has_stripped_fields" true diff --git a/tests/rustdoc-json/structs/tuple.rs b/tests/rustdoc-json/structs/tuple.rs index 6c8dc79dfe2..115ce29bd70 100644 --- a/tests/rustdoc-json/structs/tuple.rs +++ b/tests/rustdoc-json/structs/tuple.rs @@ -1,4 +1,4 @@ -//@ is "$.index[*][?(@.name=='Tuple')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='Tuple')].inner.struct" -//@ is "$.index[*][?(@.name=='Tuple')].inner.struct.kind.tuple" '[null, null]' +//@ is "$.index[?(@.name=='Tuple')].visibility" \"public\" +//@ has "$.index[?(@.name=='Tuple')].inner.struct" +//@ is "$.index[?(@.name=='Tuple')].inner.struct.kind.tuple" '[null, null]' pub struct Tuple(u32, String); diff --git a/tests/rustdoc-json/structs/tuple_empty.rs b/tests/rustdoc-json/structs/tuple_empty.rs index 137915e6c05..af5b57fb133 100644 --- a/tests/rustdoc-json/structs/tuple_empty.rs +++ b/tests/rustdoc-json/structs/tuple_empty.rs @@ -1,2 +1,2 @@ -//@ is "$.index[*][?(@.name=='TupleUnit')].inner.struct.kind.tuple" [] +//@ is "$.index[?(@.name=='TupleUnit')].inner.struct.kind.tuple" [] pub struct TupleUnit(); diff --git a/tests/rustdoc-json/structs/tuple_pub_priv.rs b/tests/rustdoc-json/structs/tuple_pub_priv.rs index 11af26e6ea3..b97a17cc46a 100644 --- a/tests/rustdoc-json/structs/tuple_pub_priv.rs +++ b/tests/rustdoc-json/structs/tuple_pub_priv.rs @@ -5,9 +5,9 @@ pub struct Demo( #[doc(hidden)] i32, ); -//@ set field = "$.index[*][?(@.docs=='field')].id" +//@ set field = "$.index[?(@.docs=='field')].id" -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[0]" null -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[1]" $field -//@ is "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[2]" null -//@ count "$.index[*][?(@.name=='Demo')].inner.struct.kind.tuple[*]" 3 +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.tuple[0]" null +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.tuple[1]" $field +//@ is "$.index[?(@.name=='Demo')].inner.struct.kind.tuple[2]" null +//@ count "$.index[?(@.name=='Demo')].inner.struct.kind.tuple[*]" 3 diff --git a/tests/rustdoc-json/structs/unit.rs b/tests/rustdoc-json/structs/unit.rs index ad6af65c0e0..6a961725206 100644 --- a/tests/rustdoc-json/structs/unit.rs +++ b/tests/rustdoc-json/structs/unit.rs @@ -1,4 +1,4 @@ -//@ is "$.index[*][?(@.name=='Unit')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='Unit')].inner.struct" -//@ is "$.index[*][?(@.name=='Unit')].inner.struct.kind" \"unit\" +//@ is "$.index[?(@.name=='Unit')].visibility" \"public\" +//@ has "$.index[?(@.name=='Unit')].inner.struct" +//@ is "$.index[?(@.name=='Unit')].inner.struct.kind" \"unit\" pub struct Unit; diff --git a/tests/rustdoc-json/structs/with_generics.rs b/tests/rustdoc-json/structs/with_generics.rs index 3e7f175a5a1..979b002d0ee 100644 --- a/tests/rustdoc-json/structs/with_generics.rs +++ b/tests/rustdoc-json/structs/with_generics.rs @@ -1,13 +1,13 @@ use std::collections::HashMap; -//@ is "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='WithGenerics')].inner.struct" -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[0].name" \"T\" -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[0].kind.type.bounds" [] -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[1].name" \"U\" -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.generics.params[1].kind.type.bounds" [] -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.kind.plain.has_stripped_fields" true -//@ is "$.index[*][?(@.name=='WithGenerics')].inner.struct.kind.plain.fields" [] +//@ is "$.index[?(@.name=='WithGenerics')].visibility" \"public\" +//@ has "$.index[?(@.name=='WithGenerics')].inner.struct" +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.generics.params[0].name" \"T\" +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.generics.params[0].kind.type.bounds" [] +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.generics.params[1].name" \"U\" +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.generics.params[1].kind.type.bounds" [] +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.kind.plain.has_stripped_fields" true +//@ is "$.index[?(@.name=='WithGenerics')].inner.struct.kind.plain.fields" [] pub struct WithGenerics<T, U> { stuff: Vec<T>, things: HashMap<U, U>, diff --git a/tests/rustdoc-json/structs/with_primitives.rs b/tests/rustdoc-json/structs/with_primitives.rs index fe99292456d..4e856bda296 100644 --- a/tests/rustdoc-json/structs/with_primitives.rs +++ b/tests/rustdoc-json/structs/with_primitives.rs @@ -1,9 +1,9 @@ -//@ is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='WithPrimitives')].inner.struct" -//@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].name" \"\'a\" -//@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].kind.lifetime.outlives" [] -//@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.kind.plain.has_stripped_fields" true -//@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.kind.plain.fields" [] +//@ is "$.index[?(@.name=='WithPrimitives')].visibility" \"public\" +//@ has "$.index[?(@.name=='WithPrimitives')].inner.struct" +//@ is "$.index[?(@.name=='WithPrimitives')].inner.struct.generics.params[0].name" \"\'a\" +//@ is "$.index[?(@.name=='WithPrimitives')].inner.struct.generics.params[0].kind.lifetime.outlives" [] +//@ is "$.index[?(@.name=='WithPrimitives')].inner.struct.kind.plain.has_stripped_fields" true +//@ is "$.index[?(@.name=='WithPrimitives')].inner.struct.kind.plain.fields" [] pub struct WithPrimitives<'a> { num: u32, s: &'a str, diff --git a/tests/rustdoc-json/trait_alias.rs b/tests/rustdoc-json/trait_alias.rs index d9ef256b106..e7a586ee95a 100644 --- a/tests/rustdoc-json/trait_alias.rs +++ b/tests/rustdoc-json/trait_alias.rs @@ -1,17 +1,17 @@ #![feature(trait_alias)] -//@ set StrLike = "$.index[*][?(@.name=='StrLike')].id" -//@ is "$.index[*][?(@.name=='StrLike')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='StrLike')].inner.trait_alias" -//@ is "$.index[*][?(@.name=='StrLike')].span.filename" $FILE +//@ set StrLike = "$.index[?(@.name=='StrLike')].id" +//@ is "$.index[?(@.name=='StrLike')].visibility" \"public\" +//@ has "$.index[?(@.name=='StrLike')].inner.trait_alias" +//@ is "$.index[?(@.name=='StrLike')].span.filename" $FILE pub trait StrLike = AsRef<str>; -//@ is "$.index[*][?(@.name=='f')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $StrLike +//@ is "$.index[?(@.name=='f')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $StrLike pub fn f() -> impl StrLike { "heya" } -//@ !is "$.index[*][?(@.name=='g')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $StrLike +//@ !is "$.index[?(@.name=='g')].inner.function.sig.output.impl_trait[0].trait_bound.trait.id" $StrLike pub fn g() -> impl AsRef<str> { "heya" } diff --git a/tests/rustdoc-json/traits/has_body.rs b/tests/rustdoc-json/traits/has_body.rs index 95e0f97b52c..d17988474f9 100644 --- a/tests/rustdoc-json/traits/has_body.rs +++ b/tests/rustdoc-json/traits/has_body.rs @@ -1,21 +1,21 @@ -//@ has "$.index[*][?(@.name=='Foo')]" +//@ has "$.index[?(@.name=='Foo')]" pub trait Foo { - //@ is "$.index[*][?(@.name=='no_self')].inner.function.has_body" false + //@ is "$.index[?(@.name=='no_self')].inner.function.has_body" false fn no_self(); - //@ is "$.index[*][?(@.name=='move_self')].inner.function.has_body" false + //@ is "$.index[?(@.name=='move_self')].inner.function.has_body" false fn move_self(self); - //@ is "$.index[*][?(@.name=='ref_self')].inner.function.has_body" false + //@ is "$.index[?(@.name=='ref_self')].inner.function.has_body" false fn ref_self(&self); - //@ is "$.index[*][?(@.name=='no_self_def')].inner.function.has_body" true + //@ is "$.index[?(@.name=='no_self_def')].inner.function.has_body" true fn no_self_def() {} - //@ is "$.index[*][?(@.name=='move_self_def')].inner.function.has_body" true + //@ is "$.index[?(@.name=='move_self_def')].inner.function.has_body" true fn move_self_def(self) {} - //@ is "$.index[*][?(@.name=='ref_self_def')].inner.function.has_body" true + //@ is "$.index[?(@.name=='ref_self_def')].inner.function.has_body" true fn ref_self_def(&self) {} } pub trait Bar: Clone { - //@ is "$.index[*][?(@.name=='method')].inner.function.has_body" false + //@ is "$.index[?(@.name=='method')].inner.function.has_body" false fn method(&self, param: usize); } diff --git a/tests/rustdoc-json/traits/implementors.rs b/tests/rustdoc-json/traits/implementors.rs index 9fdb763b61e..499acefedb7 100644 --- a/tests/rustdoc-json/traits/implementors.rs +++ b/tests/rustdoc-json/traits/implementors.rs @@ -5,14 +5,14 @@ pub struct GeorgeMichael {} impl Wham for GeorgeMichael {} // Find IDs. -//@ set wham = "$.index[*][?(@.name=='Wham')].id" -//@ set gmWham = "$.index[*][?(@.docs=='Wham for George Michael')].id" -//@ set gm = "$.index[*][?(@.name=='GeorgeMichael')].id" +//@ set wham = "$.index[?(@.name=='Wham')].id" +//@ set gmWham = "$.index[?(@.docs=='Wham for George Michael')].id" +//@ set gm = "$.index[?(@.name=='GeorgeMichael')].id" // Both struct and trait point to impl. -//@ has "$.index[*][?(@.name=='GeorgeMichael')].inner.struct.impls[*]" $gmWham -//@ is "$.index[*][?(@.name=='Wham')].inner.trait.implementations[*]" $gmWham +//@ has "$.index[?(@.name=='GeorgeMichael')].inner.struct.impls[*]" $gmWham +//@ is "$.index[?(@.name=='Wham')].inner.trait.implementations[*]" $gmWham // Impl points to both struct and trait. -//@ is "$.index[*][?(@.docs == 'Wham for George Michael')].inner.impl.trait.id" $wham -//@ is "$.index[*][?(@.docs == 'Wham for George Michael')].inner.impl.for.resolved_path.id" $gm +//@ is "$.index[?(@.docs == 'Wham for George Michael')].inner.impl.trait.id" $wham +//@ is "$.index[?(@.docs == 'Wham for George Michael')].inner.impl.for.resolved_path.id" $gm diff --git a/tests/rustdoc-json/traits/is_dyn_compatible.rs b/tests/rustdoc-json/traits/is_dyn_compatible.rs index bccf94d17d6..b172b53807b 100644 --- a/tests/rustdoc-json/traits/is_dyn_compatible.rs +++ b/tests/rustdoc-json/traits/is_dyn_compatible.rs @@ -1,19 +1,19 @@ #![no_std] -//@ has "$.index[*][?(@.name=='FooDynIncompatible')]" -//@ is "$.index[*][?(@.name=='FooDynIncompatible')].inner.trait.is_dyn_compatible" false +//@ has "$.index[?(@.name=='FooDynIncompatible')]" +//@ is "$.index[?(@.name=='FooDynIncompatible')].inner.trait.is_dyn_compatible" false pub trait FooDynIncompatible { fn foo() -> Self; } -//@ has "$.index[*][?(@.name=='BarDynIncompatible')]" -//@ is "$.index[*][?(@.name=='BarDynIncompatible')].inner.trait.is_dyn_compatible" false +//@ has "$.index[?(@.name=='BarDynIncompatible')]" +//@ is "$.index[?(@.name=='BarDynIncompatible')].inner.trait.is_dyn_compatible" false pub trait BarDynIncompatible<T> { fn foo(i: T); } -//@ has "$.index[*][?(@.name=='FooDynCompatible')]" -//@ is "$.index[*][?(@.name=='FooDynCompatible')].inner.trait.is_dyn_compatible" true +//@ has "$.index[?(@.name=='FooDynCompatible')]" +//@ is "$.index[?(@.name=='FooDynCompatible')].inner.trait.is_dyn_compatible" true pub trait FooDynCompatible { fn foo(&self); } diff --git a/tests/rustdoc-json/traits/private_supertrait.rs b/tests/rustdoc-json/traits/private_supertrait.rs index ce0642278e0..1e11abaecdf 100644 --- a/tests/rustdoc-json/traits/private_supertrait.rs +++ b/tests/rustdoc-json/traits/private_supertrait.rs @@ -1,9 +1,9 @@ -//@ !has "$.index[*][?(@.name == 'sealed')]" +//@ !has "$.index[?(@.name == 'sealed')]" mod sealed { - //@ set sealed_id = "$.index[*][?(@.name=='Sealed')].id" + //@ set sealed_id = "$.index[?(@.name=='Sealed')].id" pub trait Sealed {} } -//@ count "$.index[*][?(@.name=='Trait')].inner.trait.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='Trait')].inner.trait.bounds[0].trait_bound.trait.id" $sealed_id +//@ count "$.index[?(@.name=='Trait')].inner.trait.bounds[*]" 1 +//@ is "$.index[?(@.name=='Trait')].inner.trait.bounds[0].trait_bound.trait.id" $sealed_id pub trait Trait: sealed::Sealed {} diff --git a/tests/rustdoc-json/traits/self.rs b/tests/rustdoc-json/traits/self.rs index efd9efd556f..018bda9cc3c 100644 --- a/tests/rustdoc-json/traits/self.rs +++ b/tests/rustdoc-json/traits/self.rs @@ -7,29 +7,29 @@ pub struct Foo; // Each assertion matches 3 times, and should be the same each time. impl Foo { - //@ ismany '$.index[*][?(@.name=="by_ref")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' - //@ ismany '$.index[*][?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' - //@ ismany '$.index[*][?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' null null null - //@ ismany '$.index[*][?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' false false false + //@ ismany '$.index[?(@.name=="by_ref")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' + //@ ismany '$.index[?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' + //@ ismany '$.index[?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' null null null + //@ ismany '$.index[?(@.name=="by_ref")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' false false false pub fn by_ref(&self) {} - //@ ismany '$.index[*][?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' - //@ ismany '$.index[*][?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' - //@ ismany '$.index[*][?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' null null null - //@ ismany '$.index[*][?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' true true true + //@ ismany '$.index[?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' + //@ ismany '$.index[?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' + //@ ismany '$.index[?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' null null null + //@ ismany '$.index[?(@.name=="by_exclusive_ref")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' true true true pub fn by_exclusive_ref(&mut self) {} - //@ ismany '$.index[*][?(@.name=="by_value")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' - //@ ismany '$.index[*][?(@.name=="by_value")].inner.function.sig.inputs[0][1].generic' '"Self"' '"Self"' '"Self"' + //@ ismany '$.index[?(@.name=="by_value")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' + //@ ismany '$.index[?(@.name=="by_value")].inner.function.sig.inputs[0][1].generic' '"Self"' '"Self"' '"Self"' pub fn by_value(self) {} - //@ ismany '$.index[*][?(@.name=="with_lifetime")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' - //@ ismany '$.index[*][?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' - //@ ismany '$.index[*][?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' \"\'a\" \"\'a\" \"\'a\" - //@ ismany '$.index[*][?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' false false false + //@ ismany '$.index[?(@.name=="with_lifetime")].inner.function.sig.inputs[0][0]' '"self"' '"self"' '"self"' + //@ ismany '$.index[?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.type.generic' '"Self"' '"Self"' '"Self"' + //@ ismany '$.index[?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.lifetime' \"\'a\" \"\'a\" \"\'a\" + //@ ismany '$.index[?(@.name=="with_lifetime")].inner.function.sig.inputs[0][1].borrowed_ref.is_mutable' false false false pub fn with_lifetime<'a>(&'a self) {} - //@ ismany '$.index[*][?(@.name=="build")].inner.function.sig.output.generic' '"Self"' '"Self"' '"Self"' + //@ ismany '$.index[?(@.name=="build")].inner.function.sig.output.generic' '"Self"' '"Self"' '"Self"' pub fn build() -> Self { Self } diff --git a/tests/rustdoc-json/traits/supertrait.rs b/tests/rustdoc-json/traits/supertrait.rs index 4b6199d4b26..3accb0ff858 100644 --- a/tests/rustdoc-json/traits/supertrait.rs +++ b/tests/rustdoc-json/traits/supertrait.rs @@ -1,20 +1,20 @@ -//@ set loud_id = "$.index[*][?(@.name=='Loud')].id" +//@ set loud_id = "$.index[?(@.name=='Loud')].id" pub trait Loud {} -//@ set very_loud_id = "$.index[*][?(@.name=='VeryLoud')].id" -//@ count "$.index[*][?(@.name=='VeryLoud')].inner.trait.bounds[*]" 1 -//@ is "$.index[*][?(@.name=='VeryLoud')].inner.trait.bounds[0].trait_bound.trait.id" $loud_id +//@ set very_loud_id = "$.index[?(@.name=='VeryLoud')].id" +//@ count "$.index[?(@.name=='VeryLoud')].inner.trait.bounds[*]" 1 +//@ is "$.index[?(@.name=='VeryLoud')].inner.trait.bounds[0].trait_bound.trait.id" $loud_id pub trait VeryLoud: Loud {} -//@ set sounds_good_id = "$.index[*][?(@.name=='SoundsGood')].id" +//@ set sounds_good_id = "$.index[?(@.name=='SoundsGood')].id" pub trait SoundsGood {} -//@ count "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[*]" 2 -//@ is "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[0].trait_bound.trait.id" $very_loud_id -//@ is "$.index[*][?(@.name=='MetalBand')].inner.trait.bounds[1].trait_bound.trait.id" $sounds_good_id +//@ count "$.index[?(@.name=='MetalBand')].inner.trait.bounds[*]" 2 +//@ is "$.index[?(@.name=='MetalBand')].inner.trait.bounds[0].trait_bound.trait.id" $very_loud_id +//@ is "$.index[?(@.name=='MetalBand')].inner.trait.bounds[1].trait_bound.trait.id" $sounds_good_id pub trait MetalBand: VeryLoud + SoundsGood {} -//@ count "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[*]" 2 -//@ is "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[1].trait_bound.trait.id" $very_loud_id -//@ is "$.index[*][?(@.name=='DnabLatem')].inner.trait.bounds[0].trait_bound.trait.id" $sounds_good_id +//@ count "$.index[?(@.name=='DnabLatem')].inner.trait.bounds[*]" 2 +//@ is "$.index[?(@.name=='DnabLatem')].inner.trait.bounds[1].trait_bound.trait.id" $very_loud_id +//@ is "$.index[?(@.name=='DnabLatem')].inner.trait.bounds[0].trait_bound.trait.id" $sounds_good_id pub trait DnabLatem: SoundsGood + VeryLoud {} diff --git a/tests/rustdoc-json/traits/trait_alias.rs b/tests/rustdoc-json/traits/trait_alias.rs index 137b8947e23..497930a67c8 100644 --- a/tests/rustdoc-json/traits/trait_alias.rs +++ b/tests/rustdoc-json/traits/trait_alias.rs @@ -2,25 +2,25 @@ #![feature(trait_alias)] -//@ set Orig = "$.index[*][?(@.name == 'Orig')].id" -//@ has "$.index[*][?(@.name == 'Orig')].inner.trait" +//@ set Orig = "$.index[?(@.name == 'Orig')].id" +//@ has "$.index[?(@.name == 'Orig')].inner.trait" pub trait Orig<T> {} -//@ set Alias = "$.index[*][?(@.name == 'Alias')].id" -//@ has "$.index[*][?(@.name == 'Alias')].inner.trait_alias" -//@ is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.generics" '{"params": [], "where_predicates": []}' -//@ count "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[*]" 1 -//@ is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.id" $Orig -//@ is "$.index[*][?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.primitive" '"i32"' +//@ set Alias = "$.index[?(@.name == 'Alias')].id" +//@ has "$.index[?(@.name == 'Alias')].inner.trait_alias" +//@ is "$.index[?(@.name == 'Alias')].inner.trait_alias.generics" '{"params": [], "where_predicates": []}' +//@ count "$.index[?(@.name == 'Alias')].inner.trait_alias.params[*]" 1 +//@ is "$.index[?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.id" $Orig +//@ is "$.index[?(@.name == 'Alias')].inner.trait_alias.params[0].trait_bound.trait.args.angle_bracketed.args[0].type.primitive" '"i32"' pub trait Alias = Orig<i32>; pub struct Struct; impl Orig<i32> for Struct {} -//@ has "$.index[*][?(@.name=='takes_alias')].inner.function.sig.inputs[0][1].impl_trait" -//@ is "$.index[*][?(@.name=='takes_alias')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $Alias -//@ is "$.index[*][?(@.name=='takes_alias')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias +//@ has "$.index[?(@.name=='takes_alias')].inner.function.sig.inputs[0][1].impl_trait" +//@ is "$.index[?(@.name=='takes_alias')].inner.function.sig.inputs[0][1].impl_trait[0].trait_bound.trait.id" $Alias +//@ is "$.index[?(@.name=='takes_alias')].inner.function.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $Alias pub fn takes_alias(_: impl Alias) {} // FIXME: Should the trait be mentioned in both the decl and generics? diff --git a/tests/rustdoc-json/traits/uses_extern_trait.rs b/tests/rustdoc-json/traits/uses_extern_trait.rs index 3a93bcaefd4..52983527f08 100644 --- a/tests/rustdoc-json/traits/uses_extern_trait.rs +++ b/tests/rustdoc-json/traits/uses_extern_trait.rs @@ -1,5 +1,5 @@ #![no_std] pub fn drop_default<T: core::default::Default>(_x: T) {} -//@ !has "$.index[*][?(@.name=='Debug')]" -//@ !has "$.index[*][?(@.name=='Default')]" +//@ !has "$.index[?(@.name=='Debug')]" +//@ !has "$.index[?(@.name=='Default')]" diff --git a/tests/rustdoc-json/type/dyn.rs b/tests/rustdoc-json/type/dyn.rs index d8686d4e2fb..4e533a67f8b 100644 --- a/tests/rustdoc-json/type/dyn.rs +++ b/tests/rustdoc-json/type/dyn.rs @@ -1,45 +1,45 @@ use std::fmt::Debug; -//@ count "$.index[*][?(@.name=='dyn')].inner.module.items[*]" 3 -//@ set sync_int_gen = "$.index[*][?(@.name=='SyncIntGen')].id" -//@ set ref_fn = "$.index[*][?(@.name=='RefFn')].id" -//@ set weird_order = "$.index[*][?(@.name=='WeirdOrder')].id" -//@ ismany "$.index[*][?(@.name=='dyn')].inner.module.items[*]" $sync_int_gen $ref_fn $weird_order +//@ count "$.index[?(@.name=='dyn')].inner.module.items[*]" 3 +//@ set sync_int_gen = "$.index[?(@.name=='SyncIntGen')].id" +//@ set ref_fn = "$.index[?(@.name=='RefFn')].id" +//@ set weird_order = "$.index[?(@.name=='WeirdOrder')].id" +//@ ismany "$.index[?(@.name=='dyn')].inner.module.items[*]" $sync_int_gen $ref_fn $weird_order -//@ has "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias" -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.generics" '{"params": [], "where_predicates": []}' -//@ has "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path" -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.path" \"Box\" -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.constraints" [] -//@ count "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args" 1 -//@ has "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait" -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.lifetime" \"\'static\" -//@ count "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[*]" 3 -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].generic_params" [] -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].generic_params" [] -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].generic_params" [] -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.path" '"Fn"' -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.path" '"Send"' -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].trait.path" '"Sync"' -//@ is "$.index[*][?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"primitive": "i32"}}}' +//@ has "$.index[?(@.name=='SyncIntGen')].inner.type_alias" +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.generics" '{"params": [], "where_predicates": []}' +//@ has "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path" +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.path" \"Box\" +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.constraints" [] +//@ count "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args" 1 +//@ has "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait" +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.lifetime" \"\'static\" +//@ count "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[*]" 3 +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].generic_params" [] +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].generic_params" [] +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].generic_params" [] +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.path" '"Fn"' +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.path" '"Send"' +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[2].trait.path" '"Sync"' +//@ is "$.index[?(@.name=='SyncIntGen')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.args" '{"parenthesized": {"inputs": [],"output": {"primitive": "i32"}}}' pub type SyncIntGen = Box<dyn Fn() -> i32 + Send + Sync + 'static>; -//@ has "$.index[*][?(@.name=='RefFn')].inner.type_alias" -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}' -//@ has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref" -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.is_mutable" 'false' -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.lifetime" "\"'a\"" -//@ has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait" -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.lifetime" null -//@ count "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[*]" 1 -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.path" '"Fn"' -//@ has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref" -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref.lifetime" "\"'b\"" -//@ has "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref" -//@ is "$.index[*][?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref.lifetime" "\"'b\"" +//@ has "$.index[?(@.name=='RefFn')].inner.type_alias" +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.generics" '{"params": [{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"}],"where_predicates": []}' +//@ has "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref" +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.is_mutable" 'false' +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.lifetime" "\"'a\"" +//@ has "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait" +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.lifetime" null +//@ count "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[*]" 1 +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.path" '"Fn"' +//@ has "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref" +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.inputs[0].borrowed_ref.lifetime" "\"'b\"" +//@ has "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref" +//@ is "$.index[?(@.name=='RefFn')].inner.type_alias.type.borrowed_ref.type.dyn_trait.traits[0].trait.args.parenthesized.output.borrowed_ref.lifetime" "\"'b\"" pub type RefFn<'a> = &'a dyn for<'b> Fn(&'b i32) -> &'b i32; -//@ is "$.index[*][?(@.name=='WeirdOrder')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.path" '"Send"' -//@ is "$.index[*][?(@.name=='WeirdOrder')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.path" '"Debug"' +//@ is "$.index[?(@.name=='WeirdOrder')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[0].trait.path" '"Send"' +//@ is "$.index[?(@.name=='WeirdOrder')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.dyn_trait.traits[1].trait.path" '"Debug"' pub type WeirdOrder = Box<dyn Send + Debug>; diff --git a/tests/rustdoc-json/type/extern.rs b/tests/rustdoc-json/type/extern.rs index 97e1c3760ee..7963690e448 100644 --- a/tests/rustdoc-json/type/extern.rs +++ b/tests/rustdoc-json/type/extern.rs @@ -5,5 +5,5 @@ extern "C" { pub type Foo; } -//@ is "$.index[*][?(@.docs=='No inner information')].name" '"Foo"' -//@ is "$.index[*][?(@.docs=='No inner information')].inner" \"extern_type\" +//@ is "$.index[?(@.docs=='No inner information')].name" '"Foo"' +//@ is "$.index[?(@.docs=='No inner information')].inner" \"extern_type\" diff --git a/tests/rustdoc-json/type/fn_lifetime.rs b/tests/rustdoc-json/type/fn_lifetime.rs index aaa716bf11f..10e95cc5e56 100644 --- a/tests/rustdoc-json/type/fn_lifetime.rs +++ b/tests/rustdoc-json/type/fn_lifetime.rs @@ -1,24 +1,24 @@ -//@ has "$.index[*][?(@.name=='GenericFn')].inner.type_alias" +//@ has "$.index[?(@.name=='GenericFn')].inner.type_alias" -//@ ismany "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].name" \"\'a\" -//@ has "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime" -//@ count "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime.outlives[*]" 0 -//@ count "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.where_predicates[*]" 0 -//@ count "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.generic_params[*]" 0 -//@ count "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.inputs[*][1].borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.output.borrowed_ref.lifetime" \"\'a\" +//@ ismany "$.index[?(@.name=='GenericFn')].inner.type_alias.generics.params[*].name" \"\'a\" +//@ has "$.index[?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime" +//@ count "$.index[?(@.name=='GenericFn')].inner.type_alias.generics.params[*].kind.lifetime.outlives[*]" 0 +//@ count "$.index[?(@.name=='GenericFn')].inner.type_alias.generics.where_predicates[*]" 0 +//@ count "$.index[?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.generic_params[*]" 0 +//@ count "$.index[?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.inputs[*][1].borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='GenericFn')].inner.type_alias.type.function_pointer.sig.output.borrowed_ref.lifetime" \"\'a\" pub type GenericFn<'a> = fn(&'a i32) -> &'a i32; -//@ has "$.index[*][?(@.name=='ForAll')].inner.type_alias" -//@ count "$.index[*][?(@.name=='ForAll')].inner.type_alias.generics.params[*]" 0 -//@ count "$.index[*][?(@.name=='ForAll')].inner.type_alias.generics.where_predicates[*]" 0 -//@ count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*]" 1 -//@ is "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].name" \"\'a\" -//@ has "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime" -//@ count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime.outlives[*]" 0 -//@ count "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.inputs[*][1].borrowed_ref.lifetime" \"\'a\" -//@ is "$.index[*][?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.output.borrowed_ref.lifetime" \"\'a\" +//@ has "$.index[?(@.name=='ForAll')].inner.type_alias" +//@ count "$.index[?(@.name=='ForAll')].inner.type_alias.generics.params[*]" 0 +//@ count "$.index[?(@.name=='ForAll')].inner.type_alias.generics.where_predicates[*]" 0 +//@ count "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*]" 1 +//@ is "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].name" \"\'a\" +//@ has "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime" +//@ count "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.generic_params[*].kind.lifetime.outlives[*]" 0 +//@ count "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.inputs[*][1].borrowed_ref.lifetime" \"\'a\" +//@ is "$.index[?(@.name=='ForAll')].inner.type_alias.type.function_pointer.sig.output.borrowed_ref.lifetime" \"\'a\" pub type ForAll = for<'a> fn(&'a i32) -> &'a i32; diff --git a/tests/rustdoc-json/type/generic_default.rs b/tests/rustdoc-json/type/generic_default.rs index 2d2ce9cd103..26a232a1562 100644 --- a/tests/rustdoc-json/type/generic_default.rs +++ b/tests/rustdoc-json/type/generic_default.rs @@ -1,31 +1,31 @@ -//@ set result = "$.index[*][?(@.name=='Result')].id" +//@ set result = "$.index[?(@.name=='Result')].id" pub enum Result<T, E> { Ok(T), Err(E), } -//@ set my_error = "$.index[*][?(@.name=='MyError')].id" +//@ set my_error = "$.index[?(@.name=='MyError')].id" pub struct MyError {} -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias" -//@ count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.where_predicates[*]" 0 -//@ count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[*]" 2 -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].name" \"T\" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].name" \"E\" -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type" -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type" -//@ count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.bounds[*]" 0 -//@ count "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.bounds[*]" 0 -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.default" null -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.id" $my_error -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.path" \"MyError\" -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.id" $result -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.path" \"Result\" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.constraints" [] -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic" -//@ has "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[1].type.generic" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic" \"T\" -//@ is "$.index[*][?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[1].type.generic" \"E\" +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias" +//@ count "$.index[?(@.name=='MyResult')].inner.type_alias.generics.where_predicates[*]" 0 +//@ count "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[*]" 2 +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[0].name" \"T\" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].name" \"E\" +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type" +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type" +//@ count "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.bounds[*]" 0 +//@ count "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.bounds[*]" 0 +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[0].kind.type.default" null +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.id" $my_error +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.generics.params[1].kind.type.default.resolved_path.path" \"MyError\" +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.id" $result +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.path" \"Result\" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.constraints" [] +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic" +//@ has "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[1].type.generic" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[0].type.generic" \"T\" +//@ is "$.index[?(@.name=='MyResult')].inner.type_alias.type.resolved_path.args.angle_bracketed.args[1].type.generic" \"E\" pub type MyResult<T, E = MyError> = Result<T, E>; diff --git a/tests/rustdoc-json/type/hrtb.rs b/tests/rustdoc-json/type/hrtb.rs index 08b35b90a2b..68b7a556a69 100644 --- a/tests/rustdoc-json/type/hrtb.rs +++ b/tests/rustdoc-json/type/hrtb.rs @@ -1,5 +1,5 @@ -//@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.type" '{"generic": "F"}' -//@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +//@ is "$.index[?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.type" '{"generic": "F"}' +//@ is "$.index[?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' pub fn genfn<F>(f: F) where for<'a, 'b> F: Fn(&'a i32, &'b i32), @@ -8,12 +8,12 @@ where f(&zero, &zero); } -//@ is "$.index[*][?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}' -//@ is "$.index[*][?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}' -//@ is "$.index[*][?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.lifetime" null -//@ count "$.index[*][?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[*]" 1 -//@ is "$.index[*][?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' -//@ is "$.index[*][?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].trait.path" '"Fn"' +//@ is "$.index[?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}' +//@ is "$.index[?(@.name=='dynfn')].inner.function.generics" '{"params": [], "where_predicates": []}' +//@ is "$.index[?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.lifetime" null +//@ count "$.index[?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[*]" 1 +//@ is "$.index[?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]' +//@ is "$.index[?(@.name=='dynfn')].inner.function.sig.inputs[0][1].borrowed_ref.type.dyn_trait.traits[0].trait.path" '"Fn"' pub fn dynfn(f: &dyn for<'a, 'b> Fn(&'a i32, &'b i32)) { let zero = 0; f(&zero, &zero); diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs index e26f8f7c651..e96a92f7cfb 100644 --- a/tests/rustdoc-json/type/inherent_associated_type.rs +++ b/tests/rustdoc-json/type/inherent_associated_type.rs @@ -1,23 +1,23 @@ #![feature(inherent_associated_types)] #![allow(incomplete_features)] -//@ set OwnerMetadata = '$.index[*][?(@.name=="OwnerMetadata")].id' +//@ set OwnerMetadata = '$.index[?(@.name=="OwnerMetadata")].id' pub struct OwnerMetadata; -//@ set Owner = '$.index[*][?(@.name=="Owner")].id' +//@ set Owner = '$.index[?(@.name=="Owner")].id' pub struct Owner; pub fn create() -> Owner::Metadata { OwnerMetadata } -//@ is '$.index[*][?(@.name=="create")].inner.function.sig.output.qualified_path.name' '"Metadata"' -//@ is '$.index[*][?(@.name=="create")].inner.function.sig.output.qualified_path.trait' null -//@ is '$.index[*][?(@.name=="create")].inner.function.sig.output.qualified_path.self_type.resolved_path.id' $Owner +//@ is '$.index[?(@.name=="create")].inner.function.sig.output.qualified_path.name' '"Metadata"' +//@ is '$.index[?(@.name=="create")].inner.function.sig.output.qualified_path.trait' null +//@ is '$.index[?(@.name=="create")].inner.function.sig.output.qualified_path.self_type.resolved_path.id' $Owner /// impl impl Owner { /// iat pub type Metadata = OwnerMetadata; } -//@ set iat = '$.index[*][?(@.docs=="iat")].id' -//@ is '$.index[*][?(@.docs=="impl")].inner.impl.items[*]' $iat -//@ is '$.index[*][?(@.docs=="iat")].inner.assoc_type.type.resolved_path.id' $OwnerMetadata +//@ set iat = '$.index[?(@.docs=="iat")].id' +//@ is '$.index[?(@.docs=="impl")].inner.impl.items[*]' $iat +//@ is '$.index[?(@.docs=="iat")].inner.assoc_type.type.resolved_path.id' $OwnerMetadata diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs index 22c9c9c1149..20354909f8e 100644 --- a/tests/rustdoc-json/type/inherent_associated_type_bound.rs +++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs @@ -1,17 +1,17 @@ #![feature(inherent_associated_types)] #![allow(incomplete_features)] -//@ set Carrier = '$.index[*][?(@.name=="Carrier")].id' +//@ set Carrier = '$.index[?(@.name=="Carrier")].id' pub struct Carrier<'a>(&'a ()); -//@ count "$.index[*][?(@.name=='user')].inner.function.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='user')].inner.function.sig.inputs[0][0]" '"_"' -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.generic_params[*].name' \""'b"\" -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.self_type.resolved_path.id' $Carrier -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].lifetime' \""'b"\" -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.name' '"Focus"' -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.trait' null -//@ is '$.index[*][?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.args.angle_bracketed.args[0].type.primitive' '"i32"' +//@ count "$.index[?(@.name=='user')].inner.function.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='user')].inner.function.sig.inputs[0][0]" '"_"' +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.generic_params[*].name' \""'b"\" +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.self_type.resolved_path.id' $Carrier +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].lifetime' \""'b"\" +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.name' '"Focus"' +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.trait' null +//@ is '$.index[?(@.name=="user")].inner.function.sig.inputs[0][1].function_pointer.sig.inputs[0][1].qualified_path.args.angle_bracketed.args[0].type.primitive' '"i32"' pub fn user(_: for<'b> fn(Carrier<'b>::Focus<i32>)) {} impl<'a> Carrier<'a> { diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs index 501694dce8b..934daba11bb 100644 --- a/tests/rustdoc-json/type/inherent_associated_type_projections.rs +++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs @@ -1,15 +1,15 @@ #![feature(inherent_associated_types)] #![allow(incomplete_features)] -//@ set Parametrized = '$.index[*][?(@.name=="Parametrized")].id' +//@ set Parametrized = '$.index[?(@.name=="Parametrized")].id' pub struct Parametrized<T>(T); -//@ count "$.index[*][?(@.name=='test')].inner.function.sig.inputs[*]" 1 -//@ is "$.index[*][?(@.name=='test')].inner.function.sig.inputs[0][0]" '"_"' -//@ is '$.index[*][?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.self_type.resolved_path.id' $Parametrized -//@ is '$.index[*][?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].type.primitive' \"i32\" -//@ is '$.index[*][?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.name' '"Proj"' -//@ is '$.index[*][?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.trait' null +//@ count "$.index[?(@.name=='test')].inner.function.sig.inputs[*]" 1 +//@ is "$.index[?(@.name=='test')].inner.function.sig.inputs[0][0]" '"_"' +//@ is '$.index[?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.self_type.resolved_path.id' $Parametrized +//@ is '$.index[?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.self_type.resolved_path.args.angle_bracketed.args[0].type.primitive' \"i32\" +//@ is '$.index[?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.name' '"Proj"' +//@ is '$.index[?(@.name=="test")].inner.function.sig.inputs[0][1].qualified_path.trait' null pub fn test(_: Parametrized<i32>::Proj) {} /// param_bool @@ -24,10 +24,10 @@ impl Parametrized<i32> { pub type Proj = String; } -//@ set param_bool = '$.index[*][?(@.docs=="param_bool")].id' -//@ set param_i32 = '$.index[*][?(@.docs=="param_i32")].id' -//@ set param_bool_proj = '$.index[*][?(@.docs=="param_bool_proj")].id' -//@ set param_i32_proj = '$.index[*][?(@.docs=="param_i32_proj")].id' +//@ set param_bool = '$.index[?(@.docs=="param_bool")].id' +//@ set param_i32 = '$.index[?(@.docs=="param_i32")].id' +//@ set param_bool_proj = '$.index[?(@.docs=="param_bool_proj")].id' +//@ set param_i32_proj = '$.index[?(@.docs=="param_i32_proj")].id' -//@ is '$.index[*][?(@.docs=="param_bool")].inner.impl.items[*]' $param_bool_proj -//@ is '$.index[*][?(@.docs=="param_i32")].inner.impl.items[*]' $param_i32_proj +//@ is '$.index[?(@.docs=="param_bool")].inner.impl.items[*]' $param_bool_proj +//@ is '$.index[?(@.docs=="param_i32")].inner.impl.items[*]' $param_i32_proj diff --git a/tests/rustdoc-json/type_alias.rs b/tests/rustdoc-json/type_alias.rs index 2f2b4c42d44..7fd23a48040 100644 --- a/tests/rustdoc-json/type_alias.rs +++ b/tests/rustdoc-json/type_alias.rs @@ -1,15 +1,15 @@ -//@ set IntVec = "$.index[*][?(@.name=='IntVec')].id" -//@ is "$.index[*][?(@.name=='IntVec')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='IntVec')].inner.type_alias" -//@ is "$.index[*][?(@.name=='IntVec')].span.filename" $FILE +//@ set IntVec = "$.index[?(@.name=='IntVec')].id" +//@ is "$.index[?(@.name=='IntVec')].visibility" \"public\" +//@ has "$.index[?(@.name=='IntVec')].inner.type_alias" +//@ is "$.index[?(@.name=='IntVec')].span.filename" $FILE pub type IntVec = Vec<u32>; -//@ is "$.index[*][?(@.name=='f')].inner.function.sig.output.resolved_path.id" $IntVec +//@ is "$.index[?(@.name=='f')].inner.function.sig.output.resolved_path.id" $IntVec pub fn f() -> IntVec { vec![0; 32] } -//@ !is "$.index[*][?(@.name=='g')].inner.function.sig.output.resolved_path.id" $IntVec +//@ !is "$.index[?(@.name=='g')].inner.function.sig.output.resolved_path.id" $IntVec pub fn g() -> Vec<u32> { vec![0; 32] } diff --git a/tests/rustdoc-json/unions/field_order.rs b/tests/rustdoc-json/unions/field_order.rs index a1616f62751..b3a07a13bc8 100644 --- a/tests/rustdoc-json/unions/field_order.rs +++ b/tests/rustdoc-json/unions/field_order.rs @@ -15,24 +15,24 @@ pub union Foo { pub vll_9: i32, } -//@ set 0 = '$.index[*][?(@.name == "ews_0")].id' -//@ set 1 = '$.index[*][?(@.name == "dik_1")].id' -//@ set 2 = '$.index[*][?(@.name == "hsk_2")].id' -//@ set 3 = '$.index[*][?(@.name == "djt_3")].id' -//@ set 4 = '$.index[*][?(@.name == "jnr_4")].id' -//@ set 5 = '$.index[*][?(@.name == "dfs_5")].id' -//@ set 6 = '$.index[*][?(@.name == "bja_6")].id' -//@ set 7 = '$.index[*][?(@.name == "lyc_7")].id' -//@ set 8 = '$.index[*][?(@.name == "yqd_8")].id' -//@ set 9 = '$.index[*][?(@.name == "vll_9")].id' +//@ set 0 = '$.index[?(@.name == "ews_0")].id' +//@ set 1 = '$.index[?(@.name == "dik_1")].id' +//@ set 2 = '$.index[?(@.name == "hsk_2")].id' +//@ set 3 = '$.index[?(@.name == "djt_3")].id' +//@ set 4 = '$.index[?(@.name == "jnr_4")].id' +//@ set 5 = '$.index[?(@.name == "dfs_5")].id' +//@ set 6 = '$.index[?(@.name == "bja_6")].id' +//@ set 7 = '$.index[?(@.name == "lyc_7")].id' +//@ set 8 = '$.index[?(@.name == "yqd_8")].id' +//@ set 9 = '$.index[?(@.name == "vll_9")].id' -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[0]' $0 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[1]' $1 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[2]' $2 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[3]' $3 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[4]' $4 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[5]' $5 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[6]' $6 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[7]' $7 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[8]' $8 -//@ is '$.index[*][?(@.name == "Foo")].inner.union.fields[9]' $9 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[0]' $0 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[1]' $1 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[2]' $2 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[3]' $3 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[4]' $4 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[5]' $5 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[6]' $6 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[7]' $7 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[8]' $8 +//@ is '$.index[?(@.name == "Foo")].inner.union.fields[9]' $9 diff --git a/tests/rustdoc-json/unions/impl.rs b/tests/rustdoc-json/unions/impl.rs index 989a025f669..6f398cc23f6 100644 --- a/tests/rustdoc-json/unions/impl.rs +++ b/tests/rustdoc-json/unions/impl.rs @@ -1,15 +1,15 @@ #![no_std] -//@ is "$.index[*][?(@.name=='Ux')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='Ux')].inner.union" +//@ is "$.index[?(@.name=='Ux')].visibility" \"public\" +//@ has "$.index[?(@.name=='Ux')].inner.union" pub union Ux { a: u32, b: u64, } -//@ is "$.index[*][?(@.name=='Num')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='Num')].inner.trait" +//@ is "$.index[?(@.name=='Num')].visibility" \"public\" +//@ has "$.index[?(@.name=='Num')].inner.trait" pub trait Num {} -//@ count "$.index[*][?(@.name=='Ux')].inner.union.impls" 1 +//@ count "$.index[?(@.name=='Ux')].inner.union.impls" 1 impl Num for Ux {} diff --git a/tests/rustdoc-json/unions/union.rs b/tests/rustdoc-json/unions/union.rs index 7f135a72dec..24ee47f1957 100644 --- a/tests/rustdoc-json/unions/union.rs +++ b/tests/rustdoc-json/unions/union.rs @@ -1,14 +1,14 @@ -//@ has "$.index[*][?(@.name=='Union')].visibility" \"public\" -//@ has "$.index[*][?(@.name=='Union')].inner.union" -//@ !has "$.index[*][?(@.name=='Union')].inner.union.struct_type" -//@ set Union = "$.index[*][?(@.name=='Union')].id" +//@ has "$.index[?(@.name=='Union')].visibility" \"public\" +//@ has "$.index[?(@.name=='Union')].inner.union" +//@ !has "$.index[?(@.name=='Union')].inner.union.struct_type" +//@ set Union = "$.index[?(@.name=='Union')].id" pub union Union { int: i32, float: f32, } -//@ has "$.index[*][?(@.name=='make_int_union')].inner.function.sig.output.resolved_path" -//@ is "$.index[*][?(@.name=='make_int_union')].inner.function.sig.output.resolved_path.id" $Union +//@ has "$.index[?(@.name=='make_int_union')].inner.function.sig.output.resolved_path" +//@ is "$.index[?(@.name=='make_int_union')].inner.function.sig.output.resolved_path.id" $Union pub fn make_int_union(int: i32) -> Union { Union { int } } diff --git a/tests/rustdoc-ui/doc-cfg-check-cfg.rs b/tests/rustdoc-ui/doc-cfg-check-cfg.rs new file mode 100644 index 00000000000..e3420dc0789 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-check-cfg.rs @@ -0,0 +1,16 @@ +// Ensure that `doc(cfg())` respects `check-cfg` +// Currently not properly working +#![feature(doc_cfg)] +#![deny(unexpected_cfgs)] + +//@revisions: no_check cfg_empty cfg_foo +//@[cfg_empty] compile-flags: --check-cfg cfg() +//@[cfg_foo] compile-flags: --check-cfg cfg(foo) + +//@[no_check] check-pass +//@[cfg_empty] check-pass +//@[cfg_empty] known-bug: #138358 +//@[cfg_foo] check-pass + +#[doc(cfg(foo))] +pub fn foo() {} diff --git a/tests/rustdoc-ui/doc-cfg-unstable.rs b/tests/rustdoc-ui/doc-cfg-unstable.rs new file mode 100644 index 00000000000..14c2e83ec85 --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-unstable.rs @@ -0,0 +1,10 @@ +// #138113: rustdoc didn't gate unstable predicates inside `doc(cfg(..))` +#![feature(doc_cfg)] + +// `cfg_boolean_literals` +#[doc(cfg(false))] //~ ERROR `cfg(false)` is experimental and subject to change +pub fn cfg_boolean_literals() {} + +// `cfg_version` +#[doc(cfg(sanitize = "thread"))] //~ ERROR `cfg(sanitize)` is experimental and subject to change +pub fn cfg_sanitize() {} diff --git a/tests/rustdoc-ui/doc-cfg-unstable.stderr b/tests/rustdoc-ui/doc-cfg-unstable.stderr new file mode 100644 index 00000000000..54de3b178ed --- /dev/null +++ b/tests/rustdoc-ui/doc-cfg-unstable.stderr @@ -0,0 +1,23 @@ +error[E0658]: `cfg(false)` is experimental and subject to change + --> $DIR/doc-cfg-unstable.rs:5:11 + | +LL | #[doc(cfg(false))] + | ^^^^^ + | + = note: see issue #131204 <https://github.com/rust-lang/rust/issues/131204> for more information + = help: add `#![feature(cfg_boolean_literals)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: `cfg(sanitize)` is experimental and subject to change + --> $DIR/doc-cfg-unstable.rs:9:11 + | +LL | #[doc(cfg(sanitize = "thread"))] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #39699 <https://github.com/rust-lang/rust/issues/39699> for more information + = help: add `#![feature(cfg_sanitize)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/rustdoc/deref/deref-methods-24686-target.rs b/tests/rustdoc/deref/deref-methods-24686-target.rs new file mode 100644 index 00000000000..e019488ca80 --- /dev/null +++ b/tests/rustdoc/deref/deref-methods-24686-target.rs @@ -0,0 +1,27 @@ +#![crate_name = "foo"] + +// test for https://github.com/rust-lang/rust/issues/24686 +use std::ops::Deref; + +pub struct Foo<T>(T); +impl Foo<i32> { + pub fn get_i32(&self) -> i32 { self.0 } +} +impl Foo<u32> { + pub fn get_u32(&self) -> u32 { self.0 } +} + +// Note that the same href is used both on the method itself, +// and on the sidebar items. +//@ has foo/struct.Bar.html +//@ has - '//a[@href="#method.get_i32"]' 'get_i32' +//@ !has - '//a[@href="#method.get_u32"]' 'get_u32' +//@ count - '//ul[@class="block deref-methods"]//a' 1 +//@ count - '//a[@href="#method.get_i32"]' 2 +pub struct Bar(Foo<i32>); +impl Deref for Bar { + type Target = Foo<i32>; + fn deref(&self) -> &Foo<i32> { + &self.0 + } +} diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs index cffb41742b4..0a579a07cef 100644 --- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs +++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs @@ -18,6 +18,7 @@ extern crate stable_mir; use rustc_smir::rustc_internal; use stable_mir::mir::MirVisitor; +use stable_mir::mir::MutMirVisitor; use stable_mir::*; use std::collections::HashSet; use std::io::Write; @@ -99,6 +100,83 @@ impl<'a> mir::MirVisitor for TestVisitor<'a> { } } +fn test_mut_visitor() -> ControlFlow<()> { + let main_fn = stable_mir::entry_fn(); + let mut main_body = main_fn.unwrap().expect_body(); + let locals = main_body.locals().to_vec(); + let mut main_visitor = TestMutVisitor::collect(locals); + main_visitor.visit_body(&mut main_body); + assert!(main_visitor.ret_val.is_some()); + assert!(main_visitor.args.is_empty()); + assert!(main_visitor.tys.contains(&main_visitor.ret_val.unwrap().ty)); + assert!(!main_visitor.calls.is_empty()); + + let exit_fn = main_visitor.calls.last().unwrap(); + assert!(exit_fn.mangled_name().contains("exit_fn"), "Unexpected last function: {exit_fn:?}"); + + let mut exit_body = exit_fn.body().unwrap(); + let locals = exit_body.locals().to_vec(); + let mut exit_visitor = TestMutVisitor::collect(locals); + exit_visitor.visit_body(&mut exit_body); + assert!(exit_visitor.ret_val.is_some()); + assert_eq!(exit_visitor.args.len(), 1); + assert!(exit_visitor.tys.contains(&exit_visitor.ret_val.unwrap().ty)); + assert!(exit_visitor.tys.contains(&exit_visitor.args[0].ty)); + ControlFlow::Continue(()) +} + +struct TestMutVisitor { + locals: Vec<mir::LocalDecl>, + pub tys: HashSet<ty::Ty>, + pub ret_val: Option<mir::LocalDecl>, + pub args: Vec<mir::LocalDecl>, + pub calls: Vec<mir::mono::Instance>, +} + +impl TestMutVisitor { + fn collect(locals: Vec<mir::LocalDecl>) -> TestMutVisitor { + let visitor = TestMutVisitor { + locals: locals, + tys: Default::default(), + ret_val: None, + args: vec![], + calls: vec![], + }; + visitor + } +} + +impl mir::MutMirVisitor for TestMutVisitor { + fn visit_ty(&mut self, ty: &mut ty::Ty, _location: mir::visit::Location) { + self.tys.insert(*ty); + self.super_ty(ty) + } + + fn visit_ret_decl(&mut self, local: mir::Local, decl: &mut mir::LocalDecl) { + assert!(local == mir::RETURN_LOCAL); + assert!(self.ret_val.is_none()); + self.ret_val = Some(decl.clone()); + self.super_ret_decl(local, decl); + } + + fn visit_arg_decl(&mut self, local: mir::Local, decl: &mut mir::LocalDecl) { + self.args.push(decl.clone()); + assert_eq!(local, self.args.len()); + self.super_arg_decl(local, decl); + } + + fn visit_terminator(&mut self, term: &mut mir::Terminator, location: mir::visit::Location) { + if let mir::TerminatorKind::Call { func, .. } = &mut term.kind { + let ty::TyKind::RigidTy(ty) = func.ty(&self.locals).unwrap().kind() else { + unreachable!() + }; + let ty::RigidTy::FnDef(def, args) = ty else { unreachable!() }; + self.calls.push(mir::mono::Instance::resolve(def, &args).unwrap()); + } + self.super_terminator(term, location); + } +} + /// This test will generate and analyze a dummy crate using the stable mir. /// For that, it will first write the dummy crate into a file. /// Then it will create a `StableMir` using custom arguments and then @@ -113,7 +191,8 @@ fn main() { CRATE_NAME.to_string(), path.to_string(), ]; - run!(args, test_visitor).unwrap(); + run!(args.clone(), test_visitor).unwrap(); + run!(args, test_mut_visitor).unwrap(); } fn generate_input(path: &str) -> std::io::Result<()> { diff --git a/tests/ui/coercion/struct-coerce-vec-to-slice.rs b/tests/ui/coercion/struct-coerce-vec-to-slice.rs new file mode 100644 index 00000000000..9ef20ac4ea6 --- /dev/null +++ b/tests/ui/coercion/struct-coerce-vec-to-slice.rs @@ -0,0 +1,20 @@ +//! Regression test that ensures struct field literals can be coerced into slice and `Box` types + +//@ check-pass + +struct Thing1<'a> { + baz: &'a [Box<isize>], + bar: Box<u64>, +} + +struct Thing2<'a> { + baz: &'a [Box<isize>], + bar: u64, +} + +pub fn main() { + let _a = Thing1 { baz: &[], bar: Box::new(32) }; + let _b = Thing1 { baz: &Vec::new(), bar: Box::new(32) }; + let _c = Thing2 { baz: &[], bar: 32 }; + let _d = Thing2 { baz: &Vec::new(), bar: 32 }; +} diff --git a/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs b/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs new file mode 100644 index 00000000000..0b8ec7dc07a --- /dev/null +++ b/tests/ui/coercion/struct-literal-field-type-coercion-to-expected-type.rs @@ -0,0 +1,16 @@ +//! Regression test to check that literal expressions in a struct field can be coerced to the +//! expected field type, including block expressions. +//! +//! Issue: <https://github.com/rust-lang/rust/issues/31260> + +//@ check-pass + +pub struct Struct<K: 'static> { + pub field: K, +} + +static STRUCT: Struct<&'static [u8]> = Struct { field: { &[1] } }; + +static STRUCT2: Struct<&'static [u8]> = Struct { field: &[1] }; + +fn main() {} diff --git a/tests/ui/fn/trait-fn-generic-mismatch.rs b/tests/ui/fn/trait-fn-generic-mismatch.rs new file mode 100644 index 00000000000..dc8222e967e --- /dev/null +++ b/tests/ui/fn/trait-fn-generic-mismatch.rs @@ -0,0 +1,12 @@ +fn retry() -> impl Sized {} + +struct Core<T>(T); + +impl Core<XXX> { //~ ERROR cannot find type `XXX` in this scope + pub fn spawn(self) {} +} + +fn main() { + let core = Core(1); + core.spawn(retry()); //~ ERROR this method takes 0 arguments but 1 argument was supplied +} diff --git a/tests/ui/fn/trait-fn-generic-mismatch.stderr b/tests/ui/fn/trait-fn-generic-mismatch.stderr new file mode 100644 index 00000000000..8384d74e225 --- /dev/null +++ b/tests/ui/fn/trait-fn-generic-mismatch.stderr @@ -0,0 +1,32 @@ +error[E0412]: cannot find type `XXX` in this scope + --> $DIR/trait-fn-generic-mismatch.rs:5:11 + | +LL | impl Core<XXX> { + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl<XXX> Core<XXX> { + | +++++ + +error[E0061]: this method takes 0 arguments but 1 argument was supplied + --> $DIR/trait-fn-generic-mismatch.rs:11:10 + | +LL | core.spawn(retry()); + | ^^^^^ ------- unexpected argument of type `impl Sized` + | +note: method defined here + --> $DIR/trait-fn-generic-mismatch.rs:6:12 + | +LL | pub fn spawn(self) {} + | ^^^^^ +help: remove the extra argument + | +LL - core.spawn(retry()); +LL + core.spawn(); + | + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0061, E0412. +For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs index 2f17c0ff508..776bb7278ce 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.rs @@ -2,8 +2,7 @@ use std::fmt::Debug; fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - //~^ ERROR cannot resolve opaque type - //~| WARNING elided lifetime has a name + //~^ WARNING elided lifetime has a name |x| x //~^ ERROR expected generic lifetime parameter, found `'_` } diff --git a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr index 91550f0e284..209186db4cc 100644 --- a/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr +++ b/tests/ui/impl-trait/impl-fn-predefined-lifetimes.stderr @@ -7,24 +7,14 @@ LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { = note: `#[warn(elided_named_lifetimes)]` on by default error[E0792]: expected generic lifetime parameter, found `'_` - --> $DIR/impl-fn-predefined-lifetimes.rs:7:9 + --> $DIR/impl-fn-predefined-lifetimes.rs:6:9 | LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { | -- this generic parameter must be used with a generic lifetime parameter -... +LL | LL | |x| x | ^ -error[E0720]: cannot resolve opaque type - --> $DIR/impl-fn-predefined-lifetimes.rs:4:35 - | -LL | fn a<'a>() -> impl Fn(&'a u8) -> (impl Debug + '_) { - | ^^^^^^^^^^^^^^^ recursive opaque type -... -LL | |x| x - | ----- returning here with type `{closure@$DIR/impl-fn-predefined-lifetimes.rs:7:5: 7:8}` - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -Some errors have detailed explanations: E0720, E0792. -For more information about an error, try `rustc --explain E0720`. +For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs index c1176255f24..9e8ea439dde 100644 --- a/tests/ui/impl-trait/issues/issue-86800.rs +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -40,7 +40,6 @@ impl Context { f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O>, ) -> TransactionResult<O> { //~^ ERROR expected generic lifetime parameter, found `'_` - //~| ERROR: item does not constrain let mut conn = Connection {}; let mut transaction = TestTransaction { conn: &mut conn }; f(&mut transaction).await diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr index 11e23d97d72..80aa5d75c3c 100644 --- a/tests/ui/impl-trait/issues/issue-86800.stderr +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -24,26 +24,6 @@ note: this opaque type is supposed to be constrained LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `TransactionFuture::{opaque#0}` - --> $DIR/issue-86800.rs:41:31 - | -LL | ) -> TransactionResult<O> { - | _______________________________^ -LL | | -LL | | -LL | | let mut conn = Connection {}; -LL | | let mut transaction = TestTransaction { conn: &mut conn }; -LL | | f(&mut transaction).await -LL | | } - | |_____^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/issue-86800.rs:21:34 - | -LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0792]: expected generic lifetime parameter, found `'_` --> $DIR/issue-86800.rs:31:5 | @@ -62,13 +42,12 @@ LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionRe LL | ) -> TransactionResult<O> { | _______________________________^ LL | | -LL | | LL | | let mut conn = Connection {}; LL | | let mut transaction = TestTransaction { conn: &mut conn }; LL | | f(&mut transaction).await LL | | } | |_____^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr index 05d42247d41..aa8a2ae42db 100644 --- a/tests/ui/invalid-compile-flags/print-without-arg.stderr +++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr @@ -1,5 +1,5 @@ error: Argument to option 'print' missing Usage: - --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] + --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|supported-crate-types|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models] Compiler information to print on stdout diff --git a/tests/ui/invalid-compile-flags/print.stderr b/tests/ui/invalid-compile-flags/print.stderr index 4ea06a06539..f9cfb1616ce 100644 --- a/tests/ui/invalid-compile-flags/print.stderr +++ b/tests/ui/invalid-compile-flags/print.stderr @@ -1,5 +1,5 @@ error: unknown print request: `yyyy` | - = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/ui/issues/issue-28777.rs b/tests/ui/issues/issue-28777.rs deleted file mode 100644 index f67e11e3694..00000000000 --- a/tests/ui/issues/issue-28777.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ run-pass -#![allow(unused_braces)] -fn main() { - let v1 = { 1 + {2} * {3} }; - let v2 = 1 + {2} * {3} ; - - assert_eq!(7, v1); - assert_eq!(7, v2); - - let v3; - v3 = { 1 + {2} * {3} }; - let v4; - v4 = 1 + {2} * {3}; - assert_eq!(7, v3); - assert_eq!(7, v4); - - let v5 = { 1 + {2} * 3 }; - assert_eq!(7, v5); - - let v9 = { 1 + if 1 > 2 {1} else {2} * {3} }; - assert_eq!(7, v9); -} diff --git a/tests/ui/issues/issue-31260.rs b/tests/ui/issues/issue-31260.rs deleted file mode 100644 index 5e9fffb195c..00000000000 --- a/tests/ui/issues/issue-31260.rs +++ /dev/null @@ -1,15 +0,0 @@ -//@ check-pass -#![allow(dead_code)] -pub struct Struct<K: 'static> { - pub field: K, -} - -static STRUCT: Struct<&'static [u8]> = Struct { - field: {&[1]} -}; - -static STRUCT2: Struct<&'static [u8]> = Struct { - field: &[1] -}; - -fn main() {} diff --git a/tests/ui/issues/issue-9382.rs b/tests/ui/issues/issue-9382.rs deleted file mode 100644 index 27f9ab57743..00000000000 --- a/tests/ui/issues/issue-9382.rs +++ /dev/null @@ -1,37 +0,0 @@ -//@ run-pass -#![allow(dead_code)] - -// Tests for a previous bug that occurred due to an interaction -// between struct field initialization and the auto-coercion -// from a vector to a slice. The drop glue was being invoked on -// the temporary slice with a wrong type, triggering an LLVM assert. - - -struct Thing1<'a> { - baz: &'a [Box<isize>], - bar: Box<u64>, -} - -struct Thing2<'a> { - baz: &'a [Box<isize>], - bar: u64, -} - -pub fn main() { - let _t1_fixed = Thing1 { - baz: &[], - bar: Box::new(32), - }; - Thing1 { - baz: &Vec::new(), - bar: Box::new(32), - }; - let _t2_fixed = Thing2 { - baz: &[], - bar: 32, - }; - Thing2 { - baz: &Vec::new(), - bar: 32, - }; -} diff --git a/tests/ui/lint/inert-attr-macro.rs b/tests/ui/lint/inert-attr-macro.rs index 90303a1fc3d..5d4133d6c77 100644 --- a/tests/ui/lint/inert-attr-macro.rs +++ b/tests/ui/lint/inert-attr-macro.rs @@ -1,5 +1,6 @@ //@ check-pass +#![feature(cfg_boolean_literals)] #![warn(unused)] macro_rules! foo { @@ -17,4 +18,10 @@ fn main() { // This does work, since the attribute is on a parent // of the macro invocation. #[allow(warnings)] { #[inline] foo!(); } + + // Ok, `cfg` and `cfg_attr` are expanded eagerly and do not warn. + #[cfg(true)] foo!(); + #[cfg(false)] foo!(); + #[cfg_attr(true, cfg(true))] foo!(); + #[cfg_attr(false, nonexistent)] foo!(); } diff --git a/tests/ui/lint/inert-attr-macro.stderr b/tests/ui/lint/inert-attr-macro.stderr index 5ccb4ffe792..b85b0319e71 100644 --- a/tests/ui/lint/inert-attr-macro.stderr +++ b/tests/ui/lint/inert-attr-macro.stderr @@ -1,41 +1,41 @@ warning: unused attribute `inline` - --> $DIR/inert-attr-macro.rs:10:5 + --> $DIR/inert-attr-macro.rs:11:5 | LL | #[inline] foo!(); | ^^^^^^^^^ | note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo` - --> $DIR/inert-attr-macro.rs:10:15 + --> $DIR/inert-attr-macro.rs:11:15 | LL | #[inline] foo!(); | ^^^ note: the lint level is defined here - --> $DIR/inert-attr-macro.rs:3:9 + --> $DIR/inert-attr-macro.rs:4:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]` warning: unused attribute `allow` - --> $DIR/inert-attr-macro.rs:14:5 + --> $DIR/inert-attr-macro.rs:15:5 | LL | #[allow(warnings)] #[inline] foo!(); | ^^^^^^^^^^^^^^^^^^ | note: the built-in attribute `allow` will be ignored, since it's applied to the macro invocation `foo` - --> $DIR/inert-attr-macro.rs:14:34 + --> $DIR/inert-attr-macro.rs:15:34 | LL | #[allow(warnings)] #[inline] foo!(); | ^^^ warning: unused attribute `inline` - --> $DIR/inert-attr-macro.rs:14:24 + --> $DIR/inert-attr-macro.rs:15:24 | LL | #[allow(warnings)] #[inline] foo!(); | ^^^^^^^^^ | note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo` - --> $DIR/inert-attr-macro.rs:14:34 + --> $DIR/inert-attr-macro.rs:15:34 | LL | #[allow(warnings)] #[inline] foo!(); | ^^^ diff --git a/tests/ui/lint/linker-warning.stderr b/tests/ui/lint/linker-warning.stderr index 3a2c392fd03..c678562ab54 100644 --- a/tests/ui/lint/linker-warning.stderr +++ b/tests/ui/lint/linker-warning.stderr @@ -16,7 +16,7 @@ warning: unused attribute LL | #![allow(linker_messages)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | - = note: the `linker_warnings` lint can only be controlled at the root of a crate that needs to be linked + = note: the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked warning: 2 warnings emitted diff --git a/tests/ui/parser/operator-precedence-braces-exprs.rs b/tests/ui/parser/operator-precedence-braces-exprs.rs new file mode 100644 index 00000000000..d6f44ef879c --- /dev/null +++ b/tests/ui/parser/operator-precedence-braces-exprs.rs @@ -0,0 +1,28 @@ +//! Regression test for ensuring that operator precedence is correctly handled in the presence of +//! braces +//! +//! Issue: <https://github.com/rust-lang/rust/issues/28777> + +//@ run-pass + +#[allow(unused_braces)] +fn main() { + let v1 = { 1 + { 2 } * { 3 } }; + let v2 = 1 + { 2 } * { 3 }; + + assert_eq!(7, v1); + assert_eq!(7, v2); + + let v3; + v3 = { 1 + { 2 } * { 3 } }; + let v4; + v4 = 1 + { 2 } * { 3 }; + assert_eq!(7, v3); + assert_eq!(7, v4); + + let v5 = { 1 + { 2 } * 3 }; + assert_eq!(7, v5); + + let v9 = { 1 + if 1 > 2 { 1 } else { 2 } * { 3 } }; + assert_eq!(7, v9); +} diff --git a/tests/ui/print-request/print-lints-help.rs b/tests/ui/print-request/print-lints-help.rs new file mode 100644 index 00000000000..420eae27ed4 --- /dev/null +++ b/tests/ui/print-request/print-lints-help.rs @@ -0,0 +1,7 @@ +//! Check that we point to `-Whelp` to guide the user to find the list of lints if the user requests +//! `--print=lints` (which is not a valid print request). + +//@ compile-flags: --print lints +//@ error-pattern: error: unknown print request: `lints` +//@ error-pattern: help: use `-Whelp` to print a list of lints +//@ error-pattern: help: for more information, see the rustc book diff --git a/tests/ui/rustc-print-info-issue-138612.stderr b/tests/ui/print-request/print-lints-help.stderr index 4f7ed821952..0530d11f2e8 100644 --- a/tests/ui/rustc-print-info-issue-138612.stderr +++ b/tests/ui/print-request/print-lints-help.stderr @@ -1,6 +1,6 @@ error: unknown print request: `lints` | - = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` + = help: valid print requests are: `all-target-specs-json`, `calling-conventions`, `cfg`, `check-cfg`, `code-models`, `crate-name`, `deployment-target`, `file-names`, `host-tuple`, `link-args`, `native-static-libs`, `relocation-models`, `split-debuginfo`, `stack-protector-strategies`, `supported-crate-types`, `sysroot`, `target-cpus`, `target-features`, `target-libdir`, `target-list`, `target-spec-json`, `tls-models` = help: use `-Whelp` to print a list of lints = help: for more information, see the rustc book: https://doc.rust-lang.org/rustc/command-line-arguments.html#--print-print-compiler-information diff --git a/tests/ui/print-request/stability.rs b/tests/ui/print-request/stability.rs index b205b055569..c3421224d72 100644 --- a/tests/ui/print-request/stability.rs +++ b/tests/ui/print-request/stability.rs @@ -22,6 +22,10 @@ //@[check_cfg] compile-flags: --print=check-cfg //@[check_cfg] error-pattern: the `-Z unstable-options` flag must also be passed +//@ revisions: supported_crate_types +//@[supported_crate_types] compile-flags: --print=supported-crate-types +//@[supported_crate_types] error-pattern: the `-Z unstable-options` flag must also be passed + //@ revisions: target_spec_json //@[target_spec_json] compile-flags: --print=target-spec-json //@[target_spec_json] error-pattern: the `-Z unstable-options` flag must also be passed diff --git a/tests/ui/print-request/supported-crate-types.linux.stdout b/tests/ui/print-request/supported-crate-types.linux.stdout new file mode 100644 index 00000000000..721adb432e7 --- /dev/null +++ b/tests/ui/print-request/supported-crate-types.linux.stdout @@ -0,0 +1,7 @@ +bin +cdylib +dylib +lib +proc-macro +rlib +staticlib diff --git a/tests/ui/print-request/supported-crate-types.musl.stdout b/tests/ui/print-request/supported-crate-types.musl.stdout new file mode 100644 index 00000000000..1f4b991e49f --- /dev/null +++ b/tests/ui/print-request/supported-crate-types.musl.stdout @@ -0,0 +1,5 @@ +bin +lib +proc-macro +rlib +staticlib diff --git a/tests/ui/print-request/supported-crate-types.rs b/tests/ui/print-request/supported-crate-types.rs new file mode 100644 index 00000000000..c8b4c0c1a41 --- /dev/null +++ b/tests/ui/print-request/supported-crate-types.rs @@ -0,0 +1,20 @@ +//! Basic smoke test for `--print=supported-crate-types`, which should print a newline delimited +//! list of crate types supported by the given target. This test cherry-picks a few well-known +//! targets as examples. +//! +//! Tracking issue: <https://github.com/rust-lang/rust/issues/138640> + +// ignore-tidy-linelength + +//@ check-pass + +//@ revisions: wasm musl linux + +//@[wasm] compile-flags: --target=wasm32-unknown-unknown --print=supported-crate-types -Zunstable-options +//@[wasm] needs-llvm-components: webassembly + +//@[musl] compile-flags: --target=x86_64-unknown-linux-musl --print=supported-crate-types -Zunstable-options +//@[musl] needs-llvm-components: x86 + +//@[linux] compile-flags: --target=x86_64-unknown-linux-gnu --print=supported-crate-types -Zunstable-options +//@[linux] needs-llvm-components: x86 diff --git a/tests/ui/print-request/supported-crate-types.wasm.stdout b/tests/ui/print-request/supported-crate-types.wasm.stdout new file mode 100644 index 00000000000..ca1de519598 --- /dev/null +++ b/tests/ui/print-request/supported-crate-types.wasm.stdout @@ -0,0 +1,5 @@ +bin +cdylib +lib +rlib +staticlib diff --git a/tests/ui/rustc-print-info-issue-138612.rs b/tests/ui/rustc-print-info-issue-138612.rs deleted file mode 100644 index 65b595635b1..00000000000 --- a/tests/ui/rustc-print-info-issue-138612.rs +++ /dev/null @@ -1,2 +0,0 @@ -//@ check-fail -//@ compile-flags: /dev/null --print lints diff --git a/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs new file mode 100644 index 00000000000..b7086325d5f --- /dev/null +++ b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.rs @@ -0,0 +1,17 @@ +// Verify that the `where` clause suggestion is in the correct place +// Previously, the suggestion to add `where` clause was placed inside the derive +// like `#[derive(Clone where Inner<T>: Clone)]` +// instead of `struct Outer<T>(Inner<T>) where Inner<T>: Clone` + +#![crate_type = "lib"] + +struct Inner<T>(T); +//~^ HELP consider annotating `Inner<T>` with `#[derive(Clone)]` +impl Clone for Inner<()> { + fn clone(&self) -> Self { todo!() } +} + +#[derive(Clone)] +struct Outer<T>(Inner<T>); +//~^ ERROR the trait bound `Inner<T>: Clone` is not satisfied [E0277] +//~| HELP consider introducing a `where` clause diff --git a/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr new file mode 100644 index 00000000000..577b090ce1b --- /dev/null +++ b/tests/ui/suggestions/tuple-struct-where-clause-suggestion-91520.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `Inner<T>: Clone` is not satisfied + --> $DIR/tuple-struct-where-clause-suggestion-91520.rs:15:17 + | +LL | #[derive(Clone)] + | ----- in this derive macro expansion +LL | struct Outer<T>(Inner<T>); + | ^^^^^^^^ the trait `Clone` is not implemented for `Inner<T>` + | +help: consider annotating `Inner<T>` with `#[derive(Clone)]` + | +LL + #[derive(Clone)] +LL | struct Inner<T>(T); + | +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | struct Outer<T>(Inner<T>) where Inner<T>: Clone; + | +++++++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr index ba97bbf89f8..241eccc5f2b 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr +++ b/tests/ui/type-alias-impl-trait/const_generic_type.no_infer.stderr @@ -19,22 +19,5 @@ note: this opaque type is supposed to be constrained LL | type Bar = impl std::fmt::Display; | ^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `Bar::{opaque#0}` - --> $DIR/const_generic_type.rs:8:31 - | -LL | async fn test<const N: Bar>() { - | _______________________________^ -... | -LL | | let x: u32 = N; -LL | | } - | |_^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/const_generic_type.rs:5:12 - | -LL | type Bar = impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors diff --git a/tests/ui/type-alias-impl-trait/const_generic_type.rs b/tests/ui/type-alias-impl-trait/const_generic_type.rs index 5b093be9231..9b38f1449f8 100644 --- a/tests/ui/type-alias-impl-trait/const_generic_type.rs +++ b/tests/ui/type-alias-impl-trait/const_generic_type.rs @@ -8,7 +8,6 @@ type Bar = impl std::fmt::Display; async fn test<const N: Bar>() { //~^ ERROR: `Bar` is forbidden as the type of a const generic parameter //[no_infer]~^^ ERROR item does not constrain - //[no_infer]~| ERROR item does not constrain #[cfg(infer)] let x: u32 = N; } diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.rs b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.rs new file mode 100644 index 00000000000..d873af44adf --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] + +extern "C" { + fn a() { + //~^ ERROR incorrect function inside `extern` block + #[define_opaque(String)] + fn c() {} + } +} + +pub fn main() {} diff --git a/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.stderr b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.stderr new file mode 100644 index 00000000000..2e944257d8f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/define_opaques_attr/invalid-extern-fn-body.stderr @@ -0,0 +1,20 @@ +error: incorrect function inside `extern` block + --> $DIR/invalid-extern-fn-body.rs:4:8 + | +LL | extern "C" { + | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body +LL | fn a() { + | ________^___- + | | | + | | cannot have a body +LL | | +LL | | #[define_opaque(String)] +LL | | fn c() {} +LL | | } + | |_____- help: remove the invalid body: `;` + | + = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +error: aborting due to 1 previous error + diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs new file mode 100644 index 00000000000..a2de3957c0b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.rs @@ -0,0 +1,18 @@ +// We previously didn't taint the borrowck result in this test, +// causing an ICE later on. +#![feature(type_alias_impl_trait)] +trait T {} + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S {} + +#[define_opaque(Alias)] +fn with_positive(fun: impl Fn(Alias<'_>)) { + //~^ WARN function cannot return without recursing + with_positive(|&n| ()); + //~^ ERROR cannot move out of a shared reference +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr new file mode 100644 index 00000000000..956ce3e5936 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/error-tainting-issue-122904.stderr @@ -0,0 +1,30 @@ +warning: function cannot return without recursing + --> $DIR/error-tainting-issue-122904.rs:12:1 + | +LL | fn with_positive(fun: impl Fn(Alias<'_>)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | with_positive(|&n| ()); + | ---------------------- recursive call site + | + = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default + +error[E0507]: cannot move out of a shared reference + --> $DIR/error-tainting-issue-122904.rs:14:20 + | +LL | with_positive(|&n| ()); + | ^- + | | + | data moved here + | move occurs because `n` has type `S`, which does not implement the `Copy` trait + | +help: consider removing the borrow + | +LL - with_positive(|&n| ()); +LL + with_positive(|n| ()); + | + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0507`. diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs index 7e010918b29..cbd8150d117 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.rs @@ -22,7 +22,6 @@ where for<'any> F: FnMut(&'any mut ()) -> FutNothing<'any>, { //~^ ERROR: expected generic lifetime parameter, found `'any` - //~| ERROR item does not constrain } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr index 2ca6a199448..2c0be0cbcdc 100644 --- a/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr +++ b/tests/ui/type-alias-impl-trait/hkl_forbidden4.stderr @@ -11,21 +11,6 @@ note: this opaque type is supposed to be constrained LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: item does not constrain `FutNothing::{opaque#0}` - --> $DIR/hkl_forbidden4.rs:23:1 - | -LL | / { -... | -LL | | } - | |_^ - | - = note: consider removing `#[define_opaque]` or adding an empty `#[define_opaque()]` -note: this opaque type is supposed to be constrained - --> $DIR/hkl_forbidden4.rs:10:23 - | -LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: concrete type differs from previous defining opaque type use --> $DIR/hkl_forbidden4.rs:12:1 | @@ -54,10 +39,10 @@ LL | type FutNothing<'a> = impl 'a + Future<Output = ()>; | -- this generic parameter must be used with a generic lifetime parameter ... LL | / { -... | +LL | | LL | | } | |_^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs index 7452000b65d..92c8a8f3216 100644 --- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs +++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.rs @@ -6,7 +6,7 @@ trait Foo { } impl Foo for () { - type Assoc<'a> = impl Sized; //~ ERROR unconstrained opaque type + type Assoc<'a> = impl Sized; fn bar<'a: 'a>() where Self::Assoc<'a>:, diff --git a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr index 1274a8b60de..7ce4517fb1e 100644 --- a/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr +++ b/tests/ui/type-alias-impl-trait/in-assoc-ty-early-bound2.stderr @@ -9,14 +9,6 @@ LL | fn bar<'a: 'a>() LL | let _: Self::Assoc<'a> = x; | ^^^^^^^^^^^^^^^ -error: unconstrained opaque type - --> $DIR/in-assoc-ty-early-bound2.rs:9:22 - | -LL | type Assoc<'a> = impl Sized; - | ^^^^^^^^^^ - | - = note: `Assoc` must be used in combination with a concrete type within the same impl - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0700`. diff --git a/triagebot.toml b/triagebot.toml index 53cdd8b585b..7215cd84719 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -307,6 +307,23 @@ exclude_labels = [ "T-*", ] +trigger_labels = [ + "D-*", + "A-diagnostics", +] + +[autolabel."A-diagnostics"] + +trigger_labels = [ + "D-*", +] + +[autolabel."A-lints"] + +trigger_labels = [ + "L-*", +] + [autolabel."T-libs"] trigger_files = [ "library/alloc", |
