diff --git a/Cargo.lock b/Cargo.lock index 039dc0b0ea4d8..ba41143ff61d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -376,12 +376,41 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "bytecheck" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "rancor", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "bytecount" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + [[package]] name = "camino" version = "1.2.1" @@ -2476,6 +2505,26 @@ dependencies = [ name = "miropt-test-tools" version = "0.1.0" +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3047,6 +3096,26 @@ dependencies = [ "cc", ] +[[package]] +name = "ptr_meta" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "pulldown-cmark" version = "0.11.3" @@ -3092,6 +3161,15 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rancor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" +dependencies = [ + "ptr_meta", +] + [[package]] name = "rand" version = "0.8.5" @@ -3275,6 +3353,15 @@ dependencies = [ name = "remote-test-server" version = "0.1.0" +[[package]] +name = "rend" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" +dependencies = [ + "bytecheck", +] + [[package]] name = "replace-version-placeholder" version = "0.1.0" @@ -3283,6 +3370,36 @@ dependencies = [ "walkdir", ] +[[package]] +name = "rkyv" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" +dependencies = [ + "bytecheck", + "bytes", + "hashbrown 0.16.1", + "indexmap", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "run_make_support" version = "0.0.0" @@ -4790,6 +4907,7 @@ name = "rustdoc-json-types" version = "0.1.0" dependencies = [ "bincode", + "rkyv", "rustc-hash 2.1.1", "serde", "serde_derive", @@ -5128,6 +5246,12 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "similar" version = "2.7.0" diff --git a/compiler/rustc_abi/src/callconv.rs b/compiler/rustc_abi/src/callconv.rs index 5b43a6c5881d5..7ad7088b30899 100644 --- a/compiler/rustc_abi/src/callconv.rs +++ b/compiler/rustc_abi/src/callconv.rs @@ -83,7 +83,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { })) } - BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdScalableVector { .. } => { unreachable!("`homogeneous_aggregate` should not be called for scalable vectors") } diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 2351d58d8e82c..93c01f289d422 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -210,7 +210,7 @@ impl LayoutCalculator { VariantIdx: Idx, F: AsRef> + fmt::Debug, { - vector_type_layout(VectorKind::Scalable, self.cx.data_layout(), element, count) + vector_type_layout(SimdVectorKind::Scalable, self.cx.data_layout(), element, count) } pub fn simd_type( @@ -224,7 +224,7 @@ impl LayoutCalculator { VariantIdx: Idx, F: AsRef> + fmt::Debug, { - let kind = if repr_packed { VectorKind::PackedFixed } else { VectorKind::Fixed }; + let kind = if repr_packed { SimdVectorKind::PackedFixed } else { SimdVectorKind::Fixed }; vector_type_layout(kind, self.cx.data_layout(), element, count) } @@ -484,7 +484,7 @@ impl LayoutCalculator { BackendRepr::Scalar(..) | BackendRepr::ScalarPair(..) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => repr, }, }; @@ -557,7 +557,7 @@ impl LayoutCalculator { hide_niches(b); } BackendRepr::SimdVector { element, .. } - | BackendRepr::ScalableVector { element, .. } => hide_niches(element), + | BackendRepr::SimdScalableVector { element, .. } => hide_niches(element), BackendRepr::Memory { sized: _ } => {} } st.largest_niche = None; @@ -1524,7 +1524,7 @@ impl LayoutCalculator { } } -enum VectorKind { +enum SimdVectorKind { /// `#[rustc_scalable_vector]` Scalable, /// `#[repr(simd, packed)]` @@ -1534,7 +1534,7 @@ enum VectorKind { } fn vector_type_layout( - kind: VectorKind, + kind: SimdVectorKind, dl: &TargetDataLayout, element: F, count: u64, @@ -1559,16 +1559,16 @@ where let size = elt.size.checked_mul(count, dl).ok_or_else(|| LayoutCalculatorError::SizeOverflow)?; let (repr, align) = match kind { - VectorKind::Scalable => { - (BackendRepr::ScalableVector { element, count }, dl.llvmlike_vector_align(size)) + SimdVectorKind::Scalable => { + (BackendRepr::SimdScalableVector { element, count }, dl.llvmlike_vector_align(size)) } // Non-power-of-two vectors have padding up to the next power-of-two. // If we're a packed repr, remove the padding while keeping the alignment as close // to a vector as possible. - VectorKind::PackedFixed if !count.is_power_of_two() => { + SimdVectorKind::PackedFixed if !count.is_power_of_two() => { (BackendRepr::Memory { sized: true }, Align::max_aligned_factor(size)) } - VectorKind::PackedFixed | VectorKind::Fixed => { + SimdVectorKind::PackedFixed | SimdVectorKind::Fixed => { (BackendRepr::SimdVector { element, count }, dl.llvmlike_vector_align(size)) } }; diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ce5f257abae96..21ca92d46d1c6 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1731,7 +1731,7 @@ impl AddressSpace { pub enum BackendRepr { Scalar(Scalar), ScalarPair(Scalar, Scalar), - ScalableVector { + SimdScalableVector { element: Scalar, count: u64, }, @@ -1758,7 +1758,7 @@ impl BackendRepr { // fully implemented, scalable vectors will remain `Sized`, they just won't be // `const Sized` - whether `is_unsized` continues to return `false` at that point will // need to be revisited and will depend on what `is_unsized` is used for. - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => !sized, } @@ -1801,7 +1801,7 @@ impl BackendRepr { // The align of a Vector can vary in surprising ways BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } - | BackendRepr::ScalableVector { .. } => None, + | BackendRepr::SimdScalableVector { .. } => None, } } @@ -1825,7 +1825,7 @@ impl BackendRepr { // The size of a Vector can vary in surprising ways BackendRepr::SimdVector { .. } | BackendRepr::Memory { .. } - | BackendRepr::ScalableVector { .. } => None, + | BackendRepr::SimdScalableVector { .. } => None, } } @@ -1840,8 +1840,8 @@ impl BackendRepr { BackendRepr::SimdVector { element: element.to_union(), count } } BackendRepr::Memory { .. } => BackendRepr::Memory { sized: true }, - BackendRepr::ScalableVector { element, count } => { - BackendRepr::ScalableVector { element: element.to_union(), count } + BackendRepr::SimdScalableVector { element, count } => { + BackendRepr::SimdScalableVector { element: element.to_union(), count } } } } @@ -2085,7 +2085,7 @@ impl LayoutData { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } => false, + | BackendRepr::SimdScalableVector { .. } => false, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => true, } } @@ -2182,13 +2182,13 @@ impl LayoutData { /// Returns `true` if the size of the type is only known at runtime. pub fn is_runtime_sized(&self) -> bool { - matches!(self.backend_repr, BackendRepr::ScalableVector { .. }) + matches!(self.backend_repr, BackendRepr::SimdScalableVector { .. }) } /// Returns the elements count of a scalable vector. pub fn scalable_vector_element_count(&self) -> Option { match self.backend_repr { - BackendRepr::ScalableVector { count, .. } => Some(count), + BackendRepr::SimdScalableVector { count, .. } => Some(count), _ => None, } } @@ -2201,7 +2201,7 @@ impl LayoutData { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::ScalarPair(..) - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::SimdVector { .. } => false, BackendRepr::Memory { sized } => sized && self.size.bytes() == 0, } diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index af78db156a221..12f59467ffd16 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -140,18 +140,21 @@ pub(crate) fn expand_env<'cx>( unreachable!("`expr_to_string` ensures this is a string lit") }; + let var = var.as_str(); let guar = match err { VarError::NotPresent => { if let Some(msg_from_user) = custom_msg { cx.dcx() .emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user }) - } else if let Some(suggested_var) = find_similar_cargo_var(var.as_str()) { + } else if let Some(suggested_var) = find_similar_cargo_var(var) + && suggested_var != var + { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVarTypo { span, var: *symbol, suggested_var: Symbol::intern(suggested_var), }) - } else if is_cargo_env_var(var.as_str()) { + } else if is_cargo_env_var(var) { cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar { span, var: *symbol, @@ -177,7 +180,7 @@ pub(crate) fn expand_env<'cx>( ExpandResult::Ready(MacEager::expr(e)) } -/// Returns `true` if an environment variable from `env!` is one used by Cargo. +/// Returns `true` if an environment variable from `env!` could be one used by Cargo. fn is_cargo_env_var(var: &str) -> bool { var.starts_with("CARGO_") || var.starts_with("DEP_") @@ -187,25 +190,28 @@ fn is_cargo_env_var(var: &str) -> bool { const KNOWN_CARGO_VARS: &[&str] = &[ // List of known Cargo environment variables that are set for crates (not build scripts, OUT_DIR etc). // See: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates - "CARGO_PKG_VERSION", - "CARGO_PKG_VERSION_MAJOR", - "CARGO_PKG_VERSION_MINOR", - "CARGO_PKG_VERSION_PATCH", - "CARGO_PKG_VERSION_PRE", + // tidy-alphabetical-start + "CARGO_BIN_NAME", + "CARGO_CRATE_NAME", + "CARGO_MANIFEST_DIR", + "CARGO_MANIFEST_PATH", "CARGO_PKG_AUTHORS", - "CARGO_PKG_NAME", "CARGO_PKG_DESCRIPTION", "CARGO_PKG_HOMEPAGE", - "CARGO_PKG_REPOSITORY", "CARGO_PKG_LICENSE", "CARGO_PKG_LICENSE_FILE", - "CARGO_PKG_RUST_VERSION", + "CARGO_PKG_NAME", "CARGO_PKG_README", - "CARGO_MANIFEST_DIR", - "CARGO_MANIFEST_PATH", - "CARGO_CRATE_NAME", - "CARGO_BIN_NAME", + "CARGO_PKG_REPOSITORY", + "CARGO_PKG_RUST_VERSION", + "CARGO_PKG_VERSION", + "CARGO_PKG_VERSION_MAJOR", + "CARGO_PKG_VERSION_MINOR", + "CARGO_PKG_VERSION_PATCH", + "CARGO_PKG_VERSION_PRE", "CARGO_PRIMARY_PACKAGE", + "CARGO_TARGET_TMPDIR", + // tidy-alphabetical-end ]; fn find_similar_cargo_var(var: &str) -> Option<&'static str> { @@ -219,7 +225,13 @@ fn find_similar_cargo_var(var: &str) -> Option<&'static str> { let mut best_distance = usize::MAX; for &known_var in KNOWN_CARGO_VARS { - if let Some(distance) = edit_distance(var, known_var, max_dist) { + if let Some(mut distance) = edit_distance(var, known_var, max_dist) { + // assume `PACKAGE` to equals `PKG` + // (otherwise, `d("CARGO_PACKAGE_NAME", "CARGO_PKG_NAME") == d("CARGO_PACKAGE_NAME", "CARGO_CRATE_NAME") == 4`) + if var.contains("PACKAGE") && known_var.contains("PKG") { + distance = distance.saturating_sub(const { "PACKAGE".len() - "PKG".len() }) // == d("PACKAGE", "PKG") + } + if distance < best_distance { best_distance = distance; best_match = Some(known_var); diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 39d210e14a098..171c15eb4b9fc 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -545,6 +545,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for EnvNotDefinedWithUserMessag #[derive(Diagnostic)] pub(crate) enum EnvNotDefined<'a> { #[diag("environment variable `{$var}` not defined at compile time")] + #[help("`{$var}` may not be available for the current Cargo target")] #[help( "Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead" )] diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index fb1127ab4f48c..046a08c3df0d5 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -505,7 +505,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc let layout = self.layout_of(tp_ty).layout; let _use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, - SimdVector { .. } | ScalableVector { .. } => false, + SimdVector { .. } | SimdScalableVector { .. } => false, Memory { .. } => { // For rusty ABIs, small aggregates are actually passed // as `RegKind::Integer` (see `FnAbi::adjust_for_abi`), diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 48d1b01639099..65f4fc68f05f8 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -85,7 +85,7 @@ fn uncached_gcc_type<'gcc, 'tcx>( ); } BackendRepr::Memory { .. } => {} - BackendRepr::ScalableVector { .. } => todo!(), + BackendRepr::SimdScalableVector { .. } => todo!(), } let name = match *layout.ty.kind() { @@ -181,7 +181,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true, // FIXME(rustc_scalable_vector): Not yet implemented in rustc_codegen_gcc. - BackendRepr::ScalableVector { .. } => todo!(), + BackendRepr::SimdScalableVector { .. } => todo!(), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -191,7 +191,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index af50afa057ed4..8ceb7ba29737c 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -493,7 +493,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { let use_integer_compare = match layout.backend_repr() { Scalar(_) | ScalarPair(_, _) => true, SimdVector { .. } => false, - ScalableVector { .. } => { + SimdScalableVector { .. } => { tcx.dcx().emit_err(InvalidMonomorphization::NonScalableType { span, name: sym::raw_eq, diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 1ed06fbd28219..e586ed0dd6b07 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -24,7 +24,7 @@ fn uncached_llvm_type<'a, 'tcx>( let element = layout.scalar_llvm_type_at(cx, element); return cx.type_vector(element, count); } - BackendRepr::ScalableVector { ref element, count } => { + BackendRepr::SimdScalableVector { ref element, count } => { let element = if element.is_bool() { cx.type_i1() } else { @@ -187,7 +187,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { match self.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } => true, + | BackendRepr::SimdScalableVector { .. } => true, BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => false, } } @@ -197,7 +197,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { BackendRepr::ScalarPair(..) => true, BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 9e6b366464341..98d2c3f131b0e 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -551,7 +551,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( registers_for_primitive(scalar1.primitive()); registers_for_primitive(scalar2.primitive()); } - BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => { // Because no instance of VaArgSafe uses a non-scalar `BackendRepr`. unreachable!( "No x86-64 SysV va_arg implementation for {:?}", @@ -692,7 +692,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( } // The Previous match on `BackendRepr` means control flow already escaped. BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => unreachable!(), }; diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 56dca6c8b9021..29ae1548b7439 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2767,6 +2767,10 @@ fn add_order_independent_options( cmd.pgo_gen(); } + if sess.opts.unstable_opts.instrument_mcount { + cmd.enable_profiling(); + } + if sess.opts.cg.control_flow_guard != CFGuard::Disabled { cmd.control_flow_guard(); } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 3ace1a8c266cf..55ee9b1b974a0 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -352,6 +352,7 @@ pub(crate) trait Linker { fn add_no_exec(&mut self) {} fn add_as_needed(&mut self) {} fn reset_per_library_state(&mut self) {} + fn enable_profiling(&mut self) {} } impl dyn Linker + '_ { @@ -732,6 +733,12 @@ impl<'a> Linker for GccLinker<'a> { self.link_or_cc_args(&["-u", "__llvm_profile_runtime"]); } + fn enable_profiling(&mut self) { + // This flag is also used when linking to choose target specific + // libraries needed to enable profiling. + self.cc_arg("-pg"); + } + fn control_flow_guard(&mut self) {} fn ehcont_guard(&mut self) {} diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 85fa890453d81..e1d1ef858c017 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { } BackendRepr::ScalarPair(_, _) | BackendRepr::Memory { .. } - | BackendRepr::ScalableVector { .. } => bug!(), + | BackendRepr::SimdScalableVector { .. } => bug!(), }) }; @@ -691,7 +691,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRefBuilder<'tcx, V> { BackendRepr::ScalarPair(a, b) => { OperandValueBuilder::Pair(Either::Right(a), Either::Right(b)) } - BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => { OperandValueBuilder::Vector(Either::Right(())) } BackendRepr::Memory { .. } => { diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 8df284f0028a3..b410e8f6c57ea 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -904,7 +904,7 @@ where } // Everything else can only exist in memory anyway, so it doesn't matter. BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => true, }; diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index b72927f455c76..677bbf5d41e61 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -1331,7 +1331,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValueVisitor<'tcx, M> for ValidityVisitor<'rt, self.visit_scalar(b, b_layout)?; } } - BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => { // No checks here, we assume layout computation gets this right. // (This is harder to check since Miri does not represent these as `Immediate`. We // also cannot use field projections since this might be a newtype around a vector.) diff --git a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs index 939f9151680bb..384d7858366de 100644 --- a/compiler/rustc_const_eval/src/util/check_validity_requirement.rs +++ b/compiler/rustc_const_eval/src/util/check_validity_requirement.rs @@ -119,7 +119,7 @@ fn check_validity_requirement_lax<'tcx>( } BackendRepr::SimdVector { element: s, count } => count == 0 || scalar_allows_raw_init(s), BackendRepr::Memory { .. } => true, // Fields are checked below. - BackendRepr::ScalableVector { element, .. } => scalar_allows_raw_init(element), + BackendRepr::SimdScalableVector { element, .. } => scalar_allows_raw_init(element), }; if !valid { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 4157b110fbf6e..837eb2b1a5fd7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1489,8 +1489,17 @@ fn check_scalable_vector(tcx: TyCtxt<'_>, span: Span, def_id: LocalDefId, scalab return; } ScalableElt::Container if fields.is_empty() => { - let mut err = - tcx.dcx().struct_span_err(span, "scalable vectors must have a single field"); + let mut err = tcx + .dcx() + .struct_span_err(span, "scalable vector tuples must have at least one field"); + err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type"); + err.emit(); + return; + } + ScalableElt::Container if fields.len() > 8 => { + let mut err = tcx + .dcx() + .struct_span_err(span, "scalable vector tuples can have at most eight fields"); err.help("tuples of scalable vectors can only contain multiple of the same scalable vector type"); err.emit(); return; diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 8a73125d64765..bfc677046e0f4 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -114,6 +114,26 @@ fn success<'tcx>( Ok(InferOk { value: (adj, target), obligations }) } +/// Data extracted from a reference (pinned or not) for coercion to a reference (pinned or not). +struct CoerceMaybePinnedRef<'tcx> { + /// coercion source, must be a pinned (i.e. `Pin<&T>` or `Pin<&mut T>`) or normal reference (`&T` or `&mut T`) + a: Ty<'tcx>, + /// coercion target, must be a pinned (i.e. `Pin<&T>` or `Pin<&mut T>`) or normal reference (`&T` or `&mut T`) + b: Ty<'tcx>, + /// referent type of the source + a_ty: Ty<'tcx>, + /// pinnedness of the source + a_pin: ty::Pinnedness, + /// mutability of the source + a_mut: ty::Mutability, + /// region of the source + a_r: ty::Region<'tcx>, + /// pinnedness of the target + b_pin: ty::Pinnedness, + /// mutability of the target + b_mut: ty::Mutability, +} + /// Whether to force a leak check to occur in `Coerce::unify_raw`. /// Note that leak checks may still occur evn with `ForceLeakCheck::No`. /// @@ -269,16 +289,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { return self.coerce_to_raw_ptr(a, b, b_mutbl); } ty::Ref(r_b, _, mutbl_b) => { + if let Some(pin_ref_to_ref) = self.maybe_pin_ref_to_ref(a, b) { + return self.coerce_pin_ref_to_ref(pin_ref_to_ref); + } return self.coerce_to_ref(a, b, r_b, mutbl_b); } - ty::Adt(pin, _) - if self.tcx.features().pin_ergonomics() - && self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => - { - let pin_coerce = self.commit_if_ok(|_| self.coerce_to_pin_ref(a, b)); - if pin_coerce.is_ok() { - return pin_coerce; - } + _ if let Some(to_pin_ref) = self.maybe_to_pin_ref(a, b) => { + return self.coerce_to_pin_ref(to_pin_ref); } _ => {} } @@ -790,61 +807,131 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { Ok(()) } - /// Applies reborrowing for `Pin` + /// Create an obligation for `ty: Unpin`, where . + fn unpin_obligation( + &self, + source: Ty<'tcx>, + target: Ty<'tcx>, + ty: Ty<'tcx>, + ) -> PredicateObligation<'tcx> { + let pred = ty::TraitRef::new( + self.tcx, + self.tcx.require_lang_item(hir::LangItem::Unpin, self.cause.span), + [ty], + ); + let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target }); + PredicateObligation::new(self.tcx, cause, self.param_env, pred) + } + + /// Checks if the given types are compatible for coercion from a pinned reference to a normal reference. + fn maybe_pin_ref_to_ref(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> Option> { + if !self.tcx.features().pin_ergonomics() { + return None; + } + if let Some((a_ty, a_pin @ ty::Pinnedness::Pinned, a_mut, a_r)) = a.maybe_pinned_ref() + && let Some((_, b_pin @ ty::Pinnedness::Not, b_mut, _)) = b.maybe_pinned_ref() + { + return Some(CoerceMaybePinnedRef { a, b, a_ty, a_pin, a_mut, a_r, b_pin, b_mut }); + } + debug!("not fitting pinned ref to ref coercion (`{:?}` -> `{:?}`)", a, b); + None + } + + /// Coerces from a pinned reference to a normal reference. + #[instrument(skip(self), level = "trace")] + fn coerce_pin_ref_to_ref( + &self, + CoerceMaybePinnedRef { a, b, a_ty, a_pin, a_mut, a_r, b_pin, b_mut }: CoerceMaybePinnedRef< + 'tcx, + >, + ) -> CoerceResult<'tcx> { + debug_assert!(self.shallow_resolve(a) == a); + debug_assert!(self.shallow_resolve(b) == b); + debug_assert!(self.tcx.features().pin_ergonomics()); + debug_assert_eq!(a_pin, ty::Pinnedness::Pinned); + debug_assert_eq!(b_pin, ty::Pinnedness::Not); + + coerce_mutbls(a_mut, b_mut)?; + + let unpin_obligation = self.unpin_obligation(a, b, a_ty); + + let a = Ty::new_ref(self.tcx, a_r, a_ty, b_mut); + let mut coerce = self.unify_and( + a, + b, + [Adjustment { kind: Adjust::Deref(DerefAdjustKind::Pin), target: a_ty }], + Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(b_mut, self.allow_two_phase))), + ForceLeakCheck::No, + )?; + coerce.obligations.push(unpin_obligation); + Ok(coerce) + } + + /// Checks if the given types are compatible for coercion to a pinned reference. + fn maybe_to_pin_ref(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> Option> { + if !self.tcx.features().pin_ergonomics() { + return None; + } + if let Some((a_ty, a_pin, a_mut, a_r)) = a.maybe_pinned_ref() + && let Some((_, b_pin @ ty::Pinnedness::Pinned, b_mut, _)) = b.maybe_pinned_ref() + { + return Some(CoerceMaybePinnedRef { a, b, a_ty, a_pin, a_mut, a_r, b_pin, b_mut }); + } + debug!("not fitting ref to pinned ref coercion (`{:?}` -> `{:?}`)", a, b); + None + } + + /// Applies reborrowing and auto-borrowing that results to `Pin<&T>` or `Pin<&mut T>`: /// - /// We currently only support reborrowing `Pin<&mut T>` as `Pin<&mut T>`. This is accomplished - /// by inserting a call to `Pin::as_mut` during MIR building. + /// Currently we only support the following coercions: + /// - Reborrowing `Pin<&mut T>` -> `Pin<&mut T>` + /// - Reborrowing `Pin<&T>` -> `Pin<&T>` + /// - Auto-borrowing `&mut T` -> `Pin<&mut T>` where `T: Unpin` + /// - Auto-borrowing `&mut T` -> `Pin<&T>` where `T: Unpin` + /// - Auto-borrowing `&T` -> `Pin<&T>` where `T: Unpin` /// /// In the future we might want to support other reborrowing coercions, such as: - /// - `Pin<&mut T>` as `Pin<&T>` - /// - `Pin<&T>` as `Pin<&T>` /// - `Pin>` as `Pin<&T>` /// - `Pin>` as `Pin<&mut T>` #[instrument(skip(self), level = "trace")] - fn coerce_to_pin_ref(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> { + fn coerce_to_pin_ref( + &self, + CoerceMaybePinnedRef { a, b, a_ty, a_pin, a_mut, a_r, b_pin, b_mut }: CoerceMaybePinnedRef< + 'tcx, + >, + ) -> CoerceResult<'tcx> { debug_assert!(self.shallow_resolve(a) == a); debug_assert!(self.shallow_resolve(b) == b); - - // We need to make sure the two types are compatible for coercion. - // Then we will build a ReborrowPin adjustment and return that as an InferOk. - - // Right now we can only reborrow if this is a `Pin<&mut T>`. - let extract_pin_mut = |ty: Ty<'tcx>| { - // Get the T out of Pin - let (pin, ty) = match ty.kind() { - ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => { - (*pin, args[0].expect_ty()) - } - _ => { - debug!("can't reborrow {:?} as pinned", ty); - return Err(TypeError::Mismatch); - } - }; - // Make sure the T is something we understand (just `&mut U` for now) - match ty.kind() { - ty::Ref(region, ty, mutbl) => Ok((pin, *region, *ty, *mutbl)), - _ => { - debug!("can't reborrow pin of inner type {:?}", ty); - Err(TypeError::Mismatch) - } + debug_assert!(self.tcx.features().pin_ergonomics()); + debug_assert_eq!(b_pin, ty::Pinnedness::Pinned); + + // We need to deref the reference first before we reborrow it to a pinned reference. + let (deref, unpin_obligation) = match a_pin { + // no `Unpin` required when reborrowing a pinned reference to a pinned reference + ty::Pinnedness::Pinned => (DerefAdjustKind::Pin, None), + // `Unpin` required when reborrowing a non-pinned reference to a pinned reference + ty::Pinnedness::Not => { + (DerefAdjustKind::Builtin, Some(self.unpin_obligation(a, b, a_ty))) } }; - let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?; - let (_, _, _b_ty, mut_b) = extract_pin_mut(b)?; - - coerce_mutbls(mut_a, mut_b)?; + coerce_mutbls(a_mut, b_mut)?; // update a with b's mutability since we'll be coercing mutability - let a = Ty::new_adt( - self.tcx, - pin, - self.tcx.mk_args(&[Ty::new_ref(self.tcx, a_region, a_ty, mut_b).into()]), - ); + let a = Ty::new_pinned_ref(self.tcx, a_r, a_ty, b_mut); // To complete the reborrow, we need to make sure we can unify the inner types, and if so we // add the adjustments. - self.unify_and(a, b, [], Adjust::ReborrowPin(mut_b), ForceLeakCheck::No) + let mut coerce = self.unify_and( + a, + b, + [Adjustment { kind: Adjust::Deref(deref), target: a_ty }], + Adjust::Borrow(AutoBorrow::Pin(b_mut)), + ForceLeakCheck::No, + )?; + + coerce.obligations.extend(unpin_obligation); + Ok(coerce) } fn coerce_from_fn_pointer( diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 0a492c795b29c..b6dfda33142c5 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -736,7 +736,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx self.consume_or_copy(&place_with_id, place_with_id.hir_id); } - adjustment::Adjust::Deref(DerefAdjustKind::Builtin) => {} + adjustment::Adjust::Deref(DerefAdjustKind::Builtin | DerefAdjustKind::Pin) => {} // Autoderefs for overloaded Deref calls in fact reference // their receiver. That is, if we have `(*x)` where `x` @@ -791,7 +791,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ); } - adjustment::AutoBorrow::RawPtr(m) => { + adjustment::AutoBorrow::RawPtr(m) | adjustment::AutoBorrow::Pin(m) => { debug!("walk_autoref: expr.hir_id={} base_place={:?}", expr.hir_id, base_place); self.delegate.borrow_mut().borrow( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index c24d1127d5a62..f817ca8421473 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -331,6 +331,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Adjust::Deref(DerefAdjustKind::Builtin) => { // FIXME(const_trait_impl): We *could* enforce `&T: [const] Deref` here. } + Adjust::Deref(DerefAdjustKind::Pin) => { + // FIXME(const_trait_impl): We *could* enforce `Pin<&T>: [const] Deref` here. + } Adjust::Pointer(_pointer_coercion) => { // FIXME(const_trait_impl): We should probably enforce these. } diff --git a/compiler/rustc_lint/src/autorefs.rs b/compiler/rustc_lint/src/autorefs.rs index 34049288ea809..910a2918f9f71 100644 --- a/compiler/rustc_lint/src/autorefs.rs +++ b/compiler/rustc_lint/src/autorefs.rs @@ -173,7 +173,7 @@ fn has_implicit_borrow(Adjustment { kind, .. }: &Adjustment<'_>) -> Option<(Muta Adjust::NeverToAny | Adjust::Pointer(..) | Adjust::ReborrowPin(..) - | Adjust::Deref(DerefAdjustKind::Builtin) - | Adjust::Borrow(AutoBorrow::RawPtr(..)) => None, + | Adjust::Deref(DerefAdjustKind::Builtin | DerefAdjustKind::Pin) + | Adjust::Borrow(AutoBorrow::RawPtr(..) | AutoBorrow::Pin(..)) => None, } } diff --git a/compiler/rustc_middle/src/query/job.rs b/compiler/rustc_middle/src/query/job.rs index f1a2b3a34d0e8..23ca15d3f8a12 100644 --- a/compiler/rustc_middle/src/query/job.rs +++ b/compiler/rustc_middle/src/query/job.rs @@ -102,9 +102,31 @@ impl<'tcx> QueryLatch<'tcx> { query: Option, span: Span, ) -> Result<(), CycleError>> { + let mut info = self.info.lock(); + if info.complete { + return Ok(()); + } + let waiter = Arc::new(QueryWaiter { query, span, cycle: Mutex::new(None), condvar: Condvar::new() }); - self.wait_on_inner(tcx, &waiter); + + // We push the waiter on to the `waiters` list. It can be accessed inside + // the `wait` call below, by 1) the `set` method or 2) by deadlock detection. + // Both of these will remove it from the `waiters` list before resuming + // this thread. + info.waiters.push(Arc::clone(&waiter)); + + // Awaits the caller on this latch by blocking the current thread. + // If this detects a deadlock and the deadlock handler wants to resume this thread + // we have to be in the `wait` call. This is ensured by the deadlock handler + // getting the self.info lock. + rustc_thread_pool::mark_blocked(); + tcx.jobserver_proxy.release_thread(); + waiter.condvar.wait(&mut info); + // Release the lock before we potentially block in `acquire_thread` + drop(info); + tcx.jobserver_proxy.acquire_thread(); + // FIXME: Get rid of this lock. We have ownership of the QueryWaiter // although another thread may still have a Arc reference so we cannot // use Arc::get_mut @@ -115,28 +137,6 @@ impl<'tcx> QueryLatch<'tcx> { } } - /// Awaits the caller on this latch by blocking the current thread. - fn wait_on_inner(&self, tcx: TyCtxt<'tcx>, waiter: &Arc>) { - let mut info = self.info.lock(); - if !info.complete { - // We push the waiter on to the `waiters` list. It can be accessed inside - // the `wait` call below, by 1) the `set` method or 2) by deadlock detection. - // Both of these will remove it from the `waiters` list before resuming - // this thread. - info.waiters.push(Arc::clone(waiter)); - - // If this detects a deadlock and the deadlock handler wants to resume this thread - // we have to be in the `wait` call. This is ensured by the deadlock handler - // getting the self.info lock. - rustc_thread_pool::mark_blocked(); - tcx.jobserver_proxy.release_thread(); - waiter.condvar.wait(&mut info); - // Release the lock before we potentially block in `acquire_thread` - drop(info); - tcx.jobserver_proxy.acquire_thread(); - } - } - /// Sets the latch and resumes all waiters on it fn set(&self) { let mut info = self.info.lock(); diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 6d546aede4cf4..58687be7440b5 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -105,6 +105,7 @@ pub enum Adjust { Pointer(PointerCoercion), /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`. + // FIXME(pin_ergonomics): This can be replaced with a `Deref(Pin)` followed by a `Borrow(Pin)` ReborrowPin(hir::Mutability), } @@ -112,6 +113,7 @@ pub enum Adjust { pub enum DerefAdjustKind { Builtin, Overloaded(OverloadedDeref), + Pin, } /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)` @@ -196,6 +198,9 @@ pub enum AutoBorrow { /// Converts from T to *T. RawPtr(hir::Mutability), + + /// Converts from T to Pin<&T>. + Pin(hir::Mutability), } /// Information for `CoerceUnsized` impls, storing information we diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 2acc58422902b..9c22d158154fb 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1365,6 +1365,14 @@ impl<'tcx> Ty<'tcx> { } } + /// Returns the type, pinnedness, mutability, and the region of a reference (`&T` or `&mut T`) + /// or a pinned-reference type (`Pin<&T>` or `Pin<&mut T>`). + /// + /// Regarding the [`pin_ergonomics`] feature, one of the goals is to make pinned references + /// (`Pin<&T>` and `Pin<&mut T>`) behaves similar to normal references (`&T` and `&mut T`). + /// This function is useful when references and pinned references are processed similarly. + /// + /// [`pin_ergonomics`]: https://github.com/rust-lang/rust/issues/130494 pub fn maybe_pinned_ref( self, ) -> Option<(Ty<'tcx>, ty::Pinnedness, ty::Mutability, Region<'tcx>)> { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index c5eeb8b1aa856..c646b0fc45ea1 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -143,6 +143,19 @@ impl<'tcx> ThirBuildCx<'tcx> { adjust_span(&mut expr); ExprKind::Deref { arg: self.thir.exprs.push(expr) } } + Adjust::Deref(DerefAdjustKind::Pin) => { + adjust_span(&mut expr); + // pointer = ($expr).pointer + let pin_ty = expr.ty.pinned_ty().expect("Deref(Pin) with non-Pin type"); + let pointer_target = ExprKind::Field { + lhs: self.thir.exprs.push(expr), + variant_index: FIRST_VARIANT, + name: FieldIdx::ZERO, + }; + let expr = Expr { temp_scope_id, ty: pin_ty, span, kind: pointer_target }; + // expr = *pointer + ExprKind::Deref { arg: self.thir.exprs.push(expr) } + } Adjust::Deref(DerefAdjustKind::Overloaded(deref)) => { // We don't need to do call adjust_span here since // deref coercions always start with a built-in deref. @@ -177,6 +190,37 @@ impl<'tcx> ThirBuildCx<'tcx> { Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => { ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) } } + Adjust::Borrow(AutoBorrow::Pin(mutbl)) => { + // expr = &pin (mut|const|) arget + let borrow_kind = match mutbl { + hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default }, + hir::Mutability::Not => BorrowKind::Shared, + }; + let new_pin_target = + Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, mutbl); + let arg = self.thir.exprs.push(expr); + let expr = self.thir.exprs.push(Expr { + temp_scope_id, + ty: new_pin_target, + span, + kind: ExprKind::Borrow { borrow_kind, arg }, + }); + + // kind = Pin { pointer } + let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, span); + let args = self.tcx.mk_args(&[new_pin_target.into()]); + let kind = ExprKind::Adt(Box::new(AdtExpr { + adt_def: self.tcx.adt_def(pin_did), + variant_index: FIRST_VARIANT, + args, + fields: Box::new([FieldExpr { name: FieldIdx::ZERO, expr }]), + user_ty: None, + base: AdtExprBase::None, + })); + + debug!(?kind); + kind + } Adjust::ReborrowPin(mutbl) => { debug!("apply ReborrowPin adjustment"); // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }` diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 517bc61e5eb02..245ee6ec1cb75 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1699,7 +1699,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { !a.is_always_valid(&self.ecx) || !b.is_always_valid(&self.ecx) } BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } + | BackendRepr::SimdScalableVector { .. } | BackendRepr::Memory { .. } => false, } } diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs index a5f2ba2f1ced9..0921e57844b03 100644 --- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs +++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs @@ -36,7 +36,7 @@ fn passes_vectors_by_value(mode: &PassMode, repr: &BackendRepr) -> UsesVectorReg UsesVectorRegisters::FixedVector } PassMode::Direct(..) | PassMode::Pair(..) - if matches!(repr, BackendRepr::ScalableVector { .. }) => + if matches!(repr, BackendRepr::SimdScalableVector { .. }) => { UsesVectorRegisters::ScalableVector } diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index 582a02e918243..b3edc6194c307 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -265,7 +265,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { rustc_abi::BackendRepr::SimdVector { element, count } => { ValueAbi::Vector { element: element.stable(tables, cx), count } } - rustc_abi::BackendRepr::ScalableVector { element, count } => { + rustc_abi::BackendRepr::SimdScalableVector { element, count } => { ValueAbi::ScalableVector { element: element.stable(tables, cx), count } } rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized }, diff --git a/compiler/rustc_query_impl/src/execution.rs b/compiler/rustc_query_impl/src/execution.rs index 11749f3fb82d0..57d503ef7b076 100644 --- a/compiler/rustc_query_impl/src/execution.rs +++ b/compiler/rustc_query_impl/src/execution.rs @@ -1,5 +1,5 @@ use std::hash::Hash; -use std::mem; +use std::mem::ManuallyDrop; use rustc_data_structures::hash_table::{Entry, HashTable}; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -26,17 +26,6 @@ fn equivalent_key(k: K) -> impl Fn(&(K, V)) -> bool { move |x| x.0 == k } -/// Obtains the enclosed [`QueryJob`], or panics if this query evaluation -/// was poisoned by a panic. -fn expect_job<'tcx>(status: ActiveKeyStatus<'tcx>) -> QueryJob<'tcx> { - match status { - ActiveKeyStatus::Started(job) => job, - ActiveKeyStatus::Poisoned => { - panic!("job for query failed to start and was poisoned") - } - } -} - pub(crate) fn all_inactive<'tcx, K>(state: &QueryState<'tcx, K>) -> bool { state.active.lock_shards().all(|shard| shard.is_empty()) } @@ -104,20 +93,6 @@ where Some(()) } -/// Guard object representing the responsibility to execute a query job and -/// mark it as completed. -/// -/// This will poison the relevant query key if it is dropped without calling -/// [`Self::complete`]. -struct ActiveJobGuard<'tcx, K> -where - K: Eq + Hash + Copy, -{ - state: &'tcx QueryState<'tcx, K>, - key: K, - key_hash: u64, -} - #[cold] #[inline(never)] fn mk_cycle<'tcx, C: QueryCache>( @@ -148,39 +123,65 @@ fn mk_cycle<'tcx, C: QueryCache>( } } +/// Guard object representing the responsibility to execute a query job and +/// mark it as completed. +/// +/// This will poison the relevant query key if it is dropped without calling +/// [`Self::complete`]. +struct ActiveJobGuard<'tcx, K> +where + K: Eq + Hash + Copy, +{ + state: &'tcx QueryState<'tcx, K>, + key: K, + key_hash: u64, +} + impl<'tcx, K> ActiveJobGuard<'tcx, K> where K: Eq + Hash + Copy, { /// Completes the query by updating the query cache with the `result`, /// signals the waiter, and forgets the guard so it won't poison the query. - fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) + fn complete(self, cache: &C, value: C::Value, dep_node_index: DepNodeIndex) where C: QueryCache, { - // Forget ourself so our destructor won't poison the query. - // (Extract fields by value first to make sure we don't leak anything.) - let Self { state, key, key_hash }: Self = self; - mem::forget(self); - // Mark as complete before we remove the job from the active state // so no other thread can re-execute this query. - cache.complete(key, result, dep_node_index); - - let 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), + cache.complete(self.key, value, dep_node_index); + + let mut this = ManuallyDrop::new(self); + + // Drop everything without poisoning the query. + this.drop_and_maybe_poison(/* poison */ false); + } + + fn drop_and_maybe_poison(&mut self, poison: bool) { + let status = { + let mut shard = self.state.active.lock_shard_by_hash(self.key_hash); + match shard.find_entry(self.key_hash, equivalent_key(self.key)) { + Err(_) => { + // Note: we must not panic while holding the lock, because unwinding also looks + // at this map, which can result in a double panic. So drop it first. + drop(shard); + panic!(); + } + Ok(occupied) => { + let ((key, status), vacant) = occupied.remove(); + if poison { + vacant.insert((key, ActiveKeyStatus::Poisoned)); + } + status + } } }; - let job = expect_job(job.expect("active query job entry")); - job.signal_complete(); + // Also signal the completion of the job, so waiters will continue execution. + match status { + ActiveKeyStatus::Started(job) => job.signal_complete(), + ActiveKeyStatus::Poisoned => panic!(), + } } } @@ -192,21 +193,7 @@ where #[cold] fn drop(&mut self) { // Poison the query so jobs waiting on it panic. - let Self { state, key, key_hash } = *self; - let job = { - let mut shard = state.active.lock_shard_by_hash(key_hash); - match shard.find_entry(key_hash, equivalent_key(key)) { - Err(_) => panic!(), - Ok(occupied) => { - let ((key, value), vacant) = occupied.remove(); - vacant.insert((key, ActiveKeyStatus::Poisoned)); - expect_job(value) - } - } - }; - // Also signal the completion of the job, so waiters - // will continue execution. - job.signal_complete(); + self.drop_and_maybe_poison(/* poison */ true); } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a280acc0d51df..80538aebf5f66 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1474,7 +1474,9 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { return; } - AssocItemKind::DelegationMac(..) => bug!(), + AssocItemKind::DelegationMac(..) => { + span_bug!(item.span, "delegation mac should already have been removed") + } }; let vis = self.resolve_visibility(&item.vis); let feed = self.r.feed(item.id); diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 81820e049716b..de36f01b6d0e5 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -358,9 +358,12 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { }, ), AssocItemKind::Type(box TyAlias { ident, .. }) => (*ident, DefKind::AssocTy), - AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => { + AssocItemKind::MacCall(..) => { return self.visit_macro_invoc(i.id); } + AssocItemKind::DelegationMac(..) => { + span_bug!(i.span, "degation mac invoc should have already been handled") + } }; let def = self.create_def(i.id, Some(ident.name), def_kind, i.span); diff --git a/compiler/rustc_target/src/callconv/loongarch.rs b/compiler/rustc_target/src/callconv/loongarch.rs index d74d15446eaf6..054e9a00ea6fd 100644 --- a/compiler/rustc_target/src/callconv/loongarch.rs +++ b/compiler/rustc_target/src/callconv/loongarch.rs @@ -88,7 +88,7 @@ where BackendRepr::SimdVector { .. } => { return Err(CannotUseFpConv); } - BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), + BackendRepr::SimdScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/mod.rs b/compiler/rustc_target/src/callconv/mod.rs index 4083e28c09cbf..7dc270795281a 100644 --- a/compiler/rustc_target/src/callconv/mod.rs +++ b/compiler/rustc_target/src/callconv/mod.rs @@ -392,7 +392,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { ), BackendRepr::SimdVector { .. } => PassMode::Direct(ArgAttributes::new()), BackendRepr::Memory { .. } => Self::indirect_pass_mode(&layout), - BackendRepr::ScalableVector { .. } => PassMode::Direct(ArgAttributes::new()), + BackendRepr::SimdScalableVector { .. } => PassMode::Direct(ArgAttributes::new()), }; ArgAbi { layout, mode } } @@ -878,7 +878,7 @@ where matches!(layout.variants, Variants::Single { .. }) && fields_are_noundef(layout, cx) } }, - BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => false, + BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => false, } } diff --git a/compiler/rustc_target/src/callconv/riscv.rs b/compiler/rustc_target/src/callconv/riscv.rs index f166b83305165..18efdc5804fb6 100644 --- a/compiler/rustc_target/src/callconv/riscv.rs +++ b/compiler/rustc_target/src/callconv/riscv.rs @@ -91,7 +91,7 @@ where } } }, - BackendRepr::SimdVector { .. } | BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdVector { .. } | BackendRepr::SimdScalableVector { .. } => { return Err(CannotUseFpConv); } BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { diff --git a/compiler/rustc_target/src/callconv/sparc64.rs b/compiler/rustc_target/src/callconv/sparc64.rs index f55d03d89e8ff..55f264d89bb4d 100644 --- a/compiler/rustc_target/src/callconv/sparc64.rs +++ b/compiler/rustc_target/src/callconv/sparc64.rs @@ -65,7 +65,7 @@ fn classify<'a, Ty, C>( Primitive::Int(_, _) | Primitive::Pointer(_) => { /* pass in integer registers */ } }, BackendRepr::SimdVector { .. } => {} - BackendRepr::ScalableVector { .. } => {} + BackendRepr::SimdScalableVector { .. } => {} BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => match arg_layout.fields { FieldsShape::Primitive => { unreachable!("aggregates can't have `FieldsShape::Primitive`") diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index 5e8cab0ee9877..9aaa411db6c05 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -103,7 +103,7 @@ where } false } - BackendRepr::ScalableVector { .. } => { + BackendRepr::SimdScalableVector { .. } => { panic!("scalable vectors are unsupported") } } diff --git a/compiler/rustc_target/src/callconv/x86_64.rs b/compiler/rustc_target/src/callconv/x86_64.rs index 8fab4e444228c..dc73907c0c18a 100644 --- a/compiler/rustc_target/src/callconv/x86_64.rs +++ b/compiler/rustc_target/src/callconv/x86_64.rs @@ -59,7 +59,7 @@ where BackendRepr::SimdVector { .. } => Class::Sse, - BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), + BackendRepr::SimdScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::ScalarPair(..) | BackendRepr::Memory { .. } => { for i in 0..layout.fields.count() { diff --git a/compiler/rustc_target/src/callconv/x86_win64.rs b/compiler/rustc_target/src/callconv/x86_win64.rs index 4026c4f471a7e..624563c68e5b9 100644 --- a/compiler/rustc_target/src/callconv/x86_win64.rs +++ b/compiler/rustc_target/src/callconv/x86_win64.rs @@ -25,7 +25,7 @@ where // FIXME(eddyb) there should be a size cap here // (probably what clang calls "illegal vectors"). } - BackendRepr::ScalableVector { .. } => panic!("scalable vectors are unsupported"), + BackendRepr::SimdScalableVector { .. } => panic!("scalable vectors are unsupported"), BackendRepr::Scalar(scalar) => { if is_ret && matches!(scalar.primitive(), Primitive::Int(Integer::I128, _)) { if cx.target_spec().rustc_abi == Some(RustcAbi::Softfloat) { diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs index adb2d2c185cac..0fde0009debe7 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs @@ -272,18 +272,21 @@ impl Trait for X { values.found, values.expected, ) }; - if !(self.suggest_constraining_opaque_associated_type( - diag, - msg, - proj_ty, - values.expected, - ) || self.suggest_constraint( - diag, - &msg, - body_owner_def_id, - proj_ty, - values.expected, - )) { + let suggested_projection_constraint = proj_ty.kind(tcx) + == ty::AliasTyKind::Projection + && (self.suggest_constraining_opaque_associated_type( + diag, + msg, + proj_ty, + values.expected, + ) || self.suggest_constraint( + diag, + &msg, + body_owner_def_id, + proj_ty, + values.expected, + )); + if !suggested_projection_constraint { diag.help(msg()); diag.note( "for more information, visit \ diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 44762caf6e838..5008794bcb191 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -485,7 +485,7 @@ fn fn_abi_sanity_check<'tcx>( match arg.layout.backend_repr { BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } - | BackendRepr::ScalableVector { .. } => {} + | BackendRepr::SimdScalableVector { .. } => {} BackendRepr::ScalarPair(..) => { panic!("`PassMode::Direct` used for ScalarPair type {}", arg.layout.ty) } diff --git a/compiler/rustc_ty_utils/src/layout/invariant.rs b/compiler/rustc_ty_utils/src/layout/invariant.rs index 166e44d3c486c..03ac1674dbd50 100644 --- a/compiler/rustc_ty_utils/src/layout/invariant.rs +++ b/compiler/rustc_ty_utils/src/layout/invariant.rs @@ -250,7 +250,7 @@ pub(super) fn layout_sanity_check<'tcx>(cx: &LayoutCx<'tcx>, layout: &TyAndLayou // And the size has to be element * count plus alignment padding, of course assert!(size == (element_size * count).align_to(align)); } - BackendRepr::Memory { .. } | BackendRepr::ScalableVector { .. } => {} // Nothing to check. + BackendRepr::Memory { .. } | BackendRepr::SimdScalableVector { .. } => {} // Nothing to check. } } diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs index 7c58cd7303ebc..e0c6c777c09af 100644 --- a/compiler/rustc_type_ir/src/search_graph/mod.rs +++ b/compiler/rustc_type_ir/src/search_graph/mod.rs @@ -247,6 +247,8 @@ impl CandidateHeadUsages { pub fn merge_usages(&mut self, other: CandidateHeadUsages) { if let Some(other_usages) = other.usages { if let Some(ref mut self_usages) = self.usages { + // Each head is merged independently, so the final usage counts are the same + // regardless of hash iteration order. #[allow(rustc::potential_query_instability)] for (head_index, head) in other_usages.into_iter() { let HeadUsages { inductive, unknown, coinductive, forced_ambiguity } = head; @@ -501,6 +503,8 @@ impl NestedGoals { /// to all nested goals of that nested goal are also inductive. Otherwise the paths are /// the same as for the child. fn extend_from_child(&mut self, step_kind: PathKind, nested_goals: &NestedGoals) { + // Each nested goal is updated independently, and `insert` only unions paths for that + // goal, so traversal order cannot affect the result. #[allow(rustc::potential_query_instability)] for (input, paths_to_nested) in nested_goals.iter() { let paths_to_nested = paths_to_nested.extend_with(step_kind); @@ -508,6 +512,8 @@ impl NestedGoals { } } + // This helper intentionally exposes unstable hash iteration so each caller must opt in + // locally and justify why its traversal is order-insensitive. #[cfg_attr(feature = "nightly", rustc_lint_query_instability)] #[allow(rustc::potential_query_instability)] fn iter(&self) -> impl Iterator + '_ { @@ -710,6 +716,8 @@ impl, X: Cx> SearchGraph { pub fn ignore_candidate_head_usages(&mut self, usages: CandidateHeadUsages) { if let Some(usages) = usages.usages { let (entry_index, entry) = self.stack.last_mut_with_index().unwrap(); + // Ignoring usages only mutates the state for the current `head_index`, so the + // resulting per-head state is unchanged by iteration order. #[allow(rustc::potential_query_instability)] for (head_index, usages) in usages.into_iter() { if head_index == entry_index { @@ -901,6 +909,8 @@ impl, X: Cx> SearchGraph { /// don't depend on its value. fn clear_dependent_provisional_results_for_rerun(&mut self) { let rerun_index = self.stack.next_index(); + // Each cached entry is filtered independently based on whether it depends on + // `rerun_index`, so bucket traversal order does not matter. #[allow(rustc::potential_query_instability)] self.provisional_cache.retain(|_, entries| { entries.retain(|entry| { @@ -958,6 +968,8 @@ impl, X: Cx> SearchGraph { rebase_reason: RebaseReason, ) { let popped_head_index = self.stack.next_index(); + // Rebasing decisions depend only on each provisional entry and the current stack state, + // so traversing the cache in hash order cannot change the final cache contents. #[allow(rustc::potential_query_instability)] self.provisional_cache.retain(|&input, entries| { entries.retain_mut(|entry| { @@ -1139,6 +1151,8 @@ impl, X: Cx> SearchGraph { // The global cache entry is also invalid if there's a provisional cache entry // would apply for any of its nested goals. + // Any matching provisional entry rejects the candidate, + // so iteration order only affects when we return `false`, not the final answer. #[allow(rustc::potential_query_instability)] for (input, path_from_global_entry) in nested_goals.iter() { let Some(entries) = self.provisional_cache.get(&input) else { diff --git a/library/alloctests/benches/vec_deque_append.rs b/library/alloctests/benches/vec_deque_append.rs index 7c805da973763..71dc0813f9cc4 100644 --- a/library/alloctests/benches/vec_deque_append.rs +++ b/library/alloctests/benches/vec_deque_append.rs @@ -8,7 +8,7 @@ const BENCH_N: usize = 1000; fn main() { if cfg!(miri) { // Don't benchmark Miri... - // (Due to bootstrap quirks, this gets picked up by `x.py miri library/alloc --no-doc`.) + // (Due to bootstrap quirks, this gets picked up by `x.py miri library/alloc --all-targets`.) return; } let a: VecDeque = (0..VECDEQUE_LEN).collect(); diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 5f956f03ecb18..0268906a4664c 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -64,7 +64,7 @@ check-aux: library/core \ library/alloc \ $(BOOTSTRAP_ARGS) \ - --no-doc + --all-targets # Some doctests use file system operations to demonstrate dealing with `Result`, # so we have to run them with isolation disabled. $(Q)MIRIFLAGS="-Zmiri-disable-isolation" \ diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 3b0e7b2e30afe..7be45c5fa9d40 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -41,7 +41,7 @@ use crate::utils::helpers::{ linker_args, linker_flags, t, target_supports_cranelift_backend, up_to_date, }; use crate::utils::render_tests::{add_flags_and_try_run_tests, try_run_tests}; -use crate::{CLang, CodegenBackendKind, DocTests, GitRepo, Mode, PathSet, envify}; +use crate::{CLang, CodegenBackendKind, GitRepo, Mode, PathSet, TestTarget, envify}; mod compiletest; @@ -174,7 +174,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" ); run_cargo_test(cargo, &[], &[], "linkchecker self tests", bootstrap_host, builder); - if builder.doc_tests == DocTests::No { + if !builder.test_target.runs_doctests() { return; } @@ -827,15 +827,14 @@ impl Step for CargoMiri { // We're not using `prepare_cargo_test` so we have to do this ourselves. // (We're not using that as the test-cargo-miri crate is not known to bootstrap.) - match builder.doc_tests { - DocTests::Yes => {} - DocTests::No => { - cargo.args(["--lib", "--bins", "--examples", "--tests", "--benches"]); + match builder.test_target { + TestTarget::AllTargets => { + cargo.args(["--lib", "--bins", "--examples", "--tests", "--benches"]) } - DocTests::Only => { - cargo.arg("--doc"); - } - } + TestTarget::Default => &mut cargo, + TestTarget::DocOnly => cargo.arg("--doc"), + TestTarget::Tests => cargo.arg("--tests"), + }; cargo.arg("--").args(builder.config.test_args()); // Finally, run everything. @@ -1213,7 +1212,7 @@ impl Step for RustdocGUI { fn is_default_step(builder: &Builder<'_>) -> bool { builder.config.nodejs.is_some() - && builder.doc_tests != DocTests::Only + && builder.test_target != TestTarget::DocOnly && get_browser_ui_test_version(builder).is_some() } @@ -1303,7 +1302,7 @@ impl Step for Tidy { } fn is_default_step(builder: &Builder<'_>) -> bool { - builder.doc_tests != DocTests::Only + builder.test_target != TestTarget::DocOnly } fn make_run(run: RunConfig<'_>) { @@ -1862,7 +1861,7 @@ impl Step for Compiletest { } fn run(self, builder: &Builder<'_>) { - if builder.doc_tests == DocTests::Only { + if builder.test_target == TestTarget::DocOnly { return; } @@ -2980,15 +2979,12 @@ fn prepare_cargo_test( cargo.arg("--message-format=json"); } - match builder.doc_tests { - DocTests::Only => { - cargo.arg("--doc"); - } - DocTests::No => { - cargo.args(["--bins", "--examples", "--tests", "--benches"]); - } - DocTests::Yes => {} - } + match builder.test_target { + TestTarget::AllTargets => cargo.args(["--bins", "--examples", "--tests", "--benches"]), + TestTarget::Default => &mut cargo, + TestTarget::DocOnly => cargo.arg("--doc"), + TestTarget::Tests => cargo.arg("--tests"), + }; for krate in crates { cargo.arg("-p").arg(krate); @@ -3319,7 +3315,7 @@ impl Step for CrateRustdocJsonTypes { builder.kind, "src/rustdoc-json-types", SourceType::InTree, - &[], + &["rkyv_0_8".to_owned()], ); // FIXME: this looks very wrong, libtest doesn't accept `-C` arguments and the quotes are fishy. @@ -3868,7 +3864,7 @@ impl Step for CodegenCranelift { let host = run.build_triple(); let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, host); - if builder.doc_tests == DocTests::Only { + if builder.test_target == TestTarget::DocOnly { return; } @@ -3989,7 +3985,7 @@ impl Step for CodegenGCC { let host = run.build_triple(); let compilers = RustcPrivateCompilers::new(run.builder, run.builder.top_stage, host); - if builder.doc_tests == DocTests::Only { + if builder.test_target == TestTarget::DocOnly { return; } diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 17f256188e1be..2c3b5251e12f6 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -415,6 +415,12 @@ impl Config { "flags.exclude" = ?flags_exclude ); + if flags_cmd.no_doc() { + eprintln!( + "WARN: `x.py test --no-doc` is renamed to `--all-targets`. `--no-doc` will be removed in the near future. Additionally `--tests` is added which only executes unit and integration tests." + ) + } + // Set config values based on flags. let mut exec_ctx = ExecutionContext::new(flags_verbose, flags_cmd.fail_fast()); exec_ctx.set_dry_run(if flags_dry_run { DryRun::UserSelected } else { DryRun::Disabled }); diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index bf089d25ffec8..a2e5def39d07c 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -15,7 +15,7 @@ use crate::core::build_steps::setup::Profile; use crate::core::builder::{Builder, Kind}; use crate::core::config::Config; use crate::core::config::target_selection::{TargetSelectionList, target_selection_list}; -use crate::{Build, CodegenBackendKind, DocTests}; +use crate::{Build, CodegenBackendKind, TestTarget}; #[derive(Copy, Clone, Default, Debug, ValueEnum)] pub enum Color { @@ -357,7 +357,7 @@ pub enum Subcommand { should be compiled and run. For example: ./x.py test tests/ui ./x.py test library/std --test-args hash_map - ./x.py test library/std --stage 0 --no-doc + ./x.py test library/std --stage 0 --all-targets ./x.py test tests/ui --bless ./x.py test tests/ui --compare-mode next-solver Note that `test tests/* --stage N` does NOT depend on `build compiler/rustc --stage N`; @@ -382,11 +382,14 @@ pub enum Subcommand { #[arg(long, value_name = "ARGS", allow_hyphen_values(true))] compiletest_rustc_args: Vec, #[arg(long)] - /// do not run doc tests - no_doc: bool, + /// Run all test targets (no doc tests) + all_targets: bool, #[arg(long)] - /// only run doc tests + /// Only run doc tests doc: bool, + /// Only run unit and integration tests + #[arg(long)] + tests: bool, #[arg(long)] /// whether to automatically update stderr/stdout files bless: bool, @@ -425,6 +428,11 @@ pub enum Subcommand { #[arg(long)] /// Ignore `//@ ignore-backends` directives. bypass_ignore_backends: bool, + + /// Deprecated. Use `--all-targets` or `--tests` instead. + #[arg(long)] + #[doc(hidden)] + no_doc: bool, }, /// Build and run some test suites *in Miri* Miri { @@ -436,11 +444,19 @@ pub enum Subcommand { /// (e.g. libtest, compiletest or rustdoc) test_args: Vec, #[arg(long)] - /// do not run doc tests - no_doc: bool, + /// Run all test targets (no doc tests) + all_targets: bool, #[arg(long)] - /// only run doc tests + /// Only run doc tests doc: bool, + /// Only run unit and integration tests + #[arg(long)] + tests: bool, + + /// Deprecated. Use `--all-targets` or `--tests` instead. + #[arg(long)] + #[doc(hidden)] + no_doc: bool, }, /// Build and run some benchmarks Bench { @@ -552,18 +568,26 @@ impl Subcommand { } } - pub fn doc_tests(&self) -> DocTests { + pub fn test_target(&self) -> TestTarget { match *self { - Subcommand::Test { doc, no_doc, .. } | Subcommand::Miri { no_doc, doc, .. } => { - if doc { - DocTests::Only - } else if no_doc { - DocTests::No - } else { - DocTests::Yes + Subcommand::Test { all_targets, doc, tests, .. } + | Subcommand::Miri { all_targets, doc, tests, .. } => match (all_targets, doc, tests) { + (true, true, _) | (true, _, true) | (_, true, true) => { + panic!("You can only set one of `--all-targets`, `--doc` and `--tests`.") } - } - _ => DocTests::Yes, + (true, false, false) => TestTarget::AllTargets, + (false, true, false) => TestTarget::DocOnly, + (false, false, true) => TestTarget::Tests, + (false, false, false) => TestTarget::Default, + }, + _ => TestTarget::Default, + } + } + + pub fn no_doc(&self) -> bool { + match *self { + Subcommand::Test { no_doc, .. } | Subcommand::Miri { no_doc, .. } => no_doc, + _ => false, } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index b9a914f53cec1..f1303814f6d72 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -177,13 +177,21 @@ impl std::str::FromStr for CodegenBackendKind { } #[derive(PartialEq, Eq, Copy, Clone, Debug)] -pub enum DocTests { - /// Run normal tests and doc tests (default). - Yes, - /// Do not run any doc tests. - No, +pub enum TestTarget { + /// Run unit, integration and doc tests (default). + Default, + /// Run unit, integration, doc tests, examples, bins, benchmarks (no doc tests). + AllTargets, /// Only run doc tests. - Only, + DocOnly, + /// Only run unit and integration tests. + Tests, +} + +impl TestTarget { + fn runs_doctests(&self) -> bool { + matches!(self, TestTarget::DocOnly | TestTarget::Default) + } } pub enum GitRepo { @@ -222,7 +230,7 @@ pub struct Build { in_tree_gcc_info: GitInfo, local_rebuild: bool, fail_fast: bool, - doc_tests: DocTests, + test_target: TestTarget, verbosity: usize, /// Build triple for the pre-compiled snapshot compiler. @@ -540,7 +548,7 @@ impl Build { initial_sysroot: config.initial_sysroot.clone(), local_rebuild: config.local_rebuild, fail_fast: config.cmd.fail_fast(), - doc_tests: config.cmd.doc_tests(), + test_target: config.cmd.test_target(), verbosity: config.exec_ctx.verbosity as usize, host_target: config.host_target, diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 1077077cb97a2..f8af8f3bec031 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -73,7 +73,7 @@ pub fn human_readable_changes(changes: &[ChangeInfo]) -> String { /// Keeps track of major changes made to the bootstrap configuration. /// /// If you make any major changes (such as adding new values or changing default values), -/// please ensure adding `ChangeInfo` to the end(because the list must be sorted by the merge date) +/// please ensure adding `ChangeInfo` to the end (because the list must be sorted by the merge date) /// of this list. pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ ChangeInfo { @@ -611,4 +611,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "New option `llvm.offload-clang-dir` to allow building an in-tree llvm offload and openmp runtime with an external clang.", }, + ChangeInfo { + change_id: 153143, + severity: ChangeSeverity::Warning, + summary: "`x.py test --no-doc` is renamed to `--all-targets`. Additionally `--tests` is added which only executes unit and integration tests.", + }, ]; diff --git a/src/ci/docker/host-x86_64/dist-android/Dockerfile b/src/ci/docker/host-x86_64/dist-android/Dockerfile index 7b73326e35900..25565564e8dae 100644 --- a/src/ci/docker/host-x86_64/dist-android/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-android/Dockerfile @@ -16,15 +16,14 @@ ENV TARGETS=$TARGETS,i686-linux-android ENV TARGETS=$TARGETS,aarch64-linux-android ENV TARGETS=$TARGETS,x86_64-linux-android -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-profiler \ --android-ndk=/android/ndk/ \ - --disable-docs + --disable-docs" ENV PATH=$PATH:/android/ndk/toolchains/llvm/prebuilt/linux-x86_64/bin -ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS +ENV SCRIPT="python3 ../x.py dist --host= --target $TARGETS" COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile index 96acc5e97e94b..3ee8cb9ed7e8f 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile @@ -45,14 +45,13 @@ ENV TARGETS=$HOSTS ENV TARGETS=$TARGETS,loongarch64-unknown-none ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ --disable-docs \ --set rust.jemalloc \ --set rust.lto=thin \ - --set rust.codegen-units=1 + --set rust.codegen-units=1" -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $TARGETS +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $TARGETS" diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile index 44efc10890177..54c1869a2a04f 100644 --- a/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-loongarch64-musl/Dockerfile @@ -27,8 +27,7 @@ ENV CC_loongarch64_unknown_linux_musl=loongarch64-unknown-linux-musl-gcc \ ENV HOSTS=loongarch64-unknown-linux-musl -ENV RUST_CONFIGURE_ARGS \ - --enable-extended \ +ENV RUST_CONFIGURE_ARGS="--enable-extended \ --enable-full-tools \ --enable-profiler \ --enable-sanitizers \ @@ -37,6 +36,6 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lto=thin \ --set rust.codegen-units=1 \ --set target.loongarch64-unknown-linux-musl.crt-static=false \ - --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr + --musl-root-loongarch64=/x-tools/loongarch64-unknown-linux-musl/loongarch64-unknown-linux-musl/sysroot/usr" -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile index c0084a7cd236c..51d9e8a5798aa 100644 --- a/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-riscv64-linux/Dockerfile @@ -29,5 +29,5 @@ ENV CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ ENV HOSTS=riscv64gc-unknown-linux-gnu ENV TARGETS=riscv64gc-unknown-linux-gnu,riscv64a23-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --target $TARGETS --host $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --disable-docs" +ENV SCRIPT="python3 ../x.py dist --target $TARGETS --host $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile index de776911d628d..413249e02e87f 100644 --- a/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-s390x-linux/Dockerfile @@ -26,5 +26,5 @@ ENV \ ENV HOSTS=s390x-unknown-linux-gnu -ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --enable-sanitizers --enable-profiler --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --enable-lld --enable-sanitizers --enable-profiler --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/dist-sparcv9-solaris/Dockerfile b/src/ci/docker/host-x86_64/dist-sparcv9-solaris/Dockerfile index f7852c6364dc2..ffe28fca11656 100644 --- a/src/ci/docker/host-x86_64/dist-sparcv9-solaris/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-sparcv9-solaris/Dockerfile @@ -32,5 +32,5 @@ ENV \ ENV HOSTS=sparcv9-sun-solaris -ENV RUST_CONFIGURE_ARGS --enable-extended --disable-docs -ENV SCRIPT python3 ../x.py dist --host $HOSTS --target $HOSTS +ENV RUST_CONFIGURE_ARGS="--enable-extended --disable-docs" +ENV SCRIPT="python3 ../x.py dist --host $HOSTS --target $HOSTS" diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile index 0cae83a85b3a4..ccb7841d83ac3 100644 --- a/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/Dockerfile @@ -38,13 +38,12 @@ COPY scripts/shared.sh /tmp/ COPY scripts/build-fuchsia-toolchain.sh /tmp/ RUN /tmp/build-fuchsia-toolchain.sh -ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_AR /usr/local/bin/llvm-ar -ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS \ - -C panic=abort \ +ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_AR="/usr/local/bin/llvm-ar" +ENV CARGO_TARGET_X86_64_UNKNOWN_FUCHSIA_RUSTFLAGS="-C panic=abort \ -C force-unwind-tables=yes \ -C link-arg=--sysroot=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot \ -Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/sysroot/lib \ - -Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib + -Lnative=/usr/local/core-linux-amd64-fuchsia-sdk/arch/x64/lib" ENV TARGETS=x86_64-unknown-fuchsia ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu @@ -52,17 +51,16 @@ ENV TARGETS=$TARGETS,x86_64-unknown-linux-gnu COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -ENV RUST_INSTALL_DIR /checkout/obj/install +ENV RUST_INSTALL_DIR="/checkout/obj/install" RUN mkdir -p $RUST_INSTALL_DIR/etc # Fuchsia only supports LLVM. -ENV CODEGEN_BACKENDS llvm +ENV CODEGEN_BACKENDS="llvm" # download-rustc is not allowed for `x install` -ENV NO_DOWNLOAD_CI_RUSTC 1 +ENV NO_DOWNLOAD_CI_RUSTC="1" -ENV RUST_CONFIGURE_ARGS \ - --prefix=$RUST_INSTALL_DIR \ +ENV RUST_CONFIGURE_ARGS="--prefix=$RUST_INSTALL_DIR \ --sysconfdir=etc \ --enable-lld \ --llvm-libunwind=in-tree \ @@ -72,8 +70,7 @@ ENV RUST_CONFIGURE_ARGS \ --set target.x86_64-unknown-fuchsia.cxx=/usr/local/bin/clang++ \ --set target.x86_64-unknown-fuchsia.ar=/usr/local/bin/llvm-ar \ --set target.x86_64-unknown-fuchsia.ranlib=/usr/local/bin/llvm-ranlib \ - --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld + --set target.x86_64-unknown-fuchsia.linker=/usr/local/bin/ld.lld" -ENV SCRIPT \ - python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ - bash ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh +ENV SCRIPT="python3 ../x.py install --target $TARGETS compiler/rustc library/std clippy && \ + bash ../src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh" diff --git a/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile b/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile index 97298519cf20b..28a51ca2d6857 100644 --- a/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-rust-for-linux/Dockerfile @@ -34,7 +34,7 @@ RUN sh /scripts/sccache.sh # RfL needs access to cland, lld and llvm tools ENV PATH="${PATH}:/usr/lib/llvm-15/bin" -ENV RUST_CONFIGURE_ARGS --build=x86_64-unknown-linux-gnu +ENV RUST_CONFIGURE_ARGS="--build=x86_64-unknown-linux-gnu" COPY /scripts/rfl-build.sh /tmp/rfl-build.sh -ENV SCRIPT bash /tmp/rfl-build.sh +ENV SCRIPT="bash /tmp/rfl-build.sh" diff --git a/src/doc/rustc-dev-guide/src/tests/intro.md b/src/doc/rustc-dev-guide/src/tests/intro.md index c13f8bde29945..82fb9597cb500 100644 --- a/src/doc/rustc-dev-guide/src/tests/intro.md +++ b/src/doc/rustc-dev-guide/src/tests/intro.md @@ -62,7 +62,8 @@ would require recompiling the entire standard library, and the entirety of package tests: * `--doc` — Only runs documentation tests in the package. -* `--no-doc` — Run all tests *except* documentation tests. +* `--all-targets` — Run all tests *except* documentation tests. +* `--tests` — Only runs unit and integration tests [tidy-unit-tests]: https://github.com/rust-lang/rust/blob/HEAD/src/tools/tidy/src/unit_tests.rs diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index a837be680dcdd..427e46a32a489 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -329,14 +329,16 @@ complete -c x -n "__fish_x_using_subcommand test" -l reproducible-artifact -d 'A complete -c x -n "__fish_x_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand test" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}" complete -c x -n "__fish_x_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure' -complete -c x -n "__fish_x_using_subcommand test" -l no-doc -d 'do not run doc tests' -complete -c x -n "__fish_x_using_subcommand test" -l doc -d 'only run doc tests' +complete -c x -n "__fish_x_using_subcommand test" -l all-targets -d 'Run all test targets (no doc tests)' +complete -c x -n "__fish_x_using_subcommand test" -l doc -d 'Only run doc tests' +complete -c x -n "__fish_x_using_subcommand test" -l tests -d 'Only run unit and integration tests' complete -c x -n "__fish_x_using_subcommand test" -l bless -d 'whether to automatically update stderr/stdout files' complete -c x -n "__fish_x_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x -n "__fish_x_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x -n "__fish_x_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' complete -c x -n "__fish_x_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x -n "__fish_x_using_subcommand test" -l bypass-ignore-backends -d 'Ignore `//@ ignore-backends` directives' +complete -c x -n "__fish_x_using_subcommand test" -l no-doc -d 'Deprecated. Use `--all-targets` or `--tests` instead' complete -c x -n "__fish_x_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -374,8 +376,10 @@ complete -c x -n "__fish_x_using_subcommand miri" -l reproducible-artifact -d 'A complete -c x -n "__fish_x_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f complete -c x -n "__fish_x_using_subcommand miri" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}" complete -c x -n "__fish_x_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure' -complete -c x -n "__fish_x_using_subcommand miri" -l no-doc -d 'do not run doc tests' -complete -c x -n "__fish_x_using_subcommand miri" -l doc -d 'only run doc tests' +complete -c x -n "__fish_x_using_subcommand miri" -l all-targets -d 'Run all test targets (no doc tests)' +complete -c x -n "__fish_x_using_subcommand miri" -l doc -d 'Only run doc tests' +complete -c x -n "__fish_x_using_subcommand miri" -l tests -d 'Only run unit and integration tests' +complete -c x -n "__fish_x_using_subcommand miri" -l no-doc -d 'Deprecated. Use `--all-targets` or `--tests` instead' complete -c x -n "__fish_x_using_subcommand miri" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand miri" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand miri" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 1a02adbddfea7..ffaadf2470344 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -376,14 +376,16 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') - [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') - [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') + [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Run all test targets (no doc tests)') + [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'Only run doc tests') + [CompletionResult]::new('--tests', '--tests', [CompletionResultType]::ParameterName, 'Only run unit and integration tests') [CompletionResult]::new('--bless', '--bless', [CompletionResultType]::ParameterName, 'whether to automatically update stderr/stdout files') [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('--bypass-ignore-backends', '--bypass-ignore-backends', [CompletionResultType]::ParameterName, 'Ignore `//@ ignore-backends` directives') + [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'Deprecated. Use `--all-targets` or `--tests` instead') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -428,8 +430,10 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') - [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') - [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') + [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Run all test targets (no doc tests)') + [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'Only run doc tests') + [CompletionResult]::new('--tests', '--tests', [CompletionResultType]::ParameterName, 'Only run unit and integration tests') + [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'Deprecated. Use `--all-targets` or `--tests` instead') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index 63b7987fb290e..df5e7f3a6dda9 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -329,14 +329,16 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l reproducible-artifact complete -c x.py -n "__fish_x.py_using_subcommand test" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand test" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}" complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-fail-fast -d 'run all tests regardless of failure' -complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-doc -d 'do not run doc tests' -complete -c x.py -n "__fish_x.py_using_subcommand test" -l doc -d 'only run doc tests' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l all-targets -d 'Run all test targets (no doc tests)' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l doc -d 'Only run doc tests' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l tests -d 'Only run unit and integration tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -l bless -d 'whether to automatically update stderr/stdout files' complete -c x.py -n "__fish_x.py_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x.py -n "__fish_x.py_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x.py -n "__fish_x.py_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`' complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -l bypass-ignore-backends -d 'Ignore `//@ ignore-backends` directives' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-doc -d 'Deprecated. Use `--all-targets` or `--tests` instead' complete -c x.py -n "__fish_x.py_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' @@ -374,8 +376,10 @@ complete -c x.py -n "__fish_x.py_using_subcommand miri" -l reproducible-artifact complete -c x.py -n "__fish_x.py_using_subcommand miri" -l set -d 'override options in bootstrap.toml' -r -f complete -c x.py -n "__fish_x.py_using_subcommand miri" -l ci -d 'Make bootstrap to behave as it\'s running on the CI environment or not' -r -f -a "{true\t'',false\t''}" complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-fail-fast -d 'run all tests regardless of failure' -complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-doc -d 'do not run doc tests' -complete -c x.py -n "__fish_x.py_using_subcommand miri" -l doc -d 'only run doc tests' +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l all-targets -d 'Run all test targets (no doc tests)' +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l doc -d 'Only run doc tests' +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l tests -d 'Only run unit and integration tests' +complete -c x.py -n "__fish_x.py_using_subcommand miri" -l no-doc -d 'Deprecated. Use `--all-targets` or `--tests` instead' complete -c x.py -n "__fish_x.py_using_subcommand miri" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand miri" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand miri" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index cac70f722098f..644c033d455fd 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -376,14 +376,16 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') - [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') - [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') + [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Run all test targets (no doc tests)') + [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'Only run doc tests') + [CompletionResult]::new('--tests', '--tests', [CompletionResultType]::ParameterName, 'Only run unit and integration tests') [CompletionResult]::new('--bless', '--bless', [CompletionResultType]::ParameterName, 'whether to automatically update stderr/stdout files') [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `//rustfix_missing_coverage.txt`') [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('--bypass-ignore-backends', '--bypass-ignore-backends', [CompletionResultType]::ParameterName, 'Ignore `//@ ignore-backends` directives') + [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'Deprecated. Use `--all-targets` or `--tests` instead') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') @@ -428,8 +430,10 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--set', '--set', [CompletionResultType]::ParameterName, 'override options in bootstrap.toml') [CompletionResult]::new('--ci', '--ci', [CompletionResultType]::ParameterName, 'Make bootstrap to behave as it''s running on the CI environment or not') [CompletionResult]::new('--no-fail-fast', '--no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure') - [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests') - [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'only run doc tests') + [CompletionResult]::new('--all-targets', '--all-targets', [CompletionResultType]::ParameterName, 'Run all test targets (no doc tests)') + [CompletionResult]::new('--doc', '--doc', [CompletionResultType]::ParameterName, 'Only run doc tests') + [CompletionResult]::new('--tests', '--tests', [CompletionResultType]::ParameterName, 'Only run unit and integration tests') + [CompletionResult]::new('--no-doc', '--no-doc', [CompletionResultType]::ParameterName, 'Deprecated. Use `--all-targets` or `--tests` instead') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index cff17f431d33d..0d3765623c2f2 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -2145,7 +2145,7 @@ _x.py() { return 0 ;; x.py__miri) - opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --all-targets --doc --tests --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3875,7 +3875,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 47cdaf97befcc..caed118ae8459 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -376,14 +376,16 @@ _arguments "${_arguments_options[@]}" : \ '*--set=[override options in bootstrap.toml]:section.option=value:' \ '--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \ '--no-fail-fast[run all tests regardless of failure]' \ -'--no-doc[do not run doc tests]' \ -'--doc[only run doc tests]' \ +'--all-targets[Run all test targets (no doc tests)]' \ +'--doc[Only run doc tests]' \ +'--tests[Only run unit and integration tests]' \ '--bless[whether to automatically update stderr/stdout files]' \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ '--no-capture[don'\''t capture stdout/stderr of tests]' \ '--bypass-ignore-backends[Ignore \`//@ ignore-backends\` directives]' \ +'--no-doc[Deprecated. Use \`--all-targets\` or \`--tests\` instead]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -430,8 +432,10 @@ _arguments "${_arguments_options[@]}" : \ '*--set=[override options in bootstrap.toml]:section.option=value:' \ '--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \ '--no-fail-fast[run all tests regardless of failure]' \ -'--no-doc[do not run doc tests]' \ -'--doc[only run doc tests]' \ +'--all-targets[Run all test targets (no doc tests)]' \ +'--doc[Only run doc tests]' \ +'--tests[Only run unit and integration tests]' \ +'--no-doc[Deprecated. Use \`--all-targets\` or \`--tests\` instead]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index 700617bfeba0e..d72258aa1b9f4 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -2145,7 +2145,7 @@ _x() { return 0 ;; x__miri) - opts="-v -i -j -h --no-fail-fast --test-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --all-targets --doc --tests --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 @@ -3875,7 +3875,7 @@ _x() { return 0 ;; x__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --all-targets --doc --tests --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --test-codegen-backend --bypass-ignore-backends --no-doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --json-output --compile-time-deps --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --ci --skip-std-check-if-no-download-rustc --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index b960be4a1b10a..68aeb021b7316 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -376,14 +376,16 @@ _arguments "${_arguments_options[@]}" : \ '*--set=[override options in bootstrap.toml]:section.option=value:' \ '--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \ '--no-fail-fast[run all tests regardless of failure]' \ -'--no-doc[do not run doc tests]' \ -'--doc[only run doc tests]' \ +'--all-targets[Run all test targets (no doc tests)]' \ +'--doc[Only run doc tests]' \ +'--tests[Only run unit and integration tests]' \ '--bless[whether to automatically update stderr/stdout files]' \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`//rustfix_missing_coverage.txt\`]' \ '--no-capture[don'\''t capture stdout/stderr of tests]' \ '--bypass-ignore-backends[Ignore \`//@ ignore-backends\` directives]' \ +'--no-doc[Deprecated. Use \`--all-targets\` or \`--tests\` instead]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ @@ -430,8 +432,10 @@ _arguments "${_arguments_options[@]}" : \ '*--set=[override options in bootstrap.toml]:section.option=value:' \ '--ci=[Make bootstrap to behave as it'\''s running on the CI environment or not]:bool:(true false)' \ '--no-fail-fast[run all tests regardless of failure]' \ -'--no-doc[do not run doc tests]' \ -'--doc[only run doc tests]' \ +'--all-targets[Run all test targets (no doc tests)]' \ +'--doc[Only run doc tests]' \ +'--tests[Only run unit and integration tests]' \ +'--no-doc[Deprecated. Use \`--all-targets\` or \`--tests\` instead]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/rustdoc-json-types/Cargo.toml b/src/rustdoc-json-types/Cargo.toml index a38d34ef0e7d9..7e4e53ccaf0de 100644 --- a/src/rustdoc-json-types/Cargo.toml +++ b/src/rustdoc-json-types/Cargo.toml @@ -8,11 +8,13 @@ path = "lib.rs" [features] default = ["rustc-hash"] +rkyv_0_8 = ["dep:rkyv"] [dependencies] serde = "1.0" serde_derive = "1.0" rustc-hash = { version = "2.0", optional = true } +rkyv = { version = "0.8", optional = true } [dev-dependencies] serde_json = "1.0" diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 72a3f8b224a48..37dd226b73ce8 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -3,7 +3,11 @@ //! These types are the public API exposed through the `--output-format json` flag. The [`Crate`] //! struct is the root of the JSON blob and all other items are contained within. //! -//! We expose a `rustc-hash` feature that is disabled by default. This feature switches the +//! # Feature Flags +//! +//! ## `rustc-hash` +//! +//! We expose a `rustc-hash` feature, disabled by default. This feature switches the //! [`std::collections::HashMap`] for [`rustc_hash::FxHashMap`] to improve the performance of said //! `HashMap` in specific situations. //! @@ -12,8 +16,81 @@ //! turning this feature on, as [`FxHashMap`][2] only concerns itself with hash speed, and may //! increase the number of collisions. //! +//! ## `rkyv_0_8` +//! +//! We expose a `rkyv_0_8` feature, disabled by default. When enabled, it derives `rkyv`'s +//! [`Archive`][3], [`Serialize`][4] and [`Deserialize`][5] traits for all types in this crate. +//! Furthermore, it exposes the corresponding `Archived*` types (e.g. `ArchivedId` for [`Id`]). +//! +//! `rkyv` lets you works with JSON output without paying the deserialization cost _upfront_, +//! thanks to [zero-copy deserialization][6]. +//! You can perform various types of analyses on the `Archived*` version of the relevant types, +//! incurring the full deserialization cost only for the subset of items you actually need. +//! //! [1]: https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/rustc-hash.20and.20performance.20of.20rustdoc-types/near/474855731 //! [2]: https://crates.io/crates/rustc-hash +//! [3]: https://docs.rs/rkyv/0.8.15/rkyv/trait.Archive.html +//! [4]: https://docs.rs/rkyv/0.8.15/rkyv/trait.Serialize.html +//! [5]: https://docs.rs/rkyv/0.8.15/rkyv/trait.Deserialize.html +//! [6]: https://rkyv.org/zero-copy-deserialization.html + +// # On `rkyv` Derives +// +// In most cases, it's enough to add `#[derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]` +// on top of a type to derive the relevant `rkyv` traits. +// +// There are a few exceptions, though, where more complex macro options are required. +// The following sections break down the patterns that are showcased by `rkyv'`s +// [JSON schema example](https://github.com/rkyv/rkyv/blob/985b0230a0b9cb9fce4a4ee9facb6af148e27c8e/rkyv/examples/json_like_schema.rs). +// +// ## Recursive Types +// +// Let's look at the `Type` enum as an example. It stores a `Box` in its `Slice` variant. +// A "vanilla" `rkyv` annotation will cause an overflow in the compiler when +// building the crate, since the bounds generated by the macro will be self-referential and thus +// trap the compiler into a never-ending loop. +// +// To prevent this issue, `#[rkyv(omit_bounds)]` must be added to the relevant field. +// +// ## Co-Recursive Types +// +// The same problem occurs if a type is co-recursive—i.e. it doesn't _directly_ store a pointer +// to another instance of the same type, but one of its fields does, transitively. +// +// For example, let's look at `Path`: +// +// - `Path` has a field of type `Option>` +// - One of the variants in `GenericArgs` has a field of type `Vec` +// - One of the variants of `GenericArg` has a field of type `Type` +// - `Type::ResolvedPath` stores a `Path` instance +// +// The same logic of the recursive case applies here: we must use `#[rkyv(omit_bounds)]` to break the cycle. +// +// ## Additional Bounds +// +// Whenever `#[rkyv(omit_bounds)]` is added to a field or variant, `rkyv` omits _all_ traits bounds for that +// field in the generated impl. This may result in compilation errors due to insufficient bounds in the +// generated code. +// +// To add _some_ bounds back, `rkyv` exposes four knobs: +// +// - `#[rkyv(archive_bounds(..))]` to add predicates to all generated impls +// - `#[rkyv(serialize_bounds(..))]` to add predicates to just the `Serialize` impl +// - `#[rkyv(deserialize_bounds(..))]` to add predicates to just the `Deserialize` impl +// - `#[rkyv(bytecheck(bounds(..)))]` to add predicates to just the `CheckBytes` impl +// +// In particular, we use the following annotations in this crate: +// +// - `serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator, __S::Error: rkyv::rancor::Source)` for serializing +// variable-length types like `Vec`. `rkyv`'s zero-copy format requires the serializer to be able +// to write bytes (`Writer`) and allocate scratch space (`Allocator`) for these types +// ([`rkyv`'s `Vec` impl bounds](https://docs.rs/rkyv/0.8.15/rkyv/trait.Serialize.html#impl-Serialize%3CS%3E-for-Vec%3CT%3E)). +// The `Error: Source` bound lets error types compose. +// - `deserialize_bounds(__D::Error: rkyv::rancor::Source)` so that errors from deserializing fields behind +// `omit_bounds` (e.g. `Box`, `Vec`) can compose via the `Source` trait. +// - `bytecheck(bounds(__C: rkyv::validation::ArchiveContext, __C::Error: rkyv::rancor::Source))` for validating +// archived data. Checking that bytes represent a valid archived value requires an `ArchiveContext` that tracks +// validation state (e.g. subtree ranges, to prevent overlapping/out-of-bounds archived data). #[cfg(not(feature = "rustc-hash"))] use std::collections::HashMap; @@ -46,6 +123,8 @@ pub const FORMAT_VERSION: u32 = 57; /// about the language items in the local crate, as well as info about external items to allow /// tools to find or link to them. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Crate { /// The id of the root [`Module`] item of the local crate. pub root: Id, @@ -69,6 +148,8 @@ pub struct Crate { /// Information about a target #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Target { /// The target triple for which this documentation was generated pub triple: String, @@ -99,6 +180,8 @@ pub struct Target { /// [1]: https://doc.rust-lang.org/stable/reference/attributes/codegen.html#the-target_feature-attribute /// [2]: https://doc.rust-lang.org/reference/conditional-compilation.html#target_feature #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct TargetFeature { /// The name of this target feature. pub name: String, @@ -123,6 +206,8 @@ pub struct TargetFeature { /// Metadata of a crate, either the same crate on which `rustdoc` was invoked, or its dependency. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct ExternalCrate { /// The name of the crate. /// @@ -140,6 +225,7 @@ pub struct ExternalCrate { /// /// This will typically be a `.rlib` or `.rmeta`. It can be used to determine which crate /// this was in terms of whatever build-system invoked rustc. + #[cfg_attr(feature = "rkyv_0_8", rkyv(with = rkyv::with::AsString))] pub path: PathBuf, } @@ -150,6 +236,8 @@ pub struct ExternalCrate { /// question, or can be used by a tool that takes the json output of multiple crates to find /// the actual item definition with all the relevant info. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct ItemSummary { /// Can be used to look up the name and html_root_url of the crate this item came from in the /// `external_crates` map. @@ -171,6 +259,8 @@ pub struct ItemSummary { /// The `Item` data type holds fields that can apply to any of these, /// and leaves kind-specific details (like function args or enum variants) to the `inner` field. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Item { /// The unique identifier of this item. Can be used to find this item in various mappings. pub id: Id, @@ -209,6 +299,8 @@ pub struct Item { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] /// An attribute, e.g. `#[repr(C)]` /// @@ -256,6 +348,8 @@ pub enum Attribute { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] /// The contents of a `#[repr(...)]` attribute. /// /// Used in [`Attribute::Repr`]. @@ -275,6 +369,8 @@ pub struct AttributeRepr { } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] /// The kind of `#[repr]`. /// @@ -294,8 +390,11 @@ pub enum ReprKind { /// A range of source code. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Span { /// The path to the source file for this span relative to the path `rustdoc` was invoked with. + #[cfg_attr(feature = "rkyv_0_8", rkyv(with = rkyv::with::AsString))] pub filename: PathBuf, /// One indexed Line and Column of the first character of the `Span`. pub begin: (usize, usize), @@ -305,6 +404,8 @@ pub struct Span { /// Information about the deprecation of an [`Item`]. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Deprecation { /// Usually a version number when this [`Item`] first became deprecated. pub since: Option, @@ -314,6 +415,8 @@ pub struct Deprecation { /// Visibility of an [`Item`]. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum Visibility { /// Explicitly public visibility set with `pub`. @@ -337,6 +440,8 @@ pub enum Visibility { /// Dynamic trait object type (`dyn Trait`). #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct DynTrait { /// All the traits implemented. One of them is the vtable, and the rest must be auto traits. pub traits: Vec, @@ -352,6 +457,8 @@ pub struct DynTrait { /// A trait and potential HRTBs #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct PolyTrait { /// The path to the trait. #[serde(rename = "trait")] @@ -371,6 +478,18 @@ pub struct PolyTrait { /// ^^^^^ /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(serialize_bounds( + __S: rkyv::ser::Writer + rkyv::ser::Allocator, + __S::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(deserialize_bounds( + __D::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(bytecheck(bounds( + __C: rkyv::validation::ArchiveContext, +))))] #[serde(rename_all = "snake_case")] pub enum GenericArgs { /// `<'a, 32, B: Copy, C = u32>` @@ -387,8 +506,10 @@ pub enum GenericArgs { /// `Fn(A, B) -> C` Parenthesized { /// The input types, enclosed in parentheses. + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] inputs: Vec, /// The output type provided after the `->`, if present. + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] output: Option, }, /// `T::method(..)` @@ -399,6 +520,8 @@ pub enum GenericArgs { /// /// Part of [`GenericArgs`]. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum GenericArg { /// A lifetime argument. @@ -429,6 +552,8 @@ pub enum GenericArg { /// A constant. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Constant { /// The stringified expression of this constant. Note that its mapping to the original /// source code is unstable and it's not guaranteed that it'll match the source code. @@ -448,10 +573,24 @@ pub struct Constant { /// ^^^^^^^^^^ ^^^^^^^^^^^^^^^ /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(serialize_bounds( + __S: rkyv::ser::Writer + rkyv::ser::Allocator, + __S::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(deserialize_bounds( + __D::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(bytecheck(bounds( + __C: rkyv::validation::ArchiveContext, + <__C as rkyv::rancor::Fallible>::Error: rkyv::rancor::Source, +))))] pub struct AssocItemConstraint { /// The name of the associated type/constant. pub name: String, /// Arguments provided to the associated type/constant. + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] pub args: Option>, /// The kind of bound applied to the associated type/constant. pub binding: AssocItemConstraintKind, @@ -459,6 +598,8 @@ pub struct AssocItemConstraint { /// The way in which an associate type/constant is bound. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum AssocItemConstraintKind { /// The required value/type is specified exactly. e.g. @@ -487,6 +628,8 @@ pub enum AssocItemConstraintKind { /// should treat them as opaque keys to lookup items, and avoid attempting /// to parse them, or otherwise depend on any implementation details. #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)))] // FIXME(aDotInTheVoid): Consider making this non-public in rustdoc-types. pub struct Id(pub u32); @@ -494,6 +637,9 @@ pub struct Id(pub u32); /// /// Part of [`ItemSummary`]. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(compare(PartialEq)))] #[serde(rename_all = "snake_case")] pub enum ItemKind { /// A module declaration, e.g. `mod foo;` or `mod foo {}` @@ -569,6 +715,8 @@ pub enum ItemKind { /// /// Part of [`Item`]. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum ItemEnum { /// A module declaration, e.g. `mod foo;` or `mod foo {}` @@ -723,6 +871,8 @@ impl ItemEnum { /// A module declaration, e.g. `mod foo;` or `mod foo {}`. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Module { /// Whether this is the root item of a crate. /// @@ -738,6 +888,8 @@ pub struct Module { /// A `union`. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Union { /// The generic parameters and where clauses on this union. pub generics: Generics, @@ -755,6 +907,8 @@ pub struct Union { /// A `struct`. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Struct { /// The kind of the struct (e.g. unit, tuple-like or struct-like) and the data specific to it, /// i.e. fields. @@ -768,6 +922,8 @@ pub struct Struct { /// The kind of a [`Struct`] and the data specific to it, i.e. fields. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum StructKind { /// A struct with no fields and no parentheses. @@ -805,6 +961,8 @@ pub enum StructKind { /// An `enum`. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Enum { /// Information about the type parameters and `where` clauses of the enum. pub generics: Generics, @@ -820,6 +978,8 @@ pub struct Enum { /// A variant of an enum. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Variant { /// Whether the variant is plain, a tuple-like, or struct-like. Contains the fields. pub kind: VariantKind, @@ -829,6 +989,8 @@ pub struct Variant { /// The kind of an [`Enum`] [`Variant`] and the data specific to it, i.e. fields. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum VariantKind { /// A variant with no parentheses @@ -872,6 +1034,8 @@ pub enum VariantKind { /// The value that distinguishes a variant in an [`Enum`] from other variants. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Discriminant { /// The expression that produced the discriminant. /// @@ -890,6 +1054,8 @@ pub struct Discriminant { /// A set of fundamental properties of a function. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct FunctionHeader { /// Is this function marked as `const`? pub is_const: bool, @@ -910,6 +1076,8 @@ pub struct FunctionHeader { /// See the [Rustonomicon section](https://doc.rust-lang.org/nightly/nomicon/ffi.html#ffi-and-unwinding) /// on unwinding for more info. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub enum Abi { // We only have a concrete listing here for stable ABI's because there are so many // See rustc_ast_passes::feature_gate::PostExpansionVisitor::check_abi for the list @@ -937,6 +1105,8 @@ pub enum Abi { /// A function declaration (including methods and other associated functions). #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Function { /// Information about the function signature, or declaration. pub sig: FunctionSignature, @@ -950,6 +1120,8 @@ pub struct Function { /// Generic parameters accepted by an item and `where` clauses imposed on it and the parameters. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Generics { /// A list of generic parameter definitions (e.g. ``). pub params: Vec, @@ -959,6 +1131,8 @@ pub struct Generics { /// One generic parameter accepted by an item. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct GenericParamDef { /// Name of the parameter. /// ```rust @@ -973,6 +1147,18 @@ pub struct GenericParamDef { /// The kind of a [`GenericParamDef`]. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(serialize_bounds( + __S: rkyv::ser::Writer + rkyv::ser::Allocator, + __S::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(deserialize_bounds( + __D::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(bytecheck(bounds( + __C: rkyv::validation::ArchiveContext, +))))] #[serde(rename_all = "snake_case")] pub enum GenericParamDefKind { /// Denotes a lifetime parameter. @@ -995,6 +1181,7 @@ pub enum GenericParamDefKind { /// fn default2() -> [T; 2] where T: Clone { todo!() } /// // ^^^^^^^ /// ``` + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] bounds: Vec, /// The default type for this parameter, if provided, e.g. /// @@ -1002,6 +1189,7 @@ pub enum GenericParamDefKind { /// trait PartialEq {} /// // ^^^^ /// ``` + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] default: Option, /// This is normally `false`, which means that this generic parameter is /// declared in the Rust source text. @@ -1033,6 +1221,7 @@ pub enum GenericParamDefKind { Const { /// The type of the constant as declared. #[serde(rename = "type")] + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] type_: Type, /// The stringified expression for the default value, if provided. It's not guaranteed that /// it'll match the actual source code for the default value. @@ -1046,6 +1235,8 @@ pub enum GenericParamDefKind { /// // ^^^^^^^^^^ /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum WherePredicate { /// A type is expected to comply with a set of bounds @@ -1092,6 +1283,8 @@ pub enum WherePredicate { /// Either a trait bound or a lifetime bound. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum GenericBound { /// A trait bound. @@ -1122,6 +1315,8 @@ pub enum GenericBound { /// A set of modifiers applied to a trait. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum TraitBoundModifier { /// Marks the absence of a modifier. @@ -1137,6 +1332,8 @@ pub enum TraitBoundModifier { /// One precise capturing argument. See [the rust reference](https://doc.rust-lang.org/reference/types/impl-trait.html#precise-capturing). #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum PreciseCapturingArg { /// A lifetime. @@ -1154,6 +1351,8 @@ pub enum PreciseCapturingArg { /// Either a type or a constant, usually stored as the right-hand side of an equation in places like /// [`AssocItemConstraint`] #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum Term { /// A type. @@ -1178,6 +1377,18 @@ pub enum Term { /// A type. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(serialize_bounds( + __S: rkyv::ser::Writer + rkyv::ser::Allocator, + __S::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(deserialize_bounds( + __D::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(bytecheck(bounds( + __C: rkyv::validation::ArchiveContext, +))))] #[serde(rename_all = "snake_case")] pub enum Type { /// Structs, enums, unions and type aliases, e.g. `std::option::Option` @@ -1189,15 +1400,16 @@ pub enum Type { /// Built-in numeric types (e.g. `u32`, `f32`), `bool`, `char`. Primitive(String), /// A function pointer type, e.g. `fn(u32) -> u32`, `extern "C" fn() -> *const u8` - FunctionPointer(Box), + FunctionPointer(#[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] Box), /// A tuple type, e.g. `(String, u32, Box)` - Tuple(Vec), + Tuple(#[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] Vec), /// An unsized slice type, e.g. `[u32]`. - Slice(Box), + Slice(#[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] Box), /// An array type, e.g. `[u32; 15]` Array { /// The type of the contained element. #[serde(rename = "type")] + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] type_: Box, /// The stringified expression that is the length of the array. /// @@ -1210,6 +1422,7 @@ pub enum Type { Pat { /// The base type, e.g. the `u32` in `u32 is 1..` #[serde(rename = "type")] + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] type_: Box, #[doc(hidden)] __pat_unstable_do_not_use: String, @@ -1224,6 +1437,7 @@ pub enum Type { is_mutable: bool, /// The type of the pointee. #[serde(rename = "type")] + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] type_: Box, }, /// `&'a mut String`, `&str`, etc. @@ -1234,6 +1448,7 @@ pub enum Type { is_mutable: bool, /// The type of the pointee, e.g. the `i32` in `&'a mut i32` #[serde(rename = "type")] + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] type_: Box, }, /// Associated types like `::Name` and `T::Item` where @@ -1252,6 +1467,7 @@ pub enum Type { /// as BetterIterator>::Item<'static> /// // ^^^^^^^^^ /// ``` + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] args: Option>, /// The type with which this type is associated. /// @@ -1259,6 +1475,7 @@ pub enum Type { /// as Iterator>::Item /// // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ /// ``` + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] self_type: Box, /// `None` iff this is an *inherent* associated type. #[serde(rename = "trait")] @@ -1268,6 +1485,19 @@ pub enum Type { /// A type that has a simple path to it. This is the kind of type of structs, unions, enums, etc. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(serialize_bounds( + __S: rkyv::ser::Writer + rkyv::ser::Allocator, + __S::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(deserialize_bounds( + __D::Error: rkyv::rancor::Source, +)))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(bytecheck(bounds( + __C: rkyv::validation::ArchiveContext, + <__C as rkyv::rancor::Fallible>::Error: rkyv::rancor::Source, +))))] pub struct Path { /// The path of the type. /// @@ -1291,11 +1521,14 @@ pub struct Path { /// std::borrow::Cow<'static, str> /// // ^^^^^^^^^^^^^^ /// ``` + #[cfg_attr(feature = "rkyv_0_8", rkyv(omit_bounds))] pub args: Option>, } /// A type that is a function pointer. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct FunctionPointer { /// The signature of the function. pub sig: FunctionSignature, @@ -1312,6 +1545,8 @@ pub struct FunctionPointer { /// The signature of a function. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct FunctionSignature { /// List of argument names and their type. /// @@ -1330,6 +1565,8 @@ pub struct FunctionSignature { /// A `trait` declaration. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Trait { /// Whether the trait is marked `auto` and is thus implemented automatically /// for all applicable types. @@ -1354,6 +1591,8 @@ pub struct Trait { /// /// See [the tracking issue](https://github.com/rust-lang/rust/issues/41517) #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct TraitAlias { /// Information about the type parameters and `where` clauses of the alias. pub generics: Generics, @@ -1363,6 +1602,8 @@ pub struct TraitAlias { /// An `impl` block. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Impl { /// Whether this impl is for an unsafe trait. pub is_unsafe: bool, @@ -1401,6 +1642,8 @@ pub struct Impl { /// A `use` statement. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub struct Use { /// The full path being imported. @@ -1419,6 +1662,8 @@ pub struct Use { /// A procedural macro. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct ProcMacro { /// How this macro is supposed to be called: `foo!()`, `#[foo]` or `#[derive(foo)]` pub kind: MacroKind, @@ -1442,6 +1687,8 @@ pub struct ProcMacro { /// The way a [`ProcMacro`] is declared to be used. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] #[serde(rename_all = "snake_case")] pub enum MacroKind { /// A bang macro `foo!()`. @@ -1454,6 +1701,8 @@ pub enum MacroKind { /// A type alias declaration, e.g. `type Pig = std::borrow::Cow<'static, str>;` #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct TypeAlias { /// The type referred to by this alias. #[serde(rename = "type")] @@ -1464,6 +1713,8 @@ pub struct TypeAlias { /// A `static` declaration. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Static { /// The type of the static. #[serde(rename = "type")] @@ -1494,6 +1745,8 @@ pub struct Static { /// A primitive type declaration. Declarations of this kind can only come from the core library. #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[cfg_attr(feature = "rkyv_0_8", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize))] +#[cfg_attr(feature = "rkyv_0_8", rkyv(derive(Debug)))] pub struct Primitive { /// The name of the type. pub name: String, diff --git a/src/rustdoc-json-types/tests.rs b/src/rustdoc-json-types/tests.rs index b9363fcf1b714..e878350e43b9b 100644 --- a/src/rustdoc-json-types/tests.rs +++ b/src/rustdoc-json-types/tests.rs @@ -38,3 +38,118 @@ fn test_union_info_roundtrip() { let decoded: ItemEnum = bincode::deserialize(&encoded).unwrap(); assert_eq!(u, decoded); } + +#[cfg(feature = "rkyv_0_8")] +mod rkyv { + use std::fmt::Debug; + + use rkyv::Archive; + use rkyv::api::high::{HighDeserializer, HighSerializer}; + use rkyv::bytecheck::CheckBytes; + use rkyv::rancor::Strategy; + use rkyv::ser::allocator::ArenaHandle; + use rkyv::util::AlignedVec; + use rkyv::validation::Validator; + use rkyv::validation::archive::ArchiveValidator; + use rkyv::validation::shared::SharedValidator; + + use crate::*; + + #[test] + /// A test to exercise the (de)serialization roundtrip for a representative selection of types, + /// covering most of the rkyv-specific attributes we had to had. + fn test_rkyv_roundtrip() { + // Standard derives: a plain struct and union, mirroring the existing serde/bincode tests. + let s = ItemEnum::Struct(Struct { + generics: Generics { params: vec![], where_predicates: vec![] }, + kind: StructKind::Plain { fields: vec![Id(1), Id(2)], has_stripped_fields: false }, + impls: vec![Id(3)], + }); + rkyv_roundtrip(&s); + + let u = ItemEnum::Union(Union { + generics: Generics { params: vec![], where_predicates: vec![] }, + has_stripped_fields: false, + fields: vec![Id(1)], + impls: vec![], + }); + rkyv_roundtrip(&u); + + // Extra trait derives, via rkyv(derive(PartialEq, Eq, PartialOrd, Ord, Hash)), on the archived type. + rkyv_roundtrip(&Id(99)); + + // Recursive cycle-breaking: `BorrowedRef` has omit_bounds on its `Box` field. + let ty = Type::BorrowedRef { + lifetime: Some("'a".to_string()), + is_mutable: false, + type_: Box::new(Type::Primitive("str".to_string())), + }; + rkyv_roundtrip(&ty); + + // `Slice` and `Tuple` are tuple-variant fields with omit_bounds on the unnamed field, + // which required special syntax (attribute inside the parentheses) to compile. + let ty = Type::Slice(Box::new(Type::Tuple(vec![ + Type::Primitive("u32".to_string()), + Type::Generic("T".to_string()), + ]))); + rkyv_roundtrip(&ty); + + // `Path` has serialize_bounds/deserialize_bounds and omit_bounds on its `args` field. + // `GenericArgs::AngleBracketed` exercises the full recursive chain: `Path` -> `GenericArgs` -> `GenericArg` -> `Type`. + let path = Path { + path: "std::option::Option".to_string(), + id: Id(42), + args: Some(Box::new(GenericArgs::AngleBracketed { + args: vec![GenericArg::Type(Type::Primitive("u32".to_string()))], + constraints: vec![], + })), + }; + rkyv_roundtrip(&path); + + // `FunctionPointer` is a `Box` behind `omit_bounds` in `Type`. + // It transitively contains `Type` via `FunctionSignature`, exercising the cycle from the other direction. + let fp = Type::FunctionPointer(Box::new(FunctionPointer { + sig: FunctionSignature { + inputs: vec![("x".to_string(), Type::Primitive("i32".to_string()))], + output: Some(Type::Primitive("bool".to_string())), + is_c_variadic: false, + }, + generic_params: vec![], + header: FunctionHeader { + is_const: false, + is_unsafe: false, + is_async: false, + abi: Abi::Rust, + }, + })); + rkyv_roundtrip(&fp); + } + + /// A helper function for roundtrip testing of rkyv-powered deserialization. + fn rkyv_roundtrip(value: &T) + where + T: PartialEq + + Debug + + Archive + + for<'a> rkyv::Serialize< + HighSerializer, rkyv::rancor::Error>, + >, + T::Archived: rkyv::Deserialize> + + Debug + + for<'a> CheckBytes< + Strategy, SharedValidator>, rkyv::rancor::Error>, + >, + { + let bytes = + rkyv::api::high::to_bytes_in::<_, rkyv::rancor::Error>(value, AlignedVec::new()) + .unwrap(); + let archived = rkyv::api::high::access::(&bytes) + .expect("Failed to access archived data"); + let deserialized: T = rkyv::api::deserialize_using::<_, _, rkyv::rancor::Error>( + archived, + &mut rkyv::de::Pool::new(), + ) + .unwrap(); + assert_eq!(value, &deserialized); + } +} diff --git a/tests/run-make/instrument-mcount-link-pg/main.rs b/tests/run-make/instrument-mcount-link-pg/main.rs new file mode 100644 index 0000000000000..47ad8c634112b --- /dev/null +++ b/tests/run-make/instrument-mcount-link-pg/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello World!"); +} diff --git a/tests/run-make/instrument-mcount-link-pg/rmake.rs b/tests/run-make/instrument-mcount-link-pg/rmake.rs new file mode 100644 index 0000000000000..184bd9429bfd8 --- /dev/null +++ b/tests/run-make/instrument-mcount-link-pg/rmake.rs @@ -0,0 +1,19 @@ +// When building a binary instrumented with mcount, verify the +// binary is linked with the correct crt to enable profiling. +// +//@ only-gnu +//@ ignore-cross-compile + +use run_make_support::{path, run, rustc}; + +fn main() { + // Compile instrumentation enabled binary, and verify -pg is passed + let link_args = + rustc().input("main.rs").arg("-Zinstrument-mcount").print("link-args").run().stdout_utf8(); + assert!(link_args.contains("\"-pg\"")); + + // Run it, and verify gmon.out is created + assert!(!path("gmon.out").exists()); + run("main"); + assert!(path("gmon.out").exists()); +} diff --git a/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.rs b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.rs new file mode 100644 index 0000000000000..960e19c21a2c5 --- /dev/null +++ b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Znext-solver=globally +#![feature(inherent_associated_types)] +#![expect(incomplete_features)] + +// Regression test for https://github.com/rust-lang/rust/issues/153539: + +struct S<'a>(&'a ()); + +impl S<'_> { + //~^ ERROR the type parameter `X` is not constrained by the impl trait, self type, or predicates + type P = (); +} + +fn ret_ref_local<'e>() -> &'e i32 { + let f: for<'a> fn(&'a i32) -> S<'a>::P = |x| _ = x; + + f(&1) + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr new file mode 100644 index 0000000000000..74d88889223f3 --- /dev/null +++ b/tests/ui/associated-inherent-types/inherent-assoc-ty-mismatch-issue-153539.stderr @@ -0,0 +1,22 @@ +error[E0207]: the type parameter `X` is not constrained by the impl trait, self type, or predicates + --> $DIR/inherent-assoc-ty-mismatch-issue-153539.rs:9:6 + | +LL | impl S<'_> { + | ^ unconstrained type parameter + +error[E0308]: mismatched types + --> $DIR/inherent-assoc-ty-mismatch-issue-153539.rs:17:5 + | +LL | fn ret_ref_local<'e>() -> &'e i32 { + | ------- expected `&'e i32` because of return type +... +LL | f(&1) + | ^^^^^ expected `&i32`, found associated type + | + = help: consider constraining the associated type `S<'_>::P` to `&'e i32` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0207, E0308. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs index f859decd09ecb..f72b43bb2543c 100644 --- a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.rs @@ -1,4 +1,5 @@ //@ edition: 2021 +//@ compile-flags: --crate-type=lib // Regression test for issue #148439 // Ensure that when using misspelled Cargo environment variables in env!(), @@ -44,7 +45,14 @@ fn test_cargo_unknown_var() { // Cargo-prefixed but not similar to any known variable let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); //~^ ERROR environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time + //~| HELP `CARGO_SOMETHING_TOTALLY_UNKNOWN` may not be available for the current Cargo target //~| HELP Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead } -fn main() {} +fn test_cargo_conditional_var() { + // Only set for binairies + let _ = env!("CARGO_BIN_NAME"); + //~^ ERROR environment variable `CARGO_BIN_NAME` not defined at compile time + //~| HELP `CARGO_BIN_NAME` may not be available for the current Cargo target + //~| HELP Cargo sets build script variables at run time. Use `std::env::var("CARGO_BIN_NAME")` instead +} diff --git a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr index e16c4d9a1f4c2..50a4cf1a616be 100644 --- a/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr +++ b/tests/ui/env-macro/env-cargo-var-typo-issue-148439.stderr @@ -1,5 +1,5 @@ error: environment variable `CARGO_PACKAGE_VERSION` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:7:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:8:13 | LL | let _ = env!("CARGO_PACKAGE_VERSION"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | let _ = env!("CARGO_PACKAGE_VERSION"); = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` error: environment variable `CARGO_PACKAGE_NAME` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:13:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:14:13 | LL | let _ = env!("CARGO_PACKAGE_NAME"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -15,7 +15,7 @@ LL | let _ = env!("CARGO_PACKAGE_NAME"); = help: there is a similar Cargo environment variable: `CARGO_PKG_NAME` error: environment variable `CARGO_PACKAGE_AUTHORS` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:19:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:20:13 | LL | let _ = env!("CARGO_PACKAGE_AUTHORS"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | let _ = env!("CARGO_PACKAGE_AUTHORS"); = help: there is a similar Cargo environment variable: `CARGO_PKG_AUTHORS` error: environment variable `CARGO_MANIFEST_DIRECTORY` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:25:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:26:13 | LL | let _ = env!("CARGO_MANIFEST_DIRECTORY"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | let _ = env!("CARGO_MANIFEST_DIRECTORY"); = help: there is a similar Cargo environment variable: `CARGO_MANIFEST_DIR` error: environment variable `CARGO_PKG_VERSIO` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:31:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:32:13 | LL | let _ = env!("CARGO_PKG_VERSIO"); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -39,7 +39,7 @@ LL | let _ = env!("CARGO_PKG_VERSIO"); = help: there is a similar Cargo environment variable: `CARGO_PKG_VERSION` error: environment variable `MY_CUSTOM_VAR` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:38:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:39:13 | LL | let _ = env!("MY_CUSTOM_VAR"); | ^^^^^^^^^^^^^^^^^^^^^ @@ -47,12 +47,22 @@ LL | let _ = env!("MY_CUSTOM_VAR"); = help: use `std::env::var("MY_CUSTOM_VAR")` to read the variable at run time error: environment variable `CARGO_SOMETHING_TOTALLY_UNKNOWN` not defined at compile time - --> $DIR/env-cargo-var-typo-issue-148439.rs:45:13 + --> $DIR/env-cargo-var-typo-issue-148439.rs:46:13 | LL | let _ = env!("CARGO_SOMETHING_TOTALLY_UNKNOWN"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: `CARGO_SOMETHING_TOTALLY_UNKNOWN` may not be available for the current Cargo target = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO_SOMETHING_TOTALLY_UNKNOWN")` instead -error: aborting due to 7 previous errors +error: environment variable `CARGO_BIN_NAME` not defined at compile time + --> $DIR/env-cargo-var-typo-issue-148439.rs:54:13 + | +LL | let _ = env!("CARGO_BIN_NAME"); + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: `CARGO_BIN_NAME` may not be available for the current Cargo target + = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO_BIN_NAME")` instead + +error: aborting due to 8 previous errors diff --git a/tests/ui/env-macro/env-not-defined-default.stderr b/tests/ui/env-macro/env-not-defined-default.stderr index 77ba00e45c1c6..8340bb0e8fba6 100644 --- a/tests/ui/env-macro/env-not-defined-default.stderr +++ b/tests/ui/env-macro/env-not-defined-default.stderr @@ -4,6 +4,7 @@ error: environment variable `CARGO__HOPEFULLY_NOT_DEFINED__` not defined at comp LL | env!("CARGO__HOPEFULLY_NOT_DEFINED__"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: `CARGO__HOPEFULLY_NOT_DEFINED__` may not be available for the current Cargo target = help: Cargo sets build script variables at run time. Use `std::env::var("CARGO__HOPEFULLY_NOT_DEFINED__")` instead error: aborting due to 1 previous error diff --git a/tests/ui/pin-ergonomics/pin-coercion-check.normal.stderr b/tests/ui/pin-ergonomics/pin-coercion-check.normal.stderr new file mode 100644 index 0000000000000..0806ad64448c4 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-coercion-check.normal.stderr @@ -0,0 +1,227 @@ +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:9:36 + | +LL | |x: Pin<&mut T>| -> &mut T { x.get_mut() }; + | ^^^^^^^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required by a bound in `Pin::<&'a mut T>::get_mut` + --> $SRC_DIR/core/src/pin.rs:LL:COL +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn get() { + | ++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:18:34 + | +LL | |x: Pin<&mut T>| -> &mut T { x }; + | ------ ^ expected `&mut T`, found `Pin<&mut T>` + | | + | expected `&mut T` because of return type + | + = note: expected mutable reference `&mut T` + found struct `Pin<&mut T>` +help: consider mutably borrowing here + | +LL | |x: Pin<&mut T>| -> &mut T { &mut x }; + | ++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:21:30 + | +LL | |x: Pin<&mut T>| -> &T { x }; + | -- ^ expected `&T`, found `Pin<&mut T>` + | | + | expected `&T` because of return type + | + = note: expected reference `&T` + found struct `Pin<&mut T>` +help: consider borrowing here + | +LL | |x: Pin<&mut T>| -> &T { &x }; + | + + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:24:26 + | +LL | |x: Pin<&T>| -> &T { x }; + | -- ^ expected `&T`, found `Pin<&T>` + | | + | expected `&T` because of return type + | + = note: expected reference `&T` + found struct `Pin<&T>` +help: consider borrowing here + | +LL | |x: Pin<&T>| -> &T { &x }; + | + + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:27:30 + | +LL | |x: Pin<&T>| -> &mut T { x }; + | ------ ^ expected `&mut T`, found `Pin<&T>` + | | + | expected `&mut T` because of return type + | + = note: expected mutable reference `&mut T` + found struct `Pin<&T>` +help: consider mutably borrowing here + | +LL | |x: Pin<&T>| -> &mut T { &mut x }; + | ++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:31:34 + | +LL | |x: Pin<&mut U>| -> &mut U { x }; + | ------ ^ expected `&mut U`, found `Pin<&mut U>` + | | + | expected `&mut U` because of return type + | + = note: expected mutable reference `&mut U` + found struct `Pin<&mut U>` +help: consider mutably borrowing here + | +LL | |x: Pin<&mut U>| -> &mut U { &mut x }; + | ++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:33:30 + | +LL | |x: Pin<&mut U>| -> &U { x }; + | -- ^ expected `&U`, found `Pin<&mut U>` + | | + | expected `&U` because of return type + | + = note: expected reference `&U` + found struct `Pin<&mut U>` +help: consider borrowing here + | +LL | |x: Pin<&mut U>| -> &U { &x }; + | + + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:35:26 + | +LL | |x: Pin<&U>| -> &U { x }; + | -- ^ expected `&U`, found `Pin<&U>` + | | + | expected `&U` because of return type + | + = note: expected reference `&U` + found struct `Pin<&U>` +help: consider borrowing here + | +LL | |x: Pin<&U>| -> &U { &x }; + | + + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:37:30 + | +LL | |x: Pin<&U>| -> &mut U { x }; + | ------ ^ expected `&mut U`, found `Pin<&U>` + | | + | expected `&mut U` because of return type + | + = note: expected mutable reference `&mut U` + found struct `Pin<&U>` +help: consider mutably borrowing here + | +LL | |x: Pin<&U>| -> &mut U { &mut x }; + | ++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:43:34 + | +LL | |x: &mut T| -> Pin<&mut T> { x }; + | ----------- ^ expected `Pin<&mut T>`, found `&mut T` + | | + | expected `Pin<&mut T>` because of return type + | + = note: expected struct `Pin<&mut T>` + found mutable reference `&mut T` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:46:30 + | +LL | |x: &mut T| -> Pin<&T> { x }; + | ------- ^ expected `Pin<&T>`, found `&mut T` + | | + | expected `Pin<&T>` because of return type + | + = note: expected struct `Pin<&T>` + found mutable reference `&mut T` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:49:26 + | +LL | |x: &T| -> Pin<&T> { x }; + | ------- ^ expected `Pin<&T>`, found `&T` + | | + | expected `Pin<&T>` because of return type + | + = note: expected struct `Pin<&T>` + found reference `&T` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:52:30 + | +LL | |x: &T| -> Pin<&mut T> { x }; + | ----------- ^ expected `Pin<&mut T>`, found `&T` + | | + | expected `Pin<&mut T>` because of return type + | + = note: expected struct `Pin<&mut T>` + found reference `&T` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:56:34 + | +LL | |x: &mut U| -> Pin<&mut U> { x }; + | ----------- ^ expected `Pin<&mut U>`, found `&mut U` + | | + | expected `Pin<&mut U>` because of return type + | + = note: expected struct `Pin<&mut U>` + found mutable reference `&mut U` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:58:30 + | +LL | |x: &mut U| -> Pin<&U> { x }; + | ------- ^ expected `Pin<&U>`, found `&mut U` + | | + | expected `Pin<&U>` because of return type + | + = note: expected struct `Pin<&U>` + found mutable reference `&mut U` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:60:26 + | +LL | |x: &U| -> Pin<&U> { x }; + | ------- ^ expected `Pin<&U>`, found `&U` + | | + | expected `Pin<&U>` because of return type + | + = note: expected struct `Pin<&U>` + found reference `&U` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:62:30 + | +LL | |x: &U| -> Pin<&mut U> { x }; + | ----------- ^ expected `Pin<&mut U>`, found `&U` + | | + | expected `Pin<&mut U>` because of return type + | + = note: expected struct `Pin<&mut U>` + found reference `&U` + +error: aborting due to 17 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/pin-ergonomics/pin-coercion-check.pin_ergonomics.stderr b/tests/ui/pin-ergonomics/pin-coercion-check.pin_ergonomics.stderr new file mode 100644 index 0000000000000..3dc59cecb3c1e --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-coercion-check.pin_ergonomics.stderr @@ -0,0 +1,155 @@ +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:9:36 + | +LL | |x: Pin<&mut T>| -> &mut T { x.get_mut() }; + | ^^^^^^^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope +note: required by a bound in `Pin::<&'a mut T>::get_mut` + --> $SRC_DIR/core/src/pin.rs:LL:COL +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn get() { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:18:34 + | +LL | |x: Pin<&mut T>| -> &mut T { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `Pin<&mut T>` to `&mut T` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn pin_to_ref() { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:21:30 + | +LL | |x: Pin<&mut T>| -> &T { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `Pin<&mut T>` to `&T` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn pin_to_ref() { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:24:26 + | +LL | |x: Pin<&T>| -> &T { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `Pin<&T>` to `&T` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn pin_to_ref() { + | ++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:27:30 + | +LL | |x: Pin<&T>| -> &mut T { x }; + | ------ ^ types differ in mutability + | | + | expected `&mut T` because of return type + | + = note: expected mutable reference `&mut T` + found struct `Pin<&T>` +help: consider mutably borrowing here + | +LL | |x: Pin<&T>| -> &mut T { &mut x }; + | ++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:37:30 + | +LL | |x: Pin<&U>| -> &mut U { x }; + | ------ ^ types differ in mutability + | | + | expected `&mut U` because of return type + | + = note: expected mutable reference `&mut U` + found struct `Pin<&U>` +help: consider mutably borrowing here + | +LL | |x: Pin<&U>| -> &mut U { &mut x }; + | ++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:43:34 + | +LL | |x: &mut T| -> Pin<&mut T> { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `&mut T` to `Pin<&mut T>` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn ref_to_pin() { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:46:30 + | +LL | |x: &mut T| -> Pin<&T> { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `&mut T` to `Pin<&T>` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn ref_to_pin() { + | ++++++++++++++++++++ + +error[E0277]: `T` cannot be unpinned + --> $DIR/pin-coercion-check.rs:49:26 + | +LL | |x: &T| -> Pin<&T> { x }; + | ^ the trait `Unpin` is not implemented for `T` + | + = note: consider using the `pin!` macro + consider using `Box::pin` if you need to access the pinned value outside of the current scope + = note: required for the cast from `&T` to `Pin<&T>` +help: consider restricting type parameter `T` with trait `Unpin` + | +LL | fn ref_to_pin() { + | ++++++++++++++++++++ + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:52:30 + | +LL | |x: &T| -> Pin<&mut T> { x }; + | ----------- ^ types differ in mutability + | | + | expected `Pin<&mut T>` because of return type + | + = note: expected struct `Pin<&mut T>` + found reference `&T` + +error[E0308]: mismatched types + --> $DIR/pin-coercion-check.rs:62:30 + | +LL | |x: &U| -> Pin<&mut U> { x }; + | ----------- ^ types differ in mutability + | | + | expected `Pin<&mut U>` because of return type + | + = note: expected struct `Pin<&mut U>` + found reference `&U` + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/pin-ergonomics/pin-coercion-check.rs b/tests/ui/pin-ergonomics/pin-coercion-check.rs new file mode 100644 index 0000000000000..9b51851219ccd --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-coercion-check.rs @@ -0,0 +1,66 @@ +//@ revisions: pin_ergonomics normal +//@ edition:2024 +#![cfg_attr(pin_ergonomics, feature(pin_ergonomics))] +#![allow(incomplete_features)] + +use std::pin::Pin; + +fn get() { + |x: Pin<&mut T>| -> &mut T { x.get_mut() }; //~ ERROR `T` cannot be unpinned + |x: Pin<&T>| -> &T { x.get_ref() }; + + |x: Pin<&mut U>| -> &mut U { x.get_mut() }; + |x: Pin<&U>| -> &U { x.get_ref() }; +} + +fn pin_to_ref() { + // T: !Unpin + |x: Pin<&mut T>| -> &mut T { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: Pin<&mut T>| -> &T { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: Pin<&T>| -> &T { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: Pin<&T>| -> &mut T { x }; + //~^ ERROR mismatched types + + // U: Unpin + |x: Pin<&mut U>| -> &mut U { x }; + //[normal]~^ ERROR mismatched types + |x: Pin<&mut U>| -> &U { x }; + //[normal]~^ ERROR mismatched types + |x: Pin<&U>| -> &U { x }; + //[normal]~^ ERROR mismatched types + |x: Pin<&U>| -> &mut U { x }; + //~^ ERROR mismatched types +} + +fn ref_to_pin() { + // T: !Unpin + |x: &mut T| -> Pin<&mut T> { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: &mut T| -> Pin<&T> { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: &T| -> Pin<&T> { x }; + //[normal]~^ ERROR mismatched types + //[pin_ergonomics]~^^ ERROR `T` cannot be unpinned + |x: &T| -> Pin<&mut T> { x }; + //~^ ERROR mismatched types + + // U: Unpin + |x: &mut U| -> Pin<&mut U> { x }; + //[normal]~^ ERROR mismatched types + |x: &mut U| -> Pin<&U> { x }; + //[normal]~^ ERROR mismatched types + |x: &U| -> Pin<&U> { x }; + //[normal]~^ ERROR mismatched types + |x: &U| -> Pin<&mut U> { x }; + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/pin-ergonomics/pin-coercion.rs b/tests/ui/pin-ergonomics/pin-coercion.rs new file mode 100644 index 0000000000000..6ace4b97edb34 --- /dev/null +++ b/tests/ui/pin-ergonomics/pin-coercion.rs @@ -0,0 +1,56 @@ +//@ run-pass +//@ edition:2024 +#![feature(pin_ergonomics)] +#![allow(incomplete_features)] +#![deny(dead_code)] + +use std::cell::RefCell; + +fn coerce_mut_to_pin_mut(x: &mut T) -> &pin mut T { + x +} +fn coerce_ref_to_pin_ref(x: &T) -> &pin const T { + x +} +fn coerce_pin_mut_to_mut(x: &pin mut T) -> &mut T { + x +} +fn coerce_pin_ref_to_ref(x: &pin const T) -> &T { + x +} + +fn coerce_pin_mut_to_ref(x: &pin mut T) -> &T { + x +} +fn coerce_mut_to_pin_ref(x: &mut T) -> &pin const T { + x +} + +fn test(x: &mut RefCell) { + let mut x: &pin mut _ = coerce_mut_to_pin_mut(x); + x.get_mut().get_mut().push_str("&mut T -> &pin mut T\n"); + let x_ref: &_ = coerce_pin_mut_to_ref(x.as_mut()); + x_ref.borrow_mut().push_str("&pin mut T -> &T\n"); + let x: &mut _ = coerce_pin_mut_to_mut(x); + x.get_mut().push_str("&pin mut T -> &mut T\n"); + let x: &pin const _ = coerce_mut_to_pin_ref(x); + x.borrow_mut().push_str("&mut T -> &pin const T\n"); + let x: &_ = coerce_pin_ref_to_ref(x); + x.borrow_mut().push_str("&pin const T -> &T\n"); + let x: &pin const _ = coerce_ref_to_pin_ref(x); + x.borrow_mut().push_str("&T -> &pin const T\n"); +} + +fn main() { + let mut x = RefCell::new(String::new()); + test(&mut x); + assert_eq!( + x.borrow().as_str(), + "&mut T -> &pin mut T\n\ + &pin mut T -> &T\n\ + &pin mut T -> &mut T\n\ + &mut T -> &pin const T\n\ + &pin const T -> &T\n\ + &T -> &pin const T\n" + ); +} diff --git a/tests/ui/proc-macro/any-panic-payload.rs b/tests/ui/proc-macro/any-panic-payload.rs new file mode 100644 index 0000000000000..7a83a4e73a04e --- /dev/null +++ b/tests/ui/proc-macro/any-panic-payload.rs @@ -0,0 +1,17 @@ +//! Make sure that proc-macros which panic with a payload other than +//! `String` or `&'static str` do not ICE. +//@ proc-macro: any-panic-payload.rs + +extern crate any_panic_payload; + +use any_panic_payload::*; + +cause_panic!(); //~ ERROR proc macro panicked + +#[cause_panic_attr] //~ ERROR custom attribute panicked +struct A; + +#[derive(CausePanic)] //~ ERROR proc-macro derive panicked +struct B; + +fn main() {} diff --git a/tests/ui/proc-macro/any-panic-payload.stderr b/tests/ui/proc-macro/any-panic-payload.stderr new file mode 100644 index 0000000000000..bb369b80e9204 --- /dev/null +++ b/tests/ui/proc-macro/any-panic-payload.stderr @@ -0,0 +1,20 @@ +error: proc macro panicked + --> $DIR/any-panic-payload.rs:9:1 + | +LL | cause_panic!(); + | ^^^^^^^^^^^^^^ + +error: custom attribute panicked + --> $DIR/any-panic-payload.rs:11:1 + | +LL | #[cause_panic_attr] + | ^^^^^^^^^^^^^^^^^^^ + +error: proc-macro derive panicked + --> $DIR/any-panic-payload.rs:14:10 + | +LL | #[derive(CausePanic)] + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/proc-macro/auxiliary/any-panic-payload.rs b/tests/ui/proc-macro/auxiliary/any-panic-payload.rs new file mode 100644 index 0000000000000..e78f82506831c --- /dev/null +++ b/tests/ui/proc-macro/auxiliary/any-panic-payload.rs @@ -0,0 +1,22 @@ +extern crate proc_macro; + +use proc_macro::TokenStream; + +fn boom() -> TokenStream { + std::panic::panic_any(42) +} + +#[proc_macro] +pub fn cause_panic(_: TokenStream) -> TokenStream { + boom() +} + +#[proc_macro_attribute] +pub fn cause_panic_attr(_: TokenStream, _: TokenStream) -> TokenStream { + boom() +} + +#[proc_macro_derive(CausePanic)] +pub fn cause_panic_derive(_: TokenStream) -> TokenStream { + boom() +} diff --git a/tests/ui/scalable-vectors/illformed.rs b/tests/ui/scalable-vectors/illformed.rs index d8730f40e1029..0122b3735ff20 100644 --- a/tests/ui/scalable-vectors/illformed.rs +++ b/tests/ui/scalable-vectors/illformed.rs @@ -3,6 +3,9 @@ #![allow(internal_features)] #![feature(rustc_attrs)] +#[rustc_scalable_vector(4)] +struct Valid(f32); + #[rustc_scalable_vector(4)] struct NoFieldsStructWithElementCount {} //~^ ERROR: scalable vectors must have a single field @@ -19,16 +22,16 @@ struct NoFieldsUnitWithElementCount; #[rustc_scalable_vector] struct NoFieldsStructWithoutElementCount {} -//~^ ERROR: scalable vectors must have a single field +//~^ ERROR: scalable vector tuples must have at least one field //~^^ ERROR: scalable vectors must be tuple structs #[rustc_scalable_vector] struct NoFieldsTupleWithoutElementCount(); -//~^ ERROR: scalable vectors must have a single field +//~^ ERROR: scalable vector tuples must have at least one field #[rustc_scalable_vector] struct NoFieldsUnitWithoutElementCount; -//~^ ERROR: scalable vectors must have a single field +//~^ ERROR: scalable vector tuples must have at least one field //~^^ ERROR: scalable vectors must be tuple structs #[rustc_scalable_vector(4)] @@ -58,3 +61,8 @@ struct MultipleFieldsTupleWithoutElementCount(f32, u32); #[rustc_scalable_vector(2)] struct SingleFieldStruct { _ty: f64 } //~^ ERROR: scalable vectors must be tuple structs + +#[rustc_scalable_vector] +struct TooManyFieldsWithoutElementCount( + Valid, Valid, Valid, Valid, Valid, Valid, Valid, Valid, Valid); +//~^^ ERROR: scalable vector tuples can have at most eight fields diff --git a/tests/ui/scalable-vectors/illformed.stderr b/tests/ui/scalable-vectors/illformed.stderr index ba584a4ad4d59..29640f023e212 100644 --- a/tests/ui/scalable-vectors/illformed.stderr +++ b/tests/ui/scalable-vectors/illformed.stderr @@ -1,29 +1,29 @@ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:7:1 + --> $DIR/illformed.rs:10:1 | LL | struct NoFieldsStructWithElementCount {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:16:1 + --> $DIR/illformed.rs:19:1 | LL | struct NoFieldsUnitWithElementCount; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:21:1 + --> $DIR/illformed.rs:24:1 | LL | struct NoFieldsStructWithoutElementCount {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:30:1 + --> $DIR/illformed.rs:33:1 | LL | struct NoFieldsUnitWithoutElementCount; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:35:1 + --> $DIR/illformed.rs:38:1 | LL | / struct MultipleFieldsStructWithElementCount { LL | | @@ -34,7 +34,7 @@ LL | | } | |_^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:47:1 + --> $DIR/illformed.rs:50:1 | LL | / struct MultipleFieldsStructWithoutElementCount { LL | | @@ -44,13 +44,13 @@ LL | | } | |_^ error: scalable vectors must be tuple structs - --> $DIR/illformed.rs:59:1 + --> $DIR/illformed.rs:62:1 | LL | struct SingleFieldStruct { _ty: f64 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors must have a single field - --> $DIR/illformed.rs:7:1 + --> $DIR/illformed.rs:10:1 | LL | struct NoFieldsStructWithElementCount {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -58,7 +58,7 @@ LL | struct NoFieldsStructWithElementCount {} = help: scalable vector types' only field must be a primitive scalar type error: scalable vectors must have a single field - --> $DIR/illformed.rs:12:1 + --> $DIR/illformed.rs:15:1 | LL | struct NoFieldsTupleWithElementCount(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -66,31 +66,31 @@ LL | struct NoFieldsTupleWithElementCount(); = help: scalable vector types' only field must be a primitive scalar type error: scalable vectors must have a single field - --> $DIR/illformed.rs:16:1 + --> $DIR/illformed.rs:19:1 | LL | struct NoFieldsUnitWithElementCount; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: scalable vector types' only field must be a primitive scalar type -error: scalable vectors must have a single field - --> $DIR/illformed.rs:21:1 +error: scalable vector tuples must have at least one field + --> $DIR/illformed.rs:24:1 | LL | struct NoFieldsStructWithoutElementCount {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: tuples of scalable vectors can only contain multiple of the same scalable vector type -error: scalable vectors must have a single field - --> $DIR/illformed.rs:26:1 +error: scalable vector tuples must have at least one field + --> $DIR/illformed.rs:29:1 | LL | struct NoFieldsTupleWithoutElementCount(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: tuples of scalable vectors can only contain multiple of the same scalable vector type -error: scalable vectors must have a single field - --> $DIR/illformed.rs:30:1 +error: scalable vector tuples must have at least one field + --> $DIR/illformed.rs:33:1 | LL | struct NoFieldsUnitWithoutElementCount; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -98,28 +98,36 @@ LL | struct NoFieldsUnitWithoutElementCount; = help: tuples of scalable vectors can only contain multiple of the same scalable vector type error: scalable vectors cannot have multiple fields - --> $DIR/illformed.rs:35:1 + --> $DIR/illformed.rs:38:1 | LL | struct MultipleFieldsStructWithElementCount { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vectors cannot have multiple fields - --> $DIR/illformed.rs:43:1 + --> $DIR/illformed.rs:46:1 | LL | struct MultipleFieldsTupleWithElementCount(f32, u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: scalable vector structs can only have scalable vector fields - --> $DIR/illformed.rs:49:5 + --> $DIR/illformed.rs:52:5 | LL | _ty: f32, | ^^^^^^^^ error: scalable vector structs can only have scalable vector fields - --> $DIR/illformed.rs:55:47 + --> $DIR/illformed.rs:58:47 | LL | struct MultipleFieldsTupleWithoutElementCount(f32, u32); | ^^^ -error: aborting due to 17 previous errors +error: scalable vector tuples can have at most eight fields + --> $DIR/illformed.rs:66:1 + | +LL | struct TooManyFieldsWithoutElementCount( + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: tuples of scalable vectors can only contain multiple of the same scalable vector type + +error: aborting due to 18 previous errors diff --git a/triagebot.toml b/triagebot.toml index a3a5928a8f366..86192295e0cdb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1177,7 +1177,7 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@vakaras"] [mentions."compiler/rustc_error_messages"] message = "`rustc_error_messages` was changed" -cc = ["@davidtwco", "@TaKO8Ki"] +cc = ["@TaKO8Ki"] [mentions."compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs"] message = "`rustc_errors::annotate_snippet_emitter_writer` was changed" @@ -1189,11 +1189,11 @@ cc = ["@Muscraft"] [mentions."compiler/rustc_errors/src/formatting.rs"] message = "`rustc_errors::formatting` was changed" -cc = ["@davidtwco", "@TaKO8Ki", "@JonathanBrouwer"] +cc = ["@TaKO8Ki", "@JonathanBrouwer"] [mentions."compiler/rustc_macros/src/diagnostics"] message = "`rustc_macros::diagnostics` was changed" -cc = ["@davidtwco", "@TaKO8Ki", "@JonathanBrouwer"] +cc = ["@TaKO8Ki", "@JonathanBrouwer"] [mentions."compiler/rustc_public"] message = "This PR changes rustc_public"