diff --git a/Cargo.lock b/Cargo.lock index ecd26d6199c90..ea93fbd01f069 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2881,11 +2881,11 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.9.0", ] [[package]] @@ -3155,7 +3155,7 @@ name = "rustc_abi" version = "0.0.0" dependencies = [ "bitflags", - "rand 0.8.5", + "rand 0.9.0", "rand_xoshiro", "rustc_data_structures", "rustc_hashes", @@ -3789,7 +3789,7 @@ dependencies = [ name = "rustc_incremental" version = "0.0.0" dependencies = [ - "rand 0.8.5", + "rand 0.9.0", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -5176,8 +5176,8 @@ version = "0.1.0" dependencies = [ "indicatif", "num", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.9.0", + "rand_chacha 0.9.0", "rayon", ] diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 4713b3474bdb5..9cb6619adc95b 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -6,13 +6,13 @@ edition = "2024" [dependencies] # tidy-alphabetical-start bitflags = "2.4.1" -rand = { version = "0.8.4", default-features = false, optional = true } -rand_xoshiro = { version = "0.6.0", optional = true } -rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rand = { version = "0.9.0", default-features = false, optional = true } +rand_xoshiro = { version = "0.7.0", optional = true } +rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_hashes = { path = "../rustc_hashes" } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } -rustc_serialize = { path = "../rustc_serialize", optional = true } +rustc_serialize = { path = "../rustc_serialize", optional = true } rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index dc35d5eb89c95..32d398dc1605c 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -610,7 +610,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { Err(ErrorGuaranteed { .. }) => { // We don't run dropck on HIR, and dropck looks inside fields of // types, so there's no guarantee that it succeeds. We also - // can't rely on the the `ErrorGuaranteed` from `fully_perform` here + // can't rely on the `ErrorGuaranteed` from `fully_perform` here // because it comes from delay_span_bug. // // Do this inside of a probe because we don't particularly care (or want) diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl index f15d6fba5066c..95912b0160072 100644 --- a/compiler/rustc_codegen_ssa/messages.ftl +++ b/compiler/rustc_codegen_ssa/messages.ftl @@ -18,6 +18,8 @@ codegen_ssa_atomic_compare_exchange = Atomic compare-exchange intrinsic missing codegen_ssa_autodiff_without_lto = using the autodiff feature requires using fat-lto +codegen_ssa_bare_instruction_set = `#[instruction_set]` requires an argument + codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty codegen_ssa_cgu_not_recorded = @@ -52,6 +54,10 @@ codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$err codegen_ssa_error_writing_def_file = Error writing .DEF file: {$error} +codegen_ssa_expected_name_value_pair = expected name value pair + +codegen_ssa_expected_one_argument = expected one argument + codegen_ssa_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified @@ -88,9 +94,17 @@ codegen_ssa_incorrect_cgu_reuse_type = codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient. +codegen_ssa_invalid_argument = invalid argument + .help = valid inline arguments are `always` and `never` + +codegen_ssa_invalid_instruction_set = invalid instruction set specified + codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]` .note = the attribute requires exactly one argument +codegen_ssa_invalid_literal_value = invalid literal value + .label = value must be an integer between `0` and `255` + codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}` codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` @@ -217,6 +231,8 @@ codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions +codegen_ssa_multiple_instruction_set = cannot specify more than one instruction set + codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times .help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point @@ -229,6 +245,11 @@ codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't +codegen_ssa_null_on_export = `export_name` may not contain null characters + +codegen_ssa_out_of_range_integer = integer value out of range + .label = value must be between `0` and `255` + codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status} .note = {$output} @@ -236,6 +257,8 @@ codegen_ssa_read_file = failed to read file: {$message} codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer +codegen_ssa_requires_rust_abi = `#[track_caller]` requires Rust ABI + codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error} codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`) @@ -356,6 +379,9 @@ codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error} codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error} +codegen_ssa_unexpected_parameter_name = unexpected parameter name + .label = expected `{$prefix_nops}` or `{$entry_nops}` + codegen_ssa_unknown_archive_kind = Don't know how to build archive of type: {$kind} @@ -367,6 +393,8 @@ codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}` +codegen_ssa_unsupported_instruction_set = target does not support `#[instruction_set]` + codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 673740b4aab9f..90c53c347689b 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -8,8 +8,6 @@ use rustc_ast::{MetaItem, MetaItemInner, attr}; use rustc_attr_parsing::ReprAttr::ReprAlign; use rustc_attr_parsing::{AttributeKind, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::codes::*; -use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; @@ -236,13 +234,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().abi() != ExternAbi::Rust { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0737, - "`#[track_caller]` requires Rust ABI" - ) - .emit(); + tcx.dcx().emit_err(errors::RequiresRustAbi { span: attr.span() }); } if is_closure && !tcx.features().closure_track_caller() @@ -263,13 +255,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if s.as_str().contains('\0') { // `#[export_name = ...]` will be converted to a null-terminated string, // so it may not contain any null characters. - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0648, - "`export_name` may not contain null characters" - ) - .emit(); + tcx.dcx().emit_err(errors::NullOnExport { span: attr.span() }); } codegen_fn_attrs.export_name = Some(s); mixed_export_name_no_mangle_lint_state.track_export_name(attr.span()); @@ -394,47 +380,28 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { [sym::arm, sym::a32 | sym::t32] if !tcx.sess.target.has_thumb_interworking => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "target does not support `#[instruction_set]`" - ) - .emit(); + tcx.dcx().emit_err(errors::UnsuportedInstructionSet { + span: attr.span(), + }); None } [sym::arm, sym::a32] => Some(InstructionSetAttr::ArmA32), [sym::arm, sym::t32] => Some(InstructionSetAttr::ArmT32), _ => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "invalid instruction set specified", - ) - .emit(); + tcx.dcx().emit_err(errors::InvalidInstructionSet { + span: attr.span(), + }); None } } } [] => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0778, - "`#[instruction_set]` requires an argument" - ) - .emit(); + tcx.dcx().emit_err(errors::BareInstructionSet { span: attr.span() }); None } _ => { - struct_span_code_err!( - tcx.dcx(), - attr.span(), - E0779, - "cannot specify more than one instruction set" - ) - .emit(); + tcx.dcx() + .emit_err(errors::MultipleInstructionSet { span: attr.span() }); None } }) @@ -445,58 +412,38 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { let mut entry = None; for item in l { let Some(meta_item) = item.meta_item() else { - tcx.dcx().span_err(item.span(), "expected name value pair"); + tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); continue; }; let Some(name_value_lit) = meta_item.name_value_literal() else { - tcx.dcx().span_err(item.span(), "expected name value pair"); + tcx.dcx().emit_err(errors::ExpectedNameValuePair { span: item.span() }); continue; }; - fn emit_error_with_label( - tcx: TyCtxt<'_>, - span: Span, - error: impl Into, - label: impl Into, - ) { - let mut err: rustc_errors::Diag<'_, _> = - tcx.dcx().struct_span_err(span, error); - err.span_label(span, label); - err.emit(); - } - let attrib_to_write = match meta_item.name_or_empty() { sym::prefix_nops => &mut prefix, sym::entry_nops => &mut entry, _ => { - emit_error_with_label( - tcx, - item.span(), - "unexpected parameter name", - format!("expected {} or {}", sym::prefix_nops, sym::entry_nops), - ); + tcx.dcx().emit_err(errors::UnexpectedParameterName { + span: item.span(), + prefix_nops: sym::prefix_nops, + entry_nops: sym::entry_nops, + }); continue; } }; let rustc_ast::LitKind::Int(val, _) = name_value_lit.kind else { - emit_error_with_label( - tcx, - name_value_lit.span, - "invalid literal value", - "value must be an integer between `0` and `255`", - ); + tcx.dcx().emit_err(errors::InvalidLiteralValue { + span: name_value_lit.span, + }); continue; }; let Ok(val) = val.get().try_into() else { - emit_error_with_label( - tcx, - name_value_lit.span, - "integer value out of range", - "value must be between `0` and `255`", - ); + tcx.dcx() + .emit_err(errors::OutOfRangeInteger { span: name_value_lit.span }); continue; }; @@ -533,7 +480,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { inline_span = Some(attr.span()); let [item] = &items[..] else { - struct_span_code_err!(tcx.dcx(), attr.span(), E0534, "expected one argument").emit(); + tcx.dcx().emit_err(errors::ExpectedOneArgument { span: attr.span() }); return InlineAttr::None; }; @@ -542,9 +489,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else if item.has_name(sym::never) { InlineAttr::Never } else { - struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument") - .with_help("valid inline arguments are `always` and `never`") - .emit(); + tcx.dcx().emit_err(errors::InvalidArgument { span: items[0].span() }); InlineAttr::None } @@ -575,9 +520,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { if !attr.has_name(sym::optimize) { return ia; } - let err = |sp, s| struct_span_code_err!(tcx.dcx(), sp, E0722, "{}", s).emit(); if attr.is_word() { - err(attr.span(), "expected one argument"); + tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); return ia; } let Some(ref items) = attr.meta_item_list() else { @@ -586,7 +530,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { inline_span = Some(attr.span()); let [item] = &items[..] else { - err(attr.span(), "expected one argument"); + tcx.dcx().emit_err(errors::ExpectedOneArgumentOptimize { span: attr.span() }); return OptimizeAttr::Default; }; if item.has_name(sym::size) { @@ -596,7 +540,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } else if item.has_name(sym::none) { OptimizeAttr::DoNotOptimize } else { - err(item.span(), "invalid argument"); + tcx.dcx().emit_err(errors::InvalidArgumentOptimize { span: item.span() }); OptimizeAttr::Default } }); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index ccf6d12977f6a..394c80fcfbdcd 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -135,6 +135,110 @@ pub(crate) struct NoSavedObjectFile<'a> { pub cgu_name: &'a str, } +#[derive(Diagnostic)] +#[diag(codegen_ssa_requires_rust_abi, code = E0737)] +pub(crate) struct RequiresRustAbi { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_null_on_export, code = E0648)] +pub(crate) struct NullOnExport { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unsupported_instruction_set, code = E0779)] +pub(crate) struct UnsuportedInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_instruction_set, code = E0779)] +pub(crate) struct InvalidInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_bare_instruction_set, code = E0778)] +pub(crate) struct BareInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_multiple_instruction_set, code = E0779)] +pub(crate) struct MultipleInstructionSet { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_name_value_pair)] +pub(crate) struct ExpectedNameValuePair { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_unexpected_parameter_name)] +pub(crate) struct UnexpectedParameterName { + #[primary_span] + #[label] + pub span: Span, + pub prefix_nops: Symbol, + pub entry_nops: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_literal_value)] +pub(crate) struct InvalidLiteralValue { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_out_of_range_integer)] +pub(crate) struct OutOfRangeInteger { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_one_argument, code = E0534)] +pub(crate) struct ExpectedOneArgument { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_expected_one_argument, code = E0722)] +pub(crate) struct ExpectedOneArgumentOptimize { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_argument, code = E0535)] +#[help] +pub(crate) struct InvalidArgument { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa_invalid_argument, code = E0722)] +pub(crate) struct InvalidArgumentOptimize { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(codegen_ssa_copy_path_buf)] pub(crate) struct CopyPathBuf { diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 25d2a8253438c..3ef645a5f6172 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -363,7 +363,7 @@ pub trait Visitor<'v>: Sized { /// See the doc comments on [`Ty`] for an explanation of what it means for a type to be /// ambiguous. /// - /// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars. + /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars. fn visit_ty(&mut self, t: &'v Ty<'v, AmbigArg>) -> Self::Result { walk_ty(self, t) } @@ -374,7 +374,7 @@ pub trait Visitor<'v>: Sized { /// See the doc comments on [`ConstArg`] for an explanation of what it means for a const to be /// ambiguous. /// - /// The [`Visitor::visit_infer`] method should be overriden in order to handle infer vars. + /// The [`Visitor::visit_infer`] method should be overridden in order to handle infer vars. fn visit_const_arg(&mut self, c: &'v ConstArg<'v, AmbigArg>) -> Self::Result { walk_ambig_const_arg(self, c) } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 3611db7c68f16..e78801dd60149 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -78,13 +78,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } if self_ty.span.edition().at_least_rust_2021() { - let msg = "expected a type, found a trait"; - let label = "you can add the `dyn` keyword if you want a trait object"; - let mut diag = - rustc_errors::struct_span_code_err!(self.dcx(), self_ty.span, E0782, "{}", msg); + let mut diag = rustc_errors::struct_span_code_err!( + self.dcx(), + self_ty.span, + E0782, + "{}", + "expected a type, found a trait" + ); if self_ty.span.can_be_used_for_suggestions() && !self.maybe_suggest_impl_trait(self_ty, &mut diag) - && !self.maybe_suggest_dyn_trait(self_ty, label, sugg, &mut diag) + && !self.maybe_suggest_dyn_trait(self_ty, sugg, &mut diag) { self.maybe_suggest_add_generic_impl_trait(self_ty, &mut diag); } @@ -123,31 +126,62 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// For a struct or enum with an invalid bare trait object field, suggest turning + /// it into a generic type bound. fn maybe_suggest_add_generic_impl_trait( &self, self_ty: &hir::Ty<'_>, diag: &mut Diag<'_>, ) -> bool { let tcx = self.tcx(); - let msg = "you might be missing a type parameter"; - let mut sugg = vec![]; - let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; - let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); - match parent_item.kind { - hir::ItemKind::Struct(_, generics) | hir::ItemKind::Enum(_, generics) => { - sugg.push(( - generics.where_clause_span, - format!( - "", - self.tcx().sess.source_map().span_to_snippet(self_ty.span).unwrap() - ), - )); - sugg.push((self_ty.span, "T".to_string())); + let parent_hir_id = tcx.parent_hir_id(self_ty.hir_id); + let parent_item = tcx.hir_get_parent_item(self_ty.hir_id).def_id; + + let generics = match tcx.hir_node_by_def_id(parent_item) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Struct(variant, generics), .. + }) => { + if !variant.fields().iter().any(|field| field.hir_id == parent_hir_id) { + return false; + } + generics } - _ => {} + hir::Node::Item(hir::Item { kind: hir::ItemKind::Enum(def, generics), .. }) => { + if !def + .variants + .iter() + .flat_map(|variant| variant.data.fields().iter()) + .any(|field| field.hir_id == parent_hir_id) + { + return false; + } + generics + } + _ => return false, + }; + + let Ok(rendered_ty) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { + return false; + }; + + let param = "TUV" + .chars() + .map(|c| c.to_string()) + .chain((0..).map(|i| format!("P{i}"))) + .find(|s| !generics.params.iter().any(|param| param.name.ident().as_str() == s)) + .expect("we definitely can find at least one param name to generate"); + let mut sugg = vec![(self_ty.span, param.to_string())]; + if let Some(insertion_span) = generics.span_for_param_suggestion() { + sugg.push((insertion_span, format!(", {param}: {}", rendered_ty))); + } else { + sugg.push((generics.where_clause_span, format!("<{param}: {}>", rendered_ty))); } - diag.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable); + diag.multipart_suggestion_verbose( + "you might be missing a type parameter", + sugg, + Applicability::MachineApplicable, + ); true } /// Make sure that we are in the condition to suggest the blanket implementation. @@ -198,32 +232,59 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } + /// Try our best to approximate when adding `dyn` would be helpful for a bare + /// trait object. + /// + /// Right now, this is if the type is either directly nested in another ty, + /// or if it's in the tail field within a struct. This approximates what the + /// user would've gotten on edition 2015, except for the case where we have + /// an *obvious* knock-on `Sized` error. fn maybe_suggest_dyn_trait( &self, self_ty: &hir::Ty<'_>, - label: &str, sugg: Vec<(Span, String)>, diag: &mut Diag<'_>, ) -> bool { let tcx = self.tcx(); - let parent_id = tcx.hir_get_parent_item(self_ty.hir_id).def_id; - let parent_item = tcx.hir_node_by_def_id(parent_id).expect_item(); - // If the parent item is an enum, don't suggest the dyn trait. - if let hir::ItemKind::Enum(..) = parent_item.kind { - return false; - } + // Look at the direct HIR parent, since we care about the relationship between + // the type and the thing that directly encloses it. + match tcx.parent_hir_node(self_ty.hir_id) { + // These are all generally ok. Namely, when a trait object is nested + // into another expression or ty, it's either very certain that they + // missed the ty (e.g. `&Trait`) or it's not really possible to tell + // what their intention is, so let's not give confusing suggestions and + // just mention `dyn`. The user can make up their mind what to do here. + hir::Node::Ty(_) + | hir::Node::Expr(_) + | hir::Node::PatExpr(_) + | hir::Node::PathSegment(_) + | hir::Node::AssocItemConstraint(_) + | hir::Node::TraitRef(_) + | hir::Node::Item(_) + | hir::Node::WherePredicate(_) => {} - // If the parent item is a struct, check if self_ty is the last field. - if let hir::ItemKind::Struct(variant_data, _) = parent_item.kind { - if variant_data.fields().last().unwrap().ty.span != self_ty.span { - return false; + hir::Node::Field(field) => { + // Enums can't have unsized fields, fields can only have an unsized tail field. + if let hir::Node::Item(hir::Item { + kind: hir::ItemKind::Struct(variant, _), .. + }) = tcx.parent_hir_node(field.hir_id) + && variant + .fields() + .last() + .is_some_and(|tail_field| tail_field.hir_id == field.hir_id) + { + // Ok + } else { + return false; + } } + _ => return false, } // FIXME: Only emit this suggestion if the trait is dyn-compatible. diag.multipart_suggestion_verbose( - label.to_string(), + "you can add the `dyn` keyword if you want a trait object", sugg, Applicability::MachineApplicable, ); diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 754881309bf5f..4e5061f4f69e7 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -5,7 +5,7 @@ edition = "2024" [dependencies] # tidy-alphabetical-start -rand = "0.8.4" +rand = "0.9.0" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index 19cca48af6127..76a1ff3cf3828 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -108,7 +108,7 @@ use std::io::{self, ErrorKind}; use std::path::{Path, PathBuf}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use rand::{RngCore, thread_rng}; +use rand::{RngCore, rng}; use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::svh::Svh; @@ -445,7 +445,7 @@ fn copy_files(sess: &Session, target_dir: &Path, source_dir: &Path) -> Result PathBuf { let timestamp = timestamp_to_string(SystemTime::now()); debug!("generate_session_dir_path: timestamp = {}", timestamp); - let random_number = thread_rng().next_u32(); + let random_number = rng().next_u32(); debug!("generate_session_dir_path: random_number = {}", random_number); // Chop the first 3 characters off the timestamp. Those 3 bytes will be zero for a while. diff --git a/compiler/rustc_lint/src/default_could_be_derived.rs b/compiler/rustc_lint/src/default_could_be_derived.rs index 59e38a882dde5..58efca5e994ab 100644 --- a/compiler/rustc_lint/src/default_could_be_derived.rs +++ b/compiler/rustc_lint/src/default_could_be_derived.rs @@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultCouldBeDerived { return; } - // At least one of the fields with a default value have been overriden in + // At least one of the fields with a default value have been overridden in // the `Default` implementation. We suggest removing it and relying on `..` // instead. let any_default_field_given = diff --git a/library/Cargo.lock b/library/Cargo.lock index 405c69d95686e..8f174f284724f 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -146,9 +146,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index ae28ec4baa0b3..54a65c8459e96 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -3998,24 +3998,24 @@ unsafe fn atomic_umin(dst: *mut T, val: T, order: Ordering) -> T { /// /// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes /// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there -/// exist operations X and Y, both operating on some atomic object 'M' such +/// exist operations X and Y, both operating on some atomic object 'm' such /// that A is sequenced before X, Y is sequenced before B and Y observes -/// the change to M. This provides a happens-before dependence between A and B. +/// the change to m. This provides a happens-before dependence between A and B. /// /// ```text /// Thread 1 Thread 2 /// /// fence(Release); A -------------- -/// x.store(3, Relaxed); X --------- | +/// m.store(3, Relaxed); X --------- | /// | | /// | | -/// -------------> Y if x.load(Relaxed) == 3 { +/// -------------> Y if m.load(Relaxed) == 3 { /// |-------> B fence(Acquire); /// ... /// } /// ``` /// -/// Note that in the example above, it is crucial that the accesses to `x` are atomic. Fences cannot +/// Note that in the example above, it is crucial that the accesses to `m` are atomic. Fences cannot /// be used to establish synchronization among non-atomic accesses in different threads. However, /// thanks to the happens-before relationship between A and B, any non-atomic accesses that /// happen-before A are now also properly synchronized with any non-atomic accesses that diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 0ec167c2d1618..f7379c413f15e 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -73,7 +73,7 @@ fortanix-sgx-abi = { version = "0.5.0", features = [ ], public = true } [target.'cfg(target_os = "hermit")'.dependencies] -hermit-abi = { version = "0.4.0", features = [ +hermit-abi = { version = "0.5.0", features = [ 'rustc-dep-of-std', ], public = true } diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index e9339ff261c99..1191e335daadd 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -417,12 +417,12 @@ impl File { Ok(()) } - pub fn seek(&self, _pos: SeekFrom) -> io::Result { - Err(Error::from_raw_os_error(22)) + pub fn seek(&self, pos: SeekFrom) -> io::Result { + self.0.seek(pos) } pub fn tell(&self) -> io::Result { - self.seek(SeekFrom::Current(0)) + self.0.tell() } pub fn duplicate(&self) -> io::Result { diff --git a/library/std/src/sys/pal/hermit/fd.rs b/library/std/src/sys/pal/hermit/fd.rs index 79fc13bd4a87f..3d6b99cd77b54 100644 --- a/library/std/src/sys/pal/hermit/fd.rs +++ b/library/std/src/sys/pal/hermit/fd.rs @@ -2,8 +2,8 @@ use super::hermit_abi; use crate::cmp; -use crate::io::{self, IoSlice, IoSliceMut, Read}; -use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd, *}; +use crate::io::{self, IoSlice, IoSliceMut, Read, SeekFrom}; +use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use crate::sys::{cvt, unsupported}; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -66,9 +66,26 @@ impl FileDesc { true } + pub fn seek(&self, pos: SeekFrom) -> io::Result { + let (whence, pos) = match pos { + // Casting to `i64` is fine, too large values will end up as + // negative which will cause an error in `lseek`. + SeekFrom::Start(off) => (hermit_abi::SEEK_SET, off as i64), + SeekFrom::End(off) => (hermit_abi::SEEK_END, off), + SeekFrom::Current(off) => (hermit_abi::SEEK_CUR, off), + }; + let n = cvt(unsafe { hermit_abi::lseek(self.as_raw_fd(), pos as isize, whence) })?; + Ok(n as u64) + } + + pub fn tell(&self) -> io::Result { + self.seek(SeekFrom::Current(0)) + } + pub fn duplicate(&self) -> io::Result { self.duplicate_path(&[]) } + pub fn duplicate_path(&self, _path: &[u8]) -> io::Result { unsupported() } diff --git a/src/doc/unstable-book/src/language-features/default-field-values.md b/src/doc/unstable-book/src/language-features/default-field-values.md index 3143b2d7cae3d..6da6c4e6c57e4 100644 --- a/src/doc/unstable-book/src/language-features/default-field-values.md +++ b/src/doc/unstable-book/src/language-features/default-field-values.md @@ -67,7 +67,7 @@ have default field values. ## Lints When manually implementing the `Default` trait for a type that has default -field values, if any of these are overriden in the impl the +field values, if any of these are overridden in the impl the `default_overrides_default_fields` lint will trigger. This lint is in place to avoid surprising diverging behavior between `S { .. }` and `S::default()`, where using the same type in both ways could result in diff --git a/src/etc/test-float-parse/Cargo.toml b/src/etc/test-float-parse/Cargo.toml index 56cb5cddeea52..bacb9e09f3f6a 100644 --- a/src/etc/test-float-parse/Cargo.toml +++ b/src/etc/test-float-parse/Cargo.toml @@ -7,8 +7,8 @@ publish = false [dependencies] indicatif = { version = "0.17.8", default-features = false } num = "0.4.3" -rand = "0.8.5" -rand_chacha = "0.3" +rand = "0.9.0" +rand_chacha = "0.9.0" rayon = "1" [lib] diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen/fuzz.rs index 7fc999d167113..1d6c5562a14c8 100644 --- a/src/etc/test-float-parse/src/gen/fuzz.rs +++ b/src/etc/test-float-parse/src/gen/fuzz.rs @@ -6,7 +6,7 @@ use std::ops::Range; use std::sync::Mutex; use rand::Rng; -use rand::distributions::{Distribution, Standard}; +use rand::distr::{Distribution, StandardUniform}; use rand_chacha::ChaCha8Rng; use rand_chacha::rand_core::SeedableRng; @@ -47,7 +47,7 @@ impl Fuzz { impl Generator for Fuzz where - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { const SHORT_NAME: &'static str = "fuzz"; @@ -74,13 +74,13 @@ where impl Iterator for Fuzz where - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { type Item = >::WriteCtx; fn next(&mut self) -> Option { let _ = self.iter.next()?; - let i: F::Int = self.rng.gen(); + let i: F::Int = self.rng.random(); Some(F::from_bits(i)) } diff --git a/src/etc/test-float-parse/src/gen/many_digits.rs b/src/etc/test-float-parse/src/gen/many_digits.rs index aab8d5d704bec..741e11437fe29 100644 --- a/src/etc/test-float-parse/src/gen/many_digits.rs +++ b/src/etc/test-float-parse/src/gen/many_digits.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use std::marker::PhantomData; use std::ops::{Range, RangeInclusive}; -use rand::distributions::{Distribution, Uniform}; +use rand::distr::{Distribution, Uniform}; use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -40,7 +40,7 @@ impl Generator for RandDigits { fn new() -> Self { let rng = ChaCha8Rng::from_seed(SEED); - let range = Uniform::from(0..10); + let range = Uniform::try_from(0..10).unwrap(); Self { rng, iter: 0..ITERATIONS, uniform: range, marker: PhantomData } } @@ -55,11 +55,11 @@ impl Iterator for RandDigits { fn next(&mut self) -> Option { let _ = self.iter.next()?; - let num_digits = self.rng.gen_range(POSSIBLE_NUM_DIGITS); - let has_decimal = self.rng.gen_bool(0.2); - let has_exp = self.rng.gen_bool(0.2); + let num_digits = self.rng.random_range(POSSIBLE_NUM_DIGITS); + let has_decimal = self.rng.random_bool(0.2); + let has_exp = self.rng.random_bool(0.2); - let dec_pos = if has_decimal { Some(self.rng.gen_range(0..num_digits)) } else { None }; + let dec_pos = if has_decimal { Some(self.rng.random_range(0..num_digits)) } else { None }; let mut s = String::with_capacity(num_digits); @@ -75,7 +75,7 @@ impl Iterator for RandDigits { } if has_exp { - let exp = self.rng.gen_range(EXP_RANGE); + let exp = self.rng.random_range(EXP_RANGE); write!(s, "e{exp}").unwrap(); } diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index def66398d9fd1..e2f84b085c6f5 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -10,7 +10,7 @@ use std::sync::OnceLock; use std::sync::atomic::{AtomicU64, Ordering}; use std::{fmt, time}; -use rand::distributions::{Distribution, Standard}; +use rand::distr::{Distribution, StandardUniform}; use rayon::prelude::*; use time::{Duration, Instant}; use traits::{Float, Generator, Int}; @@ -132,7 +132,7 @@ fn register_float(tests: &mut Vec, cfg: &Config) where RangeInclusive: Iterator, >::Error: std::fmt::Debug, - Standard: Distribution<::Int>, + StandardUniform: Distribution<::Int>, { if F::BITS <= MAX_BITS_FOR_EXHAUUSTIVE { // Only run exhaustive tests if there is a chance of completion. diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 51e58b4e4fcfd..5434e708bb715 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,11 +1,12 @@ //! Checks the licenses of third-party dependencies. -use std::collections::HashSet; +use std::collections::{HashMap, HashSet}; use std::fs::{File, read_dir}; use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; +use cargo_metadata::semver::Version; use cargo_metadata::{Metadata, Package, PackageId}; #[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] @@ -446,6 +447,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", + "wit-bindgen-rt@0.33.0", // via wasi "writeable", "yoke", "yoke-derive", @@ -803,7 +805,17 @@ fn check_permitted_dependencies( // Check that the PERMITTED_DEPENDENCIES does not have unused entries. for permitted in permitted_dependencies { - if !deps.iter().any(|dep_id| &pkg_from_id(metadata, dep_id).name == permitted) { + fn compare(pkg: &Package, permitted: &str) -> bool { + if let Some((name, version)) = permitted.split_once("@") { + let Ok(version) = Version::parse(version) else { + return false; + }; + pkg.name == name && pkg.version == version + } else { + pkg.name == permitted + } + } + if !deps.iter().any(|dep_id| compare(pkg_from_id(metadata, dep_id), permitted)) { tidy_error!( bad, "could not find allowed package `{permitted}`\n\ @@ -814,14 +826,30 @@ fn check_permitted_dependencies( } // Get in a convenient form. - let permitted_dependencies: HashSet<_> = permitted_dependencies.iter().cloned().collect(); + let permitted_dependencies: HashMap<_, _> = permitted_dependencies + .iter() + .map(|s| { + if let Some((name, version)) = s.split_once('@') { + (name, Version::parse(version).ok()) + } else { + (*s, None) + } + }) + .collect(); for dep in deps { let dep = pkg_from_id(metadata, dep); // If this path is in-tree, we don't require it to be explicitly permitted. - if dep.source.is_some() && !permitted_dependencies.contains(dep.name.as_str()) { - tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id); - has_permitted_dep_error = true; + if dep.source.is_some() { + let is_eq = if let Some(version) = permitted_dependencies.get(dep.name.as_str()) { + if let Some(version) = version { version == &dep.version } else { true } + } else { + false + }; + if !is_eq { + tidy_error!(bad, "Dependency for {descr} not explicitly permitted: {}", dep.id); + has_permitted_dep_error = true; + } } } diff --git a/tests/ui/check-cfg/allow-same-level.rs b/tests/ui/check-cfg/allow-same-level.rs index 5eef50e08e21b..8260b57bad4df 100644 --- a/tests/ui/check-cfg/allow-same-level.rs +++ b/tests/ui/check-cfg/allow-same-level.rs @@ -3,7 +3,7 @@ // // It should work, but due to interactions between how #[cfg]s are // expanded, the lint machinery and the check-cfg impl, we -// miss the #[allow], althrough we probably shoudln't. +// miss the #[allow], althrough we probably shouldn't. // // cf. https://github.com/rust-lang/rust/issues/124735 // diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs index 5d607d82ea1ac..cc23c2c5055db 100644 --- a/tests/ui/dyn-keyword/dyn-2021-edition-error.rs +++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.rs @@ -7,6 +7,12 @@ fn function(x: &SomeTrait, y: Box) { //~^ ERROR expected a type, found a trait } +// Regression test for . +extern "C" { + fn foo() -> *const SomeTrait; + //~^ ERROR expected a type, found a trait +} + trait SomeTrait {} fn main() {} diff --git a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr index 8c4b809e76b04..b1d6385bde99e 100644 --- a/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr +++ b/tests/ui/dyn-keyword/dyn-2021-edition-error.stderr @@ -29,6 +29,17 @@ help: you can add the `dyn` keyword if you want a trait object LL | fn function(x: &SomeTrait, y: Box) { | +++ +error[E0782]: expected a type, found a trait + --> $DIR/dyn-2021-edition-error.rs:12:24 + | +LL | fn foo() -> *const SomeTrait; + | ^^^^^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | fn foo() -> *const dyn SomeTrait; + | +++ + error[E0782]: expected a type, found a trait --> $DIR/dyn-2021-edition-error.rs:6:14 | @@ -40,6 +51,6 @@ help: you can add the `dyn` keyword if you want a trait object LL | let _x: &dyn SomeTrait = todo!(); | +++ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0782`. diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs similarity index 60% rename from tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs rename to tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs index 9963b5be4f2b8..4d573b90d606d 100644 --- a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.rs +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.rs @@ -13,7 +13,6 @@ struct Foo2 { //~^ ERROR expected a type, found a trait } - enum Enum1 { A(Trait), //~^ ERROR expected a type, found a trait @@ -26,5 +25,17 @@ enum Enum2 { //~^ ERROR expected a type, found a trait } +// Regression test for . +pub struct InWhereClause +where + Trait:, {} +//~^ ERROR expected a type, found a trait + +struct HasGenerics { + f: Trait, + //~^ ERROR expected a type, found a trait + t: T, +} + fn main() {} diff --git a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr similarity index 58% rename from tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr rename to tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr index 433196919caf2..9584147bbc77f 100644 --- a/tests/ui/suggestions/suggest-struct-or-union-add-generic-impl-trait.stderr +++ b/tests/ui/dyn-keyword/suggest-struct-or-union-add-generic-impl-trait.stderr @@ -22,7 +22,7 @@ LL | b: dyn Trait, | +++ error[E0782]: expected a type, found a trait - --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:18:7 + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:17:7 | LL | A(Trait), | ^^^^^ @@ -34,7 +34,7 @@ LL ~ A(T), | error[E0782]: expected a type, found a trait - --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:25:7 + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:24:7 | LL | B(Trait), | ^^^^^ @@ -46,6 +46,29 @@ LL | A(u32), LL ~ B(T), | -error: aborting due to 4 previous errors +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:35:8 + | +LL | f: Trait, + | ^^^^^ + | +help: you might be missing a type parameter + | +LL ~ struct HasGenerics { +LL ~ f: U, + | + +error[E0782]: expected a type, found a trait + --> $DIR/suggest-struct-or-union-add-generic-impl-trait.rs:31:5 + | +LL | Trait:, {} + | ^^^^^ + | +help: you can add the `dyn` keyword if you want a trait object + | +LL | dyn Trait:, {} + | +++ + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0782`. diff --git a/tests/ui/linking/no-gc-encapsulation-symbols.rs b/tests/ui/linking/no-gc-encapsulation-symbols.rs new file mode 100644 index 0000000000000..36d69969199ce --- /dev/null +++ b/tests/ui/linking/no-gc-encapsulation-symbols.rs @@ -0,0 +1,25 @@ +// This test checks that encapsulation symbols are not garbage collected by the linker. +// LLD will remove them by default, so this test checks that we pass `-znostart-stop-gc` to LLD +// to avoid that behavior. Without that flag, the test should fail. +// This test is inspired by the behavior of the linkme crate. +// +//@ build-pass +//@ only-x86_64-unknown-linux-gnu + +unsafe extern "Rust" { + // The __start_ section name is magical for the linker, + // It will put link sections named EXTERNFNS after it. + #[link_name = "__start_EXTERNFNS"] + static SECTION_START: fn(); +} + +#[used] +#[unsafe(link_section = "EXTERNFNS")] +static EXTERN_FN_LOCAL: fn() = extern_fn; + +fn extern_fn() {} + +fn main() { + // We need to reference the SECTION_START symbol to avoid it being garbage collected + let slice = unsafe { SECTION_START }; +} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr index d9710c6e6a2f5..9357a86c4153f 100644 --- a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr @@ -20,7 +20,7 @@ error: unexpected parameter name --> $DIR/patchable-function-entry-attribute.rs:13:46 | LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] - | ^^^^^^^^^^^^^ expected prefix_nops or entry_nops + | ^^^^^^^^^^^^^ expected `prefix_nops` or `entry_nops` error: must specify at least one parameter --> $DIR/patchable-function-entry-attribute.rs:16:1 diff --git a/triagebot.toml b/triagebot.toml index e4231b2966baa..8db158b95eddc 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -274,7 +274,7 @@ trigger_files = [ [autolabel."A-rustdoc-search"] trigger_files = [ "src/librustdoc/html/static/js/search.js", - "tests/rustdoc-js", + "tests/rustdoc-js/", "tests/rustdoc-js-std", ]