about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2023-08-09 00:31:26 +0000
committerMaybe Lapkin <waffle.lapkin@gmail.com>2024-10-17 20:43:31 +0200
commite3800a1a04f338ce69bd403f230a019cebc54ece (patch)
tree45940f80da51d580dbb2e2451c9be4bd1cd06168 /compiler
parent3a85d3fa785d95a7b7bcf4f160b67bffba7afd4a (diff)
downloadrust-e3800a1a04f338ce69bd403f230a019cebc54ece.tar.gz
rust-e3800a1a04f338ce69bd403f230a019cebc54ece.zip
Allow dropping dyn principal
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs5
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs4
5 files changed, 13 insertions, 5 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index 5c297ebfadb..336934354e1 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -34,7 +34,9 @@ pub(crate) fn unsized_info<'tcx>(
         {
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
-            if data_a.principal_def_id() == data_b.principal_def_id() {
+            let b_principal_def_id = data_b.principal_def_id();
+            if data_a.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
+                // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
                 debug_assert!(
                     validate_trivial_unsize(fx.tcx, data_a, data_b),
                     "NOP unsize vtable changed principal trait ref: {data_a} -> {data_b}"
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index d91c0f0790d..f3d9a7d37e6 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -147,7 +147,7 @@ pub fn validate_trivial_unsize<'tcx>(
                 infcx.leak_check(universe, None).is_ok()
             })
         }
-        (None, None) => true,
+        (_, None) => true,
         _ => false,
     }
 }
@@ -175,7 +175,8 @@ fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         {
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
-            if data_a.principal_def_id() == data_b.principal_def_id() {
+            let b_principal_def_id = data_b.principal_def_id();
+            if data_a.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
                 // Codegen takes advantage of the additional assumption, where if the
                 // principal trait def id of what's being casted doesn't change,
                 // then we don't need to adjust the vtable at all. This
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 5828b2ecf34..2cbed0bceb2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -785,7 +785,8 @@ where
         let mut responses = vec![];
         // If the principal def ids match (or are both none), then we're not doing
         // trait upcasting. We're just removing auto traits (or shortening the lifetime).
-        if a_data.principal_def_id() == b_data.principal_def_id() {
+        let b_principal_def_id = b_data.principal_def_id();
+        if a_data.principal_def_id() == b_principal_def_id || b_principal_def_id.is_none() {
             responses.extend(self.consider_builtin_upcast_to_principal(
                 goal,
                 CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 52048ca79f9..aa313a526c1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -1018,7 +1018,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // #2 (region bounds).
                 let principal_def_id_a = a_data.principal_def_id();
                 let principal_def_id_b = b_data.principal_def_id();
-                if principal_def_id_a == principal_def_id_b {
+                if principal_def_id_a == principal_def_id_b || principal_def_id_b.is_none() {
                     // We may upcast to auto traits that are either explicitly listed in
                     // the object type's bounds, or implied by the principal trait ref's
                     // supertraits.
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index cc5c7532b50..0ba3b4e6e55 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1153,6 +1153,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`.
                 let iter = data_a
                     .principal()
+                    .filter(|_| {
+                        // optionally drop the principal, if we're unsizing to no principal
+                        data_b.principal().is_some()
+                    })
                     .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
                     .into_iter()
                     .chain(