diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0f896724ae56..0c5c5fe46d394 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -190,6 +190,15 @@ jobs: - name: install ninja run: src/ci/scripts/install-ninja.sh + - name: install required Python version + # LLDB on Windows requires the same Python version it was built against to be the first + # discoverable Python in $env:PATH. Only install if we're actually running Windows tests + # that use LLDB + if: ${{ startsWith(matrix.os, 'windows') && matrix.required_python_version}} + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 + with: + python-version: ${{ matrix.required_python_version }} + - name: enable ipv6 on Docker # Don't run on codebuild because systemctl is not available if: ${{ !matrix.codebuild }} diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 43c994c2d3617..0000000000000 --- a/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/Cargo.lock b/Cargo.lock index 71086e7203470..5f814babbdc0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4339,6 +4339,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", + "rustc_hashes", "rustc_hir", "rustc_index", "rustc_infer", diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index b8928aecf0cc5..0bc8f7e13ee2c 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -247,15 +247,25 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { where Ty: TyAbiInterface<'a, C> + Copy, { - let base = self.peel_transparent_wrappers(cx); + // FIXME: Peeling the wrappers above would not work correctly if we are a 1-ZST. So we make + // `#[rustc_pass_indirectly_in_non_rustic_abis]` a NOP on 1-ZST. In the future, + // `non_1zst_field` should become `non_trivial_abi_field` and + // `#[rustc_pass_indirectly_in_non_rustic_abis]` should make a type have non-trivial ABI. + if self.is_1zst() { + return false; + } + + let base = self.peel_transparent_wrappers_from_non_1zst(cx); Ty::is_pass_indirectly_in_non_rustic_abis_flag_set(base) } /// Recursively peel away transparent wrappers, returning the inner value. + /// Will not peel anything if `self` is a 1-ZST! Callers need to either check + /// that the result is not a 1-ZST, or have separate logic for that. /// /// The return value is not `repr(transparent)` and/or does /// not have a non-1zst field. - pub fn peel_transparent_wrappers(mut self, cx: &C) -> Self + pub fn peel_transparent_wrappers_from_non_1zst(mut self, cx: &C) -> Self where Ty: TyAbiInterface<'a, C> + Copy, { @@ -321,12 +331,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { where Ty: TyAbiInterface<'a, C> + Copy, { - let complex = self.peel_transparent_wrappers(cx); + // We're checking for scalar repr below which excludes 1-ZST. + let complex = self.peel_transparent_wrappers_from_non_1zst(cx); if !Ty::is_complex_number_lang_item(complex, cx) { return None; } - let component = complex.field(cx, 0).peel_transparent_wrappers(cx); + let component = complex.field(cx, 0).peel_transparent_wrappers_from_non_1zst(cx); let BackendRepr::Scalar(scalar) = component.backend_repr else { return None; diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 370c0ceeda909..5c2c3052d1d51 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -147,7 +147,7 @@ fn cs_clone_simple( &[sym::clone, sym::AssertParamIsCopy], ); } else { - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } @@ -169,18 +169,17 @@ fn cs_clone(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<'_>) -> Blo cx.expr_call_global(field.span, fn_path.clone(), args) }; - let self_ident = Ident::new(kw::SelfUpper, trait_span); let ctor_path; let all_fields; let vdata; - match substr { + match substr.fields { Struct(vdata_, af) => { - ctor_path = cx.path(trait_span, vec![self_ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident]); all_fields = af; vdata = vdata_; } EnumMatching(.., variant, af) => { - ctor_path = cx.path(trait_span, vec![self_ident, variant.ident]); + ctor_path = cx.path(trait_span, vec![substr.type_ident, variant.ident]); all_fields = af; vdata = &variant.data; } diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 2f3d2058773d8..d8355d733a7f3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -68,7 +68,7 @@ fn show_substructure( return BlockOrExpr::new_expr(cx.expr_ok(span, cx.expr_tuple(span, ThinVec::new()))); } - let (ident, vdata, fields) = match substr { + let (ident, vdata, fields) = match substr.fields { Struct(vdata, fields) => (type_ident, vdata, fields), EnumMatching(v, fields) => (v.ident, &v.data, fields), AllFieldlessEnum(enum_def) => return show_fieldless_enum(cx, span, enum_def, type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 28526bdef6b9d..268153c1cbb31 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -37,9 +37,9 @@ pub(crate) fn expand_deriving_default( attributes: thin_vec![cx.attr_word(sym::inline, span)], fieldless_variants_strategy: FieldlessVariantsStrategy::Default, combine_substructure: combine_substructure(|cx, trait_span, substr| { - match substr { + match substr.fields { StaticStruct(variant_data) => { - default_struct_substructure(cx, trait_span, variant_data) + default_struct_substructure(cx, trait_span, variant_data, substr.type_ident) } StaticEnum(enum_def) => { default_enum_substructure(cx, trait_span, enum_def, item.span) @@ -67,15 +67,16 @@ fn default_struct_substructure( cx: &ExtCtxt<'_>, trait_span: Span, variant_data: &VariantData, + type_ident: Ident, ) -> BlockOrExpr { let expr = match variant_data { - VariantData::Unit(_) => cx.expr_ident(trait_span, Ident::new(kw::SelfUpper, trait_span)), + VariantData::Unit(_) => cx.expr_ident(trait_span, type_ident), VariantData::Tuple(fields, _) => { let exprs = fields .iter() .map(|field| default_call(cx, field.span.with_ctxt(trait_span.ctxt()))) .collect(); - cx.expr_call_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), exprs) + cx.expr_call_ident(trait_span, type_ident, exprs) } VariantData::Struct { fields, .. } => { let default_fields = fields @@ -95,7 +96,7 @@ fn default_struct_substructure( cx.field_imm(span, field.ident.unwrap(), value) }) .collect(); - cx.expr_struct_ident(trait_span, Ident::new(kw::SelfUpper, trait_span), default_fields) + cx.expr_struct_ident(trait_span, type_ident, default_fields) } }; BlockOrExpr::new_expr(expr) diff --git a/compiler/rustc_builtin_macros/src/deriving/eq.rs b/compiler/rustc_builtin_macros/src/deriving/eq.rs index da38045994c7f..27be8a8cb6dff 100644 --- a/compiler/rustc_builtin_macros/src/deriving/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/eq.rs @@ -72,7 +72,7 @@ fn cs_total_eq_assert(cx: &ExtCtxt<'_>, trait_span: Span, substr: Substructure<' } }; - match substr { + match substr.fields { StaticStruct(vdata, ..) => { process_variant(vdata); } diff --git a/compiler/rustc_builtin_macros/src/deriving/from.rs b/compiler/rustc_builtin_macros/src/deriving/from.rs index df95ccd99f3e6..edd1cf75488fc 100644 --- a/compiler/rustc_builtin_macros/src/deriving/from.rs +++ b/compiler/rustc_builtin_macros/src/deriving/from.rs @@ -88,7 +88,7 @@ pub(crate) fn expand_deriving_from( }; let self_kw = Ident::new(kw::SelfUpper, span); - let expr: Box = match substructure { + let expr: Box = match substructure.fields { StaticStruct(variant) => match variant { // Self { field: value } VariantData::Struct { .. } => cx.expr_struct_ident( diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 8b15920511aca..fbbadce3a8816 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -177,7 +177,7 @@ use std::ops::Not; use std::vec; -pub(crate) use Substructure::*; +pub(crate) use SubstructureFields::*; pub(crate) use rustc_ast as ast; use rustc_ast::token::{IdentKind, LitKind, Token, TokenKind}; use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -281,8 +281,16 @@ pub(crate) struct FieldInfo { pub maybe_scalar: bool, } +pub(crate) struct Substructure<'a> { + pub fields: SubstructureFields<'a>, + // FIXME: this is currently required to avoid issues with attribute macros after derives, + // such as https://github.com/rust-lang/rust/issues/163800. + // Ideally we would just use `Self` instead. + pub type_ident: Ident, +} + /// A summary of the possible sets of fields. -pub(crate) enum Substructure<'a> { +pub(crate) enum SubstructureFields<'a> { /// A non-static method where `Self` is a struct. Struct(&'a ast::VariantData, Vec), @@ -474,9 +482,15 @@ impl<'a> TraitDef<'a> { let fields = struct_def.fields().iter(); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticStruct(struct_def)) + method_def.call_substructure_method( + cx, + span, + StaticStruct(struct_def), + *ident, + ) } else { - method_def.expand_struct_method_body(cx, span, struct_def, is_packed) + method_def + .expand_struct_method_body(cx, span, struct_def, is_packed, *ident) }; method_def.create_method(cx, span, body) @@ -494,9 +508,9 @@ impl<'a> TraitDef<'a> { let fields = enum_def.variants.iter().flat_map(|variant| variant.data.fields()); let methods = self.methods.iter().filter_map(|method_def| { let body = if from_scratch || method_def.is_static() { - method_def.call_substructure_method(cx, span, StaticEnum(enum_def)) + method_def.call_substructure_method(cx, span, StaticEnum(enum_def), *ident) } else { - method_def.expand_enum_method_body(cx, span, enum_def) + method_def.expand_enum_method_body(cx, span, enum_def, *ident) }; method_def.create_method(cx, span, body) @@ -778,9 +792,10 @@ impl<'a> MethodDef<'a> { &self, cx: &ExtCtxt<'_>, span: Span, - substructure: Substructure<'_>, + fields: SubstructureFields<'_>, + type_ident: Ident, ) -> BlockOrExpr { - (self.combine_substructure)(cx, span, substructure) + (self.combine_substructure)(cx, span, Substructure { fields, type_ident }) } fn is_static(&self) -> bool { @@ -906,12 +921,13 @@ impl<'a> MethodDef<'a> { span: Span, struct_def: &'b VariantData, is_packed: bool, + type_ident: Ident, ) -> BlockOrExpr { let selflike_args = self.get_selflike_args(cx, span); let selflike_fields = create_struct_field_access_fields(span, cx, &selflike_args, struct_def, is_packed); - self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields)) + self.call_substructure_method(cx, span, Struct(struct_def, selflike_fields), type_ident) } /// ``` @@ -954,6 +970,7 @@ impl<'a> MethodDef<'a> { cx: &ExtCtxt<'_>, span: Span, enum_def: &'b EnumDef, + type_ident: Ident, ) -> BlockOrExpr { let variants = &enum_def.variants; @@ -989,17 +1006,32 @@ impl<'a> MethodDef<'a> { // If the type is fieldless and the trait uses the discriminant and // there are multiple variants, we need just an operation on // the discriminant(s). - return self.call_substructure_method(cx, span, EnumDiscr(None)); + return self.call_substructure_method( + cx, + span, + EnumDiscr(None), + type_ident, + ); } FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless => { - return self.call_substructure_method(cx, span, AllFieldlessEnum(enum_def)); + return self.call_substructure_method( + cx, + span, + AllFieldlessEnum(enum_def), + type_ident, + ); } FieldlessVariantsStrategy::Default => (), } } else if let [variant] = variants.as_slice() { // If there is a single variant, we don't need an operation on // the discriminant(s). Just use the most degenerate result. - return self.call_substructure_method(cx, span, EnumMatching(variant, Vec::new())); + return self.call_substructure_method( + cx, + span, + EnumMatching(variant, Vec::new()), + type_ident, + ); } } @@ -1039,8 +1071,9 @@ impl<'a> MethodDef<'a> { // Self arg, assuming all are instances of VariantK. // Build up code associated with such a case. let substructure = EnumMatching(variant, fields); - let arm_expr = - self.call_substructure_method(cx, span, substructure).into_expr(cx, span); + let arm_expr = self + .call_substructure_method(cx, span, substructure, type_ident) + .into_expr(cx, span); cx.arm(span, single_pat, arm_expr) }) @@ -1052,8 +1085,13 @@ impl<'a> MethodDef<'a> { Some(v) if unify_fieldless_variants => { // We need a default case that handles all the fieldless variants. Some( - self.call_substructure_method(cx, span, EnumMatching(v, Vec::new())) - .into_expr(cx, span), + self.call_substructure_method( + cx, + span, + EnumMatching(v, Vec::new()), + type_ident, + ) + .into_expr(cx, span), ) } _ if variants.len() > 1 && selflike_args.len() > 1 => { @@ -1090,7 +1128,12 @@ impl<'a> MethodDef<'a> { // is enough. if unify_fieldless_variants && variants.len() > 1 { // Combine a discriminant check with the match. - self.call_substructure_method(cx, span, EnumDiscr(Some(get_match_expr(selflike_args)))) + self.call_substructure_method( + cx, + span, + EnumDiscr(Some(get_match_expr(selflike_args))), + type_ident, + ) } else { BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 3e0722988155c..db0e8efc99f3c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -65,7 +65,7 @@ fn hash_substructure(cx: &ExtCtxt<'_>, span: Span, substr: Substructure<'_>) -> cx.stmt_expr(expr) }; - let (stmts, match_expr) = match substr { + let (stmts, match_expr) = match substr.fields { Struct(_, fields) | EnumMatching(.., fields) => { let stmts = fields.into_iter().map(|field| call_hash(field.span, field.self_expr)).collect(); diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs index 377a32dcca4f0..180800aa72025 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_eq.rs @@ -119,7 +119,7 @@ fn get_substructure_equality_expr( span: Span, substructure: Substructure<'_>, ) -> BlockOrExpr { - BlockOrExpr::new_expr(match substructure { + BlockOrExpr::new_expr(match substructure.fields { EnumMatching(.., fields) | Struct(.., fields) => { let combine = move |acc, field: &FieldInfo| { let rhs = field diff --git a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs index 8c3e2ee58f8e2..4ce695a16200f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/partial_ord.rs @@ -202,7 +202,7 @@ pub(crate) fn cmp_body( } }; - match substructure { + match substructure.fields { EnumMatching(.., all_fields) | Struct(_, all_fields) => { let op = |old, field: FieldInfo| { // The basic case: a field expression for one or more selflike args. E.g. diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a95f259545982..5bbe1c887a939 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -33,7 +33,6 @@ use crate::back::profiling::{ }; use crate::builder::SBuilder; use crate::builder::gpu_offload::scalar_width; -use crate::common::AsCCharPtr; use crate::context::SimpleCx; use crate::diagnostics::{ CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, ParseTargetMachineConfig, @@ -548,9 +547,7 @@ pub(crate) unsafe fn llvm_optimize( } else { None }; - let passes_after_enzyme_ptr = - passes_after_enzyme.map_or(std::ptr::null(), |s| s.as_c_char_ptr()); - let passes_after_enzyme_len = passes_after_enzyme.map_or(0, |s| s.len()); + let merge_functions; let unroll_loops; let vectorize_slp; @@ -788,11 +785,11 @@ pub(crate) unsafe fn llvm_optimize( llvm_selfprofiler, selfprofile_before_pass_callback, selfprofile_after_pass_callback, - passes_after_enzyme_ptr, - passes_after_enzyme_len, - extra_passes.as_c_char_ptr(), + passes_after_enzyme.map(|s| s.as_ptr()).unwrap_or(std::ptr::null()), + passes_after_enzyme.map(|s| s.len()).unwrap_or(0), + extra_passes.as_ptr(), extra_passes.len(), - llvm_plugins.as_c_char_ptr(), + llvm_plugins.as_ptr(), llvm_plugins.len(), ) }; diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index a3bcce34566cb..e14cdeb1505d0 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -32,7 +32,7 @@ use super::CodegenUnitDebugContext; use super::namespace::mangled_name_of_instance; use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name}; use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::build_type_with_children; use crate::debuginfo::utils::{WidePtrKind, create_DIArray, wide_pointer_kind}; use crate::debuginfo::{DIBuilderExt, dwarf_const}; @@ -651,14 +651,14 @@ fn create_file<'ll>( unsafe { llvm::LLVMRustDIBuilderCreateFile( builder, - file_name.as_c_char_ptr(), + file_name.as_ptr(), file_name.len(), - directory.as_c_char_ptr(), + directory.as_ptr(), directory.len(), hash_kind, - hash_value.as_c_char_ptr(), + hash_value.as_ptr(), hash_value.len(), - source.map_or(ptr::null(), |x| x.as_c_char_ptr()), + source.map_or(ptr::null(), |x| x.as_ptr()), source.map_or(0, |x| x.len()), ) } @@ -949,20 +949,21 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( llvm::ChecksumKind::None, None, ); + let flags = c""; let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit( debug_context.builder.as_ref(), dwarf_const::DW_LANG_Rust, compile_unit_file, - producer.as_c_char_ptr(), + producer.as_ptr(), producer.len(), tcx.sess.opts.optimize != config::OptLevel::No, - c"".as_ptr(), + flags.as_ptr(), 0, // NB: this doesn't actually have any perceptible effect, it seems. LLVM will instead // put the path supplied to `MCSplitDwarfFile` into the debug info of the final // output(s). - split_name.as_c_char_ptr(), + split_name.as_ptr(), split_name.len(), kind, 0, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 37f114fc5b09e..c2aa981582aaf 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -13,7 +13,7 @@ use rustc_span::{Span, Symbol, bug}; use super::type_map::{DINodeCreationResult, UniqueTypeId}; use super::{SmallVec, size_and_align_of}; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::{self, Stub}; use crate::debuginfo::metadata::{ UNKNOWN_LINE_NUMBER, build_field_di_node, build_generic_type_param_di_nodes, @@ -141,7 +141,7 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateEnumerationType( DIB(cx), containing_scope, - type_name.as_c_char_ptr(), + type_name.as_ptr(), type_name.len(), file_metadata, line_number, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs index c0ecb14d21926..c9cac61a8bbe1 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs @@ -10,7 +10,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_span::bug; use smallvec::smallvec; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::metadata::type_map::{self, Stub, StubInfo, UniqueTypeId}; use crate::debuginfo::metadata::{ DINodeCreationResult, NO_GENERICS, SmallVec, UNKNOWN_LINE_NUMBER, create_member_type, @@ -284,7 +284,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateVariantPart( DIB(cx), enum_type_di_node, - variant_part_name.as_c_char_ptr(), + variant_part_name.as_ptr(), variant_part_name.len(), file_metadata, line_number, @@ -293,7 +293,7 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>( DIFlags::FlagZero, tag_member_di_node, create_DIArray(DIB(cx), &[]), - variant_part_unique_type_id_str.as_c_char_ptr(), + variant_part_unique_type_id_str.as_ptr(), variant_part_unique_type_id_str.len(), ) }, @@ -444,7 +444,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>( llvm::LLVMRustDIBuilderCreateVariantMemberType( DIB(cx), variant_part_di_node, - variant_member_info.variant_name.as_c_char_ptr(), + variant_member_info.variant_name.as_ptr(), variant_member_info.variant_name.len(), file_di_node, line_number, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 29448f147d103..99a54f1d74a62 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -34,7 +34,7 @@ use self::metadata::{ use self::namespace::mangled_name_of_instance; use self::utils::{DIB, create_DIArray, is_node_local_to_unit}; use crate::builder::Builder; -use crate::common::{AsCCharPtr, CodegenCx}; +use crate::common::CodegenCx; use crate::debuginfo::di_builder::DIBuilderBox; use crate::llvm::debuginfo::{ DIArray, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, @@ -197,9 +197,9 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { llvm::LLVMRustDIBuilderCreateMethod( DIB(self), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), - linkage_name.as_c_char_ptr(), + linkage_name.as_ptr(), linkage_name.len(), file_metadata, loc.line, @@ -214,9 +214,9 @@ impl<'ll, 'tcx> DebugInfoBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { llvm::LLVMRustDIBuilderCreateFunction( DIB(self), containing_scope, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), - linkage_name.as_c_char_ptr(), + linkage_name.as_ptr(), linkage_name.len(), file_metadata, loc.line, @@ -716,7 +716,7 @@ impl<'ll> CodegenCx<'ll, '_> { llvm::LLVMRustDIBuilderCreateTemplateTypeParameter( DIB(self), None, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), actual_type_metadata, ) diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 23f9fc93a4ba4..78bc5aba450aa 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -25,7 +25,6 @@ use tracing::debug; use crate::abi::FnAbiLlvmExt; use crate::attributes; -use crate::common::AsCCharPtr; use crate::context::{CodegenCx, GenericCx, SCx, SimpleCx}; use crate::llvm::AttributePlace::Function; use crate::llvm::{self, FromGeneric, Type, Value, Visibility}; @@ -43,8 +42,7 @@ pub(crate) fn declare_simple_fn<'ll>( ty: &'ll Type, ) -> &'ll Value { debug!("declare_simple_fn(name={:?}, ty={:?})", name, ty); - let llfn = - unsafe { llvm::LLVMGetOrInsertFunction(cx.llmod, name.as_c_char_ptr(), name.len(), ty) }; + let llfn = unsafe { llvm::LLVMGetOrInsertFunction(cx.llmod, name.as_ptr(), name.len(), ty) }; llvm::SetFunctionCallConv(llfn, callconv); llvm::set_unnamed_address(llfn, unnamed); @@ -96,12 +94,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { pub(crate) fn declare_global(&self, name: &str, ty: &'ll Type) -> &'ll Value { debug!("declare_global(name={:?})", name); unsafe { - llvm::LLVMRustGetOrInsertGlobal( - (**self).borrow().llmod, - name.as_c_char_ptr(), - name.len(), - ty, - ) + llvm::LLVMRustGetOrInsertGlobal((**self).borrow().llmod, name.as_ptr(), name.len(), ty) } } @@ -119,7 +112,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { unsafe { llvm::LLVMRustGetOrInsertGlobalInAddrspace( (**self).borrow().llmod, - name.as_c_char_ptr(), + name.as_ptr(), name.len(), ty, addr_space.0, @@ -261,7 +254,7 @@ impl<'ll, CX: Borrow>> GenericCx<'ll, CX> { /// Gets declared value by name. pub(crate) fn get_declared_value(&self, name: &str) -> Option<&'ll Value> { debug!("get_declared_value(name={:?})", name); - unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_c_char_ptr(), name.len()) } + unsafe { llvm::LLVMRustGetNamedValue(self.llmod(), name.as_ptr(), name.len()) } } /// Gets defined or externally defined (AvailableExternally linkage) value by diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index f576f29a17cca..78bb1750b0a27 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1132,7 +1132,7 @@ unsafe extern "C" { pub(crate) fn LLVMDeleteFunction(Fn: &Value); pub(crate) fn LLVMGetOrInsertFunction<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, FunctionTy: &'a Type, ) -> &'a Value; @@ -1991,20 +1991,20 @@ unsafe extern "C" { // Operations on global variables pub(crate) fn LLVMRustGetOrInsertGlobal<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, T: &'a Type, ) -> &'a Value; pub(crate) fn LLVMRustGetOrInsertGlobalInAddrspace<'a>( M: &'a Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, T: &'a Type, AddressSpace: c_uint, ) -> &'a Value; pub(crate) fn LLVMRustGetNamedValue( M: &Module, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, ) -> Option<&Value>; @@ -2206,12 +2206,12 @@ unsafe extern "C" { Builder: &DIBuilder<'a>, Lang: c_uint, File: &'a DIFile, - Producer: *const c_char, + Producer: *const c_uchar, // See "PTR_LEN_STR". ProducerLen: size_t, isOptimized: bool, Flags: *const c_char, RuntimeVer: c_uint, - SplitName: *const c_char, + SplitName: *const c_uchar, // See "PTR_LEN_STR". SplitNameLen: size_t, kind: DebugEmissionKind, DWOId: u64, @@ -2223,14 +2223,14 @@ unsafe extern "C" { /// _requires_ a checksum, but we sometimes don't provide one. pub(crate) fn LLVMRustDIBuilderCreateFile<'a>( Builder: &DIBuilder<'a>, - Filename: *const c_char, + Filename: *const c_uchar, // See "PTR_LEN_STR". FilenameLen: size_t, - Directory: *const c_char, + Directory: *const c_uchar, // See "PTR_LEN_STR". DirectoryLen: size_t, CSKind: ChecksumKind, - Checksum: *const c_char, + Checksum: *const c_uchar, // See "PTR_LEN_STR". ChecksumLen: size_t, - Source: *const c_char, + Source: *const c_uchar, // See "PTR_LEN_STR". SourceLen: size_t, ) -> &'a DIFile; @@ -2239,9 +2239,9 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateFunction<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, - LinkageName: *const c_char, + LinkageName: *const c_uchar, // See "PTR_LEN_STR". LinkageNameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2258,9 +2258,9 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateMethod<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIDescriptor, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, - LinkageName: *const c_char, + LinkageName: *const c_uchar, // See "PTR_LEN_STR". LinkageNameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2274,7 +2274,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateVariantMemberType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNumber: c_uint, @@ -2290,7 +2290,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateEnumerationType<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNumber: c_uint, @@ -2305,7 +2305,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateVariantPart<'a>( Builder: &DIBuilder<'a>, Scope: &'a DIScope, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, File: &'a DIFile, LineNo: c_uint, @@ -2314,7 +2314,7 @@ unsafe extern "C" { Flags: DIFlags, Discriminator: Option<&'a DIDerivedType>, Elements: &'a DIArray, - UniqueId: *const c_char, + UniqueId: *const c_uchar, // See "PTR_LEN_STR". UniqueIdLen: size_t, ) -> &'a DIDerivedType; @@ -2322,7 +2322,7 @@ unsafe extern "C" { pub(crate) fn LLVMRustDIBuilderCreateTemplateTypeParameter<'a>( Builder: &DIBuilder<'a>, Scope: Option<&'a DIScope>, - Name: *const c_char, + Name: *const c_uchar, // See "PTR_LEN_STR". NameLen: size_t, Ty: &'a DIType, ) -> &'a DITemplateTypeParameter; @@ -2461,11 +2461,11 @@ unsafe extern "C" { llvm_selfprofiler: *mut c_void, begin_callback: SelfProfileBeforePassCallback, end_callback: SelfProfileAfterPassCallback, - PostEnzymePasses: *const c_char, + PostEnzymePasses: *const c_uchar, // See "PTR_LEN_STR". PostEnzymePassesLen: size_t, - ExtraPasses: *const c_char, + ExtraPasses: *const c_uchar, // See "PTR_LEN_STR". ExtraPassesLen: size_t, - LLVMPlugins: *const c_char, + LLVMPlugins: *const c_uchar, // See "PTR_LEN_STR". LLVMPluginsLen: size_t, ) -> LLVMRustResult; pub(crate) fn LLVMRustPrintModule( diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index a582e897eef9c..ea91756b9068a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -399,7 +399,7 @@ fn update_target_reliable_float_cfg(target: &Target, cfg: &mut TargetConfig) { // This is similar to , however // does not work until LLVM 23 on Windows. (Arch::Arm64EC, _) => major >= 23, - (Arch::AArch64, _) => true, + (Arch::AArch64 | Arch::Arm, _) => true, // FIXME(f16b) until // is resolved the below do not have a reliable `f16b`, on a widening // path a call to `__truncsfbf2` is emitted. Or when using architectural diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 8408e2eefb13e..2c8618f4e3e62 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -308,7 +308,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( let va_list_addr = list.immediate(); // Peel off any newtype wrappers. - let layout = layout.peel_transparent_wrappers(bx.cx); + let layout = layout.peel_transparent_wrappers_from_non_1zst(bx.cx); // Rust does not currently support any powerpc softfloat targets. let target = &bx.cx.tcx.sess.target; @@ -561,7 +561,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( // #[repr(C)] // struct Foo([Empty; 8], i32); // ``` - let layout = layout.peel_transparent_wrappers(bx.cx); + let layout = layout.peel_transparent_wrappers_from_non_1zst(bx.cx); // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed // in the registers. If not go to step 7. diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index c74a5e788689f..6c6d20568a9f9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -112,7 +112,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { bx: &mut Bx, layout: TyAndLayout<'tcx>, ) -> Self { - if layout.peel_transparent_wrappers(bx).deref().is_scalable_vector() { + // FIXME(rustc_scalable_vector/stdarch_aarch64_sve): Scalable vectors aren't actually sized, + // but we pretend they are. Here we have to hack around that. + if layout.peel_transparent_wrappers_from_non_1zst(bx).deref().is_scalable_vector() { Self::alloca_scalable(bx, layout) } else { Self::alloca_size(bx, layout.size, layout) @@ -159,7 +161,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { layout: TyAndLayout<'tcx>, ) -> Self { PlaceValue::new_sized( - bx.alloca_with_ty(layout.peel_transparent_wrappers(bx)), + // FIXME why is this peeling at all? The LLVM type should be the same for the + // transparent wrapper and the inner type. + bx.alloca_with_ty(layout.peel_transparent_wrappers_from_non_1zst(bx)), layout.align.abi, ) .with_type(layout) diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 59e1f6e9d0098..96918cc0b2eca 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -539,12 +539,15 @@ pub trait BuilderMethods<'a, 'tcx>: let tt = tt.add_indirection(); let fnc_tree = FncTree { args: vec![tt.clone(), tt], ret: TypeTree::new() }; let bytes = self.const_usize(layout.size.bytes()); - let bytes = if layout.peel_transparent_wrappers(self).ty.is_scalable_vector() { - let vscale = self.vscale(self.type_i64()); - self.mul(vscale, bytes) - } else { - bytes - }; + let bytes = + // FIXME(rustc_scalable_vector/stdarch_aarch64_sve): Scalable vectors aren't + // actually sized, but we pretend they are. Here we have to hack around that. + if layout.peel_transparent_wrappers_from_non_1zst(self).ty.is_scalable_vector() { + let vscale = self.vscale(self.type_i64()); + self.mul(vscale, bytes) + } else { + bytes + }; self.memcpy(dst.llval, dst.align, src.llval, src.align, bytes, flags, Some(fnc_tree)); } } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index dc4b6a6fd319c..6b72f6fd90605 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -2423,15 +2423,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { fn check_test_binder_forall(&self, forall: TestBinderForall<'tcx>) { self.infcx.enter_forall(forall.binder, |body| { let u = self.infcx.universe(); - let mut builder = TransitiveRelationBuilder::default(); - for &(r1, r2) in &body.region_outlives { - builder.add(r1, r2); - } - // Deliberately unelaborated: the assumptions of a `forall` are exactly the ones - // written down in the test, no extra ones hidden behind the scenes. - let assumptions = ty::region_constraint::Assumptions::new_unelaborated( + let assumptions = self.build_test_binder_assumptions( + forall.span, body.type_outlives, - builder.freeze(), + body.region_outlives, ); self.infcx.insert_placeholder_assumptions(u, assumptions); self.check_test_binder_body(body.value); @@ -2449,6 +2444,52 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { }); } + fn build_test_binder_assumptions( + &self, + span: Span, + type_outlives: Vec>, + region_outlives: Vec>, + ) -> ty::region_constraint::Assumptions> { + for clause in &type_outlives { + if !matches!( + clause.skip_binder().0.kind(), + ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) + ) { + let mut err = self.tcx().dcx().struct_span_err( + span, + "the lhs of a forall where clause must be \ + an alias, placeholder, or lifetime", + ); + err.note(format!("the bad clause is {clause}")); + err.emit(); + } + } + let ty = type_outlives.iter().map(|c| c.map_bound(ty::ClauseKind::TypeOutlives)); + let reg = + region_outlives.iter().map(|&c| ty::Binder::dummy(ty::ClauseKind::RegionOutlives(c))); + let explicit_clauses: Vec> = + ty.chain(reg).map(|c| c.upcast(self.tcx())).collect(); + for elaborated in ty::elaborate::elaborate(self.tcx(), explicit_clauses.iter().copied()) { + if !explicit_clauses.contains(&elaborated) { + let mut err = self.tcx().dcx().struct_span_err( + span, + "all implied bounds of clauses must themselves be \ + included in the where clause of a forall", + ); + err.note(format!("missing clause is {elaborated}")); + err.emit(); + } + } + + let mut builder = TransitiveRelationBuilder::default(); + for &ty::OutlivesClause(r1, r2) in ®ion_outlives { + builder.add(r1, r2); + } + // Deliberately unelaborated: the assumptions of a `forall` are exactly the ones + // written down in the test, no extra ones hidden behind the scenes. + ty::region_constraint::Assumptions::new_unelaborated(type_outlives, builder.freeze()) + } + #[instrument(level = "debug", skip(self))] fn check_test_binder_region_constraints( &self, @@ -2742,6 +2783,6 @@ pub(crate) struct WithWhereClauses<'tcx, T> { // The where clauses on the forall. These eventually will probably get stored inside // `ty::Binder` but they're here for now. - pub type_outlives: Vec>>>, - pub region_outlives: Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, + pub type_outlives: Vec>, + pub region_outlives: Vec>, } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 1cd1fc356ca7d..9bac109664c6a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -372,62 +372,50 @@ impl<'tcx> ItemCtxt<'tcx> { TestBinderExists { span: exists.span, binder } } - // FIXME: this is likely too basic, and we'll want to evolve/make this more advanced over time. - // For example, right now, if the user writes `forall<'a> where Foo<'a>: 'b`, that's not gonna - // work - that should be destructured into `where 'a: 'b`, whether by hand (and checked it was - // indeed done so, via compiler) or automatically by the test framework, unsure, but something. fn lower_test_binder_assumptions( &self, predicate: &hir::WherePredicate<'tcx>, - type_outlives: &mut Vec>>>, - region_outlives: &mut Vec<(ty::Region<'tcx>, ty::Region<'tcx>)>, + type_outlives: &mut Vec>, + region_outlives: &mut Vec>, ) { + fn outlives_bounds<'tcx>( + dcx: DiagCtxtHandle<'tcx>, + bounds: hir::GenericBounds<'tcx>, + ) -> impl Iterator { + bounds.iter().flat_map(move |bound| match *bound { + rustc_hir::GenericBound::Trait(poly_trait_ref) => { + dcx.span_err( + poly_trait_ref.span, + "trait bounds aren't supported in forall where clauses", + ); + None + } + rustc_hir::GenericBound::Outlives(lifetime) => Some(lifetime), + rustc_hir::GenericBound::Use(_, span) => { + dcx.span_err(span, "use bounds aren't supported in forall where clauses"); + None + } + }) + } match predicate.kind { hir::WherePredicateKind::BoundPredicate(p) => { let bound_vars = self.tcx.late_bound_vars(predicate.hir_id); let ty = self.lower_ty(p.bounded_ty); - for bound in p.bounds { - match bound { - hir::GenericBound::Trait(poly_trait_ref) => { - self.dcx() - .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); - } - hir::GenericBound::Outlives(lifetime) => { - let region = self - .lowerer() - .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); - let binder = ty::Binder::bind_with_vars( - ty::OutlivesClause(ty, region), - bound_vars, - ); - type_outlives.push(binder); - } - hir::GenericBound::Use(_, span) => { - self.dcx().span_err(*span, "use bounds aren't supported yet"); - } - } + for lifetime in outlives_bounds(self.dcx(), p.bounds) { + let region = + self.lowerer().lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + let binder = + ty::Binder::bind_with_vars(ty::OutlivesClause(ty, region), bound_vars); + type_outlives.push(binder); } } - hir::WherePredicateKind::RegionPredicate(predicate) => { - let lhs = self - .lowerer() - .lower_lifetime(predicate.lifetime, RegionInferReason::RegionPredicate); - for bound in predicate.bounds { - match bound { - hir::GenericBound::Trait(poly_trait_ref) => { - self.dcx() - .span_err(poly_trait_ref.span, "trait bounds aren't supported yet"); - } - hir::GenericBound::Outlives(lifetime) => { - let rhs = self - .lowerer() - .lower_lifetime(lifetime, RegionInferReason::RegionPredicate); - region_outlives.push((lhs, rhs)); - } - hir::GenericBound::Use(_, span) => { - self.dcx().span_err(*span, "use bounds aren't supported yet"); - } - } + hir::WherePredicateKind::RegionPredicate(p) => { + let lhs = + self.lowerer().lower_lifetime(p.lifetime, RegionInferReason::RegionPredicate); + for lifetime in outlives_bounds(self.dcx(), p.bounds) { + let rhs = + self.lowerer().lower_lifetime(lifetime, RegionInferReason::RegionPredicate); + region_outlives.push(ty::OutlivesClause(lhs, rhs)); } } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs index 675e7e3c2a02a..530706b0653db 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/cmse.rs @@ -170,7 +170,7 @@ fn is_valid_cmse_output_layout<'tcx>(cx: LayoutCx<'tcx>, layout: TyAndLayout<'tc // Accept (transparently wrapped) scalar 64-bit primitives. matches!( - layout.peel_transparent_wrappers(&cx).ty.kind(), + layout.peel_transparent_wrappers_from_non_1zst(&cx).ty.kind(), ty::Int(ty::IntTy::I64) | ty::Uint(ty::UintTy::U64) | ty::Float(ty::FloatTy::F64) ) } diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml index 0024d8b26f1fb..2931bc0e3d524 100644 --- a/compiler/rustc_lint/Cargo.toml +++ b/compiler/rustc_lint/Cargo.toml @@ -15,6 +15,7 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index deea9e1bbc13c..2c84bebc71754 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -239,7 +239,7 @@ late_lint_methods!( ImplTraitOvercaptures: ImplTraitOvercaptures, ImplicitAutorefs: ImplicitAutorefs, ImplicitProvenanceCasts: ImplicitProvenanceCasts, - ImproperCTypesLint: ImproperCTypesLint, + ImproperCTypesLint: ImproperCTypesLint::default(), ImproperGpuKernelLint: ImproperGpuKernelLint, InteriorMutableConsts: InteriorMutableConsts, InternalEqTraitMethodImpls: InternalEqTraitMethodImpls, diff --git a/compiler/rustc_lint/src/types/improper_ctypes.rs b/compiler/rustc_lint/src/types/improper_ctypes.rs index e7fa0fe2960db..04b381261e428 100644 --- a/compiler/rustc_lint/src/types/improper_ctypes.rs +++ b/compiler/rustc_lint/src/types/improper_ctypes.rs @@ -1,3 +1,4 @@ +use std::cell::RefCell; use std::iter; use std::ops::ControlFlow; @@ -5,10 +6,11 @@ use bitflags::bitflags; use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{DiagMessage, msg}; +use rustc_hashes::Hash128; use rustc_hir::def::CtorKind; use rustc_hir::intravisit::Visitor; use rustc_hir::{self as hir, AmbigArg}; -use rustc_lint_defs::{declare_lint, declare_lint_pass}; +use rustc_lint_defs::{declare_lint, impl_lint_pass}; use rustc_middle::ty::{ self, Adt, AdtDef, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, Unnormalized, @@ -131,7 +133,48 @@ declare_lint! { "Structs do not follow the power alignment rule under repr(C)" } -declare_lint_pass!(ImproperCTypesLint => [ +/// Remembers types we already checked and found FFI-safe, so we don't check the +/// same type again every time it shows up in another function. +/// We only remember "safe" types, never "unsafe" ones. That way we never need to +/// keep the actual type around, just a fingerprint of it. +#[derive(Default)] +pub(crate) struct ImproperCTypesLint { + /// A fingerprint of the type, not the type itself. Uses a big 128-bit + /// fingerprint (not a smaller 64-bit one) so two different types can't + /// accidentally get treated as the same one. + known_safe: RefCell>, +} + +impl<'tcx> ImproperCTypesLint { + fn cache_key(cx: &LateContext<'tcx>, ty: Ty<'tcx>, flags: RootUseFlags) -> (Hash128, u8) { + (cx.tcx.type_id_hash(ty), flags.bits()) + } + + fn check_ffi_type( + &self, + cx: &LateContext<'tcx>, + ty: Ty<'tcx>, + state: VisitorState, + span: Span, + mode: CItemKind, + check: impl FnOnce() -> FfiResult<'tcx>, + ) { + let key = Self::cache_key(cx, ty, state.root_use_flags); + if self.known_safe.borrow().contains(&key) { + return; + } + + let ffi_res = check(); + + if matches!(ffi_res, FfiResult::FfiSafe) { + self.known_safe.borrow_mut().insert(key); + } + + self.process_ffi_result(cx, span, ffi_res, mode); + } +} + +impl_lint_pass!(ImproperCTypesLint => [ IMPROPER_CTYPES, IMPROPER_CTYPES_DEFINITIONS, USES_POWER_ALIGNMENT @@ -1102,9 +1145,11 @@ impl<'tcx> ImproperCTypesLint { fn check_foreign_static(&mut self, cx: &LateContext<'tcx>, id: hir::OwnerId, span: Span) { let ty = cx.tcx.type_of(id).instantiate_identity(); - let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); - let ffi_res = visitor.check_type(VisitorState::static_entry_point(), ty); - self.process_ffi_result(cx, span, ffi_res, CItemKind::Declaration); + let state = VisitorState::static_entry_point(); + self.check_ffi_type(cx, ty.skip_norm_wip(), state, span, CItemKind::Declaration, || { + let mut visitor = ImproperCTypesVisitor::new(cx, ty, CItemKind::Declaration); + visitor.check_type(state, ty) + }); } /// Check if a function's argument types and result type are "ffi-safe". @@ -1119,19 +1164,21 @@ impl<'tcx> ImproperCTypesLint { let sig = cx.tcx.instantiate_bound_regions_with_erased(sig); for (input_ty, input_hir) in iter::zip(sig.inputs(), decl.inputs) { - let input_ty = Unnormalized::new_wip(*input_ty); let state = VisitorState::fn_entry_point(fn_mode, FnPos::Arg); - let mut visitor = ImproperCTypesVisitor::new(cx, input_ty, fn_mode); - let ffi_res = visitor.check_type(state, input_ty); - self.process_ffi_result(cx, input_hir.span, ffi_res, fn_mode); + self.check_ffi_type(cx, *input_ty, state, input_hir.span, fn_mode, || { + let input_ty = Unnormalized::new_wip(*input_ty); + let mut visitor = ImproperCTypesVisitor::new(cx, input_ty, fn_mode); + visitor.check_type(state, input_ty) + }); } if let hir::FnRetTy::Return(ret_hir) = decl.output { - let output_ty = Unnormalized::new_wip(sig.output()); let state = VisitorState::fn_entry_point(fn_mode, FnPos::Ret); - let mut visitor = ImproperCTypesVisitor::new(cx, output_ty, fn_mode); - let ffi_res = visitor.check_type(state, output_ty); - self.process_ffi_result(cx, ret_hir.span, ffi_res, fn_mode); + self.check_ffi_type(cx, sig.output(), state, ret_hir.span, fn_mode, || { + let output_ty = Unnormalized::new_wip(sig.output()); + let mut visitor = ImproperCTypesVisitor::new(cx, output_ty, fn_mode); + visitor.check_type(state, output_ty) + }); } } diff --git a/compiler/rustc_target/src/callconv/s390x.rs b/compiler/rustc_target/src/callconv/s390x.rs index 0d29bc658b56d..146cfc3c6ee65 100644 --- a/compiler/rustc_target/src/callconv/s390x.rs +++ b/compiler/rustc_target/src/callconv/s390x.rs @@ -15,7 +15,8 @@ where // Contrary to X86, trailing padding is allowed on s390x. loop { - layout = layout.peel_transparent_wrappers(cx); + // We're only looking for scalar types that are non-ZST. + layout = layout.peel_transparent_wrappers_from_non_1zst(cx); return match layout.backend_repr { BackendRepr::Scalar(scalar) => match scalar.primitive() { diff --git a/compiler/rustc_target/src/callconv/wasm.rs b/compiler/rustc_target/src/callconv/wasm.rs index 3706caa6b6f44..237bc2960b17e 100644 --- a/compiler/rustc_target/src/callconv/wasm.rs +++ b/compiler/rustc_target/src/callconv/wasm.rs @@ -11,7 +11,8 @@ where C: HasDataLayout, { // The base case: a single scalar is a singleton scalar. - if !(layout.is_aggregate() || layout.peel_transparent_wrappers(cx).is_enum()) { + // We're only looking for scalar types that are non-ZST. + if !(layout.is_aggregate() || layout.peel_transparent_wrappers_from_non_1zst(cx).is_enum()) { let BackendRepr::Scalar(scalar) = layout.backend_repr else { return None; }; @@ -62,7 +63,9 @@ where { // An enum that is represented as an integer is not an aggregate to rust, but may still // need to be passed as one if its variants have any (even ZST) fields. - if !(val.layout.is_aggregate() || val.layout.peel_transparent_wrappers(cx).is_enum()) { + if !(val.layout.is_aggregate() + || val.layout.peel_transparent_wrappers_from_non_1zst(cx).is_enum()) + { return false; } diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index abb9f91fde161..8d9a980b17ec3 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -15,7 +15,8 @@ where let outer_size = layout.layout.size(); loop { - layout = layout.peel_transparent_wrappers(cx); + // We're only looking for scalar types that are non-ZST. + layout = layout.peel_transparent_wrappers_from_non_1zst(cx); return match layout.backend_repr { BackendRepr::Scalar(scalar) => match scalar.primitive() { diff --git a/src/ci/citool/src/jobs.rs b/src/ci/citool/src/jobs.rs index e371105ebdb01..b94f12a37cc77 100644 --- a/src/ci/citool/src/jobs.rs +++ b/src/ci/citool/src/jobs.rs @@ -31,6 +31,10 @@ pub struct Job { pub doc_url: Option, /// Whether the job is executed on AWS CodeBuild. pub codebuild: Option, + /// Which Python version (if any) is required. On Windows, this is typically required to run + /// LLDB. + #[serde(default)] + pub required_python_version: Option, } impl Job { @@ -167,6 +171,7 @@ fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> { free_disk, doc_url, codebuild, + required_python_version, // Carve-out configs allowed to be different. env: _, @@ -179,6 +184,7 @@ fn validate_job_database(db: &JobDatabase) -> anyhow::Result<()> { && *free_disk == auto_job.free_disk && *doc_url == auto_job.doc_url && *codebuild == auto_job.codebuild + && *required_python_version == auto_job.required_python_version { Ok(()) } else { @@ -244,6 +250,8 @@ struct GithubActionsJob { doc_url: Option, #[serde(skip_serializing_if = "Option::is_none")] codebuild: Option, + #[serde(skip_serializing_if = "Option::is_none")] + required_python_version: Option, } /// Replace GitHub context variables with environment variables in job configs. @@ -375,6 +383,7 @@ fn calculate_jobs( free_disk: job.free_disk, doc_url: job.doc_url, codebuild: job.codebuild, + required_python_version: job.required_python_version, } }) .collect(); diff --git a/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile b/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile index e7191aa31c47b..3552f4bc30e53 100644 --- a/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile +++ b/src/ci/docker/host-x86_64/test-x86_64-gnu-llvm-22/Dockerfile @@ -34,9 +34,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Install powershell (universal package) so we can test x.ps1 on Linux -# FIXME: need a "universal" version that supports libicu74, but for now it still works to ignore that dep. -RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \ - dpkg --ignore-depends=libicu72 -i powershell.deb && \ +RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.6.6/powershell_7.6.6-1.deb_amd64.deb" > powershell.deb && \ + dpkg -i powershell.deb && \ rm -f powershell.deb COPY scripts/sccache.sh /scripts/ diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml index 57432451b9798..05e17c335aaf0 100644 --- a/src/ci/github-actions/jobs.yml +++ b/src/ci/github-actions/jobs.yml @@ -670,9 +670,12 @@ auto: # x86_64-msvc is split into two jobs to run tests in parallel. - name: test-x86_64-msvc-1 + # required to run LLDB 22 + required_python_version: '3.11' env: RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-sanitizers --enable-profiler SCRIPT: make ci-msvc-py + LLDB_PATH: ./citools/clang-rust/bin/lldb.exe <<: *job-windows - name: test-x86_64-msvc-2 diff --git a/src/doc/nomicon b/src/doc/nomicon index 5791ca9f5d671..46fc44214afcd 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 5791ca9f5d671328af7a8fe87b42ca90c7211d28 +Subproject commit 46fc44214afcd159be175c8ee62887cad04f615d diff --git a/src/doc/reference b/src/doc/reference index 4245282b97496..a286e1ecb8ce1 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 4245282b97496585e73862b966d639cbb553bd6c +Subproject commit a286e1ecb8ce193d50056e4bb042eea9b23876ef diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index af5ef7024e885..dcc14f912bf87 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit af5ef7024e88587aa3be244422f6365e86c50e85 +Subproject commit dcc14f912bf8790792a2df082eddc82ab2539229 diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh index fb2007db9f12c..6304fabbbf6f5 100755 --- a/src/etc/pre-push.sh +++ b/src/etc/pre-push.sh @@ -35,7 +35,7 @@ echo "Running pre-push script $ROOT_DIR/x test tidy" cd "$ROOT_DIR" ./x test tidy \ --set build.locked-deps=true \ - --extra-checks auto:py,auto:cpp,auto:js + --extra-checks auto:py,auto:cpp,auto:js,if-installed:auto:spellcheck if [ $? -ne 0 ]; then echo "You may use \`git push --no-verify\` to skip this check." exit 1 diff --git a/tests/rustdoc-html/README.md b/tests/rustdoc-html/README.md index 4acb1d54bbb89..055c03b1eed35 100644 --- a/tests/rustdoc-html/README.md +++ b/tests/rustdoc-html/README.md @@ -48,6 +48,11 @@ conflicts, in particular for simpler crate names). Contains tests to check the display of items implementing the `Deref` and/or `DerefMut` traits. +## `tests/rustdoc-html/display` + +Contains tests checking how items are displayed in the docs. Ensuring that methods with a lot +of arguments or with a lot of generics are correctly split between multiple lines for example. + ## `tests/rustdoc-html/doc-cfg` Contains tests to check the rustdoc `doc_cfg` feature. diff --git a/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html b/tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.decl.html similarity index 100% rename from tests/rustdoc-html/decl-line-wrapping-empty-arg-list.decl.html rename to tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.decl.html diff --git a/tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs b/tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.rs similarity index 100% rename from tests/rustdoc-html/decl-line-wrapping-empty-arg-list.rs rename to tests/rustdoc-html/display/decl-line-wrapping-empty-arg-list.rs diff --git a/tests/rustdoc-html/decl-trailing-whitespace.declaration.html b/tests/rustdoc-html/display/decl-trailing-whitespace.declaration.html similarity index 100% rename from tests/rustdoc-html/decl-trailing-whitespace.declaration.html rename to tests/rustdoc-html/display/decl-trailing-whitespace.declaration.html diff --git a/tests/rustdoc-html/decl-trailing-whitespace.rs b/tests/rustdoc-html/display/decl-trailing-whitespace.rs similarity index 100% rename from tests/rustdoc-html/decl-trailing-whitespace.rs rename to tests/rustdoc-html/display/decl-trailing-whitespace.rs diff --git a/tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html b/tests/rustdoc-html/display/extremely_long_typename.extremely_long_typename.html similarity index 100% rename from tests/rustdoc-html/extremely_long_typename.extremely_long_typename.html rename to tests/rustdoc-html/display/extremely_long_typename.extremely_long_typename.html diff --git a/tests/rustdoc-html/extremely_long_typename.rs b/tests/rustdoc-html/display/extremely_long_typename.rs similarity index 100% rename from tests/rustdoc-html/extremely_long_typename.rs rename to tests/rustdoc-html/display/extremely_long_typename.rs diff --git a/tests/rustdoc-html/item-desc-list-at-start.item-table.html b/tests/rustdoc-html/display/item-desc-list-at-start.item-table.html similarity index 100% rename from tests/rustdoc-html/item-desc-list-at-start.item-table.html rename to tests/rustdoc-html/display/item-desc-list-at-start.item-table.html diff --git a/tests/rustdoc-html/item-desc-list-at-start.rs b/tests/rustdoc-html/display/item-desc-list-at-start.rs similarity index 100% rename from tests/rustdoc-html/item-desc-list-at-start.rs rename to tests/rustdoc-html/display/item-desc-list-at-start.rs diff --git a/tests/rustdoc-html/where.SWhere_Echo_impl.html b/tests/rustdoc-html/display/where.SWhere_Echo_impl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_Echo_impl.html rename to tests/rustdoc-html/display/where.SWhere_Echo_impl.html diff --git a/tests/rustdoc-html/where.SWhere_Simd_item-decl.html b/tests/rustdoc-html/display/where.SWhere_Simd_item-decl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_Simd_item-decl.html rename to tests/rustdoc-html/display/where.SWhere_Simd_item-decl.html diff --git a/tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html b/tests/rustdoc-html/display/where.SWhere_TraitWhere_item-decl.html similarity index 100% rename from tests/rustdoc-html/where.SWhere_TraitWhere_item-decl.html rename to tests/rustdoc-html/display/where.SWhere_TraitWhere_item-decl.html diff --git a/tests/rustdoc-html/where.alpha_trait_decl.html b/tests/rustdoc-html/display/where.alpha_trait_decl.html similarity index 100% rename from tests/rustdoc-html/where.alpha_trait_decl.html rename to tests/rustdoc-html/display/where.alpha_trait_decl.html diff --git a/tests/rustdoc-html/where.bravo_trait_decl.html b/tests/rustdoc-html/display/where.bravo_trait_decl.html similarity index 100% rename from tests/rustdoc-html/where.bravo_trait_decl.html rename to tests/rustdoc-html/display/where.bravo_trait_decl.html diff --git a/tests/rustdoc-html/where.charlie_fn_decl.html b/tests/rustdoc-html/display/where.charlie_fn_decl.html similarity index 100% rename from tests/rustdoc-html/where.charlie_fn_decl.html rename to tests/rustdoc-html/display/where.charlie_fn_decl.html diff --git a/tests/rustdoc-html/where.golf_type_alias_decl.html b/tests/rustdoc-html/display/where.golf_type_alias_decl.html similarity index 100% rename from tests/rustdoc-html/where.golf_type_alias_decl.html rename to tests/rustdoc-html/display/where.golf_type_alias_decl.html diff --git a/tests/rustdoc-html/where.rs b/tests/rustdoc-html/display/where.rs similarity index 100% rename from tests/rustdoc-html/where.rs rename to tests/rustdoc-html/display/where.rs diff --git a/tests/rustdoc-html/whitespace-after-where-clause.enum.html b/tests/rustdoc-html/display/whitespace-after-where-clause.enum.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.enum.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.enum.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.enum2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.enum2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.enum2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.enum2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.rs b/tests/rustdoc-html/display/whitespace-after-where-clause.rs similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.rs rename to tests/rustdoc-html/display/whitespace-after-where-clause.rs diff --git a/tests/rustdoc-html/whitespace-after-where-clause.struct.html b/tests/rustdoc-html/display/whitespace-after-where-clause.struct.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.struct.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.struct.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.struct2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.struct2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.struct2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.struct2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.trait.html b/tests/rustdoc-html/display/whitespace-after-where-clause.trait.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.trait.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.trait.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.trait2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.trait2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.trait2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.trait2.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.union.html b/tests/rustdoc-html/display/whitespace-after-where-clause.union.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.union.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.union.html diff --git a/tests/rustdoc-html/whitespace-after-where-clause.union2.html b/tests/rustdoc-html/display/whitespace-after-where-clause.union2.html similarity index 100% rename from tests/rustdoc-html/whitespace-after-where-clause.union2.html rename to tests/rustdoc-html/display/whitespace-after-where-clause.union2.html diff --git a/tests/rustdoc-html/auxiliary/rustdoc-ffi.rs b/tests/rustdoc-html/extern/auxiliary/rustdoc-ffi.rs similarity index 100% rename from tests/rustdoc-html/auxiliary/rustdoc-ffi.rs rename to tests/rustdoc-html/extern/auxiliary/rustdoc-ffi.rs diff --git a/tests/rustdoc-html/ffi.rs b/tests/rustdoc-html/extern/ffi.rs similarity index 100% rename from tests/rustdoc-html/ffi.rs rename to tests/rustdoc-html/extern/ffi.rs diff --git a/tests/rustdoc-html/foreigntype.rs b/tests/rustdoc-html/extern/foreigntype.rs similarity index 100% rename from tests/rustdoc-html/foreigntype.rs rename to tests/rustdoc-html/extern/foreigntype.rs diff --git a/tests/rustdoc-html/hidden-methods.rs b/tests/rustdoc-html/hidden-methods.rs deleted file mode 100644 index ed9c1ee1aac29..0000000000000 --- a/tests/rustdoc-html/hidden-methods.rs +++ /dev/null @@ -1,29 +0,0 @@ -#![crate_name = "foo"] - -#[doc(hidden)] -pub mod hidden { - pub struct Foo; - - impl Foo { - #[doc(hidden)] - pub fn this_should_be_hidden() {} - } - - pub struct Bar; - - impl Bar { - fn this_should_be_hidden() {} - } -} - -//@ has foo/struct.Foo.html -//@ !hasraw - 'Methods' -//@ !has - '//code' 'impl Foo' -//@ !hasraw - 'this_should_be_hidden' -pub use hidden::Foo; - -//@ has foo/struct.Bar.html -//@ !hasraw - 'Methods' -//@ !has - '//code' 'impl Bar' -//@ !hasraw - 'this_should_be_hidden' -pub use hidden::Bar; diff --git a/tests/rustdoc-html/doc-hidden-crate.rs b/tests/rustdoc-html/hidden/doc-hidden-crate.rs similarity index 100% rename from tests/rustdoc-html/doc-hidden-crate.rs rename to tests/rustdoc-html/hidden/doc-hidden-crate.rs diff --git a/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs b/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs new file mode 100644 index 0000000000000..8c89c8d6c76c5 --- /dev/null +++ b/tests/rustdoc-html/reexport/auxiliary/pub-extern-crate.rs @@ -0,0 +1,2 @@ +#![crate_name = "inner"] +pub struct SomeStruct; diff --git a/tests/rustdoc-html/auxiliary/reexp-stripped.rs b/tests/rustdoc-html/reexport/auxiliary/reexp-stripped.rs similarity index 100% rename from tests/rustdoc-html/auxiliary/reexp-stripped.rs rename to tests/rustdoc-html/reexport/auxiliary/reexp-stripped.rs diff --git a/tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs b/tests/rustdoc-html/reexport/duplicate-reexports-section-150211.rs similarity index 100% rename from tests/rustdoc-html/extern/duplicate-reexports-section-150211.rs rename to tests/rustdoc-html/reexport/duplicate-reexports-section-150211.rs diff --git a/tests/rustdoc-html/reexport/hidden-methods.rs b/tests/rustdoc-html/reexport/hidden-methods.rs new file mode 100644 index 0000000000000..4be81da1cf775 --- /dev/null +++ b/tests/rustdoc-html/reexport/hidden-methods.rs @@ -0,0 +1,40 @@ +#![crate_name = "foo"] + +#[doc(hidden)] +pub mod hidden { + pub struct Foo; + + impl Foo { + #[doc(hidden)] + pub fn this_should_be_hidden() {} + } + + pub struct Bar; + + impl Bar { + fn this_should_be_hidden() {} + } +} + +//@ has foo/struct.Foo.html +// Only `not_hidden` should be present. +//@ count - '//*[@id="implementations-list"]//*[@class="method"]' 1 +//@ has - '//*[@id="implementations-list"]//*[@class="method"]' 'pub fn not_hidden' +//@ count - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 1 +//@ has - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 'not_hidden' +pub use hidden::Foo; + +impl Foo { + pub fn not_hidden() {} +} + +//@ has foo/struct.Bar.html +//@ count - '//*[@id="implementations-list"]//*[@class="method"]' 1 +//@ has - '//*[@id="implementations-list"]//*[@class="method"]' 'pub fn not_hidden' +//@ count - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 1 +//@ has - '//*[@id="rustdoc-toc"]/*[@class="block method"]//a' 'not_hidden' +pub use hidden::Bar; + +impl Bar { + pub fn not_hidden() {} +} diff --git a/tests/rustdoc-html/redirect.rs b/tests/rustdoc-html/reexport/redirect.rs similarity index 100% rename from tests/rustdoc-html/redirect.rs rename to tests/rustdoc-html/reexport/redirect.rs diff --git a/tests/rustdoc-js-std/core-std-duplicates.js b/tests/rustdoc-js-std/core-std-duplicates.js new file mode 100644 index 0000000000000..4647ec6408746 --- /dev/null +++ b/tests/rustdoc-js-std/core-std-duplicates.js @@ -0,0 +1,21 @@ +// This test ensures that search results are not duplicated between `std` and `core`. +// Regression test for . + +// exact-check + +const EXPECTED = [ + { + 'query': 'primitive:char', + 'others': [ + { 'path': 'std', 'name': 'char' }, + ], + }, + { + 'query': 'char->u32', + 'others': [ + { 'path': 'std::u32', 'name': 'from' }, + { 'path': 'std::char', 'name': 'to_u32' }, + { 'path': 'std::char', 'name': 'to_digit' }, + ], + }, +]; diff --git a/tests/rustdoc-html/cap-lints.rs b/tests/rustdoc-ui/lints/cap-lints.rs similarity index 84% rename from tests/rustdoc-html/cap-lints.rs rename to tests/rustdoc-ui/lints/cap-lints.rs index 30f9be0424c6a..692a63f2f7332 100644 --- a/tests/rustdoc-html/cap-lints.rs +++ b/tests/rustdoc-ui/lints/cap-lints.rs @@ -1,9 +1,11 @@ // This should fail a normal compile due to non_camel_case_types, // It should pass a doc-compile as it only needs to type-check and // therefore should not concern itself with the lints. + +//@ check-pass + #[deny(warnings)] -//@ has cap_lints/struct.Foo.html //* 'Foo' pub struct Foo { field: i32, } diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs index 042deefcbb6e5..1ca1345b22037 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.rs @@ -1,6 +1,8 @@ //@ compile-flags: -Zassumptions-on-binders -Znext-solver=globally #![feature(test_binder_constraints)] -#![expect(incomplete_features)] + +trait Trait<'a> {} +struct Struct<'a>(&'a u32); core::test_binder_constraints! { impl<'a, 'b> { @@ -27,8 +29,6 @@ core::test_binder_constraints! { } } -trait Trait<'a> {} - core::test_binder_constraints! { impl<'a> { dyn for<'b> Trait<'b>: 'a, @@ -47,6 +47,7 @@ core::test_binder_constraints! { impl<'a> { forall where T: 'a { //~^ ERROR only lifetime parameters can be used in this context + //~| ERROR the lhs of a forall where clause must be an alias, placeholder, or lifetime T: 'a, //~^ ERROR the lhs of a ty outlives must be a placeholder } @@ -74,4 +75,13 @@ core::test_binder_constraints! { } } +core::test_binder_constraints! { + impl<'a> { + forall<'b> where Struct<'a>: 'b { + //~^ ERROR the lhs of a forall where clause must be an alias, placeholder, or lifetime + //~| ERROR all implied bounds of clauses must themselves be included in the where clause of a forall + } + } +} + fn main() {} diff --git a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr index ab025b0e0b9d6..4513fd1fdb2c7 100644 --- a/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr +++ b/tests/ui/assumptions_on_binders/test-infra-fails-properly.stderr @@ -1,11 +1,11 @@ error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` - --> $DIR/test-infra-fails-properly.rs:15:20 + --> $DIR/test-infra-fails-properly.rs:17:20 | LL | forall { } | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` error: expected one of `!`, `(`, `+`, `::`, `:`, or `<`, found `{` - --> $DIR/test-infra-fails-properly.rs:24:20 + --> $DIR/test-infra-fails-properly.rs:26:20 | LL | forall { } | ^ expected one of `!`, `(`, `+`, `::`, `:`, or `<` @@ -27,7 +27,7 @@ LL | forall where T: 'a { = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: higher-ranked lifetime bound could not be satisfied - --> $DIR/test-infra-fails-properly.rs:7:9 + --> $DIR/test-infra-fails-properly.rs:9:9 | LL | 'a: 'b | ^^^^^^ @@ -39,10 +39,18 @@ LL | dyn for<'b> Trait<'b>: 'a, | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: it is a (dyn for<'b> Trait<'b> + 'static) - = note: and here it is `Debug`ged :3 dyn [Binder { value: Trait(Trait<'b>), bound_vars: [Region(BrNamed(DefId(0:11 ~ test_infra_fails_properly[2377]::{test_binder_constraints#1}::'b)))] }] + 'static + = note: and here it is `Debug`ged :3 dyn [Binder { value: Trait(Trait<'b>), bound_vars: [Region(BrNamed(DefId(0:15 ~ test_infra_fails_properly[2377]::{test_binder_constraints#1}::'b)))] }] + 'static + +error: the lhs of a forall where clause must be an alias, placeholder, or lifetime + --> $DIR/test-infra-fails-properly.rs:48:9 + | +LL | forall where T: 'a { + | ^^^^^^ + | + = note: the bad clause is {type error}: 'a error: the lhs of a ty outlives must be a placeholder - --> $DIR/test-infra-fails-properly.rs:50:13 + --> $DIR/test-infra-fails-properly.rs:51:13 | LL | T: 'a, | ^^^^^ @@ -51,33 +59,49 @@ LL | T: 'a, = note: and here it is `Debug`ged :3 {type error} error: forall expect clause failed - --> $DIR/test-infra-fails-properly.rs:63:17 + --> $DIR/test-infra-fails-properly.rs:64:17 | LL | 'b: 'c, | ^^^^^^ | note: constraint from here - --> $DIR/test-infra-fails-properly.rs:58:9 + --> $DIR/test-infra-fails-properly.rs:59:9 | LL | forall<'a> where 'b: 'a { | ^^^^^^ = note: expected: RegionOutlives( 'b/#0, 'c/#1, - $DIR/test-infra-fails-properly.rs:63:17: 63:23 (#0), + $DIR/test-infra-fails-properly.rs:64:17: 64:23 (#0), ) = note: actual: RegionOutlives( 'c/#1, 'static, - $DIR/test-infra-fails-properly.rs:58:9: 58:15 (#0), + $DIR/test-infra-fails-properly.rs:59:9: 59:15 (#0), ) error: bound type test binder constraint must be alias (it's a AliasTyOutlivesViaEnv) - --> $DIR/test-infra-fails-properly.rs:72:15 + --> $DIR/test-infra-fails-properly.rs:73:15 | LL | for<> T: 'a | ^ -error: aborting due to 9 previous errors +error: the lhs of a forall where clause must be an alias, placeholder, or lifetime + --> $DIR/test-infra-fails-properly.rs:80:9 + | +LL | forall<'b> where Struct<'a>: 'b { + | ^^^^^^ + | + = note: the bad clause is for<'b> Struct<'a>: 'b + +error: all implied bounds of clauses must themselves be included in the where clause of a forall + --> $DIR/test-infra-fails-properly.rs:80:9 + | +LL | forall<'b> where Struct<'a>: 'b { + | ^^^^^^ + | + = note: missing clause is for<'b> 'a: 'b + +error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/assumptions_on_binders/test-infra-works.rs b/tests/ui/assumptions_on_binders/test-infra-works.rs index b36e16a545bb3..1fb534e99b6ee 100644 --- a/tests/ui/assumptions_on_binders/test-infra-works.rs +++ b/tests/ui/assumptions_on_binders/test-infra-works.rs @@ -82,4 +82,12 @@ core::test_binder_constraints! { } } +core::test_binder_constraints! { + impl { + forall<'a> where TParam: 'a { }, + forall<'a> where TParam::Assoc: 'a { }, + forall<'a, T> where T: 'a { }, + } +} + fn main() {} diff --git a/tests/ui/derives/attr-macro-changes-type-kind.rs b/tests/ui/derives/attr-macro-changes-type-kind.rs new file mode 100644 index 0000000000000..98e05af3b33b6 --- /dev/null +++ b/tests/ui/derives/attr-macro-changes-type-kind.rs @@ -0,0 +1,15 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/163800, +//! where the generated code always referred to `Self`, which was invalid +//! when an attribute macro rewrites the type to an enum. + +//@ check-pass +//@ proc-macro: struct-to-enum.rs + +extern crate struct_to_enum; +use struct_to_enum::*; + +#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +#[struct_to_enum::phantom] +struct Spooky; + +fn main() {} diff --git a/tests/ui/derives/auxiliary/struct-to-enum.rs b/tests/ui/derives/auxiliary/struct-to-enum.rs new file mode 100644 index 0000000000000..458d8453d5076 --- /dev/null +++ b/tests/ui/derives/auxiliary/struct-to-enum.rs @@ -0,0 +1,18 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro_attribute] +pub fn phantom(_: TokenStream, _: TokenStream) -> TokenStream { + " +mod __value_Spooky { + pub use super::Spooky::Spooky; +} +pub enum Spooky { + __Phantom(std::marker::PhantomData), + Spooky, +} +pub use self::__value_Spooky::*; + " + .parse() + .unwrap() +} diff --git a/tests/ui/derives/deriving-all-codegen.stdout b/tests/ui/derives/deriving-all-codegen.stdout index 05412aca82360..163658d2106dd 100644 --- a/tests/ui/derives/deriving-all-codegen.stdout +++ b/tests/ui/derives/deriving-all-codegen.stdout @@ -46,7 +46,7 @@ impl ::core::fmt::Debug for Empty { #[automatically_derived] impl ::core::default::Default for Empty { #[inline] - fn default() -> Self { Self } + fn default() -> Self { Empty } } #[automatically_derived] impl ::core::hash::Hash for Empty { @@ -109,7 +109,7 @@ impl ::core::fmt::Debug for Point { impl ::core::default::Default for Point { #[inline] fn default() -> Self { - Self { + Point { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -193,7 +193,7 @@ impl ::core::fmt::Debug for PackedPoint { impl ::core::default::Default for PackedPoint { #[inline] fn default() -> Self { - Self { + PackedPoint { x: ::core::default::Default::default(), y: ::core::default::Default::default(), } @@ -270,7 +270,9 @@ impl ::core::fmt::Debug for TupleSingleField { #[automatically_derived] impl ::core::default::Default for TupleSingleField { #[inline] - fn default() -> Self { Self(::core::default::Default::default()) } + fn default() -> Self { + TupleSingleField(::core::default::Default::default()) + } } #[automatically_derived] impl ::core::convert::From for TupleSingleField { @@ -343,7 +345,9 @@ impl ::core::fmt::Debug for SingleField { #[automatically_derived] impl ::core::default::Default for SingleField { #[inline] - fn default() -> Self { Self { foo: ::core::default::Default::default() } } + fn default() -> Self { + SingleField { foo: ::core::default::Default::default() } + } } #[automatically_derived] impl ::core::convert::From for SingleField { @@ -431,7 +435,7 @@ impl ::core::fmt::Debug for Big { impl ::core::default::Default for Big { #[inline] fn default() -> Self { - Self { + Big { b1: ::core::default::Default::default(), b2: ::core::default::Default::default(), b3: ::core::default::Default::default(), @@ -622,7 +626,7 @@ struct NonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for NonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { NonCopy(::core::clone::Clone::clone(&self.0)) } } // A packed struct that doesn't impl `Copy`, which means it gets the non-trivial @@ -632,7 +636,9 @@ struct PackedNonCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedNonCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedNonCopy(::core::clone::Clone::clone(&{ self.0 })) + } } // A struct that impls `Copy` manually, which means it gets the non-trivial @@ -641,7 +647,9 @@ struct ManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for ManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + ManualCopy(::core::clone::Clone::clone(&self.0)) + } } impl Copy for ManualCopy {} @@ -652,7 +660,9 @@ struct PackedManualCopy(u32); #[automatically_derived] impl ::core::clone::Clone for PackedManualCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&{ self.0 })) } + fn clone(&self) -> Self { + PackedManualCopy(::core::clone::Clone::clone(&{ self.0 })) + } } impl Copy for PackedManualCopy {} @@ -725,7 +735,7 @@ impl ::core::clone::Clone for Generic where T::A: ::core::clone::Clone { #[inline] fn clone(&self) -> Self { - Self { + Generic { t: ::core::clone::Clone::clone(&self.t), ta: ::core::clone::Clone::clone(&self.ta), u: ::core::clone::Clone::clone(&self.u), @@ -751,7 +761,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self { + Generic { t: ::core::default::Default::default(), ta: ::core::default::Default::default(), u: ::core::default::Default::default(), @@ -844,7 +854,7 @@ impl Self { - Self(::core::clone::Clone::clone(&{ self.0 }), + PackedGeneric(::core::clone::Clone::clone(&{ self.0 }), ::core::clone::Clone::clone(&{ self.1 }), ::core::clone::Clone::clone(&{ self.2 })) } @@ -871,7 +881,7 @@ impl T::A: ::core::default::Default { #[inline] fn default() -> Self { - Self(::core::default::Default::default(), + PackedGeneric(::core::default::Default::default(), ::core::default::Default::default(), ::core::default::Default::default()) } @@ -1019,7 +1029,7 @@ impl ::core::clone::Clone for Enum1 { fn clone(&self) -> Self { match self { Self::Single { x: __self_0 } => - Self::Single { x: ::core::clone::Clone::clone(__self_0) }, + Enum1::Single { x: ::core::clone::Clone::clone(__self_0) }, } } } @@ -1093,7 +1103,7 @@ enum Fieldless1 { #[automatically_derived] impl ::core::clone::Clone for Fieldless1 { #[inline] - fn clone(&self) -> Self { Self::A } + fn clone(&self) -> Self { Fieldless1::A } } #[automatically_derived] impl ::core::fmt::Debug for Fieldless1 { @@ -1408,11 +1418,11 @@ impl ::core::clone::Clone for Fielded { fn clone(&self) -> Self { match self { Self::X(__self_0) => - Self::X(::core::clone::Clone::clone(__self_0)), + Fielded::X(::core::clone::Clone::clone(__self_0)), Self::Y(__self_0) => - Self::Y(::core::clone::Clone::clone(__self_0)), + Fielded::Y(::core::clone::Clone::clone(__self_0)), Self::Z(__self_0) => - Self::Z(::core::clone::Clone::clone(__self_0)), + Fielded::Z(::core::clone::Clone::clone(__self_0)), } } } @@ -1511,9 +1521,9 @@ impl ::core::clone::Clone fn clone(&self) -> Self { match self { Self::One(__self_0) => - Self::One(::core::clone::Clone::clone(__self_0)), + EnumGeneric::One(::core::clone::Clone::clone(__self_0)), Self::Two(__self_0) => - Self::Two(::core::clone::Clone::clone(__self_0)), + EnumGeneric::Two(::core::clone::Clone::clone(__self_0)), } } } @@ -1712,7 +1722,9 @@ impl ::core::marker::Copy for FooCloneAndCopy { } #[automatically_derived] impl ::core::clone::Clone for FooCloneAndCopy { #[inline] - fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) } + fn clone(&self) -> Self { + FooCloneAndCopy(::core::clone::Clone::clone(&self.0)) + } } struct FooPartialOrdOrd(i32); diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr index efc3785878c39..e549d315e7fdb 100644 --- a/tests/ui/stats/macro-stats.stderr +++ b/tests/ui/stats/macro-stats.stderr @@ -2,11 +2,11 @@ macro-stats ==================================================================== macro-stats MACRO EXPANSION STATS: macro_stats macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes macro-stats ----------------------------------------------------------------------------------- -macro-stats #[derive(Clone)] 8 67 8.4 1_909 238.6 +macro-stats #[derive(Clone)] 8 67 8.4 1_895 236.9 macro-stats #[derive(Hash)] 2 17 8.5 536 268.0 macro-stats q! 1 26 26.0 519 519.0 macro-stats #[derive(Ord)] 1 15 15.0 505 505.0 -macro-stats #[derive(Default)] 2 16 8.0 409 204.5 +macro-stats #[derive(Default)] 2 16 8.0 407 203.5 macro-stats #[derive(Eq)] 1 11 11.0 312 312.0 macro-stats #[derive(Debug)] 1 8 8.0 277 277.0 macro-stats #[derive(PartialEq)] 1 9 9.0 269 269.0