Skip to content

Commit 906264b

Browse files
committed
auto merge of #8015 : msullivan/rust/default-methods, r=nikomatsakis
Lots of changes to vtable resolution, handling of super/self method calls in default methods. Fix a lot of trait inheritance bugs. r? @nikomatsakis
2 parents b30a16c + f37c7cd commit 906264b

29 files changed

+776
-630
lines changed

src/libextra/num/bigint.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,11 @@ impl Ord for Sign {
732732
}
733733
}
734734

735+
impl TotalEq for Sign {
736+
fn equals(&self, other: &Sign) -> bool {
737+
*self == *other
738+
}
739+
}
735740
impl TotalOrd for Sign {
736741

737742
fn cmp(&self, other: &Sign) -> Ordering {

src/libextra/num/rational.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,25 @@ cmp_impl!(impl TotalEq, equals)
110110
cmp_impl!(impl Ord, lt, gt, le, ge)
111111
cmp_impl!(impl TotalOrd, cmp -> cmp::Ordering)
112112

113+
impl<T: Clone + Integer + Ord> Orderable for Ratio<T> {
114+
#[inline]
115+
fn min(&self, other: &Ratio<T>) -> Ratio<T> {
116+
if *self < *other { self.clone() } else { other.clone() }
117+
}
118+
119+
#[inline]
120+
fn max(&self, other: &Ratio<T>) -> Ratio<T> {
121+
if *self > *other { self.clone() } else { other.clone() }
122+
}
123+
124+
#[inline]
125+
fn clamp(&self, mn: &Ratio<T>, mx: &Ratio<T>) -> Ratio<T> {
126+
if *self > *mx { mx.clone()} else
127+
if *self < *mn { mn.clone() } else { self.clone() }
128+
}
129+
}
130+
131+
113132
/* Arithmetic */
114133
// a/b * c/d = (a*c)/(b*d)
115134
impl<T: Clone + Integer + Ord>

src/librustc/metadata/common.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ pub static tag_misc_info: uint = 0x7f;
180180
pub static tag_misc_info_crate_items: uint = 0x80;
181181

182182
pub static tag_item_method_provided_source: uint = 0x81;
183+
pub static tag_item_impl_vtables: uint = 0x82;
183184

184185
pub struct LinkMeta {
185186
name: @str,

src/librustc/metadata/csearch.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use metadata::cstore;
1616
use metadata::decoder;
1717
use metadata;
1818
use middle::ty;
19+
use middle::typeck;
1920

2021
use std::vec;
2122
use reader = extra::ebml::reader;
@@ -216,6 +217,14 @@ pub fn get_impl_trait(tcx: ty::ctxt,
216217
decoder::get_impl_trait(cdata, def.node, tcx)
217218
}
218219

220+
// Given a def_id for an impl, return information about its vtables
221+
pub fn get_impl_vtables(tcx: ty::ctxt,
222+
def: ast::def_id) -> typeck::impl_res {
223+
let cstore = tcx.cstore;
224+
let cdata = cstore::get_crate_data(cstore, def.crate);
225+
decoder::get_impl_vtables(cdata, def.node, tcx)
226+
}
227+
219228
pub fn get_impl_method(cstore: @mut cstore::CStore,
220229
def: ast::def_id,
221230
mname: ast::ident)

src/librustc/metadata/decoder.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ use metadata::tydecode::{parse_ty_data, parse_def_id,
2121
parse_type_param_def_data,
2222
parse_bare_fn_ty_data, parse_trait_ref_data};
2323
use middle::ty;
24+
use middle::typeck;
25+
use middle::astencode::vtable_decoder_helpers;
26+
2427

2528
use std::hash::HashUtil;
2629
use std::uint;
@@ -410,6 +413,21 @@ pub fn get_impl_trait(cdata: cmd,
410413
}
411414
}
412415

416+
pub fn get_impl_vtables(cdata: cmd,
417+
id: ast::node_id,
418+
tcx: ty::ctxt) -> typeck::impl_res
419+
{
420+
let item_doc = lookup_item(id, cdata.data);
421+
let vtables_doc = reader::get_doc(item_doc, tag_item_impl_vtables);
422+
let mut decoder = reader::Decoder(vtables_doc);
423+
424+
typeck::impl_res {
425+
trait_vtables: decoder.read_vtable_res(tcx, cdata),
426+
self_vtables: decoder.read_vtable_param_res(tcx, cdata)
427+
}
428+
}
429+
430+
413431
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
414432
name: ast::ident) -> Option<ast::def_id> {
415433
let items = reader::get_doc(reader::Doc(cdata.data), tag_items);

src/librustc/metadata/encoder.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use metadata::decoder;
1717
use metadata::tyencode;
1818
use middle::ty::{node_id_to_type, lookup_item_type};
1919
use middle::ty;
20+
use middle::typeck;
21+
use middle::astencode;
2022
use middle;
2123

2224
use std::hash::HashUtil;
@@ -161,6 +163,15 @@ fn encode_trait_ref(ebml_w: &mut writer::Encoder,
161163
ebml_w.end_tag();
162164
}
163165

166+
fn encode_impl_vtables(ebml_w: &mut writer::Encoder,
167+
ecx: &EncodeContext,
168+
vtables: &typeck::impl_res) {
169+
ebml_w.start_tag(tag_item_impl_vtables);
170+
astencode::encode_vtable_res(ecx, ebml_w, vtables.trait_vtables);
171+
astencode::encode_vtable_param_res(ecx, ebml_w, vtables.self_vtables);
172+
ebml_w.end_tag();
173+
}
174+
164175
// Item info table encoding
165176
fn encode_family(ebml_w: &mut writer::Encoder, c: char) {
166177
ebml_w.start_tag(tag_items_data_item_family);
@@ -1008,6 +1019,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
10081019
let trait_ref = ty::node_id_to_trait_ref(
10091020
tcx, ast_trait_ref.ref_id);
10101021
encode_trait_ref(ebml_w, ecx, trait_ref, tag_item_trait_ref);
1022+
let impl_vtables = ty::lookup_impl_vtables(tcx, def_id);
1023+
encode_impl_vtables(ebml_w, ecx, &impl_vtables);
10111024
}
10121025
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
10131026
ebml_w.end_tag();

src/librustc/middle/astencode.rs

Lines changed: 74 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,21 @@ impl<S:serialize::Encoder> def_id_encoder_helpers for S {
250250

251251
trait def_id_decoder_helpers {
252252
fn read_def_id(&mut self, xcx: @ExtendedDecodeContext) -> ast::def_id;
253+
fn read_def_id_noxcx(&mut self,
254+
cdata: @cstore::crate_metadata) -> ast::def_id;
253255
}
254256

255257
impl<D:serialize::Decoder> def_id_decoder_helpers for D {
256258
fn read_def_id(&mut self, xcx: @ExtendedDecodeContext) -> ast::def_id {
257259
let did: ast::def_id = Decodable::decode(self);
258260
did.tr(xcx)
259261
}
262+
263+
fn read_def_id_noxcx(&mut self,
264+
cdata: @cstore::crate_metadata) -> ast::def_id {
265+
let did: ast::def_id = Decodable::decode(self);
266+
decoder::translate_def_id(cdata, did)
267+
}
260268
}
261269

262270
// ______________________________________________________________________
@@ -582,34 +590,35 @@ impl tr for method_origin {
582590
typeck::method_trait(did, m, vstore) => {
583591
typeck::method_trait(did.tr(xcx), m, vstore)
584592
}
585-
typeck::method_self(did, m) => {
586-
typeck::method_self(did.tr(xcx), m)
587-
}
588-
typeck::method_super(trait_did, m) => {
589-
typeck::method_super(trait_did.tr(xcx), m)
590-
}
591593
}
592594
}
593595
}
594596

595597
// ______________________________________________________________________
596598
// Encoding and decoding vtable_res
597599

598-
fn encode_vtable_res(ecx: &e::EncodeContext,
600+
pub fn encode_vtable_res(ecx: &e::EncodeContext,
599601
ebml_w: &mut writer::Encoder,
600602
dr: typeck::vtable_res) {
601603
// can't autogenerate this code because automatic code of
602604
// ty::t doesn't work, and there is no way (atm) to have
603605
// hand-written encoding routines combine with auto-generated
604606
// ones. perhaps we should fix this.
605607
do ebml_w.emit_from_vec(*dr) |ebml_w, param_tables| {
606-
do ebml_w.emit_from_vec(**param_tables) |ebml_w, vtable_origin| {
607-
encode_vtable_origin(ecx, ebml_w, vtable_origin)
608-
}
608+
encode_vtable_param_res(ecx, ebml_w, *param_tables);
609609
}
610610
}
611611

612-
fn encode_vtable_origin(ecx: &e::EncodeContext,
612+
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
613+
ebml_w: &mut writer::Encoder,
614+
param_tables: typeck::vtable_param_res) {
615+
do ebml_w.emit_from_vec(*param_tables) |ebml_w, vtable_origin| {
616+
encode_vtable_origin(ecx, ebml_w, vtable_origin)
617+
}
618+
}
619+
620+
621+
pub fn encode_vtable_origin(ecx: &e::EncodeContext,
613622
ebml_w: &mut writer::Encoder,
614623
vtable_origin: &typeck::vtable_origin) {
615624
do ebml_w.emit_enum("vtable_origin") |ebml_w| {
@@ -630,40 +639,46 @@ fn encode_vtable_origin(ecx: &e::EncodeContext,
630639
typeck::vtable_param(pn, bn) => {
631640
do ebml_w.emit_enum_variant("vtable_param", 1u, 2u) |ebml_w| {
632641
do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
633-
ebml_w.emit_uint(pn);
642+
pn.encode(ebml_w);
634643
}
635644
do ebml_w.emit_enum_variant_arg(1u) |ebml_w| {
636645
ebml_w.emit_uint(bn);
637646
}
638647
}
639648
}
640-
typeck::vtable_self(def_id) => {
641-
do ebml_w.emit_enum_variant("vtable_self", 2u, 1u) |ebml_w| {
642-
do ebml_w.emit_enum_variant_arg(0u) |ebml_w| {
643-
ebml_w.emit_def_id(def_id)
644-
}
645-
}
646-
}
647649
}
648650
}
649651
}
650652

651-
trait vtable_decoder_helpers {
652-
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
653+
pub trait vtable_decoder_helpers {
654+
fn read_vtable_res(&mut self,
655+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
653656
-> typeck::vtable_res;
654-
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
657+
fn read_vtable_param_res(&mut self,
658+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
659+
-> typeck::vtable_param_res;
660+
fn read_vtable_origin(&mut self,
661+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
655662
-> typeck::vtable_origin;
656663
}
657664

658665
impl vtable_decoder_helpers for reader::Decoder {
659-
fn read_vtable_res(&mut self, xcx: @ExtendedDecodeContext)
666+
fn read_vtable_res(&mut self,
667+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
660668
-> typeck::vtable_res {
661669
@self.read_to_vec(|this|
662-
@this.read_to_vec(|this|
663-
this.read_vtable_origin(xcx)))
670+
this.read_vtable_param_res(tcx, cdata))
664671
}
665672

666-
fn read_vtable_origin(&mut self, xcx: @ExtendedDecodeContext)
673+
fn read_vtable_param_res(&mut self,
674+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
675+
-> typeck::vtable_param_res {
676+
@self.read_to_vec(|this|
677+
this.read_vtable_origin(tcx, cdata))
678+
}
679+
680+
fn read_vtable_origin(&mut self,
681+
tcx: ty::ctxt, cdata: @cstore::crate_metadata)
667682
-> typeck::vtable_origin {
668683
do self.read_enum("vtable_origin") |this| {
669684
do this.read_enum_variant(["vtable_static",
@@ -674,33 +689,26 @@ impl vtable_decoder_helpers for reader::Decoder {
674689
0 => {
675690
typeck::vtable_static(
676691
do this.read_enum_variant_arg(0u) |this| {
677-
this.read_def_id(xcx)
692+
this.read_def_id_noxcx(cdata)
678693
},
679694
do this.read_enum_variant_arg(1u) |this| {
680-
this.read_tys(xcx)
695+
this.read_tys_noxcx(tcx, cdata)
681696
},
682697
do this.read_enum_variant_arg(2u) |this| {
683-
this.read_vtable_res(xcx)
698+
this.read_vtable_res(tcx, cdata)
684699
}
685700
)
686701
}
687702
1 => {
688703
typeck::vtable_param(
689704
do this.read_enum_variant_arg(0u) |this| {
690-
this.read_uint()
705+
Decodable::decode(this)
691706
},
692707
do this.read_enum_variant_arg(1u) |this| {
693708
this.read_uint()
694709
}
695710
)
696711
}
697-
2 => {
698-
typeck::vtable_self(
699-
do this.read_enum_variant_arg(0u) |this| {
700-
this.read_def_id(xcx)
701-
}
702-
)
703-
}
704712
// hard to avoid - user input
705713
_ => fail!("bad enum variant")
706714
}
@@ -995,9 +1003,35 @@ trait ebml_decoder_decoder_helpers {
9951003
source: DefIdSource,
9961004
did: ast::def_id)
9971005
-> ast::def_id;
1006+
1007+
// Versions of the type reading functions that don't need the full
1008+
// ExtendedDecodeContext.
1009+
fn read_ty_noxcx(&mut self,
1010+
tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t;
1011+
fn read_tys_noxcx(&mut self,
1012+
tcx: ty::ctxt,
1013+
cdata: @cstore::crate_metadata) -> ~[ty::t];
9981014
}
9991015

10001016
impl ebml_decoder_decoder_helpers for reader::Decoder {
1017+
fn read_ty_noxcx(&mut self,
1018+
tcx: ty::ctxt, cdata: @cstore::crate_metadata) -> ty::t {
1019+
do self.read_opaque |_, doc| {
1020+
tydecode::parse_ty_data(
1021+
*doc.data,
1022+
cdata.cnum,
1023+
doc.start,
1024+
tcx,
1025+
|_, id| decoder::translate_def_id(cdata, id))
1026+
}
1027+
}
1028+
1029+
fn read_tys_noxcx(&mut self,
1030+
tcx: ty::ctxt,
1031+
cdata: @cstore::crate_metadata) -> ~[ty::t] {
1032+
self.read_to_vec(|this| this.read_ty_noxcx(tcx, cdata) )
1033+
}
1034+
10011035
fn read_ty(&mut self, xcx: @ExtendedDecodeContext) -> ty::t {
10021036
// Note: regions types embed local node ids. In principle, we
10031037
// should translate these node ids into the new decode
@@ -1160,8 +1194,9 @@ fn decode_side_tables(xcx: @ExtendedDecodeContext,
11601194
val_dsr.read_method_map_entry(xcx));
11611195
}
11621196
c::tag_table_vtable_map => {
1163-
dcx.maps.vtable_map.insert(id,
1164-
val_dsr.read_vtable_res(xcx));
1197+
dcx.maps.vtable_map.insert(
1198+
id,
1199+
val_dsr.read_vtable_res(xcx.dcx.tcx, xcx.dcx.cdata));
11651200
}
11661201
c::tag_table_adjustments => {
11671202
let adj: @ty::AutoAdjustment = @Decodable::decode(val_dsr);

src/librustc/middle/privacy.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
use metadata::csearch;
1616
use middle::ty::{ty_struct, ty_enum};
1717
use middle::ty;
18-
use middle::typeck::{method_map, method_origin, method_param, method_self};
19-
use middle::typeck::{method_super};
18+
use middle::typeck::{method_map, method_origin, method_param};
2019
use middle::typeck::{method_static, method_trait};
2120

2221
use std::util::ignore;
@@ -291,9 +290,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
291290
method_num: method_num,
292291
_
293292
}) |
294-
method_trait(trait_id, method_num, _) |
295-
method_self(trait_id, method_num) |
296-
method_super(trait_id, method_num) => {
293+
method_trait(trait_id, method_num, _) => {
297294
if trait_id.crate == local_crate {
298295
match tcx.items.find(&trait_id.node) {
299296
Some(&node_item(item, _)) => {

0 commit comments

Comments
 (0)