Skip to content

Commit f764128

Browse files
committed
Allow classes to be cast to ifaces that are in the same crate
I had to xfail one existing test case (class-implements-int) because, I think, of the same bug described in #2272.
1 parent 1c39fda commit f764128

23 files changed

+562
-162
lines changed

src/libcore/vec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ fn map<T, U>(v: [T], f: fn(T) -> U) -> [U] {
448448
}
449449

450450
#[doc = "
451-
Apply a function eo each element of a vector and return a concatenation
451+
Apply a function to each element of a vector and return a concatenation
452452
of each result vector
453453
"]
454454
fn flat_map<T, U>(v: [T], f: fn(T) -> [U]) -> [U] {

src/librustsyntax/ast.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,10 @@ enum attr_style { attr_outer, attr_inner, }
636636
#[auto_serialize]
637637
type attribute_ = {style: attr_style, value: meta_item};
638638

639+
/*
640+
iface_refs appear in both impls and in classes that implement ifaces.
641+
resolve maps each iface_ref's id to its defining iface.
642+
*/
639643
#[auto_serialize]
640644
type iface_ref = {path: @path, id: node_id};
641645

@@ -661,14 +665,14 @@ enum item_ {
661665
node_id /* dtor id */, node_id /* ctor id */,
662666
region_param),
663667
item_class([ty_param], /* ty params for class */
664-
[iface_ref], /* ifaces this class implements */
668+
[@iface_ref], /* ifaces this class implements */
665669
[@class_member], /* methods, etc. */
666670
/* (not including ctor) */
667671
class_ctor,
668672
region_param
669673
),
670674
item_iface([ty_param], [ty_method]),
671-
item_impl([ty_param], option<@ty> /* iface */,
675+
item_impl([ty_param], option<@iface_ref> /* iface */,
672676
@ty /* self */, [@method]),
673677
}
674678

src/librustsyntax/ast_util.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@ import codemap::span;
22
import ast::*;
33

44
fn spanned<T: copy>(lo: uint, hi: uint, t: T) -> spanned<T> {
5-
ret respan(mk_sp(lo, hi), t);
5+
respan(mk_sp(lo, hi), t)
66
}
77

88
fn respan<T: copy>(sp: span, t: T) -> spanned<T> {
9-
ret {node: t, span: sp};
9+
{node: t, span: sp}
1010
}
1111

1212
fn dummy_spanned<T: copy>(t: T) -> spanned<T> {
13-
ret respan(dummy_sp(), t);
13+
respan(dummy_sp(), t)
1414
}
1515

1616
/* assuming that we're not in macro expansion */
1717
fn mk_sp(lo: uint, hi: uint) -> span {
18-
ret {lo: lo, hi: hi, expn_info: none};
18+
{lo: lo, hi: hi, expn_info: none}
1919
}
2020

2121
// make this a const, once the compiler supports it
@@ -334,6 +334,16 @@ impl inlined_item_methods for inlined_item {
334334
}
335335
}
336336
}
337+
338+
/* True if d is either a def_self, or a chain of def_upvars
339+
referring to a def_self */
340+
fn is_self(d: ast::def) -> bool {
341+
alt d {
342+
def_self(_) { true }
343+
def_upvar(_, d, _) { is_self(*d) }
344+
_ { false }
345+
}
346+
}
337347
// Local Variables:
338348
// mode: rust
339349
// fill-column: 78;

src/librustsyntax/fold.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,7 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
279279
let ctor_id = fld.new_id(ctor.node.id);
280280
item_class(
281281
typms,
282-
vec::map(ifaces, {|p|
283-
{path: fld.fold_path(p.path),
284-
id: fld.new_id(p.id)}}),
282+
vec::map(ifaces, {|p| fold_iface_ref(p, fld) }),
285283
vec::map(items, fld.fold_class_item),
286284
{node: {body: ctor_body,
287285
dec: ctor_decl,
@@ -290,7 +288,8 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
290288
rp)
291289
}
292290
item_impl(tps, ifce, ty, methods) {
293-
item_impl(tps, option::map(ifce, fld.fold_ty), fld.fold_ty(ty),
291+
item_impl(tps, option::map(ifce, {|p| fold_iface_ref(p, fld)}),
292+
fld.fold_ty(ty),
294293
vec::map(methods, fld.fold_method))
295294
}
296295
item_iface(tps, methods) { item_iface(tps, methods) }
@@ -305,6 +304,10 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
305304
};
306305
}
307306

307+
fn fold_iface_ref(&&p: @iface_ref, fld: ast_fold) -> @iface_ref {
308+
@{path: fld.fold_path(p.path), id: fld.new_id(p.id)}
309+
}
310+
308311
fn noop_fold_method(&&m: @method, fld: ast_fold) -> @method {
309312
ret @{ident: fld.fold_ident(m.ident),
310313
attrs: m.attrs,

src/librustsyntax/parse/parser.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import token::{can_begin_expr, is_ident, is_plain_ident};
55
import codemap::{span,fss_none};
66
import util::interner;
77
import ast_util::{spanned, mk_sp, ident_to_path};
8+
import ast::{node_id};
89
import lexer::reader;
910
import prec::{op_spec, as_prec};
1011
import attr::{parse_outer_attrs_or_ext,
@@ -1788,9 +1789,6 @@ fn parse_item_iface(p: parser, attrs: [ast::attribute]) -> @ast::item {
17881789
// impl name<T> for [T] { ... }
17891790
fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
17901791
let lo = p.last_span.lo;
1791-
fn wrap_path(p: parser, pt: @ast::path) -> @ast::ty {
1792-
@{id: p.get_id(), node: ast::ty_path(pt, p.get_id()), span: pt.span}
1793-
}
17941792
let mut (ident, tps) = if !is_word(p, "of") {
17951793
if p.token == token::LT { (none, parse_ty_params(p)) }
17961794
else { (some(parse_ident(p)), parse_ty_params(p)) }
@@ -1800,7 +1798,7 @@ fn parse_item_impl(p: parser, attrs: [ast::attribute]) -> @ast::item {
18001798
if option::is_none(ident) {
18011799
ident = some(vec::last(path.idents));
18021800
}
1803-
some(wrap_path(p, path))
1801+
some(@{path: path, id: p.get_id()})
18041802
} else { none };
18051803
let ident = alt ident {
18061804
some(name) { name }
@@ -1855,9 +1853,13 @@ fn ident_to_path_tys(p: parser, i: ast::ident,
18551853
}
18561854
}
18571855

1858-
fn parse_iface_ref_list(p:parser) -> [ast::iface_ref] {
1856+
fn parse_iface_ref(p:parser) -> @ast::iface_ref {
1857+
@{path: parse_path(p), id: p.get_id()}
1858+
}
1859+
1860+
fn parse_iface_ref_list(p:parser) -> [@ast::iface_ref] {
18591861
parse_seq_to_before_end(token::LBRACE, seq_sep(token::COMMA),
1860-
{|p| {path: parse_path(p), id: p.get_id()}}, p)
1862+
parse_iface_ref, p)
18611863
}
18621864

18631865
fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
@@ -1866,7 +1868,7 @@ fn parse_item_class(p: parser, attrs: [ast::attribute]) -> @ast::item {
18661868
let rp = parse_region_param(p);
18671869
let ty_params = parse_ty_params(p);
18681870
let class_path = ident_to_path_tys(p, class_name, ty_params);
1869-
let ifaces : [ast::iface_ref] = if eat_word(p, "implements")
1871+
let ifaces : [@ast::iface_ref] = if eat_word(p, "implements")
18701872
{ parse_iface_ref_list(p) }
18711873
else { [] };
18721874
expect(p, token::LBRACE);
@@ -1918,7 +1920,7 @@ fn parse_single_class_item(p: parser, privcy: ast::privacy)
19181920
enum class_contents { ctor_decl(ast::fn_decl, ast::blk, codemap::span),
19191921
members([@ast::class_member]) }
19201922

1921-
fn parse_class_item(p:parser, class_name_with_tps:@ast::path)
1923+
fn parse_class_item(p:parser, class_name_with_tps: @ast::path)
19221924
-> class_contents {
19231925
if eat_word(p, "new") {
19241926
let lo = p.last_span.lo;

src/librustsyntax/print/pprust.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -561,14 +561,11 @@ fn print_item(s: ps, &&item: @ast::item) {
561561
word(s.s, item.ident);
562562
print_type_params(s, tps);
563563
space(s.s);
564-
alt ifce {
565-
some(ty) {
564+
option::iter(ifce, {|p|
566565
word_nbsp(s, "of");
567-
print_type(s, ty);
566+
print_path(s, p.path, false);
568567
space(s.s);
569-
}
570-
_ {}
571-
}
568+
});
572569
word_nbsp(s, "for");
573570
print_type(s, ty);
574571
space(s.s);

src/librustsyntax/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
134134
}
135135
item_impl(tps, ifce, ty, methods) {
136136
v.visit_ty_params(tps, e, v);
137-
alt ifce { some(ty) { v.visit_ty(ty, e, v); } none {} }
137+
option::iter(ifce, {|p| visit_path(p.path, e, v)});
138138
v.visit_ty(ty, e, v);
139139
for methods.each {|m|
140140
visit_method_helper(m, e, v)

src/rustc/metadata/csearch.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
160160
ret {bounds: @[], rp: ast::rp_none, ty: ty};
161161
}
162162

163-
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
164-
-> option<ty::t> {
163+
// Given a def_id for an impl or class, return the iface it implements,
164+
// or none if it's not for an impl or for a class that implements ifaces
165+
fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id) -> option<ty::t> {
165166
let cstore = tcx.sess.cstore;
166167
let cdata = cstore::get_crate_data(cstore, def.crate);
167168
decoder::get_impl_iface(cdata, def.node, tcx)

src/rustc/metadata/decoder.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export get_class_method;
2727
export get_impl_method;
2828
export lookup_def;
2929
export lookup_item_name;
30-
export get_impl_iface;
3130
export resolve_path;
3231
export get_crate_attributes;
3332
export list_crate_metadata;
@@ -157,11 +156,9 @@ fn item_impl_iface(item: ebml::doc, tcx: ty::ctxt, cdata: cmd)
157156
-> option<ty::t> {
158157
let mut result = none;
159158
ebml::tagged_docs(item, tag_impl_iface) {|ity|
160-
let t = parse_ty_data(ity.data, cdata.cnum, ity.start, tcx, {|did|
161-
translate_def_id(cdata, did)
162-
});
163-
result = some(t);
164-
}
159+
result = some(parse_ty_data(ity.data, cdata.cnum, ity.start, tcx,
160+
{|did| translate_def_id(cdata, did)}));
161+
};
165162
result
166163
}
167164

src/rustc/metadata/encoder.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -659,9 +659,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
659659
}
660660
alt ifce {
661661
some(t) {
662-
let i_ty = alt check t.node {
663-
ty_path(_, id) { ty::node_id_to_type(tcx, id) }
664-
};
662+
let i_ty = ty::node_id_to_type(tcx, t.id);
665663
ebml_w.start_tag(tag_impl_iface);
666664
write_type(ecx, ebml_w, i_ty);
667665
ebml_w.end_tag();

0 commit comments

Comments
 (0)