From 3d28a1ad761f4106e62e90ceebb209af533a1f24 Mon Sep 17 00:00:00 2001 From: Keenan Gugeler Date: Wed, 14 Sep 2022 13:25:14 -0400 Subject: [PATCH 01/18] Warn about safety of `fetch_update` Specifically as it relates to the ABA problem. --- library/core/src/sync/atomic.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 3c96290fc537e..6c70517d965b2 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -955,6 +955,14 @@ impl AtomicBool { /// **Note:** This method is only available on platforms that support atomic /// operations on `u8`. /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of [`AtomicBool::compare_exchange_weak`], and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + /// /// # Examples /// /// ```rust @@ -1422,6 +1430,14 @@ impl AtomicPtr { /// **Note:** This method is only available on platforms that support atomic /// operations on pointers. /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of [`AtomicPtr::compare_exchange_weak`], and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + /// /// # Examples /// /// ```rust @@ -2510,6 +2526,16 @@ macro_rules! atomic_int { /// **Note**: This method is only available on platforms that support atomic operations on #[doc = concat!("[`", $s_int_type, "`].")] /// + /// # Considerations + /// + /// This method is not magic; it is not provided by the hardware. + /// It is implemented in terms of + #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`],")] + /// and suffers from the same drawbacks. + /// In particular, this method will not circumvent the [ABA Problem]. + /// + /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem + /// /// # Examples /// /// ```rust From 2ea770d067b186dac4be6fe22757efc8f8176eb2 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 24 Sep 2022 09:08:56 +0100 Subject: [PATCH 02/18] fs::get_path solarish version. --- library/std/src/sys/unix/fs.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index cc347e3586ae3..60545be71de17 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -1198,7 +1198,12 @@ impl FromRawFd for File { impl fmt::Debug for File { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(any(target_os = "linux", target_os = "netbsd"))] + #[cfg(any( + target_os = "linux", + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris" + ))] fn get_path(fd: c_int) -> Option { let mut p = PathBuf::from("/proc/self/fd"); p.push(&fd.to_string()); @@ -1253,7 +1258,9 @@ impl fmt::Debug for File { target_os = "macos", target_os = "vxworks", all(target_os = "freebsd", target_arch = "x86_64"), - target_os = "netbsd" + target_os = "netbsd", + target_os = "illumos", + target_os = "solaris" )))] fn get_path(_fd: c_int) -> Option { // FIXME(#24570): implement this for other Unix platforms From 2c72ea7748d4ed68178afa059a0853c3e97731e6 Mon Sep 17 00:00:00 2001 From: est31 Date: Mon, 12 Sep 2022 17:09:08 +0200 Subject: [PATCH 03/18] Stabilize map_first_last --- compiler/rustc_middle/src/lib.rs | 1 - library/alloc/benches/lib.rs | 1 - library/alloc/src/collections/btree/map.rs | 18 ++++++------------ library/alloc/src/collections/btree/set.rs | 12 ++++-------- src/tools/miri/src/lib.rs | 1 - 5 files changed, 10 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index a180706e1cf0f..9c690fc15de4f 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -32,7 +32,6 @@ #![feature(exhaustive_patterns)] #![feature(get_mut_unchecked)] #![feature(if_let_guard)] -#![feature(map_first_last)] #![feature(negative_impls)] #![feature(never_type)] #![feature(extern_types)] diff --git a/library/alloc/benches/lib.rs b/library/alloc/benches/lib.rs index 72ac897d4f178..d418965cd2f6b 100644 --- a/library/alloc/benches/lib.rs +++ b/library/alloc/benches/lib.rs @@ -3,7 +3,6 @@ #![cfg(not(target_os = "android"))] #![feature(btree_drain_filter)] #![feature(iter_next_chunk)] -#![feature(map_first_last)] #![feature(repr_simd)] #![feature(slice_partition_dedup)] #![feature(test)] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 3018d1c9125bf..ce803a18348bc 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -703,7 +703,6 @@ impl BTreeMap { /// Basic usage: /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -712,7 +711,7 @@ impl BTreeMap { /// map.insert(2, "a"); /// assert_eq!(map.first_key_value(), Some((&1, &"b"))); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn first_key_value(&self) -> Option<(&K, &V)> where K: Ord, @@ -727,7 +726,6 @@ impl BTreeMap { /// # Examples /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -741,7 +739,7 @@ impl BTreeMap { /// assert_eq!(*map.get(&1).unwrap(), "first"); /// assert_eq!(*map.get(&2).unwrap(), "b"); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn first_entry(&mut self) -> Option> where K: Ord, @@ -765,7 +763,6 @@ impl BTreeMap { /// Draining elements in ascending order, while keeping a usable map each iteration. /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -776,7 +773,7 @@ impl BTreeMap { /// } /// assert!(map.is_empty()); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn pop_first(&mut self) -> Option<(K, V)> where K: Ord, @@ -792,7 +789,6 @@ impl BTreeMap { /// Basic usage: /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -800,7 +796,7 @@ impl BTreeMap { /// map.insert(2, "a"); /// assert_eq!(map.last_key_value(), Some((&2, &"a"))); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn last_key_value(&self) -> Option<(&K, &V)> where K: Ord, @@ -815,7 +811,6 @@ impl BTreeMap { /// # Examples /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -829,7 +824,7 @@ impl BTreeMap { /// assert_eq!(*map.get(&1).unwrap(), "a"); /// assert_eq!(*map.get(&2).unwrap(), "last"); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn last_entry(&mut self) -> Option> where K: Ord, @@ -853,7 +848,6 @@ impl BTreeMap { /// Draining elements in descending order, while keeping a usable map each iteration. /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeMap; /// /// let mut map = BTreeMap::new(); @@ -864,7 +858,7 @@ impl BTreeMap { /// } /// assert!(map.is_empty()); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn pop_last(&mut self) -> Option<(K, V)> where K: Ord, diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 3caaf521240d2..09f3106dcfcdb 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -786,7 +786,6 @@ impl BTreeSet { /// Basic usage: /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); @@ -797,7 +796,7 @@ impl BTreeSet { /// assert_eq!(set.first(), Some(&1)); /// ``` #[must_use] - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn first(&self) -> Option<&T> where T: Ord, @@ -813,7 +812,6 @@ impl BTreeSet { /// Basic usage: /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); @@ -824,7 +822,7 @@ impl BTreeSet { /// assert_eq!(set.last(), Some(&2)); /// ``` #[must_use] - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn last(&self) -> Option<&T> where T: Ord, @@ -838,7 +836,6 @@ impl BTreeSet { /// # Examples /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); @@ -849,7 +846,7 @@ impl BTreeSet { /// } /// assert!(set.is_empty()); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn pop_first(&mut self) -> Option where T: Ord, @@ -863,7 +860,6 @@ impl BTreeSet { /// # Examples /// /// ``` - /// #![feature(map_first_last)] /// use std::collections::BTreeSet; /// /// let mut set = BTreeSet::new(); @@ -874,7 +870,7 @@ impl BTreeSet { /// } /// assert!(set.is_empty()); /// ``` - #[unstable(feature = "map_first_last", issue = "62924")] + #[stable(feature = "map_first_last", since = "CURRENT_RUSTC_VERSION")] pub fn pop_last(&mut self) -> Option where T: Ord, diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index cda27beab300f..aced15646a2ac 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -1,5 +1,4 @@ #![feature(rustc_private)] -#![feature(map_first_last)] #![feature(map_try_insert)] #![feature(never_type)] #![feature(try_blocks)] From 8bda13367e4987937ddc2ba9bbe01b5f7a4cce3e Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Wed, 5 Oct 2022 02:29:56 +0100 Subject: [PATCH 04/18] Interpret EH actions properly The EH actions stored in the LSDA follows the format of GCC except table (even for LLVM-generated code). An missing action in the table is the encoding for `Terminate`, see [1]. The currently code interprets it as `None`, as a workaround for #35011, an issue that seems to occur in LLVM 3.7 and not after 3.9. These are very old versions of LLVM and we don't support them anymore, so remove this workaround and interpret them properly. Note that LLVM currently does not emit any `Terminate` actions, but GCC does. Although GCC backend currently doesn't do unwinding, removing it preemptively would prevent future developers from wasting time to figure out what's wrong. [1]: https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/libsupc%2B%2B/eh_personality.cc#L522-L526 --- library/std/src/personality/dwarf/eh.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/std/src/personality/dwarf/eh.rs b/library/std/src/personality/dwarf/eh.rs index 8799137b78f98..27b50c13b77ca 100644 --- a/library/std/src/personality/dwarf/eh.rs +++ b/library/std/src/personality/dwarf/eh.rs @@ -98,9 +98,8 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result } } } - // Ip is not present in the table. This should not happen... but it does: issue #35011. - // So rather than returning EHAction::Terminate, we do this. - Ok(EHAction::None) + // Ip is not present in the table. This indicates a nounwind call. + Ok(EHAction::Terminate) } else { // SjLj version: // The "IP" is an index into the call-site table, with two exceptions: From b0b072d7477a2d10ac7bee77b84ec33151f8eb65 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Tue, 4 Oct 2022 13:23:53 -0400 Subject: [PATCH 05/18] ADD - codegen_ssa initial diags translations machinery ADD - migrate MissingNativeStaticLibrary fatal error --- compiler/rustc_codegen_ssa/src/errors.rs | 9 +++++++++ compiler/rustc_codegen_ssa/src/lib.rs | 1 + .../rustc_error_messages/locales/en-US/codegen_ssa.ftl | 1 + compiler/rustc_error_messages/src/lib.rs | 1 + 4 files changed, 12 insertions(+) create mode 100644 compiler/rustc_codegen_ssa/src/errors.rs create mode 100644 compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs new file mode 100644 index 0000000000000..170b7983dbe5f --- /dev/null +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -0,0 +1,9 @@ +//! Errors emitted by codegen_ssa + +use rustc_macros::SessionDiagnostic; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::missing_native_static_library)] +pub struct MissingNativeStaticLibrary<'a> { + pub library_name: &'a str, +} diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 3ef9a634e1857..e62b6f342b2e9 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -43,6 +43,7 @@ pub mod base; pub mod common; pub mod coverageinfo; pub mod debuginfo; +pub mod errors; pub mod glue; pub mod meth; pub mod mir; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl new file mode 100644 index 0000000000000..deba0dc6f9954 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -0,0 +1 @@ +codegen_ssa_missing_native_static_library = could not find native static library `{$library_name}`, perhaps an -L flag is missing? diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 18be60975e4eb..10f8efdffa8b6 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -63,6 +63,7 @@ fluent_messages! { symbol_mangling => "../locales/en-US/symbol_mangling.ftl", trait_selection => "../locales/en-US/trait_selection.ftl", ty_utils => "../locales/en-US/ty_utils.ftl", + codegen_ssa => "../locales/en-US/codegen_ssa.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; From 4e0de5319c3543b7960394f612a0527923522ae1 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Wed, 24 Aug 2022 23:40:07 -0400 Subject: [PATCH 06/18] ADD - migrate lib.def write fatal error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This diagnostic has no UI test 🤔 Should we add some? If so, how? --- compiler/rustc_codegen_ssa/src/back/linker.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/errors.rs | 6 ++++++ .../rustc_error_messages/locales/en-US/codegen_ssa.ftl | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index c71d332475a5f..60547acc95661 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1,5 +1,6 @@ use super::command::Command; use super::symbol_export; +use crate::errors::LibDefWriteFailure; use rustc_span::symbol::sym; use std::ffi::{OsStr, OsString}; @@ -666,7 +667,7 @@ impl<'a> Linker for GccLinker<'a> { } }; if let Err(e) = res { - self.sess.fatal(&format!("failed to write lib.def file: {}", e)); + self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); } } else if is_windows { let res: io::Result<()> = try { @@ -681,7 +682,7 @@ impl<'a> Linker for GccLinker<'a> { } }; if let Err(e) = res { - self.sess.fatal(&format!("failed to write list.def file: {}", e)); + self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); } } else { // Write an LD version script @@ -972,7 +973,7 @@ impl<'a> Linker for MsvcLinker<'a> { } }; if let Err(e) = res { - self.sess.fatal(&format!("failed to write lib.def file: {}", e)); + self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); } let mut arg = OsString::from("/DEF:"); arg.push(path); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 170b7983dbe5f..718ad5c7bf566 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -7,3 +7,9 @@ use rustc_macros::SessionDiagnostic; pub struct MissingNativeStaticLibrary<'a> { pub library_name: &'a str, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::lib_def_write_failure)] +pub struct LibDefWriteFailure { + pub error_description: String, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index deba0dc6f9954..597f3488fc1be 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -1 +1,3 @@ codegen_ssa_missing_native_static_library = could not find native static library `{$library_name}`, perhaps an -L flag is missing? + +codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error_description} From 0a2d7f83cb3aea0556ef7cfd7662a028ac974d87 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Fri, 26 Aug 2022 20:21:55 -0400 Subject: [PATCH 07/18] UPDATE - LibDefWriteFailure to accept type instead of formatted string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This follows team’s suggestions in this thread https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/.23100717.20diag.20translation/near/295305249 --- compiler/rustc_codegen_ssa/src/back/linker.rs | 12 ++++++------ compiler/rustc_codegen_ssa/src/errors.rs | 3 ++- .../locales/en-US/codegen_ssa.ftl | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 60547acc95661..e9335e53125f3 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -666,8 +666,8 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, "_{}", sym)?; } }; - if let Err(e) = res { - self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); + if let Err(error) = res { + self.sess.emit_fatal(LibDefWriteFailure { error }); } } else if is_windows { let res: io::Result<()> = try { @@ -681,8 +681,8 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {}", symbol)?; } }; - if let Err(e) = res { - self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); + if let Err(error) = res { + self.sess.emit_fatal(LibDefWriteFailure { error }); } } else { // Write an LD version script @@ -972,8 +972,8 @@ impl<'a> Linker for MsvcLinker<'a> { writeln!(f, " {}", symbol)?; } }; - if let Err(e) = res { - self.sess.emit_fatal(LibDefWriteFailure { error_description: format!("{e}") }); + if let Err(error) = res { + self.sess.emit_fatal(LibDefWriteFailure { error }); } let mut arg = OsString::from("/DEF:"); arg.push(path); diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 718ad5c7bf566..13d9c1a7b6b8d 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,6 +1,7 @@ //! Errors emitted by codegen_ssa use rustc_macros::SessionDiagnostic; +use std::io::Error; #[derive(SessionDiagnostic)] #[diag(codegen_ssa::missing_native_static_library)] @@ -11,5 +12,5 @@ pub struct MissingNativeStaticLibrary<'a> { #[derive(SessionDiagnostic)] #[diag(codegen_ssa::lib_def_write_failure)] pub struct LibDefWriteFailure { - pub error_description: String, + pub error: Error, } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 597f3488fc1be..d84a774710ac1 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -1,3 +1,3 @@ codegen_ssa_missing_native_static_library = could not find native static library `{$library_name}`, perhaps an -L flag is missing? -codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error_description} +codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} From 086e70f13e9259d7949fbfeec6fa824c6327f42d Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Fri, 7 Oct 2022 10:03:45 -0400 Subject: [PATCH 08/18] UPDATE - migrate linker.rs to new diagnostics infra --- compiler/rustc_codegen_ssa/src/back/linker.rs | 35 ++++++++-------- compiler/rustc_codegen_ssa/src/errors.rs | 42 +++++++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 18 ++++++++ 3 files changed, 77 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e9335e53125f3..debcffcd326f6 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1,6 +1,6 @@ use super::command::Command; use super::symbol_export; -use crate::errors::LibDefWriteFailure; +use crate::errors; use rustc_span::symbol::sym; use std::ffi::{OsStr, OsString}; @@ -91,13 +91,13 @@ pub fn get_linker<'a>( arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a)); cmd.arg(&arg); } else { - warn!("arch is not supported"); + sess.emit_warning(errors::UnsupportedArch); } } else { - warn!("MSVC root path lib location not found"); + sess.emit_warning(errors::MsvcPathNotFound); } } else { - warn!("link.exe not found"); + sess.emit_warning(errors::LinkExeNotFound); } } @@ -435,11 +435,11 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 doesn't support these flags but macOS 11 // has -needed-l{} / -needed_library {} // but we have no way to detect that here. - self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + self.sess.emit_warning(errors::Ld64UnimplementedModifier); } else if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--no-as-needed"); } else { - self.sess.warn("`as-needed` modifier not supported for current linker"); + self.sess.emit_warning(errors::LinkerUnsupportedModifier); } } self.hint_dynamic(); @@ -493,7 +493,7 @@ impl<'a> Linker for GccLinker<'a> { // FIXME(81490): ld64 as of macOS 11 supports the -needed_framework // flag but we have no way to detect that here. // self.cmd.arg("-needed_framework").arg(framework); - self.sess.warn("`as-needed` modifier not implemented yet for ld64"); + self.sess.emit_warning(errors::Ld64UnimplementedModifier); } self.cmd.arg("-framework").arg(framework); } @@ -667,7 +667,7 @@ impl<'a> Linker for GccLinker<'a> { } }; if let Err(error) = res { - self.sess.emit_fatal(LibDefWriteFailure { error }); + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } } else if is_windows { let res: io::Result<()> = try { @@ -682,7 +682,7 @@ impl<'a> Linker for GccLinker<'a> { } }; if let Err(error) = res { - self.sess.emit_fatal(LibDefWriteFailure { error }); + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } } else { // Write an LD version script @@ -698,8 +698,8 @@ impl<'a> Linker for GccLinker<'a> { } writeln!(f, "\n local:\n *;\n}};")?; }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write version script: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::VersionScriptWriteFailure { error }); } } @@ -916,9 +916,8 @@ impl<'a> Linker for MsvcLinker<'a> { self.cmd.arg(arg); } } - Err(err) => { - self.sess - .warn(&format!("error enumerating natvis directory: {}", err)); + Err(error) => { + self.sess.emit_warning(errors::NoNatvisDirectory { error }); } } } @@ -973,7 +972,7 @@ impl<'a> Linker for MsvcLinker<'a> { } }; if let Err(error) = res { - self.sess.emit_fatal(LibDefWriteFailure { error }); + self.sess.emit_fatal(errors::LibDefWriteFailure { error }); } let mut arg = OsString::from("/DEF:"); arg.push(path); @@ -1436,7 +1435,7 @@ impl<'a> Linker for L4Bender<'a> { fn export_symbols(&mut self, _: &Path, _: CrateType, _: &[String]) { // ToDo, not implemented, copy from GCC - self.sess.warn("exporting symbols not implemented yet for L4Bender"); + self.sess.emit_warning(errors::L4BenderExportingSymbolsUnimplemented); return; } @@ -1728,8 +1727,8 @@ impl<'a> Linker for BpfLinker<'a> { writeln!(f, "{}", sym)?; } }; - if let Err(e) = res { - self.sess.fatal(&format!("failed to write symbols file: {}", e)); + if let Err(error) = res { + self.sess.emit_fatal(errors::SymbolFileWriteFailure { error }); } else { self.cmd.arg("--export-symbols").arg(&path); } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 13d9c1a7b6b8d..05d89b32618e7 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -14,3 +14,45 @@ pub struct MissingNativeStaticLibrary<'a> { pub struct LibDefWriteFailure { pub error: Error, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::version_script_write_failure)] +pub struct VersionScriptWriteFailure { + pub error: Error, +} + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::symbol_file_write_failure)] +pub struct SymbolFileWriteFailure { + pub error: Error, +} + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::unsupported_arch)] +pub struct UnsupportedArch; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::msvc_path_not_found)] +pub struct MsvcPathNotFound; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::link_exe_not_found)] +pub struct LinkExeNotFound; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::ld64_unimplemented_modifier)] +pub struct Ld64UnimplementedModifier; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::linker_unsupported_modifier)] +pub struct LinkerUnsupportedModifier; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::L4Bender_exporting_symbols_unimplemented)] +pub struct L4BenderExportingSymbolsUnimplemented; + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::no_natvis_directory)] +pub struct NoNatvisDirectory { + pub error: Error, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index d84a774710ac1..090a4dc9510b6 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -1,3 +1,21 @@ codegen_ssa_missing_native_static_library = could not find native static library `{$library_name}`, perhaps an -L flag is missing? codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} + +codegen_ssa_version_script_write_failure = failed to write version script: {$error} + +codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} + +codegen_ssa_unsupported_arch = arch is not supported + +codegen_ssa_msvc_path_not_found = MSVC root path lib location not found + +codegen_ssa_link_exe_not_found = link.exe not found + +codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64 + +codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker + +codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender + +codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} From d9197dbbcd35c69a210806cea18d2ce0f3691839 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 28 Aug 2022 19:58:12 -0400 Subject: [PATCH 09/18] UPDATE - migrate write.rs to new diagnostics infra --- compiler/rustc_codegen_ssa/src/back/write.rs | 41 ++++++++-------- compiler/rustc_codegen_ssa/src/errors.rs | 48 +++++++++++++++++++ .../locales/en-US/codegen_ssa.ftl | 8 ++++ 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 6188094bbbdd4..125b231b27486 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -2,11 +2,11 @@ use super::link::{self, ensure_removed}; use super::lto::{self, SerializedModule}; use super::symbol_export::symbol_name_for_instance_in_crate; +use crate::errors; +use crate::traits::*; use crate::{ CachedModuleCodegen, CodegenResults, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind, }; - -use crate::traits::*; use jobserver::{Acquired, Client}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::memmap::Mmap; @@ -530,7 +530,7 @@ fn produce_final_output_artifacts( // Produce final compile outputs. let copy_gracefully = |from: &Path, to: &Path| { if let Err(e) = fs::copy(from, to) { - sess.err(&format!("could not copy {:?} to {:?}: {}", from, to, e)); + sess.emit_err(errors::CopyPath::new(from, to, e)); } }; @@ -546,7 +546,7 @@ fn produce_final_output_artifacts( ensure_removed(sess.diagnostic(), &path); } } else { - let ext = crate_output + let extension = crate_output .temp_path(output_type, None) .extension() .unwrap() @@ -557,19 +557,11 @@ fn produce_final_output_artifacts( if crate_output.outputs.contains_key(&output_type) { // 2) Multiple codegen units, with `--emit foo=some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!( - "ignoring emit path because multiple .{} files \ - were produced", - ext - )); + sess.emit_warning(errors::IgnoringEmitPath { extension }); } else if crate_output.single_output_file.is_some() { // 3) Multiple codegen units, with `-o some_name`. We have // no good solution for this case, so warn the user. - sess.warn(&format!( - "ignoring -o because multiple .{} files \ - were produced", - ext - )); + sess.emit_warning(errors::IgnoringOutput { extension }); } else { // 4) Multiple codegen units, but no explicit name. We // just leave the `foo.0.x` files in place. @@ -880,14 +872,19 @@ fn execute_copy_from_cache_work_item( ); match link_or_copy(&source_file, &output_path) { Ok(_) => Some(output_path), - Err(err) => { - let diag_handler = cgcx.create_diag_handler(); - diag_handler.err(&format!( - "unable to copy {} to {}: {}", - source_file.display(), - output_path.display(), - err - )); + Err(_) => { + // FIXME: + // Should we add Translations support in Handler, or should we pass a session here ? + // + // As Luis Cardoso mentioned here https://github.com/rust-lang/rust/pull/100753#discussion_r952975345, + // Translations support in Handler is tricky because SessionDiagnostic is not a trait, + // and we can't implement it in Handler because rustc_errors cannot depend on rustc_session. + // + // As for passing a session here, my understanding is that all these errors should be reported via + // the Shared Handler, which leads us to probably having to support Translations in another way. + + // let diag_handler = cgcx.create_diag_handler(); + // diag_handler.emit_err(errors::CopyPathBuf { source_file, output_path, error }); None } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 05d89b32618e7..2ae5e659d2dac 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,7 +1,10 @@ //! Errors emitted by codegen_ssa +use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; use rustc_macros::SessionDiagnostic; +use std::borrow::Cow; use std::io::Error; +use std::path::{Path, PathBuf}; #[derive(SessionDiagnostic)] #[diag(codegen_ssa::missing_native_static_library)] @@ -56,3 +59,48 @@ pub struct L4BenderExportingSymbolsUnimplemented; pub struct NoNatvisDirectory { pub error: Error, } + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::copy_path_buf)] +pub struct CopyPathBuf { + pub source_file: PathBuf, + pub output_path: PathBuf, + pub error: Error, +} + +// Reports Paths using `Debug` implementation rather than Path's `Display` implementation. +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::copy_path)] +pub struct CopyPath<'a> { + from: DebugArgPath<'a>, + to: DebugArgPath<'a>, + error: Error, +} + +impl<'a> CopyPath<'a> { + pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> { + CopyPath { from: DebugArgPath { path: from }, to: DebugArgPath { path: to }, error } + } +} + +struct DebugArgPath<'a> { + pub path: &'a Path, +} + +impl IntoDiagnosticArg for DebugArgPath<'_> { + fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.path))) + } +} + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::ignoring_emit_path)] +pub struct IgnoringEmitPath { + pub extension: String, +} + +#[derive(SessionDiagnostic)] +#[diag(codegen_ssa::ignoring_output)] +pub struct IgnoringOutput { + pub extension: String, +} diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 090a4dc9510b6..0d021edc4f76c 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -19,3 +19,11 @@ codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error} + +codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error} + +codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error} + +codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced + +codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced From 67eb01c3f3c9ce8237bb09ecb4a77b3030af025b Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sat, 10 Sep 2022 13:16:37 -0400 Subject: [PATCH 10/18] UPDATE - codege-ssa errors to new Diagnostic macro name --- compiler/rustc_codegen_ssa/src/errors.rs | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 2ae5e659d2dac..8c09aa96c8ef2 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,66 +1,66 @@ //! Errors emitted by codegen_ssa use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; -use rustc_macros::SessionDiagnostic; +use rustc_macros::Diagnostic; use std::borrow::Cow; use std::io::Error; use std::path::{Path, PathBuf}; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::missing_native_static_library)] pub struct MissingNativeStaticLibrary<'a> { pub library_name: &'a str, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::lib_def_write_failure)] pub struct LibDefWriteFailure { pub error: Error, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::version_script_write_failure)] pub struct VersionScriptWriteFailure { pub error: Error, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::symbol_file_write_failure)] pub struct SymbolFileWriteFailure { pub error: Error, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::unsupported_arch)] pub struct UnsupportedArch; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::msvc_path_not_found)] pub struct MsvcPathNotFound; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::link_exe_not_found)] pub struct LinkExeNotFound; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::ld64_unimplemented_modifier)] pub struct Ld64UnimplementedModifier; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::linker_unsupported_modifier)] pub struct LinkerUnsupportedModifier; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::L4Bender_exporting_symbols_unimplemented)] pub struct L4BenderExportingSymbolsUnimplemented; -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::no_natvis_directory)] pub struct NoNatvisDirectory { pub error: Error, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::copy_path_buf)] pub struct CopyPathBuf { pub source_file: PathBuf, @@ -69,7 +69,7 @@ pub struct CopyPathBuf { } // Reports Paths using `Debug` implementation rather than Path's `Display` implementation. -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::copy_path)] pub struct CopyPath<'a> { from: DebugArgPath<'a>, @@ -93,13 +93,13 @@ impl IntoDiagnosticArg for DebugArgPath<'_> { } } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::ignoring_emit_path)] pub struct IgnoringEmitPath { pub extension: String, } -#[derive(SessionDiagnostic)] +#[derive(Diagnostic)] #[diag(codegen_ssa::ignoring_output)] pub struct IgnoringOutput { pub extension: String, From 7548d952af07e7df18bb894b3f470d321f4d6c04 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sat, 10 Sep 2022 13:24:46 -0400 Subject: [PATCH 11/18] UPDATE - resolve fixme and emit errors via Handler --- compiler/rustc_codegen_ssa/src/back/write.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 125b231b27486..1f577e9f3524f 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -872,19 +872,12 @@ fn execute_copy_from_cache_work_item( ); match link_or_copy(&source_file, &output_path) { Ok(_) => Some(output_path), - Err(_) => { - // FIXME: - // Should we add Translations support in Handler, or should we pass a session here ? - // - // As Luis Cardoso mentioned here https://github.com/rust-lang/rust/pull/100753#discussion_r952975345, - // Translations support in Handler is tricky because SessionDiagnostic is not a trait, - // and we can't implement it in Handler because rustc_errors cannot depend on rustc_session. - // - // As for passing a session here, my understanding is that all these errors should be reported via - // the Shared Handler, which leads us to probably having to support Translations in another way. - - // let diag_handler = cgcx.create_diag_handler(); - // diag_handler.emit_err(errors::CopyPathBuf { source_file, output_path, error }); + Err(error) => { + cgcx.create_diag_handler().emit_err(errors::CopyPathBuf { + source_file, + output_path, + error, + }); None } } From 0f97d4a1417cdf58b7a39e351dcdf40cf58e48b9 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Tue, 13 Sep 2022 08:46:47 -0400 Subject: [PATCH 12/18] DELETE - unused error after PR# 100101 was merged --- compiler/rustc_codegen_ssa/src/errors.rs | 6 ------ compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl | 2 -- 2 files changed, 8 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 8c09aa96c8ef2..cf98cb2468ab7 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -6,12 +6,6 @@ use std::borrow::Cow; use std::io::Error; use std::path::{Path, PathBuf}; -#[derive(Diagnostic)] -#[diag(codegen_ssa::missing_native_static_library)] -pub struct MissingNativeStaticLibrary<'a> { - pub library_name: &'a str, -} - #[derive(Diagnostic)] #[diag(codegen_ssa::lib_def_write_failure)] pub struct LibDefWriteFailure { diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 0d021edc4f76c..4d43b2eb0b696 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -1,5 +1,3 @@ -codegen_ssa_missing_native_static_library = could not find native static library `{$library_name}`, perhaps an -L flag is missing? - codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error} codegen_ssa_version_script_write_failure = failed to write version script: {$error} From 12aa84bdf3231f563b7f86186dbece2023d1235a Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Sun, 2 Oct 2022 23:21:15 -0400 Subject: [PATCH 13/18] ADD - initial port of link.rs --- compiler/rustc_codegen_ssa/src/back/link.rs | 89 ++++++-------- compiler/rustc_codegen_ssa/src/errors.rs | 109 +++++++++++++++++- compiler/rustc_codegen_ssa/src/lib.rs | 1 + .../locales/en-US/codegen_ssa.ftl | 25 ++++ 4 files changed, 166 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 9a0c379b4e44d..ac2a8f969df00 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -31,7 +31,9 @@ use super::command::Command; use super::linker::{self, Linker}; use super::metadata::{create_rmeta_file, MetadataPosition}; use super::rpath::{self, RPathConfig}; -use crate::{looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib}; +use crate::{ + errors, looks_like_rust_object_file, CodegenResults, CompiledModule, CrateInfo, NativeLib, +}; use cc::windows_registry; use regex::Regex; @@ -93,7 +95,7 @@ pub fn link_binary<'a>( let tmpdir = TempFileBuilder::new() .prefix("rustc") .tempdir() - .unwrap_or_else(|err| sess.fatal(&format!("couldn't create a temp dir: {}", err))); + .unwrap_or_else(|error| sess.emit_fatal(errors::CreateTempDir { error })); let path = MaybeTempDir::new(tmpdir, sess.opts.cg.save_temps); let out_filename = out_filename( sess, @@ -208,7 +210,7 @@ pub fn link_binary<'a>( pub fn each_linked_rlib( info: &CrateInfo, f: &mut dyn FnMut(CrateNum, &Path), -) -> Result<(), String> { +) -> Result<(), errors::LinkRlibError> { let crates = info.used_crates.iter(); let mut fmts = None; for (ty, list) in info.dependency_formats.iter() { @@ -224,26 +226,23 @@ pub fn each_linked_rlib( } } let Some(fmts) = fmts else { - return Err("could not find formats for rlibs".to_string()); + return Err(errors::LinkRlibError::MissingFormat); }; for &cnum in crates { match fmts.get(cnum.as_usize() - 1) { Some(&Linkage::NotLinked | &Linkage::IncludedFromDylib) => continue, Some(_) => {} - None => return Err("could not find formats for rlibs".to_string()), + None => return Err(errors::LinkRlibError::MissingFormat), } - let name = info.crate_name[&cnum]; + let crate_name = info.crate_name[&cnum]; let used_crate_source = &info.used_crate_source[&cnum]; if let Some((path, _)) = &used_crate_source.rlib { f(cnum, &path); } else { if used_crate_source.rmeta.is_some() { - return Err(format!( - "could not find rlib for: `{}`, found rmeta (metadata) file", - name - )); + return Err(errors::LinkRlibError::OnlyRmetaFound { crate_name }); } else { - return Err(format!("could not find rlib for: `{}`", name)); + return Err(errors::LinkRlibError::NotFound { crate_name }); } } } @@ -340,10 +339,7 @@ fn link_rlib<'a>( // -whole-archive and it isn't clear how we can currently handle such a // situation correctly. // See https://github.com/rust-lang/rust/issues/88085#issuecomment-901050897 - sess.err( - "the linking modifiers `+bundle` and `+whole-archive` are not compatible \ - with each other when generating rlibs", - ); + sess.emit_err(errors::IncompatibleLinkingModifiers); } NativeLibKind::Static { bundle: None | Some(true), .. } => {} NativeLibKind::Static { bundle: Some(false), .. } @@ -365,12 +361,11 @@ fn link_rlib<'a>( )); continue; } - ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|e| { - sess.fatal(&format!( - "failed to add native library {}: {}", - location.to_string_lossy(), - e - )); + ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| { + sess.emit_fatal(errors::AddNativeLibrary { + library_path: &location.to_string_lossy(), + error, + }); }); } } @@ -385,8 +380,11 @@ fn link_rlib<'a>( tmpdir.as_ref(), ); - ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| { - sess.fatal(&format!("failed to add native library {}: {}", output_path.display(), e)); + ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| { + sess.emit_fatal(errors::AddNativeLibrary { + library_path: &output_path.display().to_string(), + error, + }); }); } @@ -451,14 +449,11 @@ fn collate_raw_dylibs( // FIXME: when we add support for ordinals, figure out if we need to do anything // if we have two DllImport values with the same name but different ordinals. if import.calling_convention != old_import.calling_convention { - sess.span_err( - import.span, - &format!( - "multiple declarations of external function `{}` from \ - library `{}` have different calling conventions", - import.name, name, - ), - ); + sess.emit_err(errors::MultipleExternalFuncDecl { + span: import.span, + function: import.name, + library_name: &name, + }); } } } @@ -560,7 +555,7 @@ fn link_staticlib<'a>( all_native_libs.extend(codegen_results.crate_info.native_libraries[&cnum].iter().cloned()); }); if let Err(e) = res { - sess.fatal(&e); + sess.emit_fatal(e); } ab.build(out_filename); @@ -673,9 +668,8 @@ fn link_dwarf_object<'a>( }) { Ok(()) => {} Err(e) => { - sess.struct_err("linking dwarf objects with thorin failed") - .note(&format!("{:?}", e)) - .emit(); + let thorin_error = errors::ThorinErrorWrapper(e); + sess.emit_err(errors::ThorinDwarfLinking { thorin_error }); sess.abort_if_errors(); } } @@ -879,23 +873,14 @@ fn link_natively<'a>( let mut output = prog.stderr.clone(); output.extend_from_slice(&prog.stdout); let escaped_output = escape_string(&output); - let mut err = sess.struct_err(&format!( - "linking with `{}` failed: {}", - linker_path.display(), - prog.status - )); - err.note(&format!("{:?}", &cmd)).note(&escaped_output); - if escaped_output.contains("undefined reference to") { - err.help( - "some `extern` functions couldn't be found; some native libraries may \ - need to be installed or have their path specified", - ); - err.note("use the `-l` flag to specify native libraries to link"); - err.note("use the `cargo:rustc-link-lib` directive to specify the native \ - libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)"); - } - err.emit(); - + // FIXME: Add UI tests for this error. + let err = errors::LinkingFailed { + linker_path: &linker_path, + exit_status: prog.status, + command: &cmd, + escaped_output: &escaped_output, + }; + sess.diagnostic().emit_err(err); // If MSVC's `link.exe` was expected but the return code // is not a Microsoft LNK error then suggest a way to fix or // install the Visual Studio build tools. diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index cf98cb2468ab7..6bd1dc2e03f66 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,10 +1,16 @@ //! Errors emitted by codegen_ssa -use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; +use crate::back::command::Command; +use rustc_errors::{ + fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, + IntoDiagnosticArg, +}; use rustc_macros::Diagnostic; +use rustc_span::{Span, Symbol}; use std::borrow::Cow; use std::io::Error; use std::path::{Path, PathBuf}; +use std::process::ExitStatus; #[derive(Diagnostic)] #[diag(codegen_ssa::lib_def_write_failure)] @@ -73,17 +79,15 @@ pub struct CopyPath<'a> { impl<'a> CopyPath<'a> { pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> { - CopyPath { from: DebugArgPath { path: from }, to: DebugArgPath { path: to }, error } + CopyPath { from: DebugArgPath(from), to: DebugArgPath(to), error } } } -struct DebugArgPath<'a> { - pub path: &'a Path, -} +struct DebugArgPath<'a>(pub &'a Path); impl IntoDiagnosticArg for DebugArgPath<'_> { fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.path))) + DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0))) } } @@ -98,3 +102,96 @@ pub struct IgnoringEmitPath { pub struct IgnoringOutput { pub extension: String, } + +#[derive(Diagnostic)] +#[diag(codegen_ssa::create_temp_dir)] +pub struct CreateTempDir { + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::incompatible_linking_modifiers)] +pub struct IncompatibleLinkingModifiers; + +#[derive(Diagnostic)] +#[diag(codegen_ssa::add_native_library)] +pub struct AddNativeLibrary<'a> { + pub library_path: &'a str, + pub error: Error, +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::multiple_external_func_decl)] +pub struct MultipleExternalFuncDecl<'a> { + #[primary_span] + pub span: Span, + pub function: Symbol, + pub library_name: &'a str, +} + +pub enum LinkRlibError { + MissingFormat, + OnlyRmetaFound { crate_name: Symbol }, + NotFound { crate_name: Symbol }, +} + +impl IntoDiagnostic<'_, !> for LinkRlibError { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { + match self { + LinkRlibError::MissingFormat => { + handler.struct_fatal(fluent::codegen_ssa::rlib_missing_format) + } + LinkRlibError::OnlyRmetaFound { crate_name } => { + let mut diag = handler.struct_fatal(fluent::codegen_ssa::rlib_only_rmeta_found); + diag.set_arg("crate_name", crate_name); + diag + } + LinkRlibError::NotFound { crate_name } => { + let mut diag = handler.struct_fatal(fluent::codegen_ssa::rlib_not_found); + diag.set_arg("crate_name", crate_name); + diag + } + } + } +} + +#[derive(Diagnostic)] +#[diag(codegen_ssa::thorin_dwarf_linking)] +#[note] +pub struct ThorinDwarfLinking { + pub thorin_error: ThorinErrorWrapper, +} +pub struct ThorinErrorWrapper(pub thorin::Error); + +// FIXME: How should we support translations for external crate errors? +impl IntoDiagnosticArg for ThorinErrorWrapper { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0))) + } +} + +pub struct LinkingFailed<'a> { + pub linker_path: &'a PathBuf, + pub exit_status: ExitStatus, + pub command: &'a Command, + pub escaped_output: &'a str, +} + +impl IntoDiagnostic<'_> for LinkingFailed<'_> { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag = handler.struct_err(fluent::codegen_ssa::linking_failed); + diag.set_arg("linker_path", format!("{}", self.linker_path.display())); + diag.set_arg("exit_status", format!("{}", self.exit_status)); + + diag.note(format!("{:?}", self.command)).note(self.escaped_output); + + // Trying to match an error from OS linkers + // which by now we have no way to translate. + if self.escaped_output.contains("undefined reference to") { + diag.note(fluent::codegen_ssa::extern_funcs_not_found) + .note(fluent::codegen_ssa::specify_libraries_to_link) + .note(fluent::codegen_ssa::use_cargo_directive); + } + diag + } +} diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index e62b6f342b2e9..ceebe4d417f7d 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -6,6 +6,7 @@ #![feature(strict_provenance)] #![feature(int_roundings)] #![feature(if_let_guard)] +#![feature(never_type)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 4d43b2eb0b696..d996a096a892e 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -25,3 +25,28 @@ codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$e codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced + +codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error} + +codegen_ssa_incompatible_linking_modifiers = the linking modifiers `+bundle` and `+whole-archive` are not compatible with each other when generating rlibs + +codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error} + +codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions + +codegen_ssa_rlib_missing_format = could not find formats for rlibs + +codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file + +codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}` + +codegen_ssa_thorin_dwarf_linking = linking dwarf objects with thorin failed + .note = {$thorin_error} + +codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} + +codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified + +codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link + +codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname) From a25f939170bb73d813c5eb4cbed631253ba0cc15 Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Tue, 4 Oct 2022 13:25:13 -0400 Subject: [PATCH 14/18] Address PR comments - UPDATE - revert migration of logs - UPDATE - use derive on LinkRlibError enum - [Gardening] UPDATE - alphabetically sort fluent_messages - UPDATE - use PathBuf and unify both AddNativeLibrary to use Display (which is what PathBuf uses when conforming to IntoDiagnosticArg) - UPDATE - fluent messages sort after rebase --- compiler/rustc_codegen_ssa/src/back/link.rs | 10 +---- compiler/rustc_codegen_ssa/src/back/linker.rs | 6 +-- compiler/rustc_codegen_ssa/src/errors.rs | 42 ++++--------------- .../locales/en-US/codegen_ssa.ftl | 6 --- compiler/rustc_error_messages/src/lib.rs | 4 +- 5 files changed, 15 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ac2a8f969df00..e798fb421df31 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -362,10 +362,7 @@ fn link_rlib<'a>( continue; } ab.add_archive(&location, Box::new(|_| false)).unwrap_or_else(|error| { - sess.emit_fatal(errors::AddNativeLibrary { - library_path: &location.to_string_lossy(), - error, - }); + sess.emit_fatal(errors::AddNativeLibrary { library_path: location, error }); }); } } @@ -381,10 +378,7 @@ fn link_rlib<'a>( ); ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| { - sess.emit_fatal(errors::AddNativeLibrary { - library_path: &output_path.display().to_string(), - error, - }); + sess.emit_fatal(errors::AddNativeLibrary { library_path: output_path, error }); }); } diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index debcffcd326f6..bad22ccb1fedd 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -91,13 +91,13 @@ pub fn get_linker<'a>( arg.push(format!("{}\\lib\\{}\\store", root_lib_path.display(), a)); cmd.arg(&arg); } else { - sess.emit_warning(errors::UnsupportedArch); + warn!("arch is not supported"); } } else { - sess.emit_warning(errors::MsvcPathNotFound); + warn!("MSVC root path lib location not found"); } } else { - sess.emit_warning(errors::LinkExeNotFound); + warn!("link.exe not found"); } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index 6bd1dc2e03f66..bd399ffb5a6f9 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -30,18 +30,6 @@ pub struct SymbolFileWriteFailure { pub error: Error, } -#[derive(Diagnostic)] -#[diag(codegen_ssa::unsupported_arch)] -pub struct UnsupportedArch; - -#[derive(Diagnostic)] -#[diag(codegen_ssa::msvc_path_not_found)] -pub struct MsvcPathNotFound; - -#[derive(Diagnostic)] -#[diag(codegen_ssa::link_exe_not_found)] -pub struct LinkExeNotFound; - #[derive(Diagnostic)] #[diag(codegen_ssa::ld64_unimplemented_modifier)] pub struct Ld64UnimplementedModifier; @@ -115,8 +103,8 @@ pub struct IncompatibleLinkingModifiers; #[derive(Diagnostic)] #[diag(codegen_ssa::add_native_library)] -pub struct AddNativeLibrary<'a> { - pub library_path: &'a str, +pub struct AddNativeLibrary { + pub library_path: PathBuf, pub error: Error, } @@ -129,30 +117,16 @@ pub struct MultipleExternalFuncDecl<'a> { pub library_name: &'a str, } +#[derive(Diagnostic)] pub enum LinkRlibError { + #[diag(codegen_ssa::rlib_missing_format)] MissingFormat, + + #[diag(codegen_ssa::rlib_only_rmeta_found)] OnlyRmetaFound { crate_name: Symbol }, - NotFound { crate_name: Symbol }, -} -impl IntoDiagnostic<'_, !> for LinkRlibError { - fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> { - match self { - LinkRlibError::MissingFormat => { - handler.struct_fatal(fluent::codegen_ssa::rlib_missing_format) - } - LinkRlibError::OnlyRmetaFound { crate_name } => { - let mut diag = handler.struct_fatal(fluent::codegen_ssa::rlib_only_rmeta_found); - diag.set_arg("crate_name", crate_name); - diag - } - LinkRlibError::NotFound { crate_name } => { - let mut diag = handler.struct_fatal(fluent::codegen_ssa::rlib_not_found); - diag.set_arg("crate_name", crate_name); - diag - } - } - } + #[diag(codegen_ssa::rlib_not_found)] + NotFound { crate_name: Symbol }, } #[derive(Diagnostic)] diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index d996a096a892e..99ddf6842dab8 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -4,12 +4,6 @@ codegen_ssa_version_script_write_failure = failed to write version script: {$err codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error} -codegen_ssa_unsupported_arch = arch is not supported - -codegen_ssa_msvc_path_not_found = MSVC root path lib location not found - -codegen_ssa_link_exe_not_found = link.exe not found - codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64 codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 10f8efdffa8b6..77f87d5b007e3 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -40,9 +40,10 @@ fluent_messages! { attr => "../locales/en-US/attr.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + codegen_gcc => "../locales/en-US/codegen_gcc.ftl", + codegen_ssa => "../locales/en-US/codegen_ssa.ftl", compiletest => "../locales/en-US/compiletest.ftl", const_eval => "../locales/en-US/const_eval.ftl", - codegen_gcc => "../locales/en-US/codegen_gcc.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", hir_analysis => "../locales/en-US/hir_analysis.ftl", @@ -63,7 +64,6 @@ fluent_messages! { symbol_mangling => "../locales/en-US/symbol_mangling.ftl", trait_selection => "../locales/en-US/trait_selection.ftl", ty_utils => "../locales/en-US/ty_utils.ftl", - codegen_ssa => "../locales/en-US/codegen_ssa.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; From 13d4f27c829a332f50a2109647f3b16bce119b8d Mon Sep 17 00:00:00 2001 From: Jhonny Bill Mena Date: Tue, 4 Oct 2022 13:21:22 -0400 Subject: [PATCH 15/18] ADD - implement IntoDiagnostic for thorin::Error wrapper --- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- compiler/rustc_codegen_ssa/src/errors.rs | 202 +++++++++++++++++- .../locales/en-US/codegen_ssa.ftl | 79 ++++++- 3 files changed, 269 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e798fb421df31..95e72184ff037 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -662,8 +662,7 @@ fn link_dwarf_object<'a>( }) { Ok(()) => {} Err(e) => { - let thorin_error = errors::ThorinErrorWrapper(e); - sess.emit_err(errors::ThorinDwarfLinking { thorin_error }); + sess.emit_err(errors::ThorinErrorWrapper(e)); sess.abort_if_errors(); } } diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index bd399ffb5a6f9..0ffe887202261 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -129,18 +129,200 @@ pub enum LinkRlibError { NotFound { crate_name: Symbol }, } -#[derive(Diagnostic)] -#[diag(codegen_ssa::thorin_dwarf_linking)] -#[note] -pub struct ThorinDwarfLinking { - pub thorin_error: ThorinErrorWrapper, -} pub struct ThorinErrorWrapper(pub thorin::Error); -// FIXME: How should we support translations for external crate errors? -impl IntoDiagnosticArg for ThorinErrorWrapper { - fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self.0))) +impl IntoDiagnostic<'_> for ThorinErrorWrapper { + fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let mut diag; + match self.0 { + thorin::Error::ReadInput(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_read_input_failure); + diag + } + thorin::Error::ParseFileKind(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_file_kind); + diag + } + thorin::Error::ParseObjectFile(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_object_file); + diag + } + thorin::Error::ParseArchiveFile(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_input_archive_file); + diag + } + thorin::Error::ParseArchiveMember(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_archive_member); + diag + } + thorin::Error::InvalidInputKind => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_invalid_input_kind); + diag + } + thorin::Error::DecompressData(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_decompress_data); + diag + } + thorin::Error::NamelessSection(_, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_section_without_name); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::RelocationWithInvalidSymbol(section, offset) => { + diag = + handler.struct_err(fluent::codegen_ssa::thorin_relocation_with_invalid_symbol); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::MultipleRelocations(section, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_relocations); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::UnsupportedRelocation(section, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_unsupported_relocation); + diag.set_arg("section", section); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::MissingDwoName(id) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_dwo_name); + diag.set_arg("id", format!("0x{:08x}", id)); + diag + } + thorin::Error::NoCompilationUnits => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_no_compilation_units); + diag + } + thorin::Error::NoDie => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_no_die); + diag + } + thorin::Error::TopLevelDieNotUnit => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_top_level_die_not_unit); + diag + } + thorin::Error::MissingRequiredSection(section) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_required_section); + diag.set_arg("section", section); + diag + } + thorin::Error::ParseUnitAbbreviations(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_abbreviations); + diag + } + thorin::Error::ParseUnitAttribute(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_attribute); + diag + } + thorin::Error::ParseUnitHeader(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit_header); + diag + } + thorin::Error::ParseUnit(_) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_unit); + diag + } + thorin::Error::IncompatibleIndexVersion(section, format, actual) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_incompatible_index_version); + diag.set_arg("section", section); + diag.set_arg("actual", actual); + diag.set_arg("format", format); + diag + } + thorin::Error::OffsetAtIndex(_, index) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_offset_at_index); + diag.set_arg("index", index); + diag + } + thorin::Error::StrAtOffset(_, offset) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_str_at_offset); + diag.set_arg("offset", format!("0x{:08x}", offset)); + diag + } + thorin::Error::ParseIndex(_, section) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_parse_index); + diag.set_arg("section", section); + diag + } + thorin::Error::UnitNotInIndex(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_unit_not_in_index); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::RowNotInIndex(_, row) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_row_not_in_index); + diag.set_arg("row", row); + diag + } + thorin::Error::SectionNotInRow => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_section_not_in_row); + diag + } + thorin::Error::EmptyUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_empty_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::MultipleDebugInfoSection => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_debug_info_section); + diag + } + thorin::Error::MultipleDebugTypesSection => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_multiple_debug_types_section); + diag + } + thorin::Error::NotSplitUnit => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_not_split_unit); + diag + } + thorin::Error::DuplicateUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_duplicate_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::MissingReferencedUnit(unit) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_missing_referenced_unit); + diag.set_arg("unit", format!("0x{:08x}", unit)); + diag + } + thorin::Error::NoOutputObjectCreated => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_not_output_object_created); + diag + } + thorin::Error::MixedInputEncodings => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_mixed_input_encodings); + diag + } + thorin::Error::Io(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_io); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::ObjectRead(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_object_read); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::ObjectWrite(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_object_write); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::GimliRead(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_gimli_read); + diag.set_arg("error", format!("{e}")); + diag + } + thorin::Error::GimliWrite(e) => { + diag = handler.struct_err(fluent::codegen_ssa::thorin_gimli_write); + diag.set_arg("error", format!("{e}")); + diag + } + _ => unimplemented!("Untranslated thorin error"), + } } } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl index 99ddf6842dab8..0d0388a039e2d 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl @@ -34,9 +34,6 @@ codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, fo codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}` -codegen_ssa_thorin_dwarf_linking = linking dwarf objects with thorin failed - .note = {$thorin_error} - codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status} codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified @@ -44,3 +41,79 @@ codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname) + +codegen_ssa_thorin_read_input_failure = failed to read input file + +codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind + +codegen_ssa_thorin_parse_input_object_file = failed to parse input object file + +codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file + +codegen_ssa_thorin_parse_archive_member = failed to parse archive member + +codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object + +codegen_ssa_thorin_decompress_data = failed to decompress compressed section + +codegen_ssa_thorin_section_without_name = section without name at offset {$offset} + +codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset} + +codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset} + +codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset} + +codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id}) + +codegen_ssa_thorin_no_compilation_units = input object has no compilation units + +codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit + +codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit + +codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}` + +codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations + +codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute + +codegen_ssa_thorin_parse_unit_header = failed to parse unit header + +codegen_ssa_thorin_parse_unit = failed to parse unit + +codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format} + +codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section + +codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section + +codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section + +codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index + +codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index + +codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index + +codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data + +codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections + +codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package + +codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier) + +codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit}) + +codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found + +codegen_ssa_thorin_not_output_object_created = no output object was created from inputs + +codegen_ssa_thorin_mixed_input_encodings = input objects haved mixed encodings + +codegen_ssa_thorin_io = {$error} +codegen_ssa_thorin_object_read = {$error} +codegen_ssa_thorin_object_write = {$error} +codegen_ssa_thorin_gimli_read = {$error} +codegen_ssa_thorin_gimli_write = {$error} From c1c159fe86317eee433ed77bcc6bb349cc941828 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 9 Oct 2022 06:54:00 +0000 Subject: [PATCH 16/18] Unify tcx.constness and param env constness checks --- .../src/const_eval/fn_queries.rs | 72 ++++++++++++++----- compiler/rustc_metadata/src/rmeta/encoder.rs | 56 +++++++++++---- compiler/rustc_ty_utils/src/ty.rs | 69 +----------------- 3 files changed, 98 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index f1674d04f8d15..cdcebb61c2e8c 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -25,12 +25,10 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return /// `Constness::NotConst`. fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { - let def_id = def_id.expect_local(); - let node = tcx.hir().get_by_def_id(def_id); - - match node { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + match tcx.hir().get(hir_id) { hir::Node::Ctor(_) => hir::Constness::Const, - hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, + hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other // foreign items cannot be evaluated at compile-time. @@ -41,20 +39,62 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { }; if is_const { hir::Constness::Const } else { hir::Constness::NotConst } } - _ => { - if let Some(fn_kind) = node.fn_kind() { - if fn_kind.constness() == hir::Constness::Const { - return hir::Constness::Const; - } - // If the function itself is not annotated with `const`, it may still be a `const fn` - // if it resides in a const trait impl. - let is_const = is_parent_const_impl_raw(tcx, def_id); - if is_const { hir::Constness::Const } else { hir::Constness::NotConst } - } else { - hir::Constness::NotConst + hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) + if tcx.is_const_default_method(def_id) => + { + hir::Constness::Const + } + + hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. }) + | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. }) + | hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. }) + | hir::Node::AnonConst(_) + | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) + | hir::Node::ImplItem(hir::ImplItem { + kind: + hir::ImplItemKind::Fn( + hir::FnSig { + header: hir::FnHeader { constness: hir::Constness::Const, .. }, + .. + }, + .., + ), + .. + }) => hir::Constness::Const, + + hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..), + .. + }) => { + let parent_hir_id = tcx.hir().get_parent_node(hir_id); + match tcx.hir().get(parent_hir_id) { + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), + .. + }) => *constness, + _ => span_bug!( + tcx.def_span(parent_hir_id.owner), + "impl item's parent node is not an impl", + ), } } + + hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..), + .. + }) + | hir::Node::TraitItem(hir::TraitItem { + kind: + hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..), + .. + }) + | hir::Node::Item(hir::Item { + kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), + .. + }) => *constness, + + _ => hir::Constness::NotConst, } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3fc10197b9129..ab4ecec2af36e 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1059,6 +1059,43 @@ fn should_encode_const(def_kind: DefKind) -> bool { } } +fn should_encode_constness(def_kind: DefKind) -> bool { + match def_kind { + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Trait + | DefKind::AssocTy + | DefKind::Fn + | DefKind::Const + | DefKind::Static(..) + | DefKind::Ctor(..) + | DefKind::AssocFn + | DefKind::AssocConst + | DefKind::AnonConst + | DefKind::InlineConst + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder + | DefKind::Impl + | DefKind::Closure + | DefKind::Generator => true, + DefKind::Variant + | DefKind::TyAlias + | DefKind::TraitAlias + | DefKind::ForeignTy + | DefKind::Field + | DefKind::TyParam + | DefKind::Mod + | DefKind::ForeignMod + | DefKind::ConstParam + | DefKind::Macro(..) + | DefKind::Use + | DefKind::LifetimeParam + | DefKind::GlobalAsm + | DefKind::ExternCrate => false, + } +} + fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { if tcx.def_kind(def_id) != DefKind::AssocFn { return false; @@ -1165,6 +1202,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { record!(self.tables.trait_impl_trait_tys[def_id] <- table); } + if should_encode_constness(def_kind) { + self.tables.constness.set(def_id.index, tcx.constness(def_id)); + } } let inherent_impls = tcx.crate_inherent_impls(()); for (def_id, implementations) in inherent_impls.inherent_impls.iter() { @@ -1192,7 +1232,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; record!(self.tables.variant_data[def_id] <- data); - self.tables.constness.set(def_id.index, hir::Constness::Const); record_array!(self.tables.children[def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index @@ -1220,7 +1259,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; record!(self.tables.variant_data[def_id] <- data); - self.tables.constness.set(def_id.index, hir::Constness::Const); if variant.ctor_kind == CtorKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } @@ -1284,7 +1322,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.variant_data[def_id] <- data); - self.tables.constness.set(def_id.index, hir::Constness::Const); if variant.ctor_kind == CtorKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } @@ -1320,7 +1357,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } }; self.tables.asyncness.set(def_id.index, m_sig.header.asyncness); - self.tables.constness.set(def_id.index, hir::Constness::NotConst); } ty::AssocKind::Type => { self.encode_explicit_item_bounds(def_id); @@ -1345,13 +1381,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() }; self.tables.asyncness.set(def_id.index, sig.header.asyncness); record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); - // Can be inside `impl const Trait`, so using sig.header.constness is not reliable - let constness = if self.tcx.is_const_fn_raw(def_id) { - hir::Constness::Const - } else { - hir::Constness::NotConst - }; - self.tables.constness.set(def_id.index, constness); } ty::AssocKind::Const | ty::AssocKind::Type => {} } @@ -1474,7 +1503,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Fn(ref sig, .., body) => { self.tables.asyncness.set(def_id.index, sig.header.asyncness); record_array!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); - self.tables.constness.set(def_id.index, sig.header.constness); } hir::ItemKind::Macro(ref macro_def, _) => { if macro_def.macro_rules { @@ -1495,7 +1523,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Struct(ref struct_def, _) => { let adt_def = self.tcx.adt_def(def_id); record!(self.tables.repr_options[def_id] <- adt_def.repr()); - self.tables.constness.set(def_id.index, hir::Constness::Const); // Encode def_ids for each field and method // for methods, write all the stuff get_trait_method @@ -1524,9 +1551,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { is_non_exhaustive: variant.is_field_list_non_exhaustive(), }); } - hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { + hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => { self.tables.impl_defaultness.set(def_id.index, *defaultness); - self.tables.constness.set(def_id.index, *constness); let trait_ref = self.tcx.impl_trait_ref(def_id); if let Some(trait_ref) = trait_ref { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 30efbf6617598..344426a18bca5 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -133,77 +133,10 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { let local_did = def_id.as_local(); let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)); - let constness = match hir_id { - Some(hir_id) => match tcx.hir().get(hir_id) { - hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. }) - if tcx.is_const_default_method(def_id) => - { - hir::Constness::Const - } - - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. }) - | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. }) - | hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Const(..), .. - }) - | hir::Node::AnonConst(_) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) - | hir::Node::ImplItem(hir::ImplItem { - kind: - hir::ImplItemKind::Fn( - hir::FnSig { - header: hir::FnHeader { constness: hir::Constness::Const, .. }, - .. - }, - .., - ), - .. - }) => hir::Constness::Const, - - hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..), - .. - }) => { - let parent_hir_id = tcx.hir().get_parent_node(hir_id); - match tcx.hir().get(parent_hir_id) { - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), - .. - }) => *constness, - _ => span_bug!( - tcx.def_span(parent_hir_id.owner), - "impl item's parent node is not an impl", - ), - } - } - - hir::Node::Item(hir::Item { - kind: - hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..), - .. - }) - | hir::Node::TraitItem(hir::TraitItem { - kind: - hir::TraitItemKind::Fn( - hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, - .., - ), - .. - }) - | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), - .. - }) => *constness, - - _ => hir::Constness::NotConst, - }, - None => hir::Constness::NotConst, - }; - let unnormalized_env = ty::ParamEnv::new( tcx.intern_predicates(&predicates), traits::Reveal::UserFacing, - constness, + tcx.constness(def_id), ); let body_id = From 68260289b5afa6728c32378c581e67c714ea4263 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Tue, 11 Oct 2022 02:43:36 +0900 Subject: [PATCH 17/18] fix #102878 --- compiler/rustc_error_messages/src/lib.rs | 13 ----- compiler/rustc_expand/src/mbe/macro_rules.rs | 19 ++++--- src/test/ui/macros/issue-102878.rs | 10 ++++ src/test/ui/macros/issue-102878.stderr | 60 ++++++++++++++++++++ 4 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 src/test/ui/macros/issue-102878.rs create mode 100644 src/test/ui/macros/issue-102878.stderr diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 18be60975e4eb..9a7cb955f216f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -336,19 +336,6 @@ impl DiagnosticMessage { } } } - - /// Returns the `String` contained within the `DiagnosticMessage::Str` variant, assuming that - /// this diagnostic message is of the legacy, non-translatable variety. Panics if this - /// assumption does not hold. - /// - /// Don't use this - it exists to support some places that do comparison with diagnostic - /// strings. - pub fn expect_str(&self) -> &str { - match self { - DiagnosticMessage::Str(s) => s, - _ => panic!("expected non-translatable diagnostic message"), - } - } } /// `From` impl that enables existing diagnostic calls to functions which now take diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 6d2c7aac6af49..30aa4f0fa3482 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -14,7 +14,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage}; use rustc_feature::Features; use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, @@ -68,19 +68,22 @@ fn emit_frag_parse_err( kind: AstFragmentKind, ) { // FIXME(davidtwco): avoid depending on the error message text - if parser.token == token::Eof && e.message[0].0.expect_str().ends_with(", found ``") { - if !e.span.is_dummy() { - // early end of macro arm (#52866) - e.replace_span_with(parser.sess.source_map().next_point(parser.token.span)); - } + if parser.token == token::Eof + && let DiagnosticMessage::Str(message) = &e.message[0].0 + && message.ends_with(", found ``") + { let msg = &e.message[0]; e.message[0] = ( - rustc_errors::DiagnosticMessage::Str(format!( + DiagnosticMessage::Str(format!( "macro expansion ends with an incomplete expression: {}", - msg.0.expect_str().replace(", found ``", ""), + message.replace(", found ``", ""), )), msg.1, ); + if !e.span.is_dummy() { + // early end of macro arm (#52866) + e.replace_span_with(parser.sess.source_map().next_point(parser.token.span)); + } } if e.span.is_dummy() { // Get around lack of span in error (#30128) diff --git a/src/test/ui/macros/issue-102878.rs b/src/test/ui/macros/issue-102878.rs new file mode 100644 index 0000000000000..aac5891939e0c --- /dev/null +++ b/src/test/ui/macros/issue-102878.rs @@ -0,0 +1,10 @@ +macro_rules!test{($l:expr,$_:r)=>({const:y y)} +//~^ ERROR mismatched closing delimiter: `)` +//~| ERROR invalid fragment specifier `r` +//~| ERROR expected identifier, found keyword `const` +//~| ERROR expected identifier, found keyword `const` +//~| ERROR expected identifier, found `:` + +fn s(){test!(1,i)} + +fn main() {} diff --git a/src/test/ui/macros/issue-102878.stderr b/src/test/ui/macros/issue-102878.stderr new file mode 100644 index 0000000000000..e0b8855a38d05 --- /dev/null +++ b/src/test/ui/macros/issue-102878.stderr @@ -0,0 +1,60 @@ +error: mismatched closing delimiter: `)` + --> $DIR/issue-102878.rs:1:35 + | +LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} + | -^ ^ mismatched closing delimiter + | || + | |unclosed delimiter + | closing delimiter possibly meant for this + +error: invalid fragment specifier `r` + --> $DIR/issue-102878.rs:1:27 + | +LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} + | ^^^^ + | + = help: valid fragment specifiers are `ident`, `block`, `stmt`, `expr`, `pat`, `ty`, `lifetime`, `literal`, `path`, `meta`, `tt`, `item` and `vis` + +error: expected identifier, found keyword `const` + --> $DIR/issue-102878.rs:1:36 + | +LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} + | ^^^^^ expected identifier, found keyword +... +LL | fn s(){test!(1,i)} + | ---------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: escape `const` to use it as an identifier + | +LL | macro_rules!test{($l:expr,$_:r)=>({r#const:y y)} + | ++ + +error: expected identifier, found keyword `const` + --> $DIR/issue-102878.rs:1:36 + | +LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} + | ^^^^^ expected identifier, found keyword +... +LL | fn s(){test!(1,i)} + | ---------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) +help: escape `const` to use it as an identifier + | +LL | macro_rules!test{($l:expr,$_:r)=>({r#const:y y)} + | ++ + +error: expected identifier, found `:` + --> $DIR/issue-102878.rs:1:41 + | +LL | macro_rules!test{($l:expr,$_:r)=>({const:y y)} + | ^ expected identifier +... +LL | fn s(){test!(1,i)} + | ---------- in this macro invocation + | + = note: this error originates in the macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 5 previous errors + From 152cd6322655bb5173655cdf0781ca64c2a7602f Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 10 Aug 2022 21:31:26 +0200 Subject: [PATCH 18/18] Report duplicate definitions in trait impls during resolution. --- .../rustc_hir_analysis/src/impl_wf_check.rs | 3 ++ compiler/rustc_resolve/src/diagnostics.rs | 13 ++++++++ compiler/rustc_resolve/src/late.rs | 33 +++++++++++++++++-- compiler/rustc_resolve/src/lib.rs | 2 ++ .../associated-item-duplicate-names-3.rs | 1 + .../associated-item-duplicate-names-3.stderr | 18 +++++++--- .../associated-item-duplicate-names.stderr | 14 +++++--- src/test/ui/error-codes/E0201.stderr | 30 ++++++++++------- src/test/ui/hygiene/impl_items-2.rs | 26 +++++++++++++++ src/test/ui/hygiene/impl_items-2.stderr | 15 +++++++++ src/test/ui/traits/issue-8153.stderr | 7 ++-- 11 files changed, 137 insertions(+), 25 deletions(-) create mode 100644 src/test/ui/hygiene/impl_items-2.rs create mode 100644 src/test/ui/hygiene/impl_items-2.stderr diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index c499364056ff9..69155a422b062 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -197,6 +197,9 @@ fn report_unused_parameter(tcx: TyCtxt<'_>, span: Span, kind: &str, name: Symbol /// Enforce that we do not have two items in an impl with the same name. fn enforce_impl_items_are_distinct(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) { + if tcx.impl_trait_ref(impl_def_id).is_some() { + return; + } let mut seen_type_items = FxHashMap::default(); let mut seen_value_items = FxHashMap::default(); for &impl_item_ref in tcx.associated_item_def_ids(impl_def_id) { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 98982240af27f..75c016af2f92f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1047,6 +1047,19 @@ impl<'a> Resolver<'a> { err.span_label(trait_item_span, "item in trait"); err } + ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => { + let mut err = struct_span_err!( + self.session, + span, + E0201, + "duplicate definitions with name `{}`:", + name, + ); + err.span_label(old_span, "previous definition here"); + err.span_label(trait_item_span, "item in trait"); + err.span_label(span, "duplicate definition"); + err + } ResolutionError::InvalidAsmSym => { let mut err = self.session.struct_span_err(span, "invalid `sym` operand"); err.span_label(span, "is a local variable"); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 431507e8e0f63..9fc8401fa07f5 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2619,8 +2619,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { this.with_current_self_type(self_type, |this| { this.with_self_rib_ns(ValueNS, Res::SelfCtor(item_def_id), |this| { debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)"); + let mut seen_trait_items = Default::default(); for item in impl_items { - this.resolve_impl_item(&**item); + this.resolve_impl_item(&**item, &mut seen_trait_items); } }); }); @@ -2634,7 +2635,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ); } - fn resolve_impl_item(&mut self, item: &'ast AssocItem) { + fn resolve_impl_item( + &mut self, + item: &'ast AssocItem, + seen_trait_items: &mut FxHashMap, + ) { use crate::ResolutionError::*; match &item.kind { AssocItemKind::Const(_, ty, default) => { @@ -2647,6 +2652,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &item.kind, ValueNS, item.span, + seen_trait_items, |i, s, c| ConstNotMemberOfTrait(i, s, c), ); @@ -2687,6 +2693,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &item.kind, ValueNS, item.span, + seen_trait_items, |i, s, c| MethodNotMemberOfTrait(i, s, c), ); @@ -2715,6 +2722,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { &item.kind, TypeNS, item.span, + seen_trait_items, |i, s, c| TypeNotMemberOfTrait(i, s, c), ); @@ -2736,6 +2744,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { kind: &AssocItemKind, ns: Namespace, span: Span, + seen_trait_items: &mut FxHashMap, err: F, ) where F: FnOnce(Ident, String, Option) -> ResolutionError<'a>, @@ -2768,7 +2777,25 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }; let res = binding.res(); - let Res::Def(def_kind, _) = res else { bug!() }; + let Res::Def(def_kind, id_in_trait) = res else { bug!() }; + + match seen_trait_items.entry(id_in_trait) { + Entry::Occupied(entry) => { + self.report_error( + span, + ResolutionError::TraitImplDuplicate { + name: ident.name, + old_span: *entry.get(), + trait_item_span: binding.span, + }, + ); + return; + } + Entry::Vacant(entry) => { + entry.insert(span); + } + }; + match (def_kind, kind) { (DefKind::AssocTy, AssocItemKind::TyAlias(..)) | (DefKind::AssocFn, AssocItemKind::Fn(..)) diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9173c3692ce6c..4c9e14db3c43a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -236,6 +236,8 @@ enum ResolutionError<'a> { trait_item_span: Span, code: rustc_errors::DiagnosticId, }, + /// Error E0201: multiple impl items for the same trait item. + TraitImplDuplicate { name: Symbol, trait_item_span: Span, old_span: Span }, /// Inline asm `sym` operand must refer to a `fn` or `static`. InvalidAsmSym, } diff --git a/src/test/ui/associated-item/associated-item-duplicate-names-3.rs b/src/test/ui/associated-item/associated-item-duplicate-names-3.rs index 6aa1b483eebdd..3a70a2f943ffd 100644 --- a/src/test/ui/associated-item/associated-item-duplicate-names-3.rs +++ b/src/test/ui/associated-item/associated-item-duplicate-names-3.rs @@ -16,4 +16,5 @@ impl Foo for Baz { fn main() { let x: Baz::Bar = 5; + //~^ ERROR ambiguous associated type } diff --git a/src/test/ui/associated-item/associated-item-duplicate-names-3.stderr b/src/test/ui/associated-item/associated-item-duplicate-names-3.stderr index 03782f6634800..bf4bd634cf1d4 100644 --- a/src/test/ui/associated-item/associated-item-duplicate-names-3.stderr +++ b/src/test/ui/associated-item/associated-item-duplicate-names-3.stderr @@ -1,11 +1,21 @@ error[E0201]: duplicate definitions with name `Bar`: --> $DIR/associated-item-duplicate-names-3.rs:14:5 | +LL | type Bar; + | --------- item in trait +... LL | type Bar = i16; - | -------- previous definition of `Bar` here + | --------------- previous definition here LL | type Bar = u16; - | ^^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^ duplicate definition -error: aborting due to previous error +error[E0223]: ambiguous associated type + --> $DIR/associated-item-duplicate-names-3.rs:18:12 + | +LL | let x: Baz::Bar = 5; + | ^^^^^^^^ help: use fully-qualified syntax: `::Bar` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0201`. +Some errors have detailed explanations: E0201, E0223. +For more information about an error, try `rustc --explain E0201`. diff --git a/src/test/ui/associated-item/associated-item-duplicate-names.stderr b/src/test/ui/associated-item/associated-item-duplicate-names.stderr index c9119c1027111..f89ea6e57cc43 100644 --- a/src/test/ui/associated-item/associated-item-duplicate-names.stderr +++ b/src/test/ui/associated-item/associated-item-duplicate-names.stderr @@ -1,18 +1,24 @@ error[E0201]: duplicate definitions with name `Ty`: --> $DIR/associated-item-duplicate-names.rs:11:5 | +LL | type Ty; + | -------- item in trait +... LL | type Ty = (); - | ------- previous definition of `Ty` here + | ------------- previous definition here LL | type Ty = usize; - | ^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^^ duplicate definition error[E0201]: duplicate definitions with name `BAR`: --> $DIR/associated-item-duplicate-names.rs:13:5 | +LL | const BAR: u32; + | --------------- item in trait +... LL | const BAR: u32 = 7; - | -------------- previous definition of `BAR` here + | ------------------- previous definition here LL | const BAR: u32 = 8; - | ^^^^^^^^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^^^^^ duplicate definition error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0201.stderr b/src/test/ui/error-codes/E0201.stderr index 94e06894144ca..f72145a82447b 100644 --- a/src/test/ui/error-codes/E0201.stderr +++ b/src/test/ui/error-codes/E0201.stderr @@ -1,27 +1,33 @@ -error[E0201]: duplicate definitions with name `bar`: - --> $DIR/E0201.rs:5:5 - | -LL | fn bar(&self) -> bool { self.0 > 5 } - | --------------------- previous definition of `bar` here -LL | fn bar() {} - | ^^^^^^^^ duplicate definition - error[E0201]: duplicate definitions with name `baz`: --> $DIR/E0201.rs:17:5 | +LL | fn baz(&self) -> bool; + | ---------------------- item in trait +... LL | fn baz(&self) -> bool { true } - | --------------------- previous definition of `baz` here + | ------------------------------ previous definition here LL | fn baz(&self) -> bool { self.0 > 5 } - | ^^^^^^^^^^^^^^^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition error[E0201]: duplicate definitions with name `Quux`: --> $DIR/E0201.rs:18:5 | +LL | type Quux; + | ---------- item in trait +... LL | type Quux = u32; - | --------- previous definition of `Quux` here + | ---------------- previous definition here ... LL | type Quux = u32; - | ^^^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^^ duplicate definition + +error[E0201]: duplicate definitions with name `bar`: + --> $DIR/E0201.rs:5:5 + | +LL | fn bar(&self) -> bool { self.0 > 5 } + | --------------------- previous definition of `bar` here +LL | fn bar() {} + | ^^^^^^^^ duplicate definition error: aborting due to 3 previous errors diff --git a/src/test/ui/hygiene/impl_items-2.rs b/src/test/ui/hygiene/impl_items-2.rs new file mode 100644 index 0000000000000..465e444aedb6b --- /dev/null +++ b/src/test/ui/hygiene/impl_items-2.rs @@ -0,0 +1,26 @@ +#![feature(decl_macro)] + +trait Trait { + fn foo() {} +} + +macro trait_impl() { + fn foo() {} +} + +// Check that we error on multiple impl items that resolve to the same trait item. +impl Trait for i32 { + trait_impl!(); + fn foo() {} + //~^ ERROR duplicate definitions with name `foo`: [E0201] +} + +struct Type; + +// Check that we do not error with inherent impls. +impl Type { + trait_impl!(); + fn foo() {} +} + +fn main() {} diff --git a/src/test/ui/hygiene/impl_items-2.stderr b/src/test/ui/hygiene/impl_items-2.stderr new file mode 100644 index 0000000000000..3c0ffeb105752 --- /dev/null +++ b/src/test/ui/hygiene/impl_items-2.stderr @@ -0,0 +1,15 @@ +error[E0201]: duplicate definitions with name `foo`: + --> $DIR/impl_items-2.rs:14:5 + | +LL | fn foo() {} + | ----------- item in trait +... +LL | fn foo() {} + | ----------- previous definition here +... +LL | fn foo() {} + | ^^^^^^^^^^^ duplicate definition + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0201`. diff --git a/src/test/ui/traits/issue-8153.stderr b/src/test/ui/traits/issue-8153.stderr index b76bbc0235fde..ae214bb9e9b4f 100644 --- a/src/test/ui/traits/issue-8153.stderr +++ b/src/test/ui/traits/issue-8153.stderr @@ -1,10 +1,13 @@ error[E0201]: duplicate definitions with name `bar`: --> $DIR/issue-8153.rs:11:5 | +LL | fn bar(&self) -> isize; + | ----------------------- item in trait +... LL | fn bar(&self) -> isize {1} - | ---------------------- previous definition of `bar` here + | -------------------------- previous definition here LL | fn bar(&self) -> isize {2} - | ^^^^^^^^^^^^^^^^^^^^^^ duplicate definition + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definition error: aborting due to previous error