diff --git a/Cargo.lock b/Cargo.lock index 1631d5362612e..a13f3bdbe2dd4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3799,18 +3799,15 @@ dependencies = [ "rustc_middle", "rustc_mir_build", "rustc_mir_transform", - "rustc_monomorphize", "rustc_parse", "rustc_passes", "rustc_pattern_analysis", - "rustc_privacy", "rustc_public", "rustc_resolve", "rustc_session", "rustc_span", "rustc_target", "rustc_trait_selection", - "rustc_ty_utils", "serde_json", "shlex", "tracing", @@ -4373,7 +4370,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", @@ -4486,7 +4482,6 @@ dependencies = [ "rustc_ast", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hir", "rustc_macros", "rustc_middle", @@ -4641,7 +4636,6 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_feature", - "rustc_fluent_macro", "rustc_fs_util", "rustc_hashes", "rustc_hir", @@ -4797,7 +4791,6 @@ dependencies = [ "rustc_abi", "rustc_data_structures", "rustc_errors", - "rustc_fluent_macro", "rustc_hashes", "rustc_hir", "rustc_index", diff --git a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs index c9da2f3b14bf9..6c52be9bd2294 100644 --- a/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs +++ b/compiler/rustc_attr_parsing/src/attributes/link_attrs.rs @@ -12,10 +12,10 @@ use super::prelude::*; use super::util::parse_single_integer; use crate::attributes::cfg::parse_cfg_entry; use crate::session_diagnostics::{ - AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ImportNameTypeRaw, ImportNameTypeX86, - IncompatibleWasmLink, InvalidLinkModifier, LinkFrameworkApple, LinkOrdinalOutOfRange, - LinkRequiresName, MultipleModifiers, NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, - WholeArchiveNeedsStatic, + AsNeededCompatibility, BundleNeedsStatic, EmptyLinkName, ExportSymbolsNeedsStatic, + ImportNameTypeRaw, ImportNameTypeX86, IncompatibleWasmLink, InvalidLinkModifier, + LinkFrameworkApple, LinkOrdinalOutOfRange, LinkRequiresName, MultipleModifiers, + NullOnLinkSection, RawDylibNoNul, RawDylibOnlyWindows, WholeArchiveNeedsStatic, }; pub(crate) struct LinkNameParser; @@ -165,6 +165,14 @@ impl CombineAttributeParser for LinkParser { cx.emit_err(BundleNeedsStatic { span }); } + (sym::export_symbols, Some(NativeLibKind::Static { export_symbols, .. })) => { + assign_modifier(export_symbols) + } + + (sym::export_symbols, _) => { + cx.emit_err(ExportSymbolsNeedsStatic { span }); + } + (sym::verbatim, _) => assign_modifier(&mut verbatim), ( @@ -190,6 +198,7 @@ impl CombineAttributeParser for LinkParser { span, &[ sym::bundle, + sym::export_symbols, sym::verbatim, sym::whole_dash_archive, sym::as_dash_needed, @@ -285,7 +294,9 @@ impl LinkParser { }; let link_kind = match link_kind { - kw::Static => NativeLibKind::Static { bundle: None, whole_archive: None }, + kw::Static => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } sym::dylib => NativeLibKind::Dylib { as_needed: None }, sym::framework => { if !sess.target.is_like_darwin { diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index fb4d9c660a190..b0a334210f746 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -909,7 +909,7 @@ pub(crate) struct RawDylibOnlyWindows { #[derive(Diagnostic)] #[diag( - "invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed" + "invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols" )] pub(crate) struct InvalidLinkModifier { #[primary_span] @@ -938,6 +938,13 @@ pub(crate) struct BundleNeedsStatic { pub span: Span, } +#[derive(Diagnostic)] +#[diag("linking modifier `export-symbols` is only compatible with `static` linking kind")] +pub(crate) struct ExportSymbolsNeedsStatic { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag("linking modifier `whole-archive` is only compatible with `static` linking kind")] pub(crate) struct WholeArchiveNeedsStatic { diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index c8109db86e2f2..5a732382c9818 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -11,10 +11,11 @@ use std::{env, fmt, fs, io, mem, str}; use find_msvc_tools; use itertools::Itertools; +use object::{Object, ObjectSection, ObjectSymbol}; use regex::Regex; use rustc_arena::TypedArena; use rustc_attr_parsing::eval_config_entry; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; use rustc_errors::{DiagCtxtHandle, LintDiagnostic}; @@ -2185,6 +2186,71 @@ fn add_rpath_args( } } +fn add_c_staticlib_symbols( + sess: &Session, + lib: &NativeLib, + out: &mut Vec<(String, SymbolExportKind)>, +) -> io::Result<()> { + let file_path = find_native_static_library(lib.name.as_str(), lib.verbatim, sess); + + let archive_map = unsafe { Mmap::map(File::open(&file_path)?)? }; + + let archive = object::read::archive::ArchiveFile::parse(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + for member in archive.members() { + let member = member.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + let data = member + .data(&*archive_map) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // clang LTO: raw LLVM bitcode + if data.starts_with(b"BC\xc0\xde") { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LLVM bitcode object in C static library (LTO not supported)", + )); + } + + let object = object::File::parse(&*data) + .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; + + // gcc / clang ELF / Mach-O LTO + if object.sections().any(|s| { + s.name().map(|n| n.starts_with(".gnu.lto_") || n == ".llvm.lto").unwrap_or(false) + }) { + return Err(io::Error::new( + io::ErrorKind::InvalidData, + "LTO object in C static library is not supported", + )); + } + + for symbol in object.symbols() { + if symbol.scope() != object::SymbolScope::Dynamic { + continue; + } + + let name = match symbol.name() { + Ok(n) => n, + Err(_) => continue, + }; + + let export_kind = match symbol.kind() { + object::SymbolKind::Text => SymbolExportKind::Text, + object::SymbolKind::Data => SymbolExportKind::Data, + _ => continue, + }; + + // FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. + // Need to be resolved. + out.push((name.to_string(), export_kind)); + } + } + + Ok(()) +} + /// Produce the linker command line containing linker path and arguments. /// /// When comments in the function say "order-(in)dependent" they mean order-dependence between @@ -2217,6 +2283,25 @@ fn linker_with_args( ); let link_output_kind = link_output_kind(sess, crate_type); + let mut export_symbols = codegen_results.crate_info.exported_symbols[&crate_type].clone(); + + if crate_type == CrateType::Cdylib { + let mut seen = FxHashSet::default(); + + for lib in &codegen_results.crate_info.used_libraries { + if let NativeLibKind::Static { export_symbols: Some(true), .. } = lib.kind + && seen.insert((lib.name, lib.verbatim)) + { + if let Err(err) = add_c_staticlib_symbols(&sess, lib, &mut export_symbols) { + sess.dcx().fatal(format!( + "failed to process C static library `{}`: {}", + lib.name, err + )); + } + } + } + } + // ------------ Early order-dependent options ------------ // If we're building something like a dynamic library then some platforms @@ -2224,11 +2309,7 @@ fn linker_with_args( // dynamic library. // Must be passed before any libraries to prevent the symbols to export from being thrown away, // at least on some platforms (e.g. windows-gnu). - cmd.export_symbols( - tmpdir, - crate_type, - &codegen_results.crate_info.exported_symbols[&crate_type], - ); + cmd.export_symbols(tmpdir, crate_type, &export_symbols); // Can be used for adding custom CRT objects or overriding order-dependent options above. // FIXME: In practice built-in target specs use this for arbitrary order-independent options, @@ -2678,7 +2759,7 @@ fn add_native_libs_from_crate( let name = lib.name.as_str(); let verbatim = lib.verbatim; match lib.kind { - NativeLibKind::Static { bundle, whole_archive } => { + NativeLibKind::Static { bundle, whole_archive, .. } => { if link_static { let bundle = bundle.unwrap_or(true); let whole_archive = whole_archive == Some(true); diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d184b6c8947c6..cae2e3b066eeb 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -33,18 +33,15 @@ rustc_metadata = { path = "../rustc_metadata" } rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_transform = { path = "../rustc_mir_transform" } -rustc_monomorphize = { path = "../rustc_monomorphize" } rustc_parse = { path = "../rustc_parse" } rustc_passes = { path = "../rustc_passes" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } -rustc_privacy = { path = "../rustc_privacy" } rustc_public = { path = "../rustc_public", features = ["rustc_internal"] } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } -rustc_ty_utils = { path = "../rustc_ty_utils" } serde_json = "1.0.59" shlex = "1.0" tracing = { version = "0.1.35" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 3059a4fefc613..3b9ca5ff7288c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -129,15 +129,11 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_middle::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_mir_transform::DEFAULT_LOCALE_RESOURCE, - rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_passes::DEFAULT_LOCALE_RESOURCE, rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE, - rustc_privacy::DEFAULT_LOCALE_RESOURCE, rustc_resolve::DEFAULT_LOCALE_RESOURCE, - rustc_session::DEFAULT_LOCALE_RESOURCE, rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, - rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6138ffc8d9544..a53eff4637ff2 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -331,6 +331,8 @@ pub enum NativeLibKind { bundle: Option, /// Whether to link static library without throwing any object files away whole_archive: Option, + /// Whether to export c static library symbols + export_symbols: Option, }, /// Dynamic library (e.g. `libfoo.so` on Linux) /// or an import library corresponding to a dynamic library (e.g. `foo.lib` on Windows/MSVC). @@ -363,8 +365,8 @@ pub enum NativeLibKind { impl NativeLibKind { pub fn has_modifiers(&self) -> bool { match self { - NativeLibKind::Static { bundle, whole_archive } => { - bundle.is_some() || whole_archive.is_some() + NativeLibKind::Static { bundle, whole_archive, export_symbols } => { + bundle.is_some() || whole_archive.is_some() || export_symbols.is_some() } NativeLibKind::Dylib { as_needed } | NativeLibKind::Framework { as_needed } diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 916618cb50496..bb22bd20ac2ac 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -55,7 +55,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec) -> Cfg { cfgs.into_iter() .map(|s| { let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); @@ -127,7 +127,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec) -> Ch for s in specs { let psess = ParseSess::emitter_with_note( - vec![rustc_parse::DEFAULT_LOCALE_RESOURCE, rustc_session::DEFAULT_LOCALE_RESOURCE], + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], format!("this occurred on the command line: `--check-cfg={s}`"), ); let filename = FileName::cfg_spec_source_code(&s); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0f60e86e0ca3c..b0272d726bc38 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -379,7 +379,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -401,7 +401,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -423,13 +423,13 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { name: String::from("b"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -445,7 +445,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -467,7 +467,7 @@ fn test_native_libs_tracking_hash_different_values() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -501,7 +501,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -528,7 +528,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { @@ -549,7 +549,7 @@ fn test_native_libs_tracking_hash_different_order() { NativeLib { name: String::from("a"), new_name: None, - kind: NativeLibKind::Static { bundle: None, whole_archive: None }, + kind: NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None }, verbatim: None, }, NativeLib { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index b160b3fe9bb3c..0c06d1be9a3fd 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -161,7 +161,7 @@ fn find_bundled_library( tcx: TyCtxt<'_>, ) -> Option { let sess = tcx.sess; - if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive } = kind + if let NativeLibKind::Static { bundle: Some(true) | None, whole_archive, .. } = kind && tcx.crate_types().iter().any(|t| matches!(t, &CrateType::Rlib | CrateType::StaticLib)) && (sess.opts.unstable_opts.packed_bundled_libs || has_cfg || whole_archive == Some(true)) { diff --git a/compiler/rustc_monomorphize/Cargo.toml b/compiler/rustc_monomorphize/Cargo.toml index 0829d52283abf..552c092ef7c46 100644 --- a/compiler/rustc_monomorphize/Cargo.toml +++ b/compiler/rustc_monomorphize/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl deleted file mode 100644 index 9c791208c0935..0000000000000 --- a/compiler/rustc_monomorphize/messages.ftl +++ /dev/null @@ -1,82 +0,0 @@ -monomorphize_abi_error_disabled_vector_type = - this function {$is_call -> - [true] call - *[false] definition - } uses {$is_scalable -> - [true] scalable - *[false] SIMD - } vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> - [true] {" "}in the caller - *[false] {""} - } - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) - -monomorphize_abi_error_unsupported_unsized_parameter = - this function {$is_call -> - [true] call - *[false] definition - } uses unsized type `{$ty}` which is not supported with the chosen ABI - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = only rustic ABIs support unsized parameters - -monomorphize_abi_error_unsupported_vector_type = - this function {$is_call -> - [true] call - *[false] definition - } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI - .label = function {$is_call -> - [true] called - *[false] defined - } here - -monomorphize_abi_required_target_feature = - this function {$is_call -> - [true] call - *[false] definition - } uses ABI "{$abi}" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> - [true] {" "}in the caller - *[false] {""} - } - .label = function {$is_call -> - [true] called - *[false] defined - } here - .help = consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable="{$required_feature}")]`) - -monomorphize_couldnt_dump_mono_stats = - unexpected error occurred while dumping monomorphization stats: {$error} - -monomorphize_encountered_error_while_instantiating = - the above error was encountered while instantiating `{$kind} {$instance}` - -monomorphize_encountered_error_while_instantiating_global_asm = - the above error was encountered while instantiating `global_asm` - -monomorphize_large_assignments = - moving {$size} bytes - .label = value moved from here - .note = the current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` - -monomorphize_no_optimized_mir = - missing optimized MIR for `{$instance}` in the crate `{$crate_name}` - .note = missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?) - -monomorphize_recursion_limit = - reached the recursion limit while instantiating `{$instance}` - .note = `{$def_path_str}` defined here - -monomorphize_start_not_found = using `fn main` requires the standard library - .help = use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]` - -monomorphize_static_initializer_cyclic = static initializer forms a cycle involving `{$head}` - .label = part of this cycle - .note = cyclic static initializers are not supported for target `{$target}` - -monomorphize_symbol_already_defined = symbol `{$symbol}` is already defined diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index 723649f22117e..d045ae0b92cba 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -3,37 +3,41 @@ use rustc_middle::ty::{Instance, Ty}; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] -#[diag(monomorphize_recursion_limit)] +#[diag("reached the recursion limit while instantiating `{$instance}`")] pub(crate) struct RecursionLimit<'tcx> { #[primary_span] pub span: Span, pub instance: Instance<'tcx>, - #[note] + #[note("`{$def_path_str}` defined here")] pub def_span: Span, pub def_path_str: String, } #[derive(Diagnostic)] -#[diag(monomorphize_no_optimized_mir)] +#[diag("missing optimized MIR for `{$instance}` in the crate `{$crate_name}`")] pub(crate) struct NoOptimizedMir { - #[note] + #[note( + "missing optimized MIR for this item (was the crate `{$crate_name}` compiled with `--emit=metadata`?)" + )] pub span: Span, pub crate_name: Symbol, pub instance: String, } #[derive(LintDiagnostic)] -#[diag(monomorphize_large_assignments)] -#[note] +#[diag("moving {$size} bytes")] +#[note( + "the current maximum size is {$limit}, but it can be customized with the move_size_limit attribute: `#![move_size_limit = \"...\"]`" +)] pub(crate) struct LargeAssignmentsLint { - #[label] + #[label("value moved from here")] pub span: Span, pub size: u64, pub limit: u64, } #[derive(Diagnostic)] -#[diag(monomorphize_symbol_already_defined)] +#[diag("symbol `{$symbol}` is already defined")] pub(crate) struct SymbolAlreadyDefined { #[primary_span] pub span: Option, @@ -41,13 +45,13 @@ pub(crate) struct SymbolAlreadyDefined { } #[derive(Diagnostic)] -#[diag(monomorphize_couldnt_dump_mono_stats)] +#[diag("unexpected error occurred while dumping monomorphization stats: {$error}")] pub(crate) struct CouldntDumpMonoStats { pub error: String, } #[derive(Diagnostic)] -#[diag(monomorphize_encountered_error_while_instantiating)] +#[diag("the above error was encountered while instantiating `{$kind} {$instance}`")] pub(crate) struct EncounteredErrorWhileInstantiating<'tcx> { #[primary_span] pub span: Span, @@ -56,23 +60,41 @@ pub(crate) struct EncounteredErrorWhileInstantiating<'tcx> { } #[derive(Diagnostic)] -#[diag(monomorphize_encountered_error_while_instantiating_global_asm)] +#[diag("the above error was encountered while instantiating `global_asm`")] pub(crate) struct EncounteredErrorWhileInstantiatingGlobalAsm { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(monomorphize_start_not_found)] -#[help] +#[diag("using `fn main` requires the standard library")] +#[help( + "use `#![no_main]` to bypass the Rust generated entrypoint and declare a platform specific entrypoint yourself, usually with `#[no_mangle]`" +)] pub(crate) struct StartNotFound; #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_disabled_vector_type)] -#[help] +#[diag("this function {$is_call -> + [true] call + *[false] definition +} uses {$is_scalable -> + [true] scalable + *[false] SIMD +} vector type `{$ty}` which (with the chosen ABI) requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {\" \"}in the caller + *[false] {\"\"} +}")] +#[help( + "consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable=\"{$required_feature}\")]`)" +)] pub(crate) struct AbiErrorDisabledVectorType<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub required_feature: &'a str, pub ty: Ty<'a>, @@ -83,11 +105,21 @@ pub(crate) struct AbiErrorDisabledVectorType<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_unsupported_unsized_parameter)] -#[help] +#[diag( + "this function {$is_call -> + [true] call + *[false] definition + } uses unsized type `{$ty}` which is not supported with the chosen ABI" +)] +#[help("only rustic ABIs support unsized parameters")] pub(crate) struct AbiErrorUnsupportedUnsizedParameter<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub ty: Ty<'a>, /// Whether this is a problem at a call site or at a declaration. @@ -95,10 +127,20 @@ pub(crate) struct AbiErrorUnsupportedUnsizedParameter<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_error_unsupported_vector_type)] +#[diag( + "this function {$is_call -> + [true] call + *[false] definition + } uses SIMD vector type `{$ty}` which is not currently supported with the chosen ABI" +)] pub(crate) struct AbiErrorUnsupportedVectorType<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> + [true] called + *[false] defined + } here" + )] pub span: Span, pub ty: Ty<'a>, /// Whether this is a problem at a call site or at a declaration. @@ -106,11 +148,24 @@ pub(crate) struct AbiErrorUnsupportedVectorType<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_abi_required_target_feature)] -#[help] +#[diag("this function {$is_call -> + [true] call + *[false] definition +} uses ABI \"{$abi}\" which requires the `{$required_feature}` target feature, which is not enabled{$is_call -> + [true] {\" \"}in the caller + *[false] {\"\"} +}")] +#[help( + "consider enabling it globally (`-C target-feature=+{$required_feature}`) or locally (`#[target_feature(enable=\"{$required_feature}\")]`)" +)] pub(crate) struct AbiRequiredTargetFeature<'a> { #[primary_span] - #[label] + #[label( + "function {$is_call -> +[true] called +*[false] defined +} here" + )] pub span: Span, pub required_feature: &'a str, pub abi: &'a str, @@ -119,12 +174,12 @@ pub(crate) struct AbiRequiredTargetFeature<'a> { } #[derive(Diagnostic)] -#[diag(monomorphize_static_initializer_cyclic)] -#[note] +#[diag("static initializer forms a cycle involving `{$head}`")] +#[note("cyclic static initializers are not supported for target `{$target}`")] pub(crate) struct StaticInitializerCyclic<'a> { #[primary_span] pub span: Span, - #[label] + #[label("part of this cycle")] pub labels: Vec, pub head: &'a str, pub target: &'a str, diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 30f6934bb9372..51753563b67c9 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -20,8 +20,6 @@ mod mono_checks; mod partitioning; mod util; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index c8bfdb913041c..ff59c19b6bb66 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -8,7 +8,6 @@ edition = "2024" rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl deleted file mode 100644 index 43c34a109d721..0000000000000 --- a/compiler/rustc_privacy/messages.ftl +++ /dev/null @@ -1,39 +0,0 @@ -privacy_field_is_private = - {$len -> - [1] field - *[other] fields - } {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> - [1] is - *[other] are - } private - .label = in this type -privacy_field_is_private_is_update_syntax_label = {$rest_len -> - [1] field - *[other] fields - } {$rest_field_names} {$rest_len -> - [1] is - *[other] are - } private -privacy_field_is_private_label = private field - -privacy_from_private_dep_in_public_interface = - {$kind} `{$descr}` from private dependency '{$krate}' in public interface - -privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface - .label = can't leak {$vis_descr} {$kind} - .visibility_label = `{$descr}` declared as {$vis_descr} - -privacy_item_is_private = {$kind} `{$descr}` is private - .label = private {$kind} - -privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` - .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` - .ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}` - -privacy_report_effective_visibility = {$descr} - -privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named - .label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}` - -privacy_unnamed_item_is_private = {$kind} is private - .label = private {$kind} diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index 4d1d58c08528c..af4f0d61aa11e 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -4,11 +4,17 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] -#[diag(privacy_field_is_private, code = E0451)] +#[diag("{$len -> + [1] field + *[other] fields +} {$field_names} of {$variant_descr} `{$def_path_str}` {$len -> + [1] is + *[other] are +} private", code = E0451)] pub(crate) struct FieldIsPrivate { #[primary_span] pub span: MultiSpan, - #[label] + #[label("in this type")] pub struct_span: Option, pub field_names: String, pub variant_descr: &'static str, @@ -20,14 +26,22 @@ pub(crate) struct FieldIsPrivate { #[derive(Subdiagnostic)] pub(crate) enum FieldIsPrivateLabel { - #[label(privacy_field_is_private_is_update_syntax_label)] + #[label( + "{$rest_len -> + [1] field + *[other] fields + } {$rest_field_names} {$rest_len -> + [1] is + *[other] are + } private" + )] IsUpdateSyntax { #[primary_span] span: Span, rest_field_names: String, rest_len: usize, }, - #[label(privacy_field_is_private_label)] + #[label("private field")] Other { #[primary_span] span: Span, @@ -35,17 +49,17 @@ pub(crate) enum FieldIsPrivateLabel { } #[derive(Diagnostic)] -#[diag(privacy_item_is_private)] +#[diag("{$kind} `{$descr}` is private")] pub(crate) struct ItemIsPrivate<'a> { #[primary_span] - #[label] + #[label("private {$kind}")] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, } #[derive(Diagnostic)] -#[diag(privacy_unnamed_item_is_private)] +#[diag("{$kind} is private")] pub(crate) struct UnnamedItemIsPrivate { #[primary_span] pub span: Span, @@ -53,20 +67,20 @@ pub(crate) struct UnnamedItemIsPrivate { } #[derive(Diagnostic)] -#[diag(privacy_in_public_interface, code = E0446)] +#[diag("{$vis_descr} {$kind} `{$descr}` in public interface", code = E0446)] pub(crate) struct InPublicInterface<'a> { #[primary_span] - #[label] + #[label("can't leak {$vis_descr} {$kind}")] pub span: Span, pub vis_descr: &'static str, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, - #[label(privacy_visibility_label)] + #[label("`{$descr}` declared as {$vis_descr}")] pub vis_span: Span, } #[derive(Diagnostic)] -#[diag(privacy_report_effective_visibility)] +#[diag("{$descr}")] pub(crate) struct ReportEffectiveVisibility { #[primary_span] pub span: Span, @@ -74,7 +88,7 @@ pub(crate) struct ReportEffectiveVisibility { } #[derive(LintDiagnostic)] -#[diag(privacy_from_private_dep_in_public_interface)] +#[diag("{$kind} `{$descr}` from private dependency '{$krate}' in public interface")] pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -82,9 +96,11 @@ pub(crate) struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[diag(privacy_unnameable_types_lint)] +#[diag("{$kind} `{$descr}` is reachable but cannot be named")] pub(crate) struct UnnameableTypesLint<'a> { - #[label] + #[label( + "reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}`" + )] pub span: Span, pub kind: &'a str, pub descr: DiagArgFromDisplay<'a>, @@ -96,14 +112,14 @@ pub(crate) struct UnnameableTypesLint<'a> { // They will replace private-in-public errors and compatibility lints in future. // See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details. #[derive(LintDiagnostic)] -#[diag(privacy_private_interface_or_bounds_lint)] +#[diag("{$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`")] pub(crate) struct PrivateInterfacesOrBoundsLint<'a> { - #[label(privacy_item_label)] + #[label("{$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`")] pub item_span: Span, pub item_kind: &'a str, pub item_descr: DiagArgFromDisplay<'a>, pub item_vis_descr: &'a str, - #[note(privacy_ty_note)] + #[note("but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`")] pub ty_span: Span, pub ty_kind: &'a str, pub ty_descr: DiagArgFromDisplay<'a>, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3336775210233..4a88ea0cc4450 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -39,8 +39,6 @@ use rustc_span::hygiene::Transparency; use rustc_span::{Ident, Span, Symbol, sym}; use tracing::debug; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - //////////////////////////////////////////////////////////////////////////////// // Generic infrastructure used to implement specific visitors below. //////////////////////////////////////////////////////////////////////////////// diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index aebac3880d2fd..d66e04f581069 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -12,7 +12,6 @@ rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl deleted file mode 100644 index 5c851cb90a667..0000000000000 --- a/compiler/rustc_session/messages.ftl +++ /dev/null @@ -1,149 +0,0 @@ -session_apple_deployment_target_invalid = - failed to parse deployment target specified in {$env_var}: {$error} - -session_apple_deployment_target_too_low = - deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min} - -session_binary_float_literal_not_supported = binary float literal is not supported -session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only supported on aarch64 - -session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static` - -session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}` - -session_cli_feature_diagnostic_help = - add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable - -session_crate_name_empty = crate name must not be empty - -session_embed_source_insufficient_dwarf_version = `-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version} - -session_embed_source_requires_debug_info = `-Zembed-source=y` requires debug information to be enabled - -session_expr_parentheses_needed = parentheses are required to parse this as an expression - -session_failed_to_create_profiler = failed to create profiler: {$err} - -session_feature_diagnostic_for_issue = - see issue #{$n} for more information - -session_feature_diagnostic_help = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_diagnostic_suggestion = - add `#![feature({$feature})]` to the crate attributes to enable - -session_feature_suggest_upgrade_compiler = - this compiler was built on {$date}; consider upgrading it if it is out of date - -session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions - -session_file_write_fail = failed to write `{$path}` due to error `{$err}` - -session_function_return_requires_x86_or_x86_64 = `-Zfunction-return` (except `keep`) is only supported on x86 and x86_64 - -session_function_return_thunk_extern_requires_non_large_code_model = `-Zfunction-return=thunk-extern` is only supported on non-large code models - -session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported - -session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target - .note = compatible flavors are: {$compatible_list} - -session_indirect_branch_cs_prefix_requires_x86_or_x86_64 = `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64 - -session_instrumentation_not_supported = {$us} instrumentation is not supported for this target - -session_int_literal_too_large = integer literal is too large - .note = value exceeds limit of `{$limit}` - -session_invalid_character_in_crate_name = invalid character {$character} in crate name: `{$crate_name}` - -session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -session_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - -session_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - -session_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - -session_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - -session_linker_plugin_lto_windows_not_supported = linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets - -session_must_be_name_of_associated_function = must be a name of an associated function - -session_not_circumvent_feature = `-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine - -session_not_supported = not supported - -session_octal_float_literal_not_supported = octal float literal is not supported - -session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist - -session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist - -session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi` - -session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi` - -session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto` - -session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1` - -session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi` - -session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort` - -session_sanitizer_not_supported = {$us} sanitizer is not supported for this target - -session_sanitizers_not_supported = {$us} sanitizers are not supported for this target - -session_skipping_const_checks = skipping const checks - -session_soft_float_deprecated = - `-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead - .note = it will be removed or ignored in a future version of Rust -session_soft_float_deprecated_issue = see issue #129893 for more information - -session_soft_float_ignored = - `-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets - .note = this may become a hard error in a future version of Rust - -session_split_debuginfo_unstable_platform = `-Csplit-debuginfo={$debuginfo}` is unstable on this platform - -session_split_lto_unit_requires_lto = `-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto` - -session_target_requires_unwind_tables = target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no` - -session_target_small_data_threshold_not_supported = `-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored - -session_target_stack_protector_not_supported = `-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored - -session_unexpected_builtin_cfg = unexpected `--cfg {$cfg}` flag - .controlled_by = config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}` - .incoherent = manually setting a built-in cfg can and does create incoherent behaviors - -session_unleashed_feature_help_named = skipping check for `{$gate}` feature -session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate - -session_unstable_virtual_function_elimination = `-Zvirtual-function-elimination` requires `-Clto` - -session_unsupported_dwarf_version = requested DWARF version {$dwarf_version} is not supported -session_unsupported_dwarf_version_help = supported DWARF versions are 2, 3, 4 and 5 - -session_unsupported_reg_struct_return_arch = `-Zreg-struct-return` is only supported on x86 -session_unsupported_regparm = `-Zregparm={$regparm}` is unsupported (valid values 0-3) -session_unsupported_regparm_arch = `-Zregparm=N` is only supported on x86 diff --git a/compiler/rustc_session/src/config/native_libs.rs b/compiler/rustc_session/src/config/native_libs.rs index 71d3e222c8a15..28e2d0f94104b 100644 --- a/compiler/rustc_session/src/config/native_libs.rs +++ b/compiler/rustc_session/src/config/native_libs.rs @@ -53,7 +53,9 @@ fn parse_native_lib(cx: &ParseNativeLibCx<'_>, value: &str) -> NativeLib { let NativeLibParts { kind, modifiers, name, new_name } = split_native_lib_value(value); let kind = kind.map_or(NativeLibKind::Unspecified, |kind| match kind { - "static" => NativeLibKind::Static { bundle: None, whole_archive: None }, + "static" => { + NativeLibKind::Static { bundle: None, whole_archive: None, export_symbols: None } + } "dylib" => NativeLibKind::Dylib { as_needed: None }, "framework" => NativeLibKind::Framework { as_needed: None }, "link-arg" => { @@ -105,7 +107,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li Some(("-", m)) => (m, false), _ => cx.early_dcx.early_fatal( "invalid linking modifier syntax, expected '+' or '-' prefix \ - before one of: bundle, verbatim, whole-archive, as-needed", + before one of: bundle, verbatim, whole-archive, as-needed, export-symbols", ), }; @@ -125,6 +127,13 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li ("bundle", _) => early_dcx .early_fatal("linking modifier `bundle` is only compatible with `static` linking kind"), + ("export-symbols", NativeLibKind::Static { export_symbols, .. }) => { + assign_modifier(export_symbols) + } + ("export-symbols", _) => early_dcx.early_fatal( + "linking modifier `export-symbols` is only compatible with `static` linking kind", + ), + ("verbatim", _) => assign_modifier(&mut native_lib.verbatim), ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => { @@ -151,7 +160,7 @@ fn parse_and_apply_modifier(cx: &ParseNativeLibCx<'_>, modifier: &str, native_li _ => early_dcx.early_fatal(format!( "unknown linking modifier `{modifier}`, expected one \ - of: bundle, verbatim, whole-archive, as-needed" + of: bundle, verbatim, whole-archive, as-needed, export-symbols" )), } } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 54e792fd7b59d..0c6a33f228082 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -15,9 +15,11 @@ use crate::parse::ParseSess; #[derive(Diagnostic)] pub(crate) enum AppleDeploymentTarget { - #[diag(session_apple_deployment_target_invalid)] + #[diag("failed to parse deployment target specified in {$env_var}: {$error}")] Invalid { env_var: &'static str, error: ParseIntError }, - #[diag(session_apple_deployment_target_too_low)] + #[diag( + "deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}" + )] TooLow { env_var: &'static str, version: String, os_min: String }, } @@ -34,13 +36,13 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for FeatureGateError { } #[derive(Subdiagnostic)] -#[note(session_feature_diagnostic_for_issue)] +#[note("see issue #{$n} for more information")] pub(crate) struct FeatureDiagnosticForIssue { pub(crate) n: NonZero, } #[derive(Subdiagnostic)] -#[note(session_feature_suggest_upgrade_compiler)] +#[note("this compiler was built on {$date}; consider upgrading it if it is out of date")] pub(crate) struct SuggestUpgradeCompiler { date: &'static str, } @@ -58,14 +60,14 @@ impl SuggestUpgradeCompiler { } #[derive(Subdiagnostic)] -#[help(session_feature_diagnostic_help)] +#[help("add `#![feature({$feature})]` to the crate attributes to enable")] pub(crate) struct FeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Subdiagnostic)] #[suggestion( - session_feature_diagnostic_suggestion, + "add `#![feature({$feature})]` to the crate attributes to enable", applicability = "maybe-incorrect", code = "#![feature({feature})]\n" )] @@ -76,169 +78,181 @@ pub struct FeatureDiagnosticSuggestion { } #[derive(Subdiagnostic)] -#[help(session_cli_feature_diagnostic_help)] +#[help("add `-Zcrate-attr=\"feature({$feature})\"` to the command-line options to enable")] pub(crate) struct CliFeatureDiagnosticHelp { pub(crate) feature: Symbol, } #[derive(Diagnostic)] -#[diag(session_must_be_name_of_associated_function)] +#[diag("must be a name of an associated function")] pub struct MustBeNameOfAssociatedFunction { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(session_not_circumvent_feature)] +#[diag( + "`-Zunleash-the-miri-inside-of-you` may not be used to circumvent feature gates, except when testing error paths in the CTFE engine" +)] pub(crate) struct NotCircumventFeature; #[derive(Diagnostic)] -#[diag(session_linker_plugin_lto_windows_not_supported)] +#[diag( + "linker plugin based LTO is not supported together with `-C prefer-dynamic` when targeting Windows-like targets" +)] pub(crate) struct LinkerPluginToWindowsNotSupported; #[derive(Diagnostic)] -#[diag(session_profile_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-use` does not exist")] pub(crate) struct ProfileUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_profile_sample_use_file_does_not_exist)] +#[diag("file `{$path}` passed to `-C profile-sample-use` does not exist")] pub(crate) struct ProfileSampleUseFileDoesNotExist<'a> { pub(crate) path: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_target_requires_unwind_tables)] +#[diag("target requires unwind tables, they cannot be disabled with `-C force-unwind-tables=no`")] pub(crate) struct TargetRequiresUnwindTables; #[derive(Diagnostic)] -#[diag(session_instrumentation_not_supported)] +#[diag("{$us} instrumentation is not supported for this target")] pub(crate) struct InstrumentationNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizer_not_supported)] +#[diag("{$us} sanitizer is not supported for this target")] pub(crate) struct SanitizerNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_sanitizers_not_supported)] +#[diag("{$us} sanitizers are not supported for this target")] pub(crate) struct SanitizersNotSupported { pub(crate) us: String, } #[derive(Diagnostic)] -#[diag(session_cannot_mix_and_match_sanitizers)] +#[diag("`-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`")] pub(crate) struct CannotMixAndMatchSanitizers { pub(crate) first: String, pub(crate) second: String, } #[derive(Diagnostic)] -#[diag(session_cannot_enable_crt_static_linux)] +#[diag( + "sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`" +)] pub(crate) struct CannotEnableCrtStaticLinux; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_lto)] +#[diag("`-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`")] pub(crate) struct SanitizerCfiRequiresLto; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_requires_single_codegen_unit)] +#[diag("`-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`")] pub(crate) struct SanitizerCfiRequiresSingleCodegenUnit; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] +#[diag("`-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`")] pub(crate) struct SanitizerCfiCanonicalJumpTablesRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiGeneralizePointersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] +#[diag("`-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerCfiNormalizeIntegersRequiresCfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_arity_requires_kcfi)] +#[diag("`-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`")] pub(crate) struct SanitizerKcfiArityRequiresKcfi; #[derive(Diagnostic)] -#[diag(session_sanitizer_kcfi_requires_panic_abort)] +#[diag("`-Z sanitizer=kcfi` requires `-C panic=abort`")] pub(crate) struct SanitizerKcfiRequiresPanicAbort; #[derive(Diagnostic)] -#[diag(session_split_lto_unit_requires_lto)] +#[diag("`-Zsplit-lto-unit` requires `-Clto`, `-Clto=thin`, or `-Clinker-plugin-lto`")] pub(crate) struct SplitLtoUnitRequiresLto; #[derive(Diagnostic)] -#[diag(session_unstable_virtual_function_elimination)] +#[diag("`-Zvirtual-function-elimination` requires `-Clto`")] pub(crate) struct UnstableVirtualFunctionElimination; #[derive(Diagnostic)] -#[diag(session_unsupported_dwarf_version)] -#[help(session_unsupported_dwarf_version_help)] +#[diag("requested DWARF version {$dwarf_version} is not supported")] +#[help("supported DWARF versions are 2, 3, 4 and 5")] pub(crate) struct UnsupportedDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_insufficient_dwarf_version)] +#[diag( + "`-Zembed-source=y` requires at least `-Z dwarf-version=5` but DWARF version is {$dwarf_version}" +)] pub(crate) struct EmbedSourceInsufficientDwarfVersion { pub(crate) dwarf_version: u32, } #[derive(Diagnostic)] -#[diag(session_embed_source_requires_debug_info)] +#[diag("`-Zembed-source=y` requires debug information to be enabled")] pub(crate) struct EmbedSourceRequiresDebugInfo; #[derive(Diagnostic)] -#[diag(session_target_stack_protector_not_supported)] +#[diag( + "`-Z stack-protector={$stack_protector}` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct StackProtectorNotSupportedForTarget<'a> { pub(crate) stack_protector: StackProtector, pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_target_small_data_threshold_not_supported)] +#[diag( + "`-Z small-data-threshold` is not supported for target {$target_triple} and will be ignored" +)] pub(crate) struct SmallDataThresholdNotSupportedForTarget<'a> { pub(crate) target_triple: &'a TargetTuple, } #[derive(Diagnostic)] -#[diag(session_branch_protection_requires_aarch64)] +#[diag("`-Zbranch-protection` is only supported on aarch64")] pub(crate) struct BranchProtectionRequiresAArch64; #[derive(Diagnostic)] -#[diag(session_split_debuginfo_unstable_platform)] +#[diag("`-Csplit-debuginfo={$debuginfo}` is unstable on this platform")] pub(crate) struct SplitDebugInfoUnstablePlatform { pub(crate) debuginfo: SplitDebuginfo, } #[derive(Diagnostic)] -#[diag(session_file_is_not_writeable)] +#[diag("output file {$file} is not writeable -- check its permissions")] pub(crate) struct FileIsNotWriteable<'a> { pub(crate) file: &'a std::path::Path, } #[derive(Diagnostic)] -#[diag(session_file_write_fail)] +#[diag("failed to write `{$path}` due to error `{$err}`")] pub(crate) struct FileWriteFail<'a> { pub(crate) path: &'a std::path::Path, pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_crate_name_empty)] +#[diag("crate name must not be empty")] pub(crate) struct CrateNameEmpty { #[primary_span] pub(crate) span: Option, } #[derive(Diagnostic)] -#[diag(session_invalid_character_in_crate_name)] +#[diag("invalid character {$character} in crate name: `{$crate_name}`")] pub(crate) struct InvalidCharacterInCrateName { #[primary_span] pub(crate) span: Option, @@ -247,7 +261,10 @@ pub(crate) struct InvalidCharacterInCrateName { } #[derive(Subdiagnostic)] -#[multipart_suggestion(session_expr_parentheses_needed, applicability = "machine-applicable")] +#[multipart_suggestion( + "parentheses are required to parse this as an expression", + applicability = "machine-applicable" +)] pub struct ExprParenthesesNeeded { #[suggestion_part(code = "(")] left: Span, @@ -262,7 +279,7 @@ impl ExprParenthesesNeeded { } #[derive(Diagnostic)] -#[diag(session_skipping_const_checks)] +#[diag("skipping const checks")] pub(crate) struct SkippingConstChecks { #[subdiagnostic] pub(crate) unleashed_features: Vec, @@ -270,13 +287,13 @@ pub(crate) struct SkippingConstChecks { #[derive(Subdiagnostic)] pub(crate) enum UnleashedFeatureHelp { - #[help(session_unleashed_feature_help_named)] + #[help("skipping check for `{$gate}` feature")] Named { #[primary_span] span: Span, gate: Symbol, }, - #[help(session_unleashed_feature_help_unnamed)] + #[help("skipping check that does not even have a feature gate")] Unnamed { #[primary_span] span: Span, @@ -284,10 +301,10 @@ pub(crate) enum UnleashedFeatureHelp { } #[derive(Diagnostic)] -#[diag(session_invalid_literal_suffix)] +#[diag("suffixes on {$kind} literals are invalid")] struct InvalidLiteralSuffix<'a> { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, // FIXME(#100717) kind: &'a str, @@ -295,8 +312,8 @@ struct InvalidLiteralSuffix<'a> { } #[derive(Diagnostic)] -#[diag(session_invalid_int_literal_width)] -#[help] +#[diag("invalid width `{$width}` for integer literal")] +#[help("valid widths are 8, 16, 32, 64 and 128")] struct InvalidIntLiteralWidth { #[primary_span] span: Span, @@ -304,28 +321,32 @@ struct InvalidIntLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_base_prefix)] -#[note] +#[diag("invalid base prefix for number literal")] +#[note("base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase")] struct InvalidNumLiteralBasePrefix { #[primary_span] - #[suggestion(applicability = "maybe-incorrect", code = "{fixed}")] + #[suggestion( + "try making the prefix lowercase", + applicability = "maybe-incorrect", + code = "{fixed}" + )] span: Span, fixed: String, } #[derive(Diagnostic)] -#[diag(session_invalid_num_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for number literal")] +#[help("the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.)")] struct InvalidNumLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_width)] -#[help] +#[diag("invalid width `{$width}` for float literal")] +#[help("valid widths are 32 and 64")] struct InvalidFloatLiteralWidth { #[primary_span] span: Span, @@ -333,18 +354,18 @@ struct InvalidFloatLiteralWidth { } #[derive(Diagnostic)] -#[diag(session_invalid_float_literal_suffix)] -#[help] +#[diag("invalid suffix `{$suffix}` for float literal")] +#[help("valid suffixes are `f32` and `f64`")] struct InvalidFloatLiteralSuffix { #[primary_span] - #[label] + #[label("invalid suffix `{$suffix}`")] span: Span, suffix: String, } #[derive(Diagnostic)] -#[diag(session_int_literal_too_large)] -#[note] +#[diag("integer literal is too large")] +#[note("value exceeds limit of `{$limit}`")] struct IntLiteralTooLarge { #[primary_span] span: Span, @@ -352,26 +373,26 @@ struct IntLiteralTooLarge { } #[derive(Diagnostic)] -#[diag(session_hexadecimal_float_literal_not_supported)] +#[diag("hexadecimal float literal is not supported")] struct HexadecimalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_octal_float_literal_not_supported)] +#[diag("octal float literal is not supported")] struct OctalFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } #[derive(Diagnostic)] -#[diag(session_binary_float_literal_not_supported)] +#[diag("binary float literal is not supported")] struct BinaryFloatLiteralNotSupported { #[primary_span] - #[label(session_not_supported)] + #[label("not supported")] span: Span, } @@ -457,60 +478,60 @@ pub fn create_lit_error(psess: &ParseSess, err: LitError, lit: token::Lit, span: } #[derive(Diagnostic)] -#[diag(session_incompatible_linker_flavor)] -#[note] +#[diag("linker flavor `{$flavor}` is incompatible with the current target")] +#[note("compatible flavors are: {$compatible_list}")] pub(crate) struct IncompatibleLinkerFlavor { pub(crate) flavor: &'static str, pub(crate) compatible_list: String, } #[derive(Diagnostic)] -#[diag(session_function_return_requires_x86_or_x86_64)] +#[diag("`-Zfunction-return` (except `keep`) is only supported on x86 and x86_64")] pub(crate) struct FunctionReturnRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_function_return_thunk_extern_requires_non_large_code_model)] +#[diag("`-Zfunction-return=thunk-extern` is only supported on non-large code models")] pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel; #[derive(Diagnostic)] -#[diag(session_indirect_branch_cs_prefix_requires_x86_or_x86_64)] +#[diag("`-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64")] pub(crate) struct IndirectBranchCsPrefixRequiresX86OrX8664; #[derive(Diagnostic)] -#[diag(session_unsupported_regparm)] +#[diag("`-Zregparm={$regparm}` is unsupported (valid values 0-3)")] pub(crate) struct UnsupportedRegparm { pub(crate) regparm: u32, } #[derive(Diagnostic)] -#[diag(session_unsupported_regparm_arch)] +#[diag("`-Zregparm=N` is only supported on x86")] pub(crate) struct UnsupportedRegparmArch; #[derive(Diagnostic)] -#[diag(session_unsupported_reg_struct_return_arch)] +#[diag("`-Zreg-struct-return` is only supported on x86")] pub(crate) struct UnsupportedRegStructReturnArch; #[derive(Diagnostic)] -#[diag(session_failed_to_create_profiler)] +#[diag("failed to create profiler: {$err}")] pub(crate) struct FailedToCreateProfiler { pub(crate) err: String, } #[derive(Diagnostic)] -#[diag(session_soft_float_ignored)] -#[note] +#[diag("`-Csoft-float` is ignored on this target; it only has an effect on *eabihf targets")] +#[note("this may become a hard error in a future version of Rust")] pub(crate) struct SoftFloatIgnored; #[derive(Diagnostic)] -#[diag(session_soft_float_deprecated)] -#[note] -#[note(session_soft_float_deprecated_issue)] +#[diag("`-Csoft-float` is unsound and deprecated; use a corresponding *eabi target instead")] +#[note("it will be removed or ignored in a future version of Rust")] +#[note("see issue #129893 for more information")] pub(crate) struct SoftFloatDeprecated; #[derive(LintDiagnostic)] -#[diag(session_unexpected_builtin_cfg)] -#[note(session_controlled_by)] -#[note(session_incoherent)] +#[diag("unexpected `--cfg {$cfg}` flag")] +#[note("config `{$cfg_name}` is only supposed to be controlled by `{$controlled_by}`")] +#[note("manually setting a built-in cfg can and does create incoherent behaviors")] pub(crate) struct UnexpectedBuiltinCfg { pub(crate) cfg: String, pub(crate) cfg_name: Symbol, diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 90108e9110440..98731a235d41d 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -32,8 +32,6 @@ pub mod output; pub use getopts; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b0ef95d10ffa0..c88dd0948b2a9 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1002,6 +1002,7 @@ symbols! { explicit_tail_calls, export_name, export_stable, + export_symbols: "export-symbols", expr, expr_2021, expr_fragment_specifier_2024, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 14e83cf3d2de8..9799f3e50ae24 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -3363,6 +3363,9 @@ impl Target { Err(format!("could not find specification for target {target_tuple:?}")) } + TargetTuple::TargetJson { ref contents, .. } if !unstable_options => { + Err("custom targets are unstable and require `-Zunstable-options`".to_string()) + } TargetTuple::TargetJson { ref contents, .. } => Target::from_json(contents), } } diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index ce08b300cc800..682cf941561fc 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -9,7 +9,6 @@ itertools = "0.12" rustc_abi = { path = "../rustc_abi" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } -rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_hashes = { path = "../rustc_hashes" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl deleted file mode 100644 index c1684bfb43b66..0000000000000 --- a/compiler/rustc_ty_utils/messages.ftl +++ /dev/null @@ -1,61 +0,0 @@ -ty_utils_address_and_deref_not_supported = dereferencing or taking the address is not supported in generic constants - -ty_utils_adt_not_supported = struct/enum construction is not supported in generic constants - -ty_utils_array_not_supported = array construction is not supported in generic constants - -ty_utils_assign_not_supported = assignment is not supported in generic constants - -ty_utils_binary_not_supported = unsupported binary operation in generic constants - -ty_utils_block_not_supported = blocks are not supported in generic constants - -ty_utils_borrow_not_supported = borrowing is not supported in generic constants - -ty_utils_box_not_supported = allocations are not allowed in generic constants - -ty_utils_by_use_not_supported = .use is not allowed in generic constants - -ty_utils_closure_and_return_not_supported = closures and function keywords are not supported in generic constants - -ty_utils_const_block_not_supported = const blocks are not supported in generic constants - -ty_utils_control_flow_not_supported = control flow is not supported in generic constants - -ty_utils_field_not_supported = field access is not supported in generic constants - -ty_utils_generic_constant_too_complex = overly complex generic constant - .help = consider moving this anonymous constant into a `const` function - .maybe_supported = this operation may be supported in the future - -ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope - .label = generic argument `{$arg}` used twice - .note = for this opaque type - -ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope - .label = argument `{$arg}` is not a generic parameter - .note = for this opaque type - -ty_utils_index_not_supported = indexing is not supported in generic constants - -ty_utils_inline_asm_not_supported = assembly is not supported in generic constants - -ty_utils_logical_op_not_supported = unsupported operation in generic constants, short-circuiting operations would imply control flow - -ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants - -ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop - -ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants - -ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}` - -ty_utils_operation_not_supported = unsupported operation in generic constants - -ty_utils_pointer_not_supported = pointer casts are not allowed in generic constants - -ty_utils_tuple_not_supported = tuple construction is not supported in generic constants - -ty_utils_unexpected_fnptr_associated_item = `FnPtr` trait with unexpected associated item - -ty_utils_yield_not_supported = coroutine control flow is not allowed in generic constants diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index f92c405242ce9..ccea5a49bd7cf 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -6,18 +6,18 @@ use rustc_middle::ty::{GenericArg, Ty}; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(ty_utils_needs_drop_overflow)] +#[diag("overflow while checking whether `{$query_ty}` requires drop")] pub(crate) struct NeedsDropOverflow<'tcx> { pub query_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_generic_constant_too_complex)] -#[help] +#[diag("overly complex generic constant")] +#[help("consider moving this anonymous constant into a `const` function")] pub(crate) struct GenericConstantTooComplex { #[primary_span] pub span: Span, - #[note(ty_utils_maybe_supported)] + #[note("this operation may be supported in the future")] pub maybe_supported: bool, #[subdiagnostic] pub sub: GenericConstantTooComplexSub, @@ -25,84 +25,88 @@ pub(crate) struct GenericConstantTooComplex { #[derive(Subdiagnostic)] pub(crate) enum GenericConstantTooComplexSub { - #[label(ty_utils_borrow_not_supported)] + #[label("borrowing is not supported in generic constants")] BorrowNotSupported(#[primary_span] Span), - #[label(ty_utils_address_and_deref_not_supported)] + #[label("dereferencing or taking the address is not supported in generic constants")] AddressAndDerefNotSupported(#[primary_span] Span), - #[label(ty_utils_array_not_supported)] + #[label("array construction is not supported in generic constants")] ArrayNotSupported(#[primary_span] Span), - #[label(ty_utils_block_not_supported)] + #[label("blocks are not supported in generic constants")] BlockNotSupported(#[primary_span] Span), - #[label(ty_utils_never_to_any_not_supported)] + #[label("coercing the `never` type is not supported in generic constants")] NeverToAnyNotSupported(#[primary_span] Span), - #[label(ty_utils_tuple_not_supported)] + #[label("tuple construction is not supported in generic constants")] TupleNotSupported(#[primary_span] Span), - #[label(ty_utils_index_not_supported)] + #[label("indexing is not supported in generic constants")] IndexNotSupported(#[primary_span] Span), - #[label(ty_utils_field_not_supported)] + #[label("field access is not supported in generic constants")] FieldNotSupported(#[primary_span] Span), - #[label(ty_utils_const_block_not_supported)] + #[label("const blocks are not supported in generic constants")] ConstBlockNotSupported(#[primary_span] Span), - #[label(ty_utils_adt_not_supported)] + #[label("struct/enum construction is not supported in generic constants")] AdtNotSupported(#[primary_span] Span), - #[label(ty_utils_pointer_not_supported)] + #[label("pointer casts are not allowed in generic constants")] PointerNotSupported(#[primary_span] Span), - #[label(ty_utils_yield_not_supported)] + #[label("coroutine control flow is not allowed in generic constants")] YieldNotSupported(#[primary_span] Span), - #[label(ty_utils_loop_not_supported)] + #[label("loops and loop control flow are not supported in generic constants")] LoopNotSupported(#[primary_span] Span), - #[label(ty_utils_box_not_supported)] + #[label("allocations are not allowed in generic constants")] BoxNotSupported(#[primary_span] Span), - #[label(ty_utils_binary_not_supported)] + #[label("unsupported binary operation in generic constants")] BinaryNotSupported(#[primary_span] Span), - #[label(ty_utils_by_use_not_supported)] + #[label(".use is not allowed in generic constants")] ByUseNotSupported(#[primary_span] Span), - #[label(ty_utils_logical_op_not_supported)] + #[label( + "unsupported operation in generic constants, short-circuiting operations would imply control flow" + )] LogicalOpNotSupported(#[primary_span] Span), - #[label(ty_utils_assign_not_supported)] + #[label("assignment is not supported in generic constants")] AssignNotSupported(#[primary_span] Span), - #[label(ty_utils_closure_and_return_not_supported)] + #[label("closures and function keywords are not supported in generic constants")] ClosureAndReturnNotSupported(#[primary_span] Span), - #[label(ty_utils_control_flow_not_supported)] + #[label("control flow is not supported in generic constants")] ControlFlowNotSupported(#[primary_span] Span), - #[label(ty_utils_inline_asm_not_supported)] + #[label("assembly is not supported in generic constants")] InlineAsmNotSupported(#[primary_span] Span), - #[label(ty_utils_operation_not_supported)] + #[label("unsupported operation in generic constants")] OperationNotSupported(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(ty_utils_unexpected_fnptr_associated_item)] +#[diag("`FnPtr` trait with unexpected associated item")] pub(crate) struct UnexpectedFnPtrAssociatedItem { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_non_primitive_simd_type)] +#[diag( + "monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}`" +)] pub(crate) struct NonPrimitiveSimdType<'tcx> { pub ty: Ty<'tcx>, pub e_ty: Ty<'tcx>, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_duplicate_arg)] +#[diag("non-defining opaque type use in defining scope")] pub(crate) struct DuplicateArg<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("generic argument `{$arg}` used twice")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, } #[derive(Diagnostic)] -#[diag(ty_utils_impl_trait_not_param, code = E0792)] +#[diag("non-defining opaque type use in defining scope", code = E0792)] pub(crate) struct NotParam<'tcx> { pub arg: GenericArg<'tcx>, #[primary_span] - #[label] + #[label("argument `{$arg}` is not a generic parameter")] pub span: Span, - #[note] + #[note("for this opaque type")] pub opaque_span: Span, } diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index d8b50b2d2e42f..9f8f3b240890b 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -31,8 +31,6 @@ pub mod sig_types; mod structural_match; mod ty; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { abi::provide(providers); assoc::provide(providers); diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 6d0b261dcadcf..42f3ccc340b27 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -2301,6 +2301,57 @@ fn test_fs_set_times() { } } +#[test] +fn test_fs_set_times_on_dir() { + #[cfg(target_vendor = "apple")] + use crate::os::darwin::fs::FileTimesExt; + #[cfg(windows)] + use crate::os::windows::fs::FileTimesExt; + + let tmp = tmpdir(); + let dir_path = tmp.join("testdir"); + fs::create_dir(&dir_path).unwrap(); + + let mut times = FileTimes::new(); + let accessed = SystemTime::UNIX_EPOCH + Duration::from_secs(12345); + let modified = SystemTime::UNIX_EPOCH + Duration::from_secs(54321); + times = times.set_accessed(accessed).set_modified(modified); + + #[cfg(any(windows, target_vendor = "apple"))] + let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123); + #[cfg(any(windows, target_vendor = "apple"))] + { + times = times.set_created(created); + } + + match fs::set_times(&dir_path, times) { + // Allow unsupported errors on platforms which don't support setting times. + #[cfg(not(any( + windows, + all( + unix, + not(any( + target_os = "android", + target_os = "redox", + target_os = "espidf", + target_os = "horizon" + )) + ) + )))] + Err(e) if e.kind() == ErrorKind::Unsupported => return, + Err(e) => panic!("error setting directory times: {e:?}"), + Ok(_) => {} + } + + let metadata = fs::metadata(&dir_path).unwrap(); + assert_eq!(metadata.accessed().unwrap(), accessed); + assert_eq!(metadata.modified().unwrap(), modified); + #[cfg(any(windows, target_vendor = "apple"))] + { + assert_eq!(metadata.created().unwrap(), created); + } +} + #[test] fn test_fs_set_times_follows_symlink() { #[cfg(target_vendor = "apple")] diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index fc8aec2f3f7c4..74854cdeb498d 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -1556,7 +1556,7 @@ pub fn set_perm(p: &WCStr, perm: FilePermissions) -> io::Result<()> { pub fn set_times(p: &WCStr, times: FileTimes) -> io::Result<()> { let mut opts = OpenOptions::new(); - opts.write(true); + opts.access_mode(c::FILE_WRITE_ATTRIBUTES); opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS); let file = File::open_native(p, &opts)?; file.set_times(times) @@ -1564,7 +1564,7 @@ pub fn set_times(p: &WCStr, times: FileTimes) -> io::Result<()> { pub fn set_times_nofollow(p: &WCStr, times: FileTimes) -> io::Result<()> { let mut opts = OpenOptions::new(); - opts.write(true); + opts.access_mode(c::FILE_WRITE_ATTRIBUTES); // `FILE_FLAG_OPEN_REPARSE_POINT` for no_follow behavior opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT); let file = File::open_native(p, &opts)?; diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs index 07157e364158d..98dd952033e5c 100644 --- a/src/build_helper/src/metrics.rs +++ b/src/build_helper/src/metrics.rs @@ -111,6 +111,29 @@ pub struct JsonStepSystemStats { pub cpu_utilization_percent: f64, } +#[derive(Eq, Hash, PartialEq, Debug)] +pub enum DebuggerKind { + Gdb, + Lldb, + Cdb, +} + +impl DebuggerKind { + pub fn debuginfo_kind(name: &str) -> Option { + let name = name.to_ascii_lowercase(); + + if name.contains("debuginfo-gdb") { + Some(DebuggerKind::Gdb) + } else if name.contains("debuginfo-lldb") { + Some(DebuggerKind::Lldb) + } else if name.contains("debuginfo-cdb") { + Some(DebuggerKind::Cdb) + } else { + None + } + } +} + fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result { use serde::Deserialize as _; Option::::deserialize(d).map(|f| f.unwrap_or(f64::NAN)) diff --git a/src/ci/citool/src/analysis.rs b/src/ci/citool/src/analysis.rs index e91d27a36092a..b8048f341ea2e 100644 --- a/src/ci/citool/src/analysis.rs +++ b/src/ci/citool/src/analysis.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use std::time::Duration; use build_helper::metrics::{ - BuildStep, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, + BuildStep, DebuggerKind, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, escape_step_name, format_build_steps, }; @@ -139,11 +139,39 @@ fn record_test_suites(metrics: &JsonRoot) { let table = render_table(aggregated); println!("\n# Test results\n"); println!("{table}"); + report_debuginfo_statistics(&suites); } else { eprintln!("No test suites found in metrics"); } } +fn report_debuginfo_statistics(suites: &[&TestSuite]) { + let mut debugger_test_record: HashMap = HashMap::new(); + for suite in suites { + if let TestSuiteMetadata::Compiletest { .. } = suite.metadata { + for test in &suite.tests { + if let Some(kind) = DebuggerKind::debuginfo_kind(&test.name) { + let record = + debugger_test_record.entry(kind).or_insert(TestSuiteRecord::default()); + match test.outcome { + TestOutcome::Passed => record.passed += 1, + TestOutcome::Ignored { .. } => record.ignored += 1, + TestOutcome::Failed => record.failed += 1, + } + } + } + } + } + + println!("## DebugInfo Test Statistics"); + for (kind, record) in debugger_test_record { + println!( + "- {:?}: Passed ✅={}, Failed ❌={}, Ignored 🚫={}", + kind, record.passed, record.failed, record.ignored + ); + } +} + fn render_table(suites: BTreeMap) -> String { use std::fmt::Write; diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh index e7f86e10f55a5..5352505577400 100755 --- a/src/ci/docker/scripts/rfl-build.sh +++ b/src/ci/docker/scripts/rfl-build.sh @@ -2,8 +2,8 @@ set -euo pipefail -# https://github.com/rust-lang/rust/pull/145974 -LINUX_VERSION=842cfd8e5aff3157cb25481b2900b49c188d628a +# https://github.com/rust-lang/rust/pull/151534 +LINUX_VERSION=eb268c7972f65fa0b11b051c5ef2b92747bb2b62 # Build rustc, rustdoc, cargo, clippy-driver and rustfmt ../x.py build --stage 2 library rustdoc clippy rustfmt diff --git a/src/tools/rustbook/README.md b/src/tools/rustbook/README.md index d9570c23ead17..a9fd1b75b5724 100644 --- a/src/tools/rustbook/README.md +++ b/src/tools/rustbook/README.md @@ -10,7 +10,7 @@ This is invoked automatically when building mdbook-style documentation, for exam ## Cargo workspace -This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786): +This package defines a separate cargo workspace from the main Rust workspace for a few reasons (ref [#127786](https://github.com/rust-lang/rust/pull/127786)): - Avoids requiring checking out submodules for developers who are not working on the documentation. Otherwise, some submodules such as those that have custom preprocessors would be required for cargo to find the dependencies. - Avoids problems with updating dependencies. Unfortunately this workspace has a rather large set of dependencies, which can make coordinating updates difficult (see [#127890](https://github.com/rust-lang/rust/issues/127890)). diff --git a/tests/codegen-llvm/autodiff/abi_handling.rs b/tests/codegen-llvm/autodiff/abi_handling.rs index 5c8126898a8d7..a8bc482fc293f 100644 --- a/tests/codegen-llvm/autodiff/abi_handling.rs +++ b/tests/codegen-llvm/autodiff/abi_handling.rs @@ -38,14 +38,14 @@ fn square(x: f32) -> f32 { // CHECK-LABEL: ; abi_handling::df1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } -// debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%bx_0) // release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val, float %x.4.val) // CHECK-LABEL: ; abi_handling::f1 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x) +// debug-SAME: (ptr {{.*}}%x) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val, float %x.4.val) #[autodiff_forward(df1, Dual, Dual)] @@ -58,7 +58,7 @@ fn f1(x: &[f32; 2]) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr %f, float %x, float %dret) -// release-NEXT: define internal fastcc float +// release-NEXT: define internal fastcc noundef float // release-SAME: (float noundef %x) // CHECK-LABEL: ; abi_handling::f2 @@ -77,13 +77,13 @@ fn f2(f: fn(f32) -> f32, x: f32) -> f32 { // CHECK-NEXT: Function Attrs // debug-NEXT: define internal { float, float } // debug-SAME: (ptr align 4 %x, ptr align 4 %bx_0, ptr align 4 %y, ptr align 4 %by_0) -// release-NEXT: define internal fastcc { float, float } +// release-NEXT: define internal fastcc float // release-SAME: (float %x.0.val) // CHECK-LABEL: ; abi_handling::f3 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x, ptr align 4 %y) +// debug-SAME: (ptr {{.*}}%x, ptr {{.*}}%y) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.val) #[autodiff_forward(df3, Dual, Dual, Dual)] @@ -160,7 +160,7 @@ fn f6(i: NestedInput) -> f32 { // CHECK-LABEL: ; abi_handling::f7 // CHECK-NEXT: Function Attrs // debug-NEXT: define internal float -// debug-SAME: (ptr align 4 %x.0, ptr align 4 %x.1) +// debug-SAME: (ptr {{.*}}%x.0, ptr {{.*}}%x.1) // release-NEXT: define internal fastcc noundef float // release-SAME: (float %x.0.0.val, float %x.1.0.val) #[autodiff_forward(df7, Dual, Dual)] diff --git a/tests/codegen-llvm/autodiff/batched.rs b/tests/codegen-llvm/autodiff/batched.rs index 0ff6134bc07d5..5a723ff041839 100644 --- a/tests/codegen-llvm/autodiff/batched.rs +++ b/tests/codegen-llvm/autodiff/batched.rs @@ -1,13 +1,11 @@ //@ compile-flags: -Zautodiff=Enable,NoTT,NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme -// -// In Enzyme, we test against a large range of LLVM versions (5+) and don't have overly many -// breakages. One benefit is that we match the IR generated by Enzyme only after running it -// through LLVM's O3 pipeline, which will remove most of the noise. -// However, our integration test could also be affected by changes in how rustc lowers MIR into -// LLVM-IR, which could cause additional noise and thus breakages. If that's the case, we should -// reduce this test to only match the first lines and the ret instructions. + +// This test combines two features of Enzyme, automatic differentiation and batching. As such, it is +// especially prone to breakages. I reduced it therefore to a minimal check matches argument/return +// types. Based on the original batching author, implementing the batching feature over MLIR instead +// of LLVM should give significantly more reliable performance. #![feature(autodiff)] @@ -22,69 +20,20 @@ fn square(x: &f32) -> f32 { x * x } +// The base ("scalar") case d_square3, without batching. +// CHECK: define internal fastcc float @fwddiffesquare(float %x.0.val, float %"x'.0.val") +// CHECK: %0 = fadd fast float %"x'.0.val", %"x'.0.val" +// CHECK-NEXT: %1 = fmul fast float %0, %x.0.val +// CHECK-NEXT: ret float %1 +// CHECK-NEXT: } + // d_square2 -// CHECK: define internal [4 x float] @fwddiffe4square(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: ret [4 x float] %19 +// CHECK: define internal fastcc [4 x float] @fwddiffe4square(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret [4 x float] // CHECK-NEXT: } -// d_square3, the extra float is the original return value (x * x) -// CHECK: define internal { float, [4 x float] } @fwddiffe4square.1(ptr noalias noundef readonly align 4 captures(none) dereferenceable(4) %x, [4 x ptr] %"x'") -// CHECK-NEXT: start: -// CHECK-NEXT: %0 = extractvalue [4 x ptr] %"x'", 0 -// CHECK-NEXT: %"_2'ipl" = load float, ptr %0, align 4 -// CHECK-NEXT: %1 = extractvalue [4 x ptr] %"x'", 1 -// CHECK-NEXT: %"_2'ipl1" = load float, ptr %1, align 4 -// CHECK-NEXT: %2 = extractvalue [4 x ptr] %"x'", 2 -// CHECK-NEXT: %"_2'ipl2" = load float, ptr %2, align 4 -// CHECK-NEXT: %3 = extractvalue [4 x ptr] %"x'", 3 -// CHECK-NEXT: %"_2'ipl3" = load float, ptr %3, align 4 -// CHECK-NEXT: %_2 = load float, ptr %x, align 4 -// CHECK-NEXT: %_0 = fmul float %_2, %_2 -// CHECK-NEXT: %4 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %5 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %6 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %7 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %8 = fmul fast float %"_2'ipl", %_2 -// CHECK-NEXT: %9 = fmul fast float %"_2'ipl1", %_2 -// CHECK-NEXT: %10 = fmul fast float %"_2'ipl2", %_2 -// CHECK-NEXT: %11 = fmul fast float %"_2'ipl3", %_2 -// CHECK-NEXT: %12 = fadd fast float %4, %8 -// CHECK-NEXT: %13 = insertvalue [4 x float] undef, float %12, 0 -// CHECK-NEXT: %14 = fadd fast float %5, %9 -// CHECK-NEXT: %15 = insertvalue [4 x float] %13, float %14, 1 -// CHECK-NEXT: %16 = fadd fast float %6, %10 -// CHECK-NEXT: %17 = insertvalue [4 x float] %15, float %16, 2 -// CHECK-NEXT: %18 = fadd fast float %7, %11 -// CHECK-NEXT: %19 = insertvalue [4 x float] %17, float %18, 3 -// CHECK-NEXT: %20 = insertvalue { float, [4 x float] } undef, float %_0, 0 -// CHECK-NEXT: %21 = insertvalue { float, [4 x float] } %20, [4 x float] %19, 1 -// CHECK-NEXT: ret { float, [4 x float] } %21 +// CHECK: define internal fastcc { float, [4 x float] } @fwddiffe4square.{{.*}}(float %x.0.val, [4 x ptr] %"x'") +// CHECK: ret { float, [4 x float] } // CHECK-NEXT: } fn main() { diff --git a/tests/codegen-llvm/autodiff/generic.rs b/tests/codegen-llvm/autodiff/generic.rs index 6f56460a2b6d1..b31468c91c9c2 100644 --- a/tests/codegen-llvm/autodiff/generic.rs +++ b/tests/codegen-llvm/autodiff/generic.rs @@ -1,6 +1,14 @@ //@ compile-flags: -Zautodiff=Enable -Zautodiff=NoPostopt -C opt-level=3 -Clto=fat //@ no-prefer-dynamic //@ needs-enzyme +//@ revisions: F32 F64 Main + +// Here we verify that the function `square` can be differentiated over f64. +// This is interesting to test, since the user never calls `square` with f64, so on it's own rustc +// would have no reason to monomorphize it that way. However, Enzyme needs the f64 version of +// `square` in order to be able to differentiate it, so we have logic to enforce the +// monomorphization. Here, we test this logic. + #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -12,32 +20,37 @@ fn square + Copy>(x: &T) -> T { } // Ensure that `d_square::` code is generated -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: {{.*}} -// CHECK-NEXT: define internal {{.*}} float -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul float + +// F32-LABEL: ; generic::square:: +// F32-NEXT: ; Function Attrs: {{.*}} +// F32-NEXT: define internal {{.*}} float +// F32-NEXT: start: +// F32-NOT: ret +// F32: fmul float // Ensure that `d_square::` code is generated even if `square::` was never called -// -// CHECK: ; generic::square -// CHECK-NEXT: ; Function Attrs: -// CHECK-NEXT: define internal {{.*}} double -// CHECK-NEXT: start: -// CHECK-NOT: ret -// CHECK: fmul double + +// F64-LABEL: ; generic::d_square:: +// F64-NEXT: ; Function Attrs: {{.*}} +// F64-NEXT: define internal {{.*}} void +// F64-NEXT: start: +// F64-NEXT: {{(tail )?}}call {{(fastcc )?}}void @diffe_{{.*}}(double {{.*}}, ptr {{.*}}) +// F64-NEXT: ret void + +// Main-LABEL: ; generic::main +// Main: ; call generic::square:: +// Main: ; call generic::d_square:: fn main() { let xf32: f32 = std::hint::black_box(3.0); let xf64: f64 = std::hint::black_box(3.0); + let seed: f64 = std::hint::black_box(1.0); let outputf32 = square::(&xf32); assert_eq!(9.0, outputf32); let mut df_dxf64: f64 = std::hint::black_box(0.0); - let output_f64 = d_square::(&xf64, &mut df_dxf64, 1.0); + let output_f64 = d_square::(&xf64, &mut df_dxf64, seed); assert_eq!(6.0, df_dxf64); } diff --git a/tests/codegen-llvm/autodiff/identical_fnc.rs b/tests/codegen-llvm/autodiff/identical_fnc.rs index 1c18e7acc4b63..a8b186c302ea1 100644 --- a/tests/codegen-llvm/autodiff/identical_fnc.rs +++ b/tests/codegen-llvm/autodiff/identical_fnc.rs @@ -8,7 +8,7 @@ // merged placeholder function anymore, and compilation would fail. We prevent this by disabling // LLVM's merge_function pass before AD. Here we implicetely test that our solution keeps working. // We also explicetly test that we keep running merge_function after AD, by checking for two -// identical function calls in the LLVM-IR, while having two different calls in the Rust code. +// identical function calls in the LLVM-IR, despite having two different calls in the Rust code. #![feature(autodiff)] use std::autodiff::autodiff_reverse; @@ -27,14 +27,14 @@ fn square2(x: &f64) -> f64 { // CHECK:; identical_fnc::main // CHECK-NEXT:; Function Attrs: -// CHECK-NEXT:define internal void @_ZN13identical_fnc4main17h6009e4f751bf9407E() +// CHECK-NEXT:define internal void // CHECK-NEXT:start: // CHECK-NOT:br // CHECK-NOT:ret // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) +// CHECK-NEXT:call fastcc void @[[HASH:.+]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx1) // CHECK:; call identical_fnc::d_square -// CHECK-NEXT:call fastcc void @_ZN13identical_fnc8d_square[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) +// CHECK-NEXT:call fastcc void @[[HASH]](double %x.val, ptr noalias noundef align 8 dereferenceable(8) %dx2) fn main() { let x = std::hint::black_box(3.0); diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.c b/tests/run-make/cdylib-export-c-library-symbols/foo.c new file mode 100644 index 0000000000000..a062aca03b315 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.c @@ -0,0 +1 @@ +void my_function() {} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo.rs b/tests/run-make/cdylib-export-c-library-symbols/foo.rs new file mode 100644 index 0000000000000..ac641aaed00f8 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo.rs @@ -0,0 +1,10 @@ +extern "C" { + pub fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs new file mode 100644 index 0000000000000..1eda294ef41c3 --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/foo_export.rs @@ -0,0 +1,10 @@ +extern "C" { + fn my_function(); +} + +#[no_mangle] +pub extern "C" fn rust_entry() { + unsafe { + my_function(); + } +} diff --git a/tests/run-make/cdylib-export-c-library-symbols/rmake.rs b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs new file mode 100644 index 0000000000000..cb237eceedadf --- /dev/null +++ b/tests/run-make/cdylib-export-c-library-symbols/rmake.rs @@ -0,0 +1,36 @@ +//@ ignore-nvptx64 +//@ ignore-wasm +//@ ignore-cross-compile +// FIXME:The symbol mangle rules are slightly different in Windows(32-bit) and Apple. +// Need to be resolved. +//@ ignore-windows +//@ ignore-apple +// Reason: the compiled binary is executed + +use run_make_support::{build_native_static_lib, cc, dynamic_lib_name, is_darwin, llvm_nm, rustc}; + +fn main() { + cc().input("foo.c").arg("-c").out_exe("foo.o").run(); + build_native_static_lib("foo"); + + rustc().input("foo.rs").arg("-lstatic=foo").crate_type("cdylib").run(); + + let out = llvm_nm() + .input(dynamic_lib_name("foo")) + .run() + .assert_stdout_not_contains_regex("T *my_function"); + + rustc().input("foo_export.rs").arg("-lstatic:+export-symbols=foo").crate_type("cdylib").run(); + + if is_darwin() { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T _my_function"); + } else { + let out = llvm_nm() + .input(dynamic_lib_name("foo_export")) + .run() + .assert_stdout_contains("T my_function"); + } +} diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 90ba424ffe940..d281d820f47b4 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -15,7 +15,11 @@ fn main() { // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking // the linker to display its version number with a link-arg. assert_rustc_uses_lld( - rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"), + rustc() + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zunstable-options") + .input("lib.rs"), ); // But it can also be disabled via linker features. diff --git a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs index d43aa9b90ac72..8660556564f1e 100644 --- a/tests/run-make/rustdoc-target-spec-json-path/rmake.rs +++ b/tests/run-make/rustdoc-target-spec-json-path/rmake.rs @@ -5,8 +5,14 @@ use run_make_support::{cwd, rustc, rustdoc}; fn main() { let out_dir = "rustdoc-target-spec-json-path"; - rustc().crate_type("lib").input("dummy_core.rs").target("target.json").run(); + rustc() + .arg("-Zunstable-options") + .crate_type("lib") + .input("dummy_core.rs") + .target("target.json") + .run(); rustdoc() + .arg("-Zunstable-options") .input("my_crate.rs") .out_dir(out_dir) .library_search_path(cwd()) diff --git a/tests/run-make/target-specs/rmake.rs b/tests/run-make/target-specs/rmake.rs index 69292af5fd69c..6c88f3164e9e4 100644 --- a/tests/run-make/target-specs/rmake.rs +++ b/tests/run-make/target-specs/rmake.rs @@ -20,13 +20,20 @@ fn main() { .target("my-incomplete-platform.json") .run_fail() .assert_stderr_contains("missing field `llvm-target`"); - let test_platform = rustc() + let _ = rustc() .input("foo.rs") .target("my-x86_64-unknown-linux-gnu-platform") .crate_type("lib") .emit("asm") .run_fail() .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); + let _ = rustc() + .input("foo.rs") + .target("my-awesome-platform.json") + .crate_type("lib") + .emit("asm") + .run_fail() + .assert_stderr_contains("custom targets are unstable and require `-Zunstable-options`"); rustc() .arg("-Zunstable-options") .env("RUST_TARGET_PATH", ".") diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index defb286ed19be..21b6af9b55605 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -4,7 +4,8 @@ //@ check-pass //@ no-auto-check-cfg //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json +//@ compile-flags: --crate-type=lib --check-cfg=cfg() +//@ compile-flags: -Zunstable-options --target={{src-base}}/check-cfg/my-awesome-platform.json //@ ignore-backends: gcc #![feature(lang_items, no_core, auto_traits, rustc_attrs)] diff --git a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr index 4d65db3c66d0b..218a4769d9542 100644 --- a/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr +++ b/tests/ui/feature-gates/feature-gate-link-arg-attribute.in_flag.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `link-arg`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/link-arg-error2.rs b/tests/ui/link-native-libs/link-arg-error2.rs new file mode 100644 index 0000000000000..a51dec0614b5f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.rs @@ -0,0 +1,5 @@ +//@ compile-flags: -l link-arg:+export-symbols=arg -Z unstable-options + +fn main() {} + +//~? ERROR linking modifier `export-symbols` is only compatible with `static` linking kind diff --git a/tests/ui/link-native-libs/link-arg-error2.stderr b/tests/ui/link-native-libs/link-arg-error2.stderr new file mode 100644 index 0000000000000..61bcf7dba2829 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-error2.stderr @@ -0,0 +1,2 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.rs b/tests/ui/link-native-libs/link-arg-from-rs2.rs new file mode 100644 index 0000000000000..3074fec6c1c8f --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.rs @@ -0,0 +1,7 @@ +#![feature(link_arg_attribute)] + +#[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] +//~^ ERROR linking modifier `export-symbols` is only compatible with `static` linking kind +extern "C" {} + +pub fn main() {} diff --git a/tests/ui/link-native-libs/link-arg-from-rs2.stderr b/tests/ui/link-native-libs/link-arg-from-rs2.stderr new file mode 100644 index 0000000000000..af3b25253e052 --- /dev/null +++ b/tests/ui/link-native-libs/link-arg-from-rs2.stderr @@ -0,0 +1,8 @@ +error: linking modifier `export-symbols` is only compatible with `static` linking kind + --> $DIR/link-arg-from-rs2.rs:3:53 + | +LL | #[link(kind = "link-arg", name = "arg", modifiers = "+export-symbols")] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/link-native-libs/link-attr-validation-late.stderr b/tests/ui/link-native-libs/link-attr-validation-late.stderr index b09431f923aaf..4a4a193752070 100644 --- a/tests/ui/link-native-libs/link-attr-validation-late.stderr +++ b/tests/ui/link-native-libs/link-attr-validation-late.stderr @@ -178,13 +178,13 @@ LL | #[link(name = "...", wasm_import_module())] | = note: for more information, visit -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:31:34 | LL | #[link(name = "...", modifiers = "")] | ^^ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols --> $DIR/link-attr-validation-late.rs:32:34 | LL | #[link(name = "...", modifiers = "no-plus-minus")] @@ -196,7 +196,7 @@ error[E0539]: malformed `link` attribute input LL | #[link(name = "...", modifiers = "+unknown")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------^^ | | - | valid arguments are "bundle", "verbatim", "whole-archive" or "as-needed" + | valid arguments are "bundle", "export-symbols", "verbatim", "whole-archive" or "as-needed" | = note: for more information, visit diff --git a/tests/ui/link-native-libs/modifiers-bad.blank.stderr b/tests/ui/link-native-libs/modifiers-bad.blank.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.blank.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.blank.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr index ea36af0b4cfa9..6a1953e008eef 100644 --- a/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.no-prefix.stderr @@ -1,2 +1,2 @@ -error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed +error: invalid linking modifier syntax, expected '+' or '-' prefix before one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr index 1e701374688fe..46720cf0b15e9 100644 --- a/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.prefix-only.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier ``, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols diff --git a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr index 75950ad9c64c7..d47694a5aeca8 100644 --- a/tests/ui/link-native-libs/modifiers-bad.unknown.stderr +++ b/tests/ui/link-native-libs/modifiers-bad.unknown.stderr @@ -1,2 +1,2 @@ -error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed +error: unknown linking modifier `ferris`, expected one of: bundle, verbatim, whole-archive, as-needed, export-symbols