Skip to content

Commit 649b26f

Browse files
committed
Rework vtable_res to not be flattened. It is now a list of the resolutions for each param.
1 parent 57ee34c commit 649b26f

File tree

8 files changed

+76
-90
lines changed

8 files changed

+76
-90
lines changed

src/librustc/middle/astencode.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,10 @@ fn encode_vtable_res(ecx: &e::EncodeContext,
599599
// ty::t doesn't work, and there is no way (atm) to have
600600
// hand-written encoding routines combine with auto-generated
601601
// ones. perhaps we should fix this.
602-
do ebml_w.emit_from_vec(*dr) |ebml_w, vtable_origin| {
603-
encode_vtable_origin(ecx, ebml_w, vtable_origin)
602+
do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| {
603+
do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| {
604+
encode_vtable_origin(ecx, ebml_w, vtable_origin)
605+
}
604606
}
605607
}
606608

@@ -653,7 +655,9 @@ trait vtable_decoder_helpers {
653655
impl vtable_decoder_helpers for reader::Decoder {
654656
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
655657
-> typeck::vtable_res {
656-
@self.read_to_vec(|this| this.read_vtable_origin(xcx))
658+
@self.read_to_vec(|this|
659+
@this.read_to_vec(|this|
660+
this.read_vtable_origin(xcx)))
657661
}
658662

659663
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)

src/librustc/middle/trans/callee.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// closure.
1818

1919
use core::prelude::*;
20+
use core::vec;
2021

2122
use back::abi;
2223
use driver::session;
@@ -274,9 +275,7 @@ pub fn trans_fn_ref_with_vtables(
274275
let receiver_vtables = match vtables {
275276
None => @~[],
276277
Some(call_vtables) => {
277-
let num_method_vtables =
278-
ty::count_traits_and_supertraits(tcx, *param_defs);
279-
@call_vtables.initn(num_method_vtables).to_owned()
278+
@call_vtables.initn(param_defs.len()).to_owned()
280279
}
281280
};
282281

@@ -305,6 +304,27 @@ pub fn trans_fn_ref_with_vtables(
305304
}
306305
};
307306

307+
// XXX: this is *completely* bad and wrong. I feel bad. Handling
308+
// of vtables is currently bogus for default methods, and changing
309+
// to an unflattented representation of vtables causes this to
310+
// show up in cases that it did not previously. We need to make
311+
// the vtables list be the same length as the substs. There is
312+
// nothing right about this. I really need to emphasize just how
313+
// wrong it is: it is completely wrong.
314+
// XXX: bad.
315+
// This will be fixed in the next commit.
316+
let vtables = do vtables.map |vtbls| {
317+
if vtbls.len() < substs.tps.len() {
318+
@(vec::from_elem(substs.tps.len() - vtbls.len(), @~[]) +
319+
**vtbls)
320+
} else if vtbls.len() > substs.tps.len() {
321+
@vtbls.tailn(vtbls.len() - substs.tps.len()).to_owned()
322+
} else {
323+
*vtbls
324+
}
325+
};
326+
327+
308328
// Check whether this fn has an inlined copy and, if so, redirect
309329
// def_id to the local id of the inlined copy.
310330
let def_id = {

src/librustc/middle/trans/common.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,8 @@ pub fn node_vtables(bcx: block, id: ast::node_id)
10351035

10361036
pub fn resolve_vtables_in_fn_ctxt(fcx: fn_ctxt, vts: typeck::vtable_res)
10371037
-> typeck::vtable_res {
1038-
@vec::map(*vts, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d))
1038+
@vec::map(*vts, |ds|
1039+
@vec::map(**ds, |d| resolve_vtable_in_fn_ctxt(fcx, copy *d)))
10391040
}
10401041

10411042
// Apply the typaram substitutions in the fn_ctxt to a vtable. This should
@@ -1090,13 +1091,7 @@ pub fn find_vtable(tcx: ty::ctxt, ps: &param_substs,
10901091
debug!("find_vtable(n_param=%u, n_bound=%u, ps=%s)",
10911092
n_param, n_bound, ps.repr(tcx));
10921093

1093-
// Vtables are stored in a flat array, finding the right one is
1094-
// somewhat awkward
1095-
let first_n_type_param_defs = ps.type_param_defs.slice(0, n_param);
1096-
let vtables_to_skip =
1097-
ty::count_traits_and_supertraits(tcx, first_n_type_param_defs);
1098-
let vtable_off = vtables_to_skip + n_bound;
1099-
/*bad*/ copy ps.vtables.get()[vtable_off]
1094+
/*bad*/ copy ps.vtables.get()[n_param][n_bound]
11001095
}
11011096

11021097
pub fn dummy_substs(tps: ~[ty::t]) -> ty::substs {

src/librustc/middle/trans/meth.rs

Lines changed: 23 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,9 @@ pub fn trans_static_method_callee(bcx: block,
292292
//
293293
// So when we see a call to this function foo, we have to figure
294294
// out which impl the `Trait<T1...Tn>` bound on the type `self` was
295-
// bound to. Due to the fact that we use a flattened list of
296-
// impls, one per bound, this means we have to total up the bounds
297-
// found on the type parametesr T1...Tn to find the index of the
298-
// one we are interested in.
299-
let bound_index = {
300-
let trait_def = ty::lookup_trait_def(bcx.tcx(), trait_id);
301-
ty::count_traits_and_supertraits(
302-
bcx.tcx(), *trait_def.generics.type_param_defs)
303-
};
295+
// bound to.
296+
let bound_index = ty::lookup_trait_def(bcx.tcx(), trait_id).
297+
generics.type_param_defs.len();
304298

305299
let mname = if method_id.crate == ast::local_crate {
306300
match bcx.tcx().items.get_copy(&method_id.node) {
@@ -322,17 +316,17 @@ pub fn trans_static_method_callee(bcx: block,
322316
let vtbls = resolve_vtables_in_fn_ctxt(
323317
bcx.fcx, ccx.maps.vtable_map.get_copy(&callee_id));
324318

325-
match vtbls[bound_index] {
319+
match vtbls[bound_index][0] {
326320
typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => {
327321
assert!(rcvr_substs.iter().all(|t| !ty::type_needs_infer(*t)));
328322

329323
let mth_id = method_with_name_or_default(bcx.ccx(),
330324
impl_did,
331325
mname);
332-
let callee_substs = combine_impl_and_methods_tps(
333-
bcx, mth_id, impl_did, callee_id, *rcvr_substs);
334-
let callee_origins = combine_impl_and_methods_origins(
335-
bcx, mth_id, impl_did, callee_id, rcvr_origins);
326+
let (callee_substs, callee_origins) =
327+
combine_impl_and_methods_tps(
328+
bcx, mth_id, impl_did, callee_id,
329+
*rcvr_substs, rcvr_origins);
336330

337331
let FnData {llfn: lval} =
338332
trans_fn_ref_with_vtables(bcx,
@@ -428,10 +422,10 @@ pub fn trans_monomorphized_callee(bcx: block,
428422

429423
// create a concatenated set of substitutions which includes
430424
// those from the impl and those from the method:
431-
let callee_substs = combine_impl_and_methods_tps(
432-
bcx, mth_id, impl_did, callee_id, *rcvr_substs);
433-
let callee_origins = combine_impl_and_methods_origins(
434-
bcx, mth_id, impl_did, callee_id, rcvr_origins);
425+
let (callee_substs, callee_origins) =
426+
combine_impl_and_methods_tps(
427+
bcx, mth_id, impl_did, callee_id,
428+
*rcvr_substs, rcvr_origins);
435429

436430
// translate the function
437431
let callee = trans_fn_ref_with_vtables(bcx,
@@ -471,8 +465,9 @@ pub fn combine_impl_and_methods_tps(bcx: block,
471465
mth_did: ast::def_id,
472466
impl_did: ast::def_id,
473467
callee_id: ast::node_id,
474-
rcvr_substs: &[ty::t])
475-
-> ~[ty::t] {
468+
rcvr_substs: &[ty::t],
469+
rcvr_origins: typeck::vtable_res)
470+
-> (~[ty::t], typeck::vtable_res) {
476471
/*!
477472
*
478473
* Creates a concatenated set of substitutions which includes
@@ -501,52 +496,18 @@ pub fn combine_impl_and_methods_tps(bcx: block,
501496
debug!("node_substs=%?", node_substs.map(|t| bcx.ty_to_str(*t)));
502497
debug!("ty_substs=%?", ty_substs.map(|t| bcx.ty_to_str(*t)));
503498

504-
return ty_substs;
505-
}
506-
507-
pub fn combine_impl_and_methods_origins(bcx: block,
508-
mth_did: ast::def_id,
509-
impl_did: ast::def_id,
510-
callee_id: ast::node_id,
511-
rcvr_origins: typeck::vtable_res)
512-
-> typeck::vtable_res {
513-
/*!
514-
*
515-
* Similar to `combine_impl_and_methods_tps`, but for vtables.
516-
* This is much messier because of the flattened layout we are
517-
* currently using (for some reason that I fail to understand).
518-
* The proper fix is described in #3446.
519-
*/
520-
521499

522-
// Find the bounds for the method, which are the tail of the
523-
// bounds found in the item type, as the item type combines the
524-
// rcvr + method bounds.
525-
let ccx = bcx.ccx();
526-
let tcx = bcx.tcx();
527-
let n_m_tps = method_ty_param_count(ccx, mth_did, impl_did);
528-
let ty::ty_param_bounds_and_ty {
529-
generics: r_m_generics,
530-
_
531-
} = ty::lookup_item_type(tcx, mth_did);
532-
let n_r_m_tps = r_m_generics.type_param_defs.len(); // rcvr + method tps
533-
let m_type_param_defs =
534-
r_m_generics.type_param_defs.slice(n_r_m_tps - n_m_tps, n_r_m_tps);
535-
536-
// Flatten out to find the number of vtables the method expects.
537-
let m_vtables = ty::count_traits_and_supertraits(tcx, m_type_param_defs);
538-
539-
// Find the vtables we computed at type check time and monomorphize them
500+
// Now, do the same work for the vtables. The vtables might not
501+
// exist, in which case we need to make them.
540502
let r_m_origins = match node_vtables(bcx, callee_id) {
541503
Some(vt) => vt,
542-
None => @~[]
504+
None => @vec::from_elem(node_substs.len(), @~[])
543505
};
506+
let vtables
507+
= @vec::append(rcvr_origins.to_owned(),
508+
r_m_origins.tailn(r_m_origins.len() - n_m_tps));
544509

545-
// Extract those that belong to method:
546-
let m_origins = r_m_origins.tailn(r_m_origins.len() - m_vtables);
547-
548-
// Combine rcvr + method to find the final result:
549-
@vec::append(/*bad*/copy *rcvr_origins, m_origins)
510+
return (ty_substs, vtables);
550511
}
551512

552513

@@ -845,7 +806,7 @@ pub fn trans_trait_cast(bcx: block,
845806
bcx = expr::trans_into(bcx, val, SaveIn(llboxdest));
846807

847808
// Store the vtable into the pair or triple.
848-
let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0];
809+
let orig = /*bad*/copy ccx.maps.vtable_map.get(&id)[0][0];
849810
let orig = resolve_vtable_in_fn_ctxt(bcx.fcx, orig);
850811
let vtable = get_vtable(bcx, v_ty, orig);
851812
Store(bcx, vtable, PointerCast(bcx,

src/librustc/middle/trans/monomorphize.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,10 @@ pub fn make_mono_id(ccx: @mut CrateContext,
340340
param_uses: Option<@~[type_use::type_uses]>) -> mono_id {
341341
let precise_param_ids = match vtables {
342342
Some(vts) => {
343-
let item_ty = ty::lookup_item_type(ccx.tcx, item);
344-
let mut i = 0;
345-
vec::map_zip(*item_ty.generics.type_param_defs, substs, |type_param_def, subst| {
346-
let mut v = ~[];
347-
for type_param_def.bounds.trait_bounds.iter().advance |_bound| {
348-
v.push(meth::vtable_id(ccx, &vts[i]));
349-
i += 1;
350-
}
343+
debug!("make_mono_id vtables=%s substs=%s",
344+
vts.repr(ccx.tcx), substs.repr(ccx.tcx));
345+
vec::map_zip(*vts, substs, |vtable, subst| {
346+
let v = vtable.map(|vt| meth::vtable_id(ccx, vt));
351347
(*subst, if !v.is_empty() { Some(@v) } else { None })
352348
})
353349
}

src/librustc/middle/typeck/check/vtable.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ fn lookup_vtables(vcx: &VtableContext,
9090
let mut i = 0u;
9191
for substs.tps.iter().advance |ty| {
9292
// ty is the value supplied for the type parameter A...
93+
let mut param_result = ~[];
9394

9495
for ty::each_bound_trait_and_supertraits(
9596
tcx, type_param_defs[i].bounds) |trait_ref|
@@ -106,7 +107,7 @@ fn lookup_vtables(vcx: &VtableContext,
106107
debug!("after subst: %s", trait_ref.repr(tcx));
107108

108109
match lookup_vtable(vcx, location_info, *ty, &trait_ref, is_early) {
109-
Some(vtable) => result.push(vtable),
110+
Some(vtable) => param_result.push(vtable),
110111
None => {
111112
vcx.tcx().sess.span_fatal(
112113
location_info.span,
@@ -117,6 +118,7 @@ fn lookup_vtables(vcx: &VtableContext,
117118
}
118119
}
119120
}
121+
result.push(@param_result);
120122
i += 1u;
121123
}
122124
debug!("lookup_vtables result(\
@@ -600,7 +602,8 @@ pub fn early_resolve_expr(ex: @ast::expr,
600602
// vtable (that is: "ex has vtable
601603
// <vtable>")
602604
if !is_early {
603-
insert_vtables(fcx, ex.id, @~[vtable]);
605+
insert_vtables(fcx, ex.id,
606+
@~[@~[vtable]]);
604607
}
605608
}
606609
None => {

src/librustc/middle/typeck/check/writeback.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ use middle::typeck::check::{FnCtxt, SelfInfo};
2020
use middle::typeck::infer::{force_all, resolve_all, resolve_region};
2121
use middle::typeck::infer::resolve_type;
2222
use middle::typeck::infer;
23-
use middle::typeck::{vtable_origin, vtable_static, vtable_param, vtable_self};
23+
use middle::typeck::{vtable_res, vtable_origin};
24+
use middle::typeck::{vtable_static, vtable_param, vtable_self};
2425
use middle::typeck::method_map_entry;
2526
use middle::typeck::write_substs_to_tcx;
2627
use middle::typeck::write_ty_to_tcx;
@@ -84,21 +85,26 @@ fn resolve_vtable_map_entry(fcx: @mut FnCtxt, sp: span, id: ast::node_id) {
8485
match fcx.inh.vtable_map.find(&id) {
8586
None => {}
8687
Some(origins) => {
87-
let r_origins = @origins.map(|o| resolve_origin(fcx, sp, o));
88+
let r_origins = resolve_origins(fcx, sp, *origins);
8889
let vtable_map = fcx.ccx.vtable_map;
8990
vtable_map.insert(id, r_origins);
9091
debug!("writeback::resolve_vtable_map_entry(id=%d, vtables=%?)",
9192
id, r_origins.repr(fcx.tcx()));
9293
}
9394
}
9495

96+
fn resolve_origins(fcx: @mut FnCtxt, sp: span,
97+
vtbls: vtable_res) -> vtable_res {
98+
@vtbls.map(|os| @os.map(|o| resolve_origin(fcx, sp, o)))
99+
}
100+
95101
fn resolve_origin(fcx: @mut FnCtxt,
96102
sp: span,
97103
origin: &vtable_origin) -> vtable_origin {
98104
match origin {
99105
&vtable_static(def_id, ref tys, origins) => {
100106
let r_tys = resolve_type_vars_in_types(fcx, sp, *tys);
101-
let r_origins = @origins.map(|o| resolve_origin(fcx, sp, o));
107+
let r_origins = resolve_origins(fcx, sp, origins);
102108
vtable_static(def_id, r_tys, r_origins)
103109
}
104110
&vtable_param(n, b) => {

src/librustc/middle/typeck/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,9 @@ pub struct method_map_entry {
135135
// of the method to be invoked
136136
pub type method_map = @mut HashMap<ast::node_id, method_map_entry>;
137137

138+
pub type vtable_param_res = @~[vtable_origin];
138139
// Resolutions for bounds of all parameters, left to right, for a given path.
139-
pub type vtable_res = @~[vtable_origin];
140+
pub type vtable_res = @~[vtable_param_res];
140141

141142
pub enum vtable_origin {
142143
/*

0 commit comments

Comments
 (0)