diff options
| author | Michael Goulet <michael@errs.io> | 2025-01-11 19:31:28 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2025-01-30 17:44:28 +0000 |
| commit | d98b99af56e1260f520102a93f198ffe47793722 (patch) | |
| tree | a979e01fa24aa7e24982892e0ad70394b1c483a3 /compiler/rustc_trait_selection/src/traits/vtable.rs | |
| parent | 9dc41a048d7dc765b28102d557eec40ff050e6ab (diff) | |
| download | rust-d98b99af56e1260f520102a93f198ffe47793722.tar.gz rust-d98b99af56e1260f520102a93f198ffe47793722.zip | |
More assertions, tests, and miri coverage
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/vtable.rs')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/vtable.rs | 57 |
1 files changed, 23 insertions, 34 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index abdf5df6f72..000e6a765d3 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -2,8 +2,6 @@ use std::fmt::Debug; use std::ops::ControlFlow; use rustc_hir::def_id::DefId; -use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::ObligationCause; use rustc_infer::traits::util::PredicateSet; use rustc_middle::bug; use rustc_middle::query::Providers; @@ -14,7 +12,7 @@ use rustc_span::DUMMY_SP; use smallvec::{SmallVec, smallvec}; use tracing::debug; -use crate::traits::{ObligationCtxt, impossible_predicates, is_vtable_safe_method}; +use crate::traits::{impossible_predicates, is_vtable_safe_method}; #[derive(Clone, Debug)] pub enum VtblSegment<'tcx> { @@ -228,6 +226,11 @@ fn vtable_entries<'tcx>( trait_ref: ty::TraitRef<'tcx>, ) -> &'tcx [VtblEntry<'tcx>] { debug_assert!(!trait_ref.has_non_region_infer() && !trait_ref.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), trait_ref), + trait_ref, + "vtable trait ref should be normalized" + ); debug!("vtable_entries({:?})", trait_ref); @@ -305,6 +308,11 @@ fn vtable_entries<'tcx>( // for `Supertrait`'s methods in the vtable of `Subtrait`. pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRef<'tcx>) -> usize { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + key, + "vtable trait ref should be normalized" + ); let ty::Dynamic(source, _, _) = *key.self_ty().kind() else { bug!(); @@ -323,11 +331,9 @@ pub(crate) fn first_method_vtable_slot<'tcx>(tcx: TyCtxt<'tcx>, key: ty::TraitRe vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len(); } VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => { - if trait_refs_are_compatible( - tcx, - ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal), - target_principal, - ) { + if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal) + == target_principal + { return ControlFlow::Break(vptr_offset); } @@ -358,6 +364,12 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( ), ) -> Option<usize> { debug_assert!(!key.has_non_region_infer() && !key.has_non_region_param()); + debug_assert_eq!( + tcx.normalize_erasing_regions(ty::TypingEnv::fully_monomorphized(), key), + key, + "upcasting trait refs should be normalized" + ); + let (source, target) = key; // If the target principal is `None`, we can just return `None`. @@ -384,11 +396,9 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( VtblSegment::TraitOwnEntries { trait_ref: vtable_principal, emit_vptr } => { vptr_offset += tcx.own_existential_vtable_entries(vtable_principal.def_id).len(); - if trait_refs_are_compatible( - tcx, - ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal), - target_principal, - ) { + if ty::ExistentialTraitRef::erase_self_ty(tcx, vtable_principal) + == target_principal + { if emit_vptr { return ControlFlow::Break(Some(vptr_offset)); } else { @@ -408,27 +418,6 @@ pub(crate) fn supertrait_vtable_slot<'tcx>( prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap() } -fn trait_refs_are_compatible<'tcx>( - tcx: TyCtxt<'tcx>, - vtable_principal: ty::ExistentialTraitRef<'tcx>, - target_principal: ty::ExistentialTraitRef<'tcx>, -) -> bool { - if vtable_principal.def_id != target_principal.def_id { - return false; - } - - let (infcx, param_env) = - tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv::fully_monomorphized()); - let ocx = ObligationCtxt::new(&infcx); - let source_principal = ocx.normalize(&ObligationCause::dummy(), param_env, vtable_principal); - let target_principal = ocx.normalize(&ObligationCause::dummy(), param_env, target_principal); - let Ok(()) = ocx.eq(&ObligationCause::dummy(), param_env, target_principal, source_principal) - else { - return false; - }; - ocx.select_all_or_error().is_empty() -} - pub(super) fn provide(providers: &mut Providers) { *providers = Providers { own_existential_vtable_entries, |
