Skip to content

Commit c6ea222

Browse files
committed
---
yaml --- r: 22605 b: refs/heads/master c: 3ac5b4a h: refs/heads/master i: 22603: 6e46ced v: v3
1 parent 4be04c1 commit c6ea222

File tree

15 files changed

+127
-64
lines changed

15 files changed

+127
-64
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 1528256fdc26199dd58b390e42e2d0dc53b9703d
2+
refs/heads/master: 3ac5b4a86fa37d2b2c17ef5ffdb6e521630ea4ac
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
55
refs/heads/try: ffbe0e0e00374358b789b0037bcb3a577cd218be

trunk/src/libsyntax/ast.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,8 +635,10 @@ enum item_ {
635635
option<class_dtor>
636636
),
637637
item_trait(~[ty_param], ~[trait_method]),
638-
item_impl(~[ty_param], option<@trait_ref> /* trait */,
639-
@ty /* self */, ~[@method]),
638+
item_impl(~[ty_param],
639+
~[@trait_ref], /* traits this impl implements */
640+
@ty, /* self */
641+
~[@method]),
640642
item_mac(mac),
641643
}
642644

trunk/src/libsyntax/ext/pipes/pipec.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import ast_builder::append_types;
2121
import ast_builder::ast_builder;
2222
import ast_builder::methods;
2323
import ast_builder::path;
24+
import ast_builder::path_concat;
2425

2526
trait gen_send {
2627
fn gen_send(cx: ext_ctxt) -> @ast::item;

trunk/src/libsyntax/parse/parser.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,13 +2085,22 @@ class parser {
20852085
(some(id), self.parse_ty_params())
20862086
}
20872087
};
2088-
let ifce = if self.eat_keyword(~"of") {
2089-
let path = self.parse_path_with_tps(false);
2090-
if option::is_none(ident) {
2091-
ident = some(vec::last(path.idents));
2088+
let traits;
2089+
if self.eat_keyword(~"of") {
2090+
let for_atom = interner::intern(*self.reader.interner(), @~"for");
2091+
traits = self.parse_trait_ref_list(token::IDENT(for_atom, false));
2092+
if traits.len() >= 1 && option::is_none(ident) {
2093+
ident = some(vec::last(traits[0].path.idents));
20922094
}
2093-
some(@{path: path, ref_id: self.get_id(), impl_id: self.get_id()})
2094-
} else { none };
2095+
if traits.len() == 0 {
2096+
self.fatal(~"BUG: 'of' but no trait");
2097+
}
2098+
if traits.len() > 1 {
2099+
self.fatal(~"BUG: multiple traits");
2100+
}
2101+
} else {
2102+
traits = ~[];
2103+
};
20952104
let ident = alt ident {
20962105
some(name) { name }
20972106
none { self.expect_keyword(~"of"); fail; }
@@ -2103,7 +2112,7 @@ class parser {
21032112
while !self.eat(token::RBRACE) {
21042113
vec::push(meths, self.parse_method(public));
21052114
}
2106-
(ident, item_impl(tps, ifce, ty, meths), none)
2115+
(ident, item_impl(tps, traits, ty, meths), none)
21072116
}
21082117
21092118
// Instantiates ident <i> with references to <typarams> as arguments.
@@ -2127,9 +2136,9 @@ class parser {
21272136
ref_id: self.get_id(), impl_id: self.get_id()}
21282137
}
21292138
2130-
fn parse_trait_ref_list() -> ~[@trait_ref] {
2139+
fn parse_trait_ref_list(ket: token::token) -> ~[@trait_ref] {
21312140
self.parse_seq_to_before_end(
2132-
token::LBRACE, seq_sep_trailing_disallowed(token::COMMA),
2141+
ket, seq_sep_trailing_disallowed(token::COMMA),
21332142
|p| p.parse_trait_ref())
21342143
}
21352144
@@ -2139,7 +2148,7 @@ class parser {
21392148
let ty_params = self.parse_ty_params();
21402149
let class_path = self.ident_to_path_tys(class_name, ty_params);
21412150
let traits : ~[@trait_ref] = if self.eat(token::COLON)
2142-
{ self.parse_trait_ref_list() }
2151+
{ self.parse_trait_ref_list(token::LBRACE) }
21432152
else { ~[] };
21442153
self.expect(token::LBRACE);
21452154
let mut ms: ~[@class_member] = ~[];

trunk/src/libsyntax/print/pprust.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -558,16 +558,18 @@ fn print_item(s: ps, &&item: @ast::item) {
558558
}
559559
bclose(s, item.span);
560560
}
561-
ast::item_impl(tps, ifce, ty, methods) {
561+
ast::item_impl(tps, traits, ty, methods) {
562562
head(s, ~"impl");
563563
word(s.s, *item.ident);
564564
print_type_params(s, tps);
565565
space(s.s);
566-
option::iter(ifce, |p| {
566+
if vec::len(traits) != 0u {
567567
word_nbsp(s, ~"of");
568-
print_path(s, p.path, false);
568+
do commasep(s, inconsistent, traits) |s, p| {
569+
print_path(s, p.path, false);
570+
}
569571
space(s.s);
570-
});
572+
}
571573
word_nbsp(s, ~"for");
572574
print_type(s, ty);
573575
space(s.s);

trunk/src/libsyntax/visit.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,11 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
135135
for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); }
136136
}
137137
}
138-
item_impl(tps, ifce, ty, methods) {
138+
item_impl(tps, traits, ty, methods) {
139139
v.visit_ty_params(tps, e, v);
140-
option::iter(ifce, |p| visit_path(p.path, e, v));
140+
for traits.each |p| {
141+
visit_path(p.path, e, v);
142+
}
141143
v.visit_ty(ty, e, v);
142144
for methods.each |m| {
143145
visit_method_helper(m, e, v)

trunk/src/rustc/metadata/encoder.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,7 @@ fn encode_info_for_mod(ecx: @encode_ctxt, ebml_w: ebml::writer, md: _mod,
410410
ref, we need to map it to its parent class */
411411
ebml_w.wr_str(def_to_str(local_def(it.id)));
412412
}
413-
some(ast_map::node_item(@{node: item_impl(_,
414-
some(ifce),_,_),_},_)) {
415-
ebml_w.wr_str(def_to_str(did));
416-
}
417-
some(_) {
418-
ebml_w.wr_str(def_to_str(did));
419-
}
420-
none {
413+
_ {
421414
// Must be a re-export, then!
422415
// ...or an iface ref
423416
ebml_w.wr_str(def_to_str(did));
@@ -715,7 +708,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
715708
encode_index(ebml_w, bkts, write_int);
716709
ebml_w.end_tag();
717710
}
718-
item_impl(tps, ifce, _, methods) {
711+
item_impl(tps, traits, _, methods) {
719712
add_to_index();
720713
ebml_w.start_tag(tag_items_data_item);
721714
encode_def_id(ebml_w, local_def(item.id));
@@ -729,9 +722,12 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
729722
ebml_w.writer.write(str::bytes(def_to_str(local_def(m.id))));
730723
ebml_w.end_tag();
731724
}
732-
do option::iter(ifce) |t| {
733-
encode_trait_ref(ebml_w, ecx, t)
734-
};
725+
if traits.len() > 1 {
726+
fail ~"multiple traits!!";
727+
}
728+
for traits.each |associated_trait| {
729+
encode_trait_ref(ebml_w, ecx, associated_trait)
730+
}
735731
encode_path(ebml_w, path, ast_map::path_name(item.ident));
736732
ebml_w.end_tag();
737733

trunk/src/rustc/middle/resolve3.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2966,16 +2966,20 @@ class Resolver {
29662966
}
29672967
}
29682968

2969-
item_impl(type_parameters, interface_reference, self_type,
2969+
item_impl(type_parameters, implemented_traits, self_type,
29702970
methods) {
29712971

2972-
self.resolve_implementation(item.id,
2973-
item.span,
2974-
type_parameters,
2975-
interface_reference,
2976-
self_type,
2977-
methods,
2978-
visitor);
2972+
// XXX: Should take an array of traits.
2973+
let trait_reference;
2974+
if implemented_traits.len() == 0 {
2975+
trait_reference = none;
2976+
} else {
2977+
trait_reference = some(implemented_traits[0]);
2978+
}
2979+
2980+
self.resolve_implementation(item.id, item.span,
2981+
type_parameters, trait_reference,
2982+
self_type, methods, visitor);
29792983
}
29802984

29812985
item_trait(type_parameters, methods) {

trunk/src/rustc/middle/ty.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,13 +2474,16 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
24742474
result
24752475
}
24762476

2477+
// XXX: Needs to return an array of traits.
24772478
fn impl_trait(cx: ctxt, id: ast::def_id) -> option<t> {
24782479
if id.crate == ast::local_crate {
24792480
#debug("(impl_trait) searching for trait impl %?", id);
24802481
alt cx.items.find(id.node) {
2481-
some(ast_map::node_item(@{node: ast::item_impl(
2482-
_, some(@{ref_id: id, _}), _, _), _}, _)) {
2483-
some(node_id_to_type(cx, id))
2482+
some(ast_map::node_item(@{
2483+
node: ast::item_impl(_, traits, _, _),
2484+
_},
2485+
_)) if traits.len() >= 1 {
2486+
some(node_id_to_type(cx, traits[0].ref_id))
24842487
}
24852488
some(ast_map::node_item(@{node: ast::item_class(*),
24862489
_},_)) {

trunk/src/rustc/middle/typeck/check/method.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ class lookup {
454454
for (*trait_ids).each |trait_id| {
455455
#debug("(adding inherent and extension candidates) \
456456
trying trait: %s",
457-
node_id_to_str(self.tcx().items, trait_id.node));
457+
self.def_id_to_str(trait_id));
458458

459459
let coherence_info = self.fcx.ccx.coherence_info;
460460
alt coherence_info.extension_methods.find(trait_id) {
@@ -463,6 +463,10 @@ class lookup {
463463
}
464464
some(extension_methods) {
465465
for extension_methods.each |implementation| {
466+
#debug("(adding inherent and extension \
467+
candidates) adding impl %s",
468+
self.def_id_to_str
469+
(implementation.did));
466470
self.add_candidates_from_impl
467471
(implementation, use_assignability);
468472
}
@@ -473,6 +477,14 @@ class lookup {
473477
}
474478
}
475479

480+
fn def_id_to_str(def_id: ast::def_id) -> ~str {
481+
if def_id.crate == ast::local_crate {
482+
node_id_to_str(self.tcx().items, def_id.node)
483+
} else {
484+
ast_map::path_to_str(csearch::get_item_path(self.tcx(), def_id))
485+
}
486+
}
487+
476488
fn write_mty_from_candidate(cand: candidate) -> method_map_entry {
477489
let tcx = self.fcx.ccx.tcx;
478490

trunk/src/rustc/middle/typeck/coherence.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,21 @@ class CoherenceChecker {
154154

155155
visit_crate(*crate, (), mk_simple_visitor(@{
156156
visit_item: |item| {
157+
#debug("(checking coherence) item '%s'", *item.ident);
158+
157159
alt item.node {
158-
item_impl(_, associated_trait, self_type, _) {
159-
self.check_implementation(item, associated_trait);
160+
item_impl(_, associated_traits, self_type, _) {
161+
// XXX: Accept an array of traits.
162+
let optional_associated_trait;
163+
if associated_traits.len() == 0 {
164+
optional_associated_trait = none;
165+
} else {
166+
optional_associated_trait =
167+
some(associated_traits[0]);
168+
}
169+
170+
self.check_implementation(item,
171+
optional_associated_trait);
160172
}
161173
_ {
162174
// Nothing to do.
@@ -189,6 +201,10 @@ class CoherenceChecker {
189201
let self_type = self.crate_context.tcx.tcache.get(local_def(item.id));
190202
alt optional_associated_trait {
191203
none {
204+
#debug("(checking implementation) no associated trait for \
205+
item '%s'",
206+
*item.ident);
207+
192208
alt get_base_type_def_id(self.inference_context,
193209
item.span,
194210
self_type.ty) {
@@ -207,6 +223,12 @@ class CoherenceChecker {
207223
some(associated_trait) {
208224
let def = self.crate_context.tcx.def_map.get
209225
(associated_trait.ref_id);
226+
#debug("(checking implementation) adding impl for trait \
227+
'%s', item '%s'",
228+
ast_map::node_id_to_str(self.crate_context.tcx.items,
229+
associated_trait.ref_id),
230+
*item.ident);
231+
210232
let implementation = self.create_impl_from_item(item);
211233
self.add_trait_method(def_id_of_def(def), implementation);
212234
}
@@ -362,7 +384,15 @@ class CoherenceChecker {
362384
self.privileged_types.remove(privileged_type);
363385
}
364386
}
365-
item_impl(_, optional_trait_ref, _, _) {
387+
item_impl(_, associated_traits, _, _) {
388+
// XXX: Accept an array of traits.
389+
let optional_trait_ref;
390+
if associated_traits.len() == 0 {
391+
optional_trait_ref = none;
392+
} else {
393+
optional_trait_ref = some(associated_traits[0]);
394+
}
395+
366396
alt self.base_type_def_ids.find(local_def(item.id)) {
367397
none {
368398
// Nothing to do.

trunk/src/rustdoc/doc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type methoddoc = {
110110

111111
type impldoc = {
112112
item: itemdoc,
113-
trait_ty: option<~str>,
113+
trait_types: ~[~str],
114114
self_ty: option<~str>,
115115
methods: ~[methoddoc]
116116
};

trunk/src/rustdoc/extract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ fn impldoc_from_impl(
235235
) -> doc::impldoc {
236236
{
237237
item: itemdoc,
238-
trait_ty: none,
238+
trait_types: ~[],
239239
self_ty: none,
240240
methods: do vec::map(methods) |method| {
241241
{

trunk/src/rustdoc/markdown_pass.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,16 @@ fn header_name(doc: doc::itemtag) -> ~str {
224224
doc::impltag(doc) {
225225
assert option::is_some(doc.self_ty);
226226
let self_ty = option::get(doc.self_ty);
227-
alt doc.trait_ty {
228-
some(trait_ty) {
229-
#fmt("%s of %s for %s", doc.name(), trait_ty, self_ty)
230-
}
231-
none {
232-
#fmt("%s for %s", doc.name(), self_ty)
233-
}
227+
let mut trait_part = ~"";
228+
for doc.trait_types.eachi |i, trait_type| {
229+
if i == 0 {
230+
trait_part += ~" of ";
231+
} else {
232+
trait_part += ", ";
233+
}
234+
trait_part += trait_type;
234235
}
236+
#fmt("%s%s for %s", doc.name(), trait_part, self_ty)
235237
}
236238
_ {
237239
doc.name()

0 commit comments

Comments
 (0)