Properly track and export information about vtables for impls in metadata.
Partially rework how vtables are handled in default method calls. Closes #7460.
This commit is contained in:
parent
304a5f0786
commit
79f8a7fee5
@ -180,6 +180,7 @@ pub static tag_misc_info: uint = 0x7f;
|
||||
pub static tag_misc_info_crate_items: uint = 0x80;
|
||||
|
||||
pub static tag_item_method_provided_source: uint = 0x81;
|
||||
pub static tag_item_impl_vtables: uint = 0x82;
|
||||
|
||||
pub struct LinkMeta {
|
||||
name: @str,
|
||||
|
@ -16,6 +16,7 @@ use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
|
||||
use std::vec;
|
||||
use reader = extra::ebml::reader;
|
||||
@ -216,6 +217,14 @@ pub fn get_impl_trait(tcx: ty::ctxt,
|
||||
decoder::get_impl_trait(cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
// Given a def_id for an impl, return information about its vtables
|
||||
pub fn get_impl_vtables(tcx: ty::ctxt,
|
||||
def: ast::def_id) -> typeck::impl_res {
|
||||
let cstore = tcx.cstore;
|
||||
let cdata = cstore::get_crate_data(cstore, def.crate);
|
||||
decoder::get_impl_vtables(cdata, def.node, tcx)
|
||||
}
|
||||
|
||||
pub fn get_impl_method(cstore: @mut cstore::CStore,
|
||||
def: ast::def_id,
|
||||
mname: ast::ident)
|
||||
|
@ -21,6 +21,9 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
|
||||
parse_type_param_def_data,
|
||||
parse_bare_fn_ty_data, parse_trait_ref_data};
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::astencode::vtable_decoder_helpers;
|
||||
|
||||
|
||||
use std::hash::HashUtil;
|
||||
use std::int;
|
||||
@ -410,6 +413,21 @@ pub fn get_impl_trait(cdata: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_impl_vtables(cdata: cmd,
|
||||
id: ast::node_id,
|
||||
tcx: ty::ctxt) -> typeck::impl_res
|
||||
{
|
||||
let item_doc = lookup_item(id, cdata.data);
|
||||
let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
|
||||
let mut decoder = reader::Decoder(vtables_doc);
|
||||
|
||||
typeck::impl_res {
|
||||
trait_vtables: decoder.read_vtable_res(tcx, cdata),
|
||||
self_vtables: decoder.read_vtable_param_res(tcx, cdata)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
||||
name: ast::ident) -> Option<ast::def_id> {
|
||||
let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
|
||||
|
@ -17,6 +17,8 @@ use metadata::decoder;
|
||||
use metadata::tyencode;
|
||||
use middle::ty::{node_id_to_type, lookup_item_type};
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::astencode;
|
||||
use middle;
|
||||
|
||||
use std::hash::HashUtil;
|
||||
@ -162,6 +164,15 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder,
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_impl_vtables(ebml_w: &mut writer::Encoder,
|
||||
ecx: &EncodeContext,
|
||||
vtables: &typeck::impl_res) {
|
||||
ebml_w.start_tag(tag_item_impl_vtables);
|
||||
astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_vtables);
|
||||
astencode::encode_vtable_param_res(ecx, ebml_w, vtables.self_vtables);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
// Item info table encoding
|
||||
fn encode_family(ebml_w: &mut writer::Encoder, c: char) {
|
||||
ebml_w.start_tag(tag_items_data_item_family);
|
||||
@ -1009,6 +1020,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||
let trait_ref = ty::node_id_to_trait_ref(
|
||||
tcx, ast_trait_ref.ref_id);
|
||||
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
|
||||
let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
|
||||
encode_impl_vtables(ebml_w, ecx, &impl_vtables);
|
||||
}
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||
ebml_w.end_tag();
|
||||
|
@ -250,6 +250,8 @@ impl<S:serialize::Encoder> def_id_encoder_helpers for S {
|
||||
|
||||
trait def_id_decoder_helpers {
|
||||
fn read_def_id(&mut self, xcx: @ExtendedDecodeContext) -> ast::def_id;
|
||||
fn read_def_id_noxcx(&mut self,
|
||||
cdata: @cstore::crate_metadata) -> ast::def_id;
|
||||
}
|
||||
|
||||
impl<D:serialize::Decoder> def_id_decoder_helpers for D {
|
||||
@ -257,6 +259,12 @@ impl<D:serialize::Decoder> def_id_decoder_helpers for D {
|
||||
let did: ast::def_id = Decodable::decode(self);
|
||||
did.tr(xcx)
|
||||
}
|
||||
|
||||
fn read_def_id_noxcx(&mut self,
|
||||
cdata: @cstore::crate_metadata) -> ast::def_id {
|
||||
let did: ast::def_id = Decodable::decode(self);
|
||||
decoder::translate_def_id(cdata, did)
|
||||
}
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
@ -595,7 +603,7 @@ impl tr for method_origin {
|
||||
// ______________________________________________________________________
|
||||
// Encoding and decoding vtable_res
|
||||
|
||||
fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||
pub fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
dr: typeck::vtable_res) {
|
||||
// can't autogenerate this code because automatic code of
|
||||
@ -603,13 +611,20 @@ fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||
// hand-written encoding routines combine with auto-generated
|
||||
// ones. perhaps we should fix this.
|
||||
do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| {
|
||||
do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| {
|
||||
encode_vtable_origin(ecx, ebml_w, vtable_origin)
|
||||
}
|
||||
encode_vtable_param_res(ecx, ebml_w, *param_tables);
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
param_tables: typeck::vtable_param_res) {
|
||||
do ebml_w.emit_from_vec(*param_tables) |ebml_w, vtable_origin| {
|
||||
encode_vtable_origin(ecx, ebml_w, vtable_origin)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||
ebml_w: &mut writer::Encoder,
|
||||
vtable_origin: &typeck::vtable_origin) {
|
||||
do ebml_w.emit_enum("vtable_origin") |ebml_w| {
|
||||
@ -648,22 +663,35 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||
}
|
||||
}
|
||||
|
||||
trait vtable_decoder_helpers {
|
||||
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
|
||||
pub trait vtable_decoder_helpers {
|
||||
fn read_vtable_res(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_res;
|
||||
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
|
||||
fn read_vtable_param_res(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_param_res;
|
||||
fn read_vtable_origin(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_origin;
|
||||
}
|
||||
|
||||
impl vtable_decoder_helpers for reader::Decoder {
|
||||
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
|
||||
fn read_vtable_res(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_res {
|
||||
@self.read_to_vec(|this|
|
||||
@this.read_to_vec(|this|
|
||||
this.read_vtable_origin(xcx)))
|
||||
this.read_vtable_param_res(tcx, cdata))
|
||||
}
|
||||
|
||||
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
|
||||
fn read_vtable_param_res(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_param_res {
|
||||
@self.read_to_vec(|this|
|
||||
this.read_vtable_origin(tcx, cdata))
|
||||
}
|
||||
|
||||
fn read_vtable_origin(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
|
||||
-> typeck::vtable_origin {
|
||||
do self.read_enum("vtable_origin") |this| {
|
||||
do this.read_enum_variant(["vtable_static",
|
||||
@ -674,13 +702,13 @@ impl vtable_decoder_helpers for reader::Decoder {
|
||||
0 => {
|
||||
typeck::vtable_static(
|
||||
do this.read_enum_variant_arg(0u) |this| {
|
||||
this.read_def_id(xcx)
|
||||
this.read_def_id_noxcx(cdata)
|
||||
},
|
||||
do this.read_enum_variant_arg(1u) |this| {
|
||||
this.read_tys(xcx)
|
||||
this.read_tys_noxcx(tcx, cdata)
|
||||
},
|
||||
do this.read_enum_variant_arg(2u) |this| {
|
||||
this.read_vtable_res(xcx)
|
||||
this.read_vtable_res(tcx, cdata)
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -697,7 +725,7 @@ impl vtable_decoder_helpers for reader::Decoder {
|
||||
2 => {
|
||||
typeck::vtable_self(
|
||||
do this.read_enum_variant_arg(0u) |this| {
|
||||
this.read_def_id(xcx)
|
||||
this.read_def_id_noxcx(cdata)
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -995,9 +1023,35 @@ trait ebml_decoder_decoder_helpers {
|
||||
source: DefIdSource,
|
||||
did: ast::def_id)
|
||||
-> ast::def_id;
|
||||
|
||||
// Versions of the type reading functions that don't need the full
|
||||
// ExtendedDecodeContext.
|
||||
fn read_ty_noxcx(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t;
|
||||
fn read_tys_noxcx(&mut self,
|
||||
tcx: ty::ctxt,
|
||||
cdata: @cstore::crate_metadata) -> ~[ty::t];
|
||||
}
|
||||
|
||||
impl ebml_decoder_decoder_helpers for reader::Decoder {
|
||||
fn read_ty_noxcx(&mut self,
|
||||
tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t {
|
||||
do self.read_opaque |_, doc| {
|
||||
tydecode::parse_ty_data(
|
||||
*doc.data,
|
||||
cdata.cnum,
|
||||
doc.start,
|
||||
tcx,
|
||||
|_, id| decoder::translate_def_id(cdata, id))
|
||||
}
|
||||
}
|
||||
|
||||
fn read_tys_noxcx(&mut self,
|
||||
tcx: ty::ctxt,
|
||||
cdata: @cstore::crate_metadata) -> ~[ty::t] {
|
||||
self.read_to_vec(|this| this.read_ty_noxcx(tcx, cdata) )
|
||||
}
|
||||
|
||||
fn read_ty(&mut self, xcx: @ExtendedDecodeContext) -> ty::t {
|
||||
// Note: regions types embed local node ids. In principle, we
|
||||
// should translate these node ids into the new decode
|
||||
@ -1160,8 +1214,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
|
||||
val_dsr.read_method_map_entry(xcx));
|
||||
}
|
||||
c::tag_table_vtable_map => {
|
||||
dcx.maps.vtable_map.insert(id,
|
||||
val_dsr.read_vtable_res(xcx));
|
||||
dcx.maps.vtable_map.insert(
|
||||
id,
|
||||
val_dsr.read_vtable_res(xcx.dcx.tcx, xcx.dcx.cdata));
|
||||
}
|
||||
c::tag_table_adjustments => {
|
||||
let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);
|
||||
|
@ -193,30 +193,15 @@ pub fn trans_fn_ref_with_vtables_to_callee(
|
||||
type_params, vtables))}
|
||||
}
|
||||
|
||||
fn get_impl_resolutions(bcx: @mut Block,
|
||||
impl_id: ast::def_id)
|
||||
-> typeck::vtable_res {
|
||||
if impl_id.crate == ast::local_crate {
|
||||
bcx.ccx().maps.vtable_map.get_copy(&impl_id.node)
|
||||
} else {
|
||||
// XXX: This is a temporary hack to work around not properly
|
||||
// exporting information about resolutions for impls.
|
||||
// This doesn't actually work if the trait has param bounds,
|
||||
// but it does allow us to survive the case when it does not.
|
||||
let trait_ref = ty::impl_trait_ref(bcx.tcx(), impl_id).get();
|
||||
@vec::from_elem(trait_ref.substs.tps.len(), @~[])
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_default_method_vtables(bcx: @mut Block,
|
||||
impl_id: ast::def_id,
|
||||
method: &ty::Method,
|
||||
substs: &ty::substs,
|
||||
impl_vtables: Option<typeck::vtable_res>)
|
||||
-> typeck::vtable_res {
|
||||
-> (typeck::vtable_res, typeck::vtable_param_res) {
|
||||
|
||||
// Get the vtables that the impl implements the trait at
|
||||
let trait_vtables = get_impl_resolutions(bcx, impl_id);
|
||||
let impl_res = ty::lookup_impl_vtables(bcx.tcx(), impl_id);
|
||||
|
||||
// Build up a param_substs that we are going to resolve the
|
||||
// trait_vtables under.
|
||||
@ -224,11 +209,11 @@ fn resolve_default_method_vtables(bcx: @mut Block,
|
||||
tys: substs.tps.clone(),
|
||||
self_ty: substs.self_ty,
|
||||
vtables: impl_vtables,
|
||||
self_vtable: None
|
||||
self_vtables: None
|
||||
});
|
||||
|
||||
let trait_vtables_fixed = resolve_vtables_under_param_substs(
|
||||
bcx.tcx(), param_substs, trait_vtables);
|
||||
bcx.tcx(), param_substs, impl_res.trait_vtables);
|
||||
|
||||
// Now we pull any vtables for parameters on the actual method.
|
||||
let num_method_vtables = method.generics.type_param_defs.len();
|
||||
@ -241,7 +226,12 @@ fn resolve_default_method_vtables(bcx: @mut Block,
|
||||
None => vec::from_elem(num_method_vtables, @~[])
|
||||
};
|
||||
|
||||
@(*trait_vtables_fixed + method_vtables)
|
||||
let param_vtables = @(*trait_vtables_fixed + method_vtables);
|
||||
|
||||
let self_vtables = resolve_param_vtables_under_param_substs(
|
||||
bcx.tcx(), param_substs, impl_res.self_vtables);
|
||||
|
||||
(param_vtables, self_vtables)
|
||||
}
|
||||
|
||||
|
||||
@ -296,7 +286,7 @@ pub fn trans_fn_ref_with_vtables(
|
||||
// We need to do a bunch of special handling for default methods.
|
||||
// We need to modify the def_id and our substs in order to monomorphize
|
||||
// the function.
|
||||
let (is_default, def_id, substs, self_vtable, vtables) =
|
||||
let (is_default, def_id, substs, self_vtables, vtables) =
|
||||
match ty::provided_source(tcx, def_id) {
|
||||
None => (false, def_id, substs, None, vtables),
|
||||
Some(source_id) => {
|
||||
@ -319,20 +309,6 @@ pub fn trans_fn_ref_with_vtables(
|
||||
.expect("could not find trait_ref for impl with \
|
||||
default methods");
|
||||
|
||||
// Get all of the type params for the receiver
|
||||
let param_defs = method.generics.type_param_defs;
|
||||
let receiver_substs =
|
||||
type_params.initn(param_defs.len()).to_owned();
|
||||
let receiver_vtables = match vtables {
|
||||
None => @~[],
|
||||
Some(call_vtables) => {
|
||||
@call_vtables.initn(param_defs.len()).to_owned()
|
||||
}
|
||||
};
|
||||
|
||||
let self_vtable =
|
||||
typeck::vtable_static(impl_id, receiver_substs,
|
||||
receiver_vtables);
|
||||
// Compute the first substitution
|
||||
let first_subst = make_substs_for_receiver_types(
|
||||
tcx, impl_id, trait_ref, method);
|
||||
@ -341,20 +317,22 @@ pub fn trans_fn_ref_with_vtables(
|
||||
let new_substs = first_subst.subst(tcx, &substs);
|
||||
|
||||
|
||||
let vtables =
|
||||
let (param_vtables, self_vtables) =
|
||||
resolve_default_method_vtables(bcx, impl_id,
|
||||
method, &substs, vtables);
|
||||
|
||||
debug!("trans_fn_with_vtables - default method: \
|
||||
substs = %s, trait_subst = %s, \
|
||||
first_subst = %s, new_subst = %s, \
|
||||
self_vtable = %s, vtables = %s",
|
||||
vtables = %s, \
|
||||
self_vtable = %s, param_vtables = %s",
|
||||
substs.repr(tcx), trait_ref.substs.repr(tcx),
|
||||
first_subst.repr(tcx), new_substs.repr(tcx),
|
||||
self_vtable.repr(tcx), vtables.repr(tcx));
|
||||
vtables.repr(tcx),
|
||||
self_vtables.repr(tcx), param_vtables.repr(tcx));
|
||||
|
||||
(true, source_id,
|
||||
new_substs, Some(self_vtable), Some(vtables))
|
||||
new_substs, Some(self_vtables), Some(param_vtables))
|
||||
}
|
||||
};
|
||||
|
||||
@ -400,7 +378,7 @@ pub fn trans_fn_ref_with_vtables(
|
||||
|
||||
let (val, must_cast) =
|
||||
monomorphize::monomorphic_fn(ccx, def_id, &substs,
|
||||
vtables, self_vtable,
|
||||
vtables, self_vtables,
|
||||
Some(ref_id));
|
||||
let mut val = val;
|
||||
if must_cast && ref_id != 0 {
|
||||
|
@ -133,7 +133,7 @@ pub struct param_substs {
|
||||
tys: ~[ty::t],
|
||||
self_ty: Option<ty::t>,
|
||||
vtables: Option<typeck::vtable_res>,
|
||||
self_vtable: Option<typeck::vtable_origin>
|
||||
self_vtables: Option<typeck::vtable_param_res>
|
||||
}
|
||||
|
||||
impl param_substs {
|
||||
@ -1037,14 +1037,25 @@ pub fn resolve_vtables_under_param_substs(tcx: ty::ctxt,
|
||||
vts: typeck::vtable_res)
|
||||
-> typeck::vtable_res {
|
||||
@vts.iter().transform(|ds|
|
||||
@ds.iter().transform(
|
||||
|d| resolve_vtable_under_param_substs(tcx,
|
||||
param_substs,
|
||||
d))
|
||||
.collect::<~[typeck::vtable_origin]>())
|
||||
.collect::<~[typeck::vtable_param_res]>()
|
||||
resolve_param_vtables_under_param_substs(tcx,
|
||||
param_substs,
|
||||
*ds))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn resolve_param_vtables_under_param_substs(
|
||||
tcx: ty::ctxt,
|
||||
param_substs: Option<@param_substs>,
|
||||
ds: typeck::vtable_param_res)
|
||||
-> typeck::vtable_param_res {
|
||||
@ds.iter().transform(
|
||||
|d| resolve_vtable_under_param_substs(tcx,
|
||||
param_substs,
|
||||
d))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Apply the typaram substitutions in the FunctionContext to a vtable. This should
|
||||
// eliminate any vtable_params.
|
||||
@ -1088,8 +1099,8 @@ pub fn resolve_vtable_under_param_substs(tcx: ty::ctxt,
|
||||
typeck::vtable_self(_trait_id) => {
|
||||
match param_substs {
|
||||
Some(@param_substs
|
||||
{self_vtable: Some(ref self_vtable), _}) => {
|
||||
(*self_vtable).clone()
|
||||
{self_vtables: Some(self_vtables), _}) => {
|
||||
self_vtables[0].clone()
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.bug(fmt!(
|
||||
|
@ -222,14 +222,15 @@ pub fn trans_method_callee(bcx: @mut Block,
|
||||
typeck::method_self(trait_id, method_index) => {
|
||||
match bcx.fcx.param_substs {
|
||||
Some(@param_substs
|
||||
{self_vtable: Some(ref vtbl), _}) => {
|
||||
{self_vtables: Some(vtbls), _}) => {
|
||||
let vtbl = vtbls[0].clone();
|
||||
trans_monomorphized_callee(bcx,
|
||||
callee_id,
|
||||
this,
|
||||
mentry,
|
||||
trait_id,
|
||||
method_index,
|
||||
(*vtbl).clone())
|
||||
vtbl)
|
||||
}
|
||||
_ => {
|
||||
fail!("trans_method_callee: missing self_vtable")
|
||||
@ -611,7 +612,7 @@ pub fn vtable_id(ccx: @mut CrateContext,
|
||||
tys: (*substs).clone(),
|
||||
vtables: Some(sub_vtables),
|
||||
self_ty: None,
|
||||
self_vtable: None
|
||||
self_vtables: None
|
||||
};
|
||||
|
||||
monomorphize::make_mono_id(
|
||||
|
@ -41,7 +41,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||
fn_id: ast::def_id,
|
||||
real_substs: &ty::substs,
|
||||
vtables: Option<typeck::vtable_res>,
|
||||
self_vtable: Option<typeck::vtable_origin>,
|
||||
self_vtables: Option<typeck::vtable_param_res>,
|
||||
ref_id: Option<ast::node_id>)
|
||||
-> (ValueRef, bool)
|
||||
{
|
||||
@ -54,7 +54,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||
fn_id.repr(ccx.tcx),
|
||||
real_substs.repr(ccx.tcx),
|
||||
vtables.repr(ccx.tcx),
|
||||
self_vtable.repr(ccx.tcx),
|
||||
self_vtables.repr(ccx.tcx),
|
||||
ref_id);
|
||||
|
||||
assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t)));
|
||||
@ -72,7 +72,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext,
|
||||
tys: real_substs.tps.map(|x| do_normalize(x)),
|
||||
vtables: vtables,
|
||||
self_ty: real_substs.self_ty.map(|x| do_normalize(x)),
|
||||
self_vtable: self_vtable
|
||||
self_vtables: self_vtables
|
||||
};
|
||||
|
||||
for real_substs.tps.iter().advance |s| { assert!(!ty::type_has_params(*s)); }
|
||||
@ -371,8 +371,7 @@ pub fn make_mono_id(ccx: @mut CrateContext,
|
||||
Some(vts) => {
|
||||
debug!("make_mono_id vtables=%s substs=%s",
|
||||
vts.repr(ccx.tcx), substs.tys.repr(ccx.tcx));
|
||||
let self_vtables = substs.self_vtable.map(|vtbl| @~[(*vtbl).clone()]);
|
||||
let vts_iter = self_vtables.iter().chain_(vts.iter());
|
||||
let vts_iter = substs.self_vtables.iter().chain_(vts.iter());
|
||||
vts_iter.zip(substs_iter).transform(|(vtable, subst)| {
|
||||
let v = vtable.map(|vt| meth::vtable_id(ccx, vt));
|
||||
(*subst, if !v.is_empty() { Some(@v) } else { None })
|
||||
|
@ -317,6 +317,9 @@ struct ctxt_ {
|
||||
// some point. Local variable definitions not in this set can be warned
|
||||
// about.
|
||||
used_mut_nodes: @mut HashSet<ast::node_id>,
|
||||
|
||||
// vtable resolution information for impl declarations
|
||||
impl_vtables: typeck::impl_vtable_map
|
||||
}
|
||||
|
||||
pub enum tbox_flag {
|
||||
@ -911,6 +914,7 @@ pub fn mk_ctxt(s: session::Session,
|
||||
impls: @mut HashMap::new(),
|
||||
used_unsafe: @mut HashSet::new(),
|
||||
used_mut_nodes: @mut HashSet::new(),
|
||||
impl_vtables: @mut HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -3955,6 +3959,14 @@ pub fn lookup_item_type(cx: ctxt,
|
||||
|| csearch::get_type(cx, did))
|
||||
}
|
||||
|
||||
pub fn lookup_impl_vtables(cx: ctxt,
|
||||
did: ast::def_id)
|
||||
-> typeck::impl_res {
|
||||
lookup_locally_or_in_crate_store(
|
||||
"impl_vtables", did, cx.impl_vtables,
|
||||
|| csearch::get_impl_vtables(cx, did) )
|
||||
}
|
||||
|
||||
/// Given the did of a trait, returns its canonical trait ref.
|
||||
pub fn lookup_trait_def(cx: ctxt, did: ast::def_id) -> @ty::TraitDef {
|
||||
match cx.trait_defs.find(&did) {
|
||||
|
@ -17,7 +17,7 @@ use middle::typeck::infer::fixup_err_to_str;
|
||||
use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::{CrateCtxt, vtable_origin, vtable_res, vtable_param_res};
|
||||
use middle::typeck::{vtable_static, vtable_param, vtable_self};
|
||||
use middle::typeck::{vtable_static, vtable_param, vtable_self, impl_res};
|
||||
use middle::subst::Subst;
|
||||
use util::common::indenter;
|
||||
use util::ppaux;
|
||||
@ -725,9 +725,6 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
|
||||
&trait_ref.substs,
|
||||
false);
|
||||
|
||||
// FIXME(#7450): Doesn't work cross crate
|
||||
ccx.vtable_map.insert(impl_item.id, vtbls);
|
||||
|
||||
// Now, locate the vtable for the impl itself. The real
|
||||
// purpose of this is to check for supertrait impls,
|
||||
// but that falls out of doing this.
|
||||
@ -740,10 +737,16 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) {
|
||||
// Right now, we don't have any place to store this.
|
||||
// We will need to make one so we can use this information
|
||||
// for compiling default methods that refer to supertraits.
|
||||
let _self_vtable_res =
|
||||
let self_vtable_res =
|
||||
lookup_vtables_for_param(&vcx, &loc_info, None,
|
||||
¶m_bounds, t, false);
|
||||
|
||||
|
||||
let res = impl_res {
|
||||
trait_vtables: vtbls,
|
||||
self_vtables: self_vtable_res
|
||||
};
|
||||
ccx.tcx.impl_vtables.insert(def_id, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,6 +187,28 @@ impl Repr for vtable_origin {
|
||||
|
||||
pub type vtable_map = @mut HashMap<ast::node_id, vtable_res>;
|
||||
|
||||
|
||||
// Information about the vtable resolutions for for a trait impl.
|
||||
// Mostly the information is important for implementing default
|
||||
// methods.
|
||||
#[deriving(Clone)]
|
||||
pub struct impl_res {
|
||||
// resolutions for any bounded params on the trait definition
|
||||
trait_vtables: vtable_res,
|
||||
// resolutions for the trait /itself/ (and for supertraits)
|
||||
self_vtables: vtable_param_res
|
||||
}
|
||||
|
||||
impl Repr for impl_res {
|
||||
fn repr(&self, tcx: ty::ctxt) -> ~str {
|
||||
fmt!("impl_res {trait_vtables=%s, self_vtables=%s}",
|
||||
self.trait_vtables.repr(tcx),
|
||||
self.self_vtables.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
pub type impl_vtable_map = @mut HashMap<ast::def_id, impl_res>;
|
||||
|
||||
pub struct CrateCtxt {
|
||||
// A mapping from method call sites to traits that have that method.
|
||||
trait_map: resolve::TraitMap,
|
||||
|
Loading…
x
Reference in New Issue
Block a user