Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deduplication mismatches in vtables leading to upcasting unsoundness #135318

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

compiler-errors
Copy link
Member

@compiler-errors compiler-errors commented Jan 10, 2025

We currently have two cases where subtleties in supertraits can trigger disagreements in the vtable layout, e.g. leading to a different vtable layout being accessed at a callsite compared to what was prepared during unsizing. Namely:

#135315

In this example, we were not normalizing supertraits when preparing vtables. In the example,

trait Supertrait<T> {
    fn _print_numbers(&self, mem: &[usize; 100]) {
        println!("{mem:?}");
    }
}
impl<T> Supertrait<T> for () {}

trait Identity {
    type Selff;
}
impl<Selff> Identity for Selff {
    type Selff = Selff;
}

trait Middle<T>: Supertrait<()> + Supertrait<T> {
    fn say_hello(&self, _: &usize) {
        println!("Hello!");
    }
}
impl<T> Middle<T> for () {}

trait Trait: Middle<<() as Identity>::Selff> {}
impl Trait for () {}

fn main() {
    (&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
}

When we prepare dyn Trait, we see a supertrait of Middle<<() as Identity>::Selff>, which itself has two supertraits Supertrait<()> and Supertrait<<() as Identity>::Selff>. These two supertraits are identical, but they are not duplicated because we were using structural equality and not considering normalization. This leads to a vtable layout with two trait pointers.

When we upcast to dyn Middle<()>, those two supertraits are now the same, leading to a vtable layout with only one trait pointer. This leads to an offset error, and we call the wrong method.

#135316

This one is a bit more interesting, and is the bulk of the changes in this PR. It's a bit similar, except it uses binder equality instead of normalization to make the compiler get confused about two vtable layouts. In the example,

trait Supertrait<T> {
    fn _print_numbers(&self, mem: &[usize; 100]) {
        println!("{mem:?}");
    }
}
impl<T> Supertrait<T> for () {}

trait Trait<T, U>: Supertrait<T> + Supertrait<U> {
    fn say_hello(&self, _: &usize) {
        println!("Hello!");
    }
}
impl<T, U> Trait<T, U> for () {}

fn main() {
    (&() as &'static dyn for<'a> Trait<&'static (), &'a ()>
        as &'static dyn Trait<&'static (), &'static ()>)
        .say_hello(&0);
}

When we prepare the vtable for dyn for<'a> Trait<&'static (), &'a ()>, we currently consider the PolyTraitRef of the vtable as the key for a supertrait. This leads two two supertraits -- Supertrait<&'static ()> and for<'a> Supertrait<&'a ()>.

However, we can upcast1 without offsetting the vtable from dyn for<'a> Trait<&'static (), &'a ()> to dyn Trait<&'static (), &'static ()>. This is just instantiating the principal trait ref for a specific 'a = 'static. However, when considering those supertraits, we now have only one distinct supertrait -- Supertrait<&'static ()> (which is deduplicated since there are two supertraits with the same substitutions). This leads to similar offsetting issues, leading to the wrong method being called.

The solution here is to recognize that a vtable isn't really meaningfully higher ranked, and to just treat a vtable as corresponding to a TraitRef so we can do this deduplication more faithfully. That is to say, the vtable for dyn for<'a> Tr<'a> and dyn Tr<'x> are always identical, since they both would correspond to a set of free regions on an impl... Do note that Tr<for<'a> fn(&'a ())> and Tr<fn(&'static ())> are still distinct.


There's a bit more that can be cleaned up. In codegen, we can stop using PolyExistentialTraitRef basically everywhere. We can also fix SMIR to stop storing PolyExistentialTraitRef in its vtable allocations.

As for testing, it's difficult to actually turn this into something that can be tested with rustc_dump_vtable, since having multiple supertraits that are identical is a recipe for ambiguity errors. Maybe someone else is more creative with getting that attr to work, since the tests I added being run-pass tests is a bit unsatisfying. Miri also doesn't help here, since it doesn't really generate vtables that are offset by an index in the same way as codegen.

r? @lcnr for the vibe check? Or reassign, idk. Maybe let's talk about whether this makes sense.

(I guess an alternative would also be to not do any deduplication of vtable supertraits (or only a really conservative subset) rather than trying to normalize and deduplicate more faithfully here. Not sure if that works and is sufficient tho.)

cc @steffahn -- ty for the minimizations
cc @WaffleLapkin -- since you're overseeing the feature stabilization :3

Fixes #135315
Fixes #135316

Footnotes

  1. I say upcast but this is a cast that is allowed on stable, since it's not changing the vtable at all, just instantiating the binder of the principal trait ref for some lifetime.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 10, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jan 10, 2025

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the CTFE machinery

cc @rust-lang/wg-const-eval

@rust-log-analyzer

This comment has been minimized.

@rustbot
Copy link
Collaborator

rustbot commented Jan 10, 2025

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@RalfJung
Copy link
Member

Miri also doesn't help here, since it doesn't really generate vtables that are offset by an index in the same way as codegen.

We do have assertions that are intended to ensure that looking up the method via the offset leads to the same result as the type-driven "direct" lookup. If those did not catch this problem, something seems odd. Note that these are debug assertions so you won't see this in cargo miri or on the playground, but if you run tests via ./x test debug assertions should be on.

@lcnr
Copy link
Contributor

lcnr commented Jan 10, 2025

vibeck 👍 can talk about it regardless, but this feels very reasonable to me modulo the nit above

wrt to hr-trait objects, the important part is that all trait object args are invariant so you can't subtype types in the args: going from dyn Trait<for<'a> fn(&'a ()>> to dyn Trait<fn(&'erased ())> is impossible and would be able to change the vtable. The vtable for higher ranked trait bounds has to be the same as for instantiated ones

@rustbot rustbot added the A-rustc-dev-guide Area: rustc-dev-guide label Jan 10, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jan 10, 2025

The rustc-dev-guide subtree was changed. If this PR only touches the dev guide consider submitting a PR directly to rust-lang/rustc-dev-guide otherwise thank you for updating the dev guide with your changes.

cc @BoxyUwU, @jieyouxu, @Kobzol

@compiler-errors
Copy link
Member Author

I've reworked the rustc_dump_vtable attr to be a bit more eager. You can put it on either:

  1. Non-generic impls, to generate the vtable for that impl.
  2. Non-generic type aliases of dyn Trait, i.e. type X = dyn Trait, to generate the vtable of that object type.

I've also removed the print_vtable_sizes attr, since that's no longer needed. I don't think we're doing any more investigation about vtable sizes these days, and it wasn't working correctly with unnormalized types anyways.

@compiler-errors
Copy link
Member Author

I've also changed a bunch of PolyExistentialTraitRef to ExistentialTraitRef in codegen to reflect the fact that vtables are not higher ranked.

@steffahn
Copy link
Member

I've tested out the new behavior (before the force-push, but it sounds like that wasn't changing anything about it) a little bit, and it seems quite convincing to me :-)

@compiler-errors
Copy link
Member Author

didnt change anything behaviorally since the rebase

@RalfJung
Copy link
Member

RalfJung commented Jan 11, 2025

FWIW running the test from #135315 in Miri with debug assertions does ICE, so the existing check do in fact enable Miri to catch problems like this:

thread 'rustc' panicked at /home/r/src/rust/rustc.2/compiler/rustc_const_eval/src/interpret/cast.rs:444:25:
assertion failed: &vtable_entries[..vtable_entries_b.len()] == vtable_entries_b

Same for the test in #135316.

Maybe we should just always enable these checks for Miri? That makes virtual calls slightly more expensive, but it seems hard to imagine that becoming a bottleneck.

@compiler-errors
Copy link
Member Author

Maybe we should just always enable these checks for Miri?

Yeah, my first reaction was to test it in miri and not it triggering did give me a false impression that miri was not affected here :) I'll change the debug assertion to be a regular assertion.

@RalfJung
Copy link
Member

Miri is indeed not affected, but it'd still be nice to have Miri catch issues that only affect code using the actual vtable entries.

@rustbot
Copy link
Collaborator

rustbot commented Jan 11, 2025

The Miri subtree was changed

cc @rust-lang/miri

@WaffleLapkin
Copy link
Member

cc @WaffleLapkin -- since you're overseeing the feature stabilization :3

I haven't looked too closely at the implementation, but the changes make sense to me 💚

@steffahn
Copy link
Member

Here’s a new ICE on this PR

#![feature(trait_upcasting)]

trait Supertrait<T> {
    fn method(&self) {}
}
impl<T> Supertrait<T> for () {}

trait WithAssoc {
    type Assoc;
}
trait Trait<P: WithAssoc>: Supertrait<P::Assoc> + Supertrait<()> {}

fn upcast<P>(x: &dyn Trait<P>) -> &dyn Supertrait<()> {
    x
}

fn main() {
    println!("{:p}", upcast::<()> as *const ());
}
Error
error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:169:13: Failed to normalize Alias(Projection, AliasTy { args: [()], def_id: DefId(0:9 ~ play9[5703]::WithAssoc::Assoc), .. }) in typing_env=TypingEnv { typing_mode: PostAnalysis, param_env: ParamEnv { caller_bounds: [] } }, maybe try to call `try_normalize_erasing_regions` instead


thread 'rustc' panicked at compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:169:13:
Box<dyn Any>
stack backtrace:
   0: std::panicking::begin_panic::<rustc_errors::ExplicitBug>
             at /home/frank/repos/rust/library/std/src/panicking.rs:764:5
   1: std::panic::panic_any::<rustc_errors::ExplicitBug>
             at /home/frank/repos/rust/library/std/src/panic.rs:259:5
   2: <rustc_errors::diagnostic::BugAbort as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
             at /home/frank/repos/rust/compiler/rustc_errors/src/diagnostic.rs:82:9
   3: <rustc_errors::diagnostic::Diag<rustc_errors::diagnostic::BugAbort>>::emit
             at /home/frank/repos/rust/compiler/rustc_errors/src/diagnostic.rs:1330:9
   4: <rustc_errors::DiagCtxtHandle>::bug::<alloc::string::String>
             at /home/frank/repos/rust/compiler/rustc_errors/src/lib.rs:1163:9
   5: {closure#0}<rustc_span::span_encoding::Span>
             at /home/frank/repos/rust/compiler/rustc_middle/src/util/bug.rs:39:38
   6: {closure#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:148:23
   7: with_context_opt<rustc_middle::ty::context::tls::with_opt::{closure_env#0}<rustc_middle::util::bug::opt_span_bug_fmt::{closure_env#0}<rustc_span::span_encoding::Span>, !>, !>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:91:18
   8: rustc_middle::ty::context::tls::with_opt::<rustc_middle::util::bug::opt_span_bug_fmt<rustc_span::span_encoding::Span>::{closure#0}, !>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:146:5
   9: rustc_middle::util::bug::opt_span_bug_fmt::<rustc_span::span_encoding::Span>
             at /home/frank/repos/rust/compiler/rustc_middle/src/util/bug.rs:33:5
  10: rustc_middle::util::bug::bug_fmt
             at /home/frank/repos/rust/compiler/rustc_middle/src/util/bug.rs:17:5
  11: {closure#0}
             at /home/frank/repos/rust/compiler/rustc_middle/src/macros.rs:24:9
  12: unwrap_or_else<rustc_middle::ty::generic_args::GenericArg, rustc_type_ir::solve::NoSolution, rustc_middle::ty::normalize_erasing_regions::{impl#2}::normalize_generic_arg_after_erasing_regions::{closure_env#0}>
             at /home/frank/repos/rust/library/core/src/result.rs:1463:23
  13: normalize_generic_arg_after_erasing_regions
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:168:9
  14: fold_ty
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:185:9
  15: try_fold_with<rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/generic_args.rs:591:30
  16: try_fold_with<rustc_middle::ty::context::TyCtxt, rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder>
             at /home/frank/repos/rust/compiler/rustc_type_ir/src/predicate.rs:52:33
  17: try_fold_with<rustc_middle::ty::context::TyCtxt, rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder>
             at /home/frank/repos/rust/compiler/rustc_type_ir/src/predicate.rs:124:33
  18: fold_with<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt>, rustc_middle::ty::context::TyCtxt, rustc_middle::ty::normalize_erasing_regions::NormalizeAfterErasingRegionsFolder>
             at /home/frank/repos/rust/compiler/rustc_type_ir/src/fold.rs:93:15
  19: {closure#0}<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:58:13
  20: normalize_erasing_regions<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:38:5
  21: normalize_erasing_late_bound_regions<rustc_type_ir::predicate::TraitPredicate<rustc_middle::ty::context::TyCtxt>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:116:9
  22: {closure#0}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_trait_selection/src/traits/vtable.rs:128:25
  23: {closure#0}<(rustc_middle::ty::predicate::Clause, rustc_span::span_encoding::Span), rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, (), core::ops::control_flow::ControlFlow<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, ()>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#0}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>, core::iter::traits::iterator::Iterator::find::check::{closure_env#0}<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#1}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>>>
             at /home/frank/repos/rust/library/core/src/iter/adapters/filter_map.rs:49:28
  24: try_fold<rustc_type_ir::binder::IterIdentityCopied<&[(rustc_middle::ty::predicate::Clause, rustc_span::span_encoding::Span)]>, (), core::iter::adapters::filter_map::filter_map_try_fold::{closure_env#0}<(rustc_middle::ty::predicate::Clause, rustc_span::span_encoding::Span), rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, (), core::ops::control_flow::ControlFlow<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, ()>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#0}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>, core::iter::traits::iterator::Iterator::find::check::{closure_env#0}<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#1}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>>>, core::ops::control_flow::ControlFlow<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, ()>>
             at /home/frank/repos/rust/library/core/src/iter/traits/iterator.rs:2370:21
  25: try_fold<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, rustc_type_ir::binder::IterIdentityCopied<&[(rustc_middle::ty::predicate::Clause, rustc_span::span_encoding::Span)]>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#0}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>, (), core::iter::traits::iterator::Iterator::find::check::{closure_env#0}<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#1}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>>, core::ops::control_flow::ControlFlow<rustc_type_ir::predicate::TraitRef<rustc_middle::ty::context::TyCtxt>, ()>>
             at /home/frank/repos/rust/library/core/src/iter/adapters/filter_map.rs:140:9
  26: find<core::iter::adapters::filter_map::FilterMap<rustc_type_ir::binder::IterIdentityCopied<&[(rustc_middle::ty::predicate::Clause, rustc_span::span_encoding::Span)]>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#0}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>>, rustc_trait_selection::traits::vtable::prepare_vtable_segments_inner::{closure_env#1}<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>>
             at /home/frank/repos/rust/library/core/src/iter/traits/iterator.rs:2833:9
  27: prepare_vtable_segments_inner<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_trait_selection/src/traits/vtable.rs:141:19
  28: prepare_vtable_segments<core::option::Option<usize>, rustc_trait_selection::traits::vtable::supertrait_vtable_slot::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_trait_selection/src/traits/vtable.rs:31:5
  29: supertrait_vtable_slot
             at /home/frank/repos/rust/compiler/rustc_trait_selection/src/traits/vtable.rs:420:5
  30: {closure#0}
             at /home/frank/repos/rust/compiler/rustc_query_impl/src/plumbing.rs:283:9
      [... omitted 36 frames ...]
  31: query_get_at<rustc_query_system::query::caches::DefaultCache<(rustc_middle::ty::Ty, rustc_middle::ty::Ty), rustc_middle::query::erase::Erased<[u8; 16]>>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/query/plumbing.rs:143:17
  32: supertrait_vtable_slot
             at /home/frank/repos/rust/compiler/rustc_middle/src/query/plumbing.rs:422:31
  33: supertrait_vtable_slot
             at /home/frank/repos/rust/compiler/rustc_middle/src/query/plumbing.rs:413:17
  34: unsized_info<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/base.rs:197:34
  35: unsize_ptr<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/base.rs:230:19
  36: codegen_rvalue_operand<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/mir/rvalue.rs:523:29
  37: codegen_statement<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/mir/statement.rs:21:43
  38: codegen_block<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/mir/block.rs:1241:17
  39: codegen_mir<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/mir/mod.rs:299:9
  40: codegen_instance<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/base.rs:419:5
  41: define<rustc_codegen_llvm::builder::Builder>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/mono_item.rs:105:17
  42: module_codegen
             at /home/frank/repos/rust/compiler/rustc_codegen_llvm/src/base.rs:94:17
  43: {closure#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:364:64
  44: {closure#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:72:9
  45: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/library/std/src/thread/local.rs:308:12
  46: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/library/std/src/thread/local.rs:272:9
  47: enter_context<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:69:5
  48: {closure#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:33:13
  49: {closure#0}<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:102:36
  50: with_context_opt<rustc_middle::ty::context::tls::with_context::{closure_env#0}<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:91:18
  51: with_context<rustc_middle::dep_graph::{impl#0}::with_deps::{closure_env#0}<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:102:5
  52: with_deps<rustc_query_system::dep_graph::graph::{impl#4}::with_task::{closure#0}::{closure_env#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/dep_graph/mod.rs:30:9
  53: {closure#0}<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:364:37
  54: with_task<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:375:14
  55: with_task<rustc_middle::dep_graph::DepsType, rustc_middle::ty::context::TyCtxt, rustc_span::symbol::Symbol, rustc_codegen_ssa::ModuleCodegen<rustc_codegen_llvm::ModuleLlvm>>
             at /home/frank/repos/rust/compiler/rustc_query_system/src/dep_graph/graph.rs:290:27
  56: compile_codegen_unit
             at /home/frank/repos/rust/compiler/rustc_codegen_llvm/src/base.rs:63:23
  57: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::ExtraBackendMethods>::compile_codegen_unit
             at /home/frank/repos/rust/compiler/rustc_codegen_llvm/src/lib.rs:134:9
  58: codegen_crate<rustc_codegen_llvm::LlvmCodegenBackend>
             at /home/frank/repos/rust/compiler/rustc_codegen_ssa/src/base.rs:776:34
  59: codegen_crate
             at /home/frank/repos/rust/compiler/rustc_codegen_llvm/src/lib.rs:360:18
  60: {closure#0}
             at /home/frank/repos/rust/compiler/rustc_interface/src/passes.rs:1044:9
  61: run<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_data_structures/src/profiling.rs:753:9
  62: time<alloc::boxed::Box<dyn core::any::Any, alloc::alloc::Global>, rustc_interface::passes::start_codegen::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_session/src/utils.rs:16:9
  63: start_codegen
             at /home/frank/repos/rust/compiler/rustc_interface/src/passes.rs:1043:19
  64: codegen_and_build_linker
             at /home/frank/repos/rust/compiler/rustc_interface/src/queries.rs:29:31
  65: {closure#2}
             at /home/frank/repos/rust/compiler/rustc_driver_impl/src/lib.rs:452:18
  66: {closure#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /home/frank/repos/rust/compiler/rustc_interface/src/passes.rs:812:27
  67: {closure#3}<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context.rs:1556:37
  68: {closure#0}<rustc_middle::ty::context::{impl#23}::create_global_ctxt::{closure_env#3}<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>, core::option::Option<rustc_interface::queries::Linker>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:72:9
  69: try_with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#23}::create_global_ctxt::{closure_env#3}<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /home/frank/repos/rust/library/std/src/thread/local.rs:308:12
  70: with<core::cell::Cell<*const ()>, rustc_middle::ty::context::tls::enter_context::{closure_env#0}<rustc_middle::ty::context::{impl#23}::create_global_ctxt::{closure_env#3}<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>, core::option::Option<rustc_interface::queries::Linker>>, core::option::Option<rustc_interface::queries::Linker>>
             at /home/frank/repos/rust/library/std/src/thread/local.rs:272:9
  71: enter_context<rustc_middle::ty::context::{impl#23}::create_global_ctxt::{closure_env#3}<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>, core::option::Option<rustc_interface::queries::Linker>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context/tls.rs:69:5
  72: create_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_interface::passes::create_and_enter_global_ctxt::{closure#2}::{closure_env#0}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>>
             at /home/frank/repos/rust/compiler/rustc_middle/src/ty/context.rs:1556:9
  73: {closure#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /home/frank/repos/rust/compiler/rustc_interface/src/passes.rs:780:9
  74: call_once<rustc_interface::passes::create_and_enter_global_ctxt::{closure_env#2}<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>, (&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2})>
             at /home/frank/repos/rust/library/core/src/ops/function.rs:250:5
  75: call_once<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}), dyn core::ops::function::FnOnce<(&rustc_session::session::Session, rustc_middle::ty::context::CurrentGcx, &std::sync::once_lock::OnceLock<rustc_middle::ty::context::GlobalCtxt>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_middle::arena::Arena>, &rustc_data_structures::sync::worker_local::WorkerLocal<rustc_hir::Arena>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}), Output=core::option::Option<rustc_interface::queries::Linker>>, alloc::alloc::Global>
             at /home/frank/repos/rust/library/alloc/src/boxed.rs:2013:9
  76: create_and_enter_global_ctxt<core::option::Option<rustc_interface::queries::Linker>, rustc_driver_impl::run_compiler::{closure#0}::{closure_env#2}>
             at /home/frank/repos/rust/compiler/rustc_interface/src/passes.rs:820:5
  77: {closure#0}
             at /home/frank/repos/rust/compiler/rustc_driver_impl/src/lib.rs:417:22
  78: {closure#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_interface/src/interface.rs:499:80
  79: call_once<(), rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>
             at /home/frank/repos/rust/library/core/src/panic/unwind_safe.rs:272:9
  80: do_call<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
             at /home/frank/repos/rust/library/std/src/panicking.rs:584:40
  81: try<(), core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>>
             at /home/frank/repos/rust/library/std/src/panicking.rs:547:19
  82: catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<rustc_interface::interface::run_compiler::{closure#1}::{closure_env#0}<(), rustc_driver_impl::run_compiler::{closure_env#0}>>, ()>
             at /home/frank/repos/rust/library/std/src/panic.rs:358:14
  83: {closure#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>
             at /home/frank/repos/rust/compiler/rustc_interface/src/interface.rs:499:23
  84: {closure#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>
             at /home/frank/repos/rust/compiler/rustc_interface/src/util.rs:143:13
  85: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
             at /home/frank/repos/rust/compiler/rustc_interface/src/util.rs:106:21
  86: set<rustc_span::SessionGlobals, rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>, ()>
             at /home/frank/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scoped-tls-1.0.1/src/lib.rs:137:9
  87: create_session_globals_then<(), rustc_interface::util::run_in_thread_with_globals::{closure#0}::{closure#0}::{closure_env#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>>
             at /home/frank/repos/rust/compiler/rustc_span/src/lib.rs:138:5
  88: {closure#0}<rustc_interface::util::run_in_thread_pool_with_globals::{closure_env#0}<rustc_interface::interface::run_compiler::{closure_env#1}<(), rustc_driver_impl::run_compiler::{closure_env#0}>, ()>, ()>
             at /home/frank/repos/rust/compiler/rustc_interface/src/util.rs:105:17
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: please attach the file at `/home/frank/playground/play9/rustc-ice-2025-01-13T23_53_50-3614898.txt` to your bug report

note: compiler flags: --crate-type bin -C embed-bitcode=no -C debuginfo=2 -C incremental=[REDACTED]

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
#0 [supertrait_vtable_slot] finding the slot within vtable for trait object `dyn Supertrait<()>` vtable ptr during trait upcasting coercion from `dyn Trait<()>` vtable
end of query stack
warning: `play9` (bin "play9") generated 1 warning
error: could not compile `play9` (bin "play9"); 1 warning emitted

@compiler-errors
Copy link
Member Author

@steffahn: Different bug, probably shouldn't block this PR. I'll open a different PR exploring a strategy to fix that one.

@steffahn
Copy link
Member

I’ve commented it here, because I haven’t quite found a repro yet for this particular ICE without this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustc-dev-guide Area: rustc-dev-guide S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
8 participants