about summary refs log tree commit diff
path: root/compiler/rustc_errors
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-07-08 16:28:15 +0200
committerGitHub <noreply@github.com>2024-07-08 16:28:15 +0200
commitc4ee2df539c96041b458294f05e5381ac6af218f (patch)
treedcf7d4d0e1f9551d329429b1a0adc216c1279f31 /compiler/rustc_errors
parent59a4f02f836f74c4cf08f47d76c9f6069a2f8276 (diff)
parentf3c13bf2809f02d2e8f79496a27cf41c7a1fbd80 (diff)
downloadrust-c4ee2df539c96041b458294f05e5381ac6af218f.tar.gz
rust-c4ee2df539c96041b458294f05e5381ac6af218f.zip
Rollup merge of #120248 - WaffleLapkin:bonk-ptr-object-casts, r=compiler-errors,oli-obk,lnicola
Make casts of pointers to trait objects stricter

This is an attempt to `fix` https://github.com/rust-lang/rust/issues/120222 and https://github.com/rust-lang/rust/issues/120217.

This is done by adding restrictions on casting pointers to trait objects.

Before this PR the rules were as follows:

> When casting `*const X<dyn A>` -> `*const Y<dyn B>`, principal traits in `A` and `B` must refer to the same trait definition (or no trait).

With this PR the rules are changed to

> When casting `*const X<dyn Src>` -> `*const Y<dyn Dst>`
> - if `Dst` has a principal trait `DstP`,
>   - `Src` must have a principal trait `SrcP`
>   - `dyn SrcP` and `dyn DstP` must be the same type (modulo the trait object lifetime, `dyn T+'a` -> `dyn T+'b` is allowed)
>   - Auto traits in `Dst` must be a subset of auto traits in `Src`
>     - Not adhering to this is currently a FCW (warn-by-default + `FutureReleaseErrorReportInDeps`), instead of an error
> - if `Src` has a principal trait `Dst` must as well
>   - this restriction will be removed in a follow up PR

This ensures that
1. Principal trait's generic arguments match (no `*const dyn Tr<A>` -> `*const dyn Tr<B>` casts, which are a problem for [#120222](https://github.com/rust-lang/rust/issues/120222))
2. Principal trait's lifetime arguments match (no `*const dyn Tr<'a>` -> `*const dyn Tr<'b>` casts, which are a problem for [#120217](https://github.com/rust-lang/rust/issues/120217))
3. No auto traits can be _added_ (this is a problem for arbitrary self types, see [this comment](https://github.com/rust-lang/rust/pull/120248#discussion_r1463835350))

Some notes:
 - We only care about the metadata/last field, so you can still cast `*const dyn T` to `*const WithHeader<dyn T>`, etc
- The lifetime of the trait object itself (`dyn A + 'lt`) is not checked, so you can still cast `*mut FnOnce() + '_` to `*mut FnOnce() + 'static`, etc
  - This feels fishy, but I couldn't come up with a reason it must be checked

The diagnostics are currently not great, to say the least, but as far as I can tell this correctly fixes the issues.

cc `@oli-obk` `@compiler-errors` `@lcnr`
Diffstat (limited to 'compiler/rustc_errors')
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs14
1 files changed, 10 insertions, 4 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 0af80bc5c67..e6ca1bf7bc4 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -298,15 +298,21 @@ impl IntoDiagArg for hir::def::Namespace {
 }
 
 #[derive(Clone)]
-pub struct DiagSymbolList(Vec<Symbol>);
+pub struct DiagSymbolList<S = Symbol>(Vec<S>);
 
-impl From<Vec<Symbol>> for DiagSymbolList {
-    fn from(v: Vec<Symbol>) -> Self {
+impl<S> From<Vec<S>> for DiagSymbolList<S> {
+    fn from(v: Vec<S>) -> Self {
         DiagSymbolList(v)
     }
 }
 
-impl IntoDiagArg for DiagSymbolList {
+impl<S> FromIterator<S> for DiagSymbolList<S> {
+    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
+        iter.into_iter().collect::<Vec<_>>().into()
+    }
+}
+
+impl<S: std::fmt::Display> IntoDiagArg for DiagSymbolList<S> {
     fn into_diag_arg(self) -> DiagArgValue {
         DiagArgValue::StrListSepByAnd(
             self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),