parent
75d7d5210a
commit
087ec2aa24
3 changed files with 147 additions and 20 deletions
|
@ -581,41 +581,48 @@ impl tr for moves::CaptureVar {
|
||||||
// Encoding and decoding of MethodCallee
|
// Encoding and decoding of MethodCallee
|
||||||
|
|
||||||
trait read_method_callee_helper {
|
trait read_method_callee_helper {
|
||||||
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> MethodCallee;
|
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encode_method_callee(ecx: &e::EncodeContext,
|
fn encode_method_callee(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut writer::Encoder,
|
ebml_w: &mut writer::Encoder,
|
||||||
|
autoderef: u32,
|
||||||
method: &MethodCallee) {
|
method: &MethodCallee) {
|
||||||
ebml_w.emit_struct("MethodCallee", 3, |ebml_w| {
|
ebml_w.emit_struct("MethodCallee", 4, |ebml_w| {
|
||||||
ebml_w.emit_struct_field("origin", 0u, |ebml_w| {
|
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
|
||||||
|
autoderef.encode(ebml_w);
|
||||||
|
});
|
||||||
|
ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
|
||||||
method.origin.encode(ebml_w);
|
method.origin.encode(ebml_w);
|
||||||
});
|
});
|
||||||
ebml_w.emit_struct_field("ty", 1u, |ebml_w| {
|
ebml_w.emit_struct_field("ty", 2u, |ebml_w| {
|
||||||
ebml_w.emit_ty(ecx, method.ty);
|
ebml_w.emit_ty(ecx, method.ty);
|
||||||
});
|
});
|
||||||
ebml_w.emit_struct_field("substs", 2u, |ebml_w| {
|
ebml_w.emit_struct_field("substs", 3u, |ebml_w| {
|
||||||
ebml_w.emit_substs(ecx, &method.substs);
|
ebml_w.emit_substs(ecx, &method.substs);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> read_method_callee_helper for reader::Decoder<'a> {
|
impl<'a> read_method_callee_helper for reader::Decoder<'a> {
|
||||||
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> MethodCallee {
|
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee) {
|
||||||
self.read_struct("MethodCallee", 3, |this| {
|
self.read_struct("MethodCallee", 4, |this| {
|
||||||
MethodCallee {
|
let autoderef = this.read_struct_field("autoderef", 0, |this| {
|
||||||
origin: this.read_struct_field("origin", 0, |this| {
|
Decodable::decode(this)
|
||||||
|
});
|
||||||
|
(autoderef, MethodCallee {
|
||||||
|
origin: this.read_struct_field("origin", 1, |this| {
|
||||||
let method_origin: MethodOrigin =
|
let method_origin: MethodOrigin =
|
||||||
Decodable::decode(this);
|
Decodable::decode(this);
|
||||||
method_origin.tr(xcx)
|
method_origin.tr(xcx)
|
||||||
}),
|
}),
|
||||||
ty: this.read_struct_field("ty", 1, |this| {
|
ty: this.read_struct_field("ty", 2, |this| {
|
||||||
this.read_ty(xcx)
|
this.read_ty(xcx)
|
||||||
}),
|
}),
|
||||||
substs: this.read_struct_field("substs", 2, |this| {
|
substs: this.read_struct_field("substs", 3, |this| {
|
||||||
this.read_substs(xcx)
|
this.read_substs(xcx)
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,6 +654,20 @@ impl tr for MethodOrigin {
|
||||||
// ______________________________________________________________________
|
// ______________________________________________________________________
|
||||||
// Encoding and decoding vtable_res
|
// Encoding and decoding vtable_res
|
||||||
|
|
||||||
|
fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
|
||||||
|
ebml_w: &mut writer::Encoder,
|
||||||
|
autoderef: u32,
|
||||||
|
dr: typeck::vtable_res) {
|
||||||
|
ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| {
|
||||||
|
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
|
||||||
|
autoderef.encode(ebml_w);
|
||||||
|
});
|
||||||
|
ebml_w.emit_struct_field("vtable_res", 1u, |ebml_w| {
|
||||||
|
encode_vtable_res(ecx, ebml_w, dr);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn encode_vtable_res(ecx: &e::EncodeContext,
|
pub fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||||
ebml_w: &mut writer::Encoder,
|
ebml_w: &mut writer::Encoder,
|
||||||
dr: typeck::vtable_res) {
|
dr: typeck::vtable_res) {
|
||||||
|
@ -701,6 +722,10 @@ pub fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait vtable_decoder_helpers {
|
pub trait vtable_decoder_helpers {
|
||||||
|
fn read_vtable_res_with_key(&mut self,
|
||||||
|
tcx: &ty::ctxt,
|
||||||
|
cdata: @cstore::crate_metadata)
|
||||||
|
-> (u32, typeck::vtable_res);
|
||||||
fn read_vtable_res(&mut self,
|
fn read_vtable_res(&mut self,
|
||||||
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
||||||
-> typeck::vtable_res;
|
-> typeck::vtable_res;
|
||||||
|
@ -713,6 +738,20 @@ pub trait vtable_decoder_helpers {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> vtable_decoder_helpers for reader::Decoder<'a> {
|
impl<'a> vtable_decoder_helpers for reader::Decoder<'a> {
|
||||||
|
fn read_vtable_res_with_key(&mut self,
|
||||||
|
tcx: &ty::ctxt,
|
||||||
|
cdata: @cstore::crate_metadata)
|
||||||
|
-> (u32, typeck::vtable_res) {
|
||||||
|
self.read_struct("VtableWithKey", 2, |this| {
|
||||||
|
let autoderef = this.read_struct_field("autoderef", 0, |this| {
|
||||||
|
Decodable::decode(this)
|
||||||
|
});
|
||||||
|
(autoderef, this.read_struct_field("vtable_res", 1, |this| {
|
||||||
|
this.read_vtable_res(tcx, cdata)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn read_vtable_res(&mut self,
|
fn read_vtable_res(&mut self,
|
||||||
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
tcx: &ty::ctxt, cdata: @cstore::crate_metadata)
|
||||||
-> typeck::vtable_res {
|
-> typeck::vtable_res {
|
||||||
|
@ -1018,7 +1057,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
|
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
|
||||||
ebml_w.id(id);
|
ebml_w.id(id);
|
||||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
encode_method_callee(ecx, ebml_w, method)
|
encode_method_callee(ecx, ebml_w, method_call.autoderef, method)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1027,12 +1066,39 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
|
||||||
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
|
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
|
||||||
ebml_w.id(id);
|
ebml_w.id(id);
|
||||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
encode_vtable_res(ecx, ebml_w, *dr);
|
encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, *dr);
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
for adj in tcx.adjustments.borrow().find(&id).iter() {
|
for adj in tcx.adjustments.borrow().find(&id).iter() {
|
||||||
|
match ***adj {
|
||||||
|
ty::AutoDerefRef(adj) => {
|
||||||
|
for autoderef in range(0, adj.autoderefs) {
|
||||||
|
let method_call = MethodCall::autoderef(id, autoderef as u32);
|
||||||
|
for &method in maps.method_map.borrow().find(&method_call).iter() {
|
||||||
|
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
|
||||||
|
ebml_w.id(id);
|
||||||
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
|
encode_method_callee(ecx, ebml_w, method_call.autoderef, method)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for &dr in maps.vtable_map.borrow().find(&method_call).iter() {
|
||||||
|
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
|
||||||
|
ebml_w.id(id);
|
||||||
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
|
encode_vtable_res_with_key(ecx, ebml_w,
|
||||||
|
method_call.autoderef, *dr);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
ebml_w.tag(c::tag_table_adjustments, |ebml_w| {
|
ebml_w.tag(c::tag_table_adjustments, |ebml_w| {
|
||||||
ebml_w.id(id);
|
ebml_w.id(id);
|
||||||
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
ebml_w.tag(c::tag_table_val, |ebml_w| {
|
||||||
|
@ -1336,15 +1402,21 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
|
||||||
dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds);
|
dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds);
|
||||||
}
|
}
|
||||||
c::tag_table_method_map => {
|
c::tag_table_method_map => {
|
||||||
let method = val_dsr.read_method_callee(xcx);
|
let (autoderef, method) = val_dsr.read_method_callee(xcx);
|
||||||
let method_call = MethodCall::expr(id);
|
let method_call = MethodCall {
|
||||||
|
expr_id: id,
|
||||||
|
autoderef: autoderef
|
||||||
|
};
|
||||||
dcx.maps.method_map.borrow_mut().insert(method_call, method);
|
dcx.maps.method_map.borrow_mut().insert(method_call, method);
|
||||||
}
|
}
|
||||||
c::tag_table_vtable_map => {
|
c::tag_table_vtable_map => {
|
||||||
let vtable_res =
|
let (autoderef, vtable_res) =
|
||||||
val_dsr.read_vtable_res(xcx.dcx.tcx,
|
val_dsr.read_vtable_res_with_key(xcx.dcx.tcx,
|
||||||
xcx.dcx.cdata);
|
xcx.dcx.cdata);
|
||||||
let vtable_key = MethodCall::expr(id);
|
let vtable_key = MethodCall {
|
||||||
|
expr_id: id,
|
||||||
|
autoderef: autoderef
|
||||||
|
};
|
||||||
dcx.maps.vtable_map.borrow_mut().insert(vtable_key, vtable_res);
|
dcx.maps.vtable_map.borrow_mut().insert(vtable_key, vtable_res);
|
||||||
}
|
}
|
||||||
c::tag_table_adjustments => {
|
c::tag_table_adjustments => {
|
||||||
|
|
37
src/test/auxiliary/overloaded_autoderef_xc.rs
Normal file
37
src/test/auxiliary/overloaded_autoderef_xc.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
struct DerefWithHelper<H, T> {
|
||||||
|
helper: H
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Helper<T> {
|
||||||
|
fn helper_borrow<'a>(&'a self) -> &'a T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Helper<T> for Option<T> {
|
||||||
|
fn helper_borrow<'a>(&'a self) -> &'a T {
|
||||||
|
self.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, H: Helper<T>> Deref<T> for DerefWithHelper<H, T> {
|
||||||
|
fn deref<'a>(&'a self) -> &'a T {
|
||||||
|
self.helper.helper_borrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test cross-crate autoderef + vtable.
|
||||||
|
pub fn check<T: Eq>(x: T, y: T) -> bool {
|
||||||
|
let d: DerefWithHelper<Option<T>, T> = DerefWithHelper { helper: Some(x) };
|
||||||
|
d.eq(&y)
|
||||||
|
}
|
18
src/test/run-pass/overloaded-autoderef-xcrate.rs
Normal file
18
src/test/run-pass/overloaded-autoderef-xcrate.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// ignore-fast
|
||||||
|
// aux-build:overloaded_autoderef_xc.rs
|
||||||
|
|
||||||
|
extern crate overloaded_autoderef_xc;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert!(overloaded_autoderef_xc::check(5, 5));
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue