Skip to content

Commit 3b9adbe

Browse files
Only compute vtable information during codegen
1 parent f8e5660 commit 3b9adbe

File tree

14 files changed

+141
-195
lines changed

14 files changed

+141
-195
lines changed

compiler/rustc_codegen_cranelift/src/unsize.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ pub(crate) fn unsized_info<'tcx>(
3939
}
4040

4141
// trait upcasting coercion
42-
let vptr_entry_idx =
43-
fx.tcx.vtable_trait_upcasting_coercion_new_vptr_slot((source, target));
42+
let vptr_entry_idx = fx.tcx.supertrait_vtable_slot((source, target));
4443

4544
if let Some(entry_idx) = vptr_entry_idx {
4645
let entry_idx = u32::try_from(entry_idx).unwrap();

compiler/rustc_codegen_ssa/src/base.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
163163

164164
// trait upcasting coercion
165165

166-
let vptr_entry_idx =
167-
cx.tcx().vtable_trait_upcasting_coercion_new_vptr_slot((source, target));
166+
let vptr_entry_idx = cx.tcx().supertrait_vtable_slot((source, target));
168167

169168
if let Some(entry_idx) = vptr_entry_idx {
170169
let ptr_size = bx.data_layout().pointer_size;

compiler/rustc_middle/src/query/keys.rs

+8
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,14 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::TraitRef<'tcx>) {
360360
}
361361
}
362362

363+
impl<'tcx> Key for ty::TraitRef<'tcx> {
364+
type Cache<V> = DefaultCache<Self, V>;
365+
366+
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
367+
tcx.def_span(self.def_id)
368+
}
369+
}
370+
363371
impl<'tcx> Key for ty::PolyTraitRef<'tcx> {
364372
type Cache<V> = DefaultCache<Self, V>;
365373

compiler/rustc_middle/src/query/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use crate::traits::{
4646
};
4747
use crate::ty::fast_reject::SimplifiedType;
4848
use crate::ty::layout::ValidityRequirement;
49+
use crate::ty::print::PrintTraitRefExt;
4950
use crate::ty::util::AlwaysRequiresDrop;
5051
use crate::ty::TyCtxtFeed;
5152
use crate::ty::{
@@ -1271,7 +1272,11 @@ rustc_queries! {
12711272
desc { |tcx| "finding all vtable entries for trait `{}`", tcx.def_path_str(key.def_id()) }
12721273
}
12731274

1274-
query vtable_trait_upcasting_coercion_new_vptr_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> {
1275+
query first_method_vtable_slot(key: ty::TraitRef<'tcx>) -> usize {
1276+
desc { |tcx| "finding the slot within the vtable of `{}` for the implementation of `{}`", key.self_ty(), key.print_only_trait_name() }
1277+
}
1278+
1279+
query supertrait_vtable_slot(key: (Ty<'tcx>, Ty<'tcx>)) -> Option<usize> {
12751280
desc { |tcx| "finding the slot within vtable for trait object `{}` vtable ptr during trait upcasting coercion from `{}` vtable",
12761281
key.1, key.0 }
12771282
}

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use rustc_hir::def_id::DefId;
44
use rustc_infer::infer::InferCtxt;
55
use rustc_infer::traits::query::NoSolution;
6+
use rustc_infer::traits::util::supertraits;
67
use rustc_middle::bug;
78
use rustc_middle::traits::solve::inspect::ProbeKind;
89
use rustc_middle::traits::solve::{
@@ -743,14 +744,14 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
743744
// a projection goal.
744745
if let Some(principal) = bounds.principal() {
745746
let principal_trait_ref = principal.with_self_ty(tcx, self_ty);
746-
self.walk_vtable(principal_trait_ref, |ecx, assumption, vtable_base, _| {
747+
for (idx, assumption) in supertraits(self.interner(), principal_trait_ref).enumerate() {
747748
candidates.extend(G::probe_and_consider_object_bound_candidate(
748-
ecx,
749-
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base }),
749+
self,
750+
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(idx)),
750751
goal,
751752
assumption.upcast(tcx),
752753
));
753-
});
754+
}
754755
}
755756
}
756757

compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

-36
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Gen
2424
use std::ops::ControlFlow;
2525

2626
use crate::traits::coherence;
27-
use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
2827

2928
use super::inspect::ProofTreeBuilder;
3029
use super::{search_graph, GoalEvaluationKind, FIXPOINT_STEP_LIMIT};
@@ -1022,41 +1021,6 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
10221021
}
10231022
}
10241023
}
1025-
1026-
/// Walk through the vtable of a principal trait ref, executing a `supertrait_visitor`
1027-
/// for every trait ref encountered (including the principal). Passes both the vtable
1028-
/// base and the (optional) vptr slot.
1029-
pub(super) fn walk_vtable(
1030-
&mut self,
1031-
principal: ty::PolyTraitRef<'tcx>,
1032-
mut supertrait_visitor: impl FnMut(&mut Self, ty::PolyTraitRef<'tcx>, usize, Option<usize>),
1033-
) {
1034-
let tcx = self.interner();
1035-
let mut offset = 0;
1036-
prepare_vtable_segments::<()>(tcx, principal, |segment| {
1037-
match segment {
1038-
VtblSegment::MetadataDSA => {
1039-
offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
1040-
}
1041-
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
1042-
let own_vtable_entries = count_own_vtable_entries(tcx, trait_ref);
1043-
1044-
supertrait_visitor(
1045-
self,
1046-
trait_ref,
1047-
offset,
1048-
emit_vptr.then(|| offset + own_vtable_entries),
1049-
);
1050-
1051-
offset += own_vtable_entries;
1052-
if emit_vptr {
1053-
offset += 1;
1054-
}
1055-
}
1056-
}
1057-
ControlFlow::Continue(())
1058-
});
1059-
}
10601024
}
10611025

10621026
/// Eagerly replace aliases with inference variables, emitting `AliasRelate`

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
114114
// In the old trait solver, we arbitrarily choose lower vtable candidates
115115
// over higher ones.
116116
(
117-
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: a }),
118-
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: b }),
117+
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(a)),
118+
CandidateSource::BuiltinImpl(BuiltinImplSource::Object(b)),
119119
) => a >= b,
120120
// Prefer dyn candidates over non-dyn candidates. This is necessary to
121121
// handle the unsoundness between `impl<T: ?Sized> Any for T` and `dyn Any: Any`.

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+14-18
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc_hir::{LangItem, Movability};
99
use rustc_infer::infer::InferCtxt;
1010
use rustc_infer::traits::query::NoSolution;
1111
use rustc_infer::traits::solve::MaybeCause;
12+
use rustc_infer::traits::util::supertraits;
1213
use rustc_middle::bug;
1314
use rustc_middle::traits::solve::inspect::ProbeKind;
1415
use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal, QueryResult};
@@ -756,24 +757,19 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
756757
a_data.principal(),
757758
));
758759
} else if let Some(a_principal) = a_data.principal() {
759-
self.walk_vtable(
760-
a_principal.with_self_ty(tcx, a_ty),
761-
|ecx, new_a_principal, _, vtable_vptr_slot| {
762-
responses.extend(ecx.consider_builtin_upcast_to_principal(
763-
goal,
764-
CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting {
765-
vtable_vptr_slot,
766-
}),
767-
a_data,
768-
a_region,
769-
b_data,
770-
b_region,
771-
Some(new_a_principal.map_bound(|trait_ref| {
772-
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
773-
})),
774-
));
775-
},
776-
);
760+
for new_a_principal in supertraits(tcx, a_principal.with_self_ty(tcx, a_ty)).skip(1) {
761+
responses.extend(self.consider_builtin_upcast_to_principal(
762+
goal,
763+
CandidateSource::BuiltinImpl(BuiltinImplSource::TraitUpcasting),
764+
a_data,
765+
a_region,
766+
b_data,
767+
b_region,
768+
Some(new_a_principal.map_bound(|trait_ref| {
769+
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
770+
})),
771+
));
772+
}
777773
}
778774

779775
responses

compiler/rustc_trait_selection/src/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub use self::structural_match::search_for_structural_match_violation;
6565
pub use self::structural_normalize::StructurallyNormalizeExt;
6666
pub use self::util::elaborate;
6767
pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo};
68-
pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices};
68+
pub use self::util::{impl_item_is_final, upcast_choices};
6969
pub use self::util::{supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item};
7070
pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
7171

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-41
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ use rustc_span::def_id::DefId;
2222

2323
use crate::traits::normalize::{normalize_with_depth, normalize_with_depth_to};
2424
use crate::traits::util::{self, closure_trait_ref_and_return_type};
25-
use crate::traits::vtable::{
26-
count_own_vtable_entries, prepare_vtable_segments, vtable_trait_first_method_offset,
27-
VtblSegment,
28-
};
2925
use crate::traits::{
3026
ImplDerivedCause, ImplSource, ImplSourceUserDefinedData, Normalized, Obligation,
3127
ObligationCause, PolyTraitObligation, PredicateObligation, Selection, SelectionError,
@@ -689,13 +685,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
689685

690686
debug!(?nested, "object nested obligations");
691687

692-
let vtable_base = vtable_trait_first_method_offset(
693-
tcx,
694-
unnormalized_upcast_trait_ref,
695-
ty::Binder::dummy(object_trait_ref),
696-
);
697-
698-
Ok(ImplSource::Builtin(BuiltinImplSource::Object { vtable_base: vtable_base }, nested))
688+
Ok(ImplSource::Builtin(BuiltinImplSource::Object(index), nested))
699689
}
700690

701691
fn confirm_fn_pointer_candidate(
@@ -1125,36 +1115,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11251115
)?
11261116
.expect("did not expect ambiguity during confirmation");
11271117

1128-
let vtable_segment_callback = {
1129-
let mut vptr_offset = 0;
1130-
move |segment| {
1131-
match segment {
1132-
VtblSegment::MetadataDSA => {
1133-
vptr_offset += TyCtxt::COMMON_VTABLE_ENTRIES.len();
1134-
}
1135-
VtblSegment::TraitOwnEntries { trait_ref, emit_vptr } => {
1136-
vptr_offset += count_own_vtable_entries(tcx, trait_ref);
1137-
if trait_ref == unnormalized_upcast_principal {
1138-
if emit_vptr {
1139-
return ControlFlow::Break(Some(vptr_offset));
1140-
} else {
1141-
return ControlFlow::Break(None);
1142-
}
1143-
}
1144-
1145-
if emit_vptr {
1146-
vptr_offset += 1;
1147-
}
1148-
}
1149-
}
1150-
ControlFlow::Continue(())
1151-
}
1152-
};
1153-
1154-
let vtable_vptr_slot =
1155-
prepare_vtable_segments(tcx, source_principal, vtable_segment_callback).unwrap();
1156-
1157-
Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { vtable_vptr_slot }, nested))
1118+
Ok(ImplSource::Builtin(BuiltinImplSource::TraitUpcasting, nested))
11581119
}
11591120

11601121
fn confirm_builtin_unsize_candidate(

compiler/rustc_trait_selection/src/traits/util.rs

-17
Original file line numberDiff line numberDiff line change
@@ -208,23 +208,6 @@ pub fn upcast_choices<'tcx>(
208208
supertraits(tcx, source_trait_ref).filter(|r| r.def_id() == target_trait_def_id).collect()
209209
}
210210

211-
/// Given an upcast trait object described by `object`, returns the
212-
/// index of the method `method_def_id` (which should be part of
213-
/// `object.upcast_trait_ref`) within the vtable for `object`.
214-
pub fn get_vtable_index_of_object_method<'tcx>(
215-
tcx: TyCtxt<'tcx>,
216-
vtable_base: usize,
217-
method_def_id: DefId,
218-
) -> Option<usize> {
219-
// Count number of methods preceding the one we are selecting and
220-
// add them to the total offset.
221-
tcx.own_existential_vtable_entries(tcx.parent(method_def_id))
222-
.iter()
223-
.copied()
224-
.position(|def_id| def_id == method_def_id)
225-
.map(|index| vtable_base + index)
226-
}
227-
228211
pub fn closure_trait_ref_and_return_type<'tcx>(
229212
tcx: TyCtxt<'tcx>,
230213
fn_trait_def_id: DefId,

0 commit comments

Comments
 (0)