about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRuihan Li <lrh2000@pku.edu.cn>2024-10-15 21:45:46 +0800
committerRuihan Li <lrh2000@pku.edu.cn>2024-10-18 12:34:56 +0800
commit781bff049905d325bb877935978f1bce8ea6af86 (patch)
treecda6d34fd378631ef97cd1daa1307e6435f6ac9f
parent88f311479dd19288e5ad85e22cd80368489ce1e9 (diff)
downloadrust-781bff049905d325bb877935978f1bce8ea6af86.tar.gz
rust-781bff049905d325bb877935978f1bce8ea6af86.zip
Never emit `vptr` for empty/auto traits
-rw-r--r--compiler/rustc_trait_selection/src/traits/vtable.rs11
-rw-r--r--tests/ui/traits/object/print_vtable_sizes.stdout4
-rw-r--r--tests/ui/traits/upcast_reorder.rs29
-rw-r--r--tests/ui/traits/vtable/multiple-markers.stderr6
4 files changed, 36 insertions, 14 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs
index 6e6f948a2cd..ed221e2a183 100644
--- a/compiler/rustc_trait_selection/src/traits/vtable.rs
+++ b/compiler/rustc_trait_selection/src/traits/vtable.rs
@@ -154,18 +154,17 @@ fn prepare_vtable_segments_inner<'tcx, T>(
 
         // emit innermost item, move to next sibling and stop there if possible, otherwise jump to outer level.
         while let Some((inner_most_trait_ref, emit_vptr, mut siblings)) = stack.pop() {
+            let has_entries =
+                has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id());
+
             segment_visitor(VtblSegment::TraitOwnEntries {
                 trait_ref: inner_most_trait_ref,
-                emit_vptr: emit_vptr && !tcx.sess.opts.unstable_opts.no_trait_vptr,
+                emit_vptr: emit_vptr && has_entries && !tcx.sess.opts.unstable_opts.no_trait_vptr,
             })?;
 
             // If we've emitted (fed to `segment_visitor`) a trait that has methods present in the vtable,
             // we'll need to emit vptrs from now on.
-            if !emit_vptr_on_new_entry
-                && has_own_existential_vtable_entries(tcx, inner_most_trait_ref.def_id())
-            {
-                emit_vptr_on_new_entry = true;
-            }
+            emit_vptr_on_new_entry |= has_entries;
 
             if let Some(next_inner_most_trait_ref) =
                 siblings.find(|&sibling| visited.insert(sibling.upcast(tcx)))
diff --git a/tests/ui/traits/object/print_vtable_sizes.stdout b/tests/ui/traits/object/print_vtable_sizes.stdout
index b43e168df3f..4daf4769576 100644
--- a/tests/ui/traits/object/print_vtable_sizes.stdout
+++ b/tests/ui/traits/object/print_vtable_sizes.stdout
@@ -1,8 +1,8 @@
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "E", "entries": "6", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "2", "upcasting_cost_percent": "50" }
-print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "G", "entries": "14", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "3", "upcasting_cost_percent": "27.27272727272727" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "A", "entries": "6", "entries_ignoring_upcasting": "5", "entries_for_upcasting": "1", "upcasting_cost_percent": "20" }
+print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "G", "entries": "13", "entries_ignoring_upcasting": "11", "entries_for_upcasting": "2", "upcasting_cost_percent": "18.181818181818183" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "B", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "D", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
+print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "E", "entries": "4", "entries_ignoring_upcasting": "4", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "F", "entries": "6", "entries_ignoring_upcasting": "6", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
 print-vtable-sizes { "crate_name": "print_vtable_sizes", "trait_name": "_::S", "entries": "3", "entries_ignoring_upcasting": "3", "entries_for_upcasting": "0", "upcasting_cost_percent": "0" }
diff --git a/tests/ui/traits/upcast_reorder.rs b/tests/ui/traits/upcast_reorder.rs
new file mode 100644
index 00000000000..55e6ad4c368
--- /dev/null
+++ b/tests/ui/traits/upcast_reorder.rs
@@ -0,0 +1,29 @@
+//@ run-pass
+//
+// issue: <https://github.com/rust-lang/rust/issues/131813>
+
+#![feature(trait_upcasting)]
+
+trait Pollable {
+    #[allow(unused)]
+    fn poll(&self) {}
+}
+trait FileIo: Pollable + Send + Sync {
+    fn read(&self) {}
+}
+trait Terminal: Send + Sync + FileIo {}
+
+struct A;
+
+impl Pollable for A {}
+impl FileIo for A {}
+impl Terminal for A {}
+
+fn main() {
+    let a = A;
+
+    let b = &a as &dyn Terminal;
+    let c = b as &dyn FileIo;
+
+    c.read();
+}
diff --git a/tests/ui/traits/vtable/multiple-markers.stderr b/tests/ui/traits/vtable/multiple-markers.stderr
index 4497c703ae8..36ac8b24eb5 100644
--- a/tests/ui/traits/vtable/multiple-markers.stderr
+++ b/tests/ui/traits/vtable/multiple-markers.stderr
@@ -14,7 +14,6 @@ error: vtable entries for `<S as B>`: [
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
-           TraitVPtr(<S as M2>),
        ]
   --> $DIR/multiple-markers.rs:24:1
    |
@@ -26,8 +25,6 @@ error: vtable entries for `<S as C>`: [
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
-           TraitVPtr(<S as M1>),
-           TraitVPtr(<S as M2>),
        ]
   --> $DIR/multiple-markers.rs:27:1
    |
@@ -39,9 +36,6 @@ error: vtable entries for `<S as D>`: [
            MetadataSize,
            MetadataAlign,
            Method(<S as T>::method),
-           TraitVPtr(<S as M0>),
-           TraitVPtr(<S as M1>),
-           TraitVPtr(<S as M2>),
        ]
   --> $DIR/multiple-markers.rs:30:1
    |