Remove support for multiple traits in a single impl
There was half-working support for them, but they were never fully implemented or even approved. Remove them altogether. Closes #3410
This commit is contained in:
parent
62ab9d70f4
commit
f5093dff7b
9 changed files with 44 additions and 35 deletions
|
@ -1267,7 +1267,7 @@ enum item_ {
|
||||||
item_class(@struct_def, ~[ty_param]),
|
item_class(@struct_def, ~[ty_param]),
|
||||||
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
|
item_trait(~[ty_param], ~[@trait_ref], ~[trait_method]),
|
||||||
item_impl(~[ty_param],
|
item_impl(~[ty_param],
|
||||||
~[@trait_ref], /* traits this impl implements */
|
Option<@trait_ref>, /* (optional) trait this impl implements */
|
||||||
@ty, /* self */
|
@ty, /* self */
|
||||||
~[@method]),
|
~[@method]),
|
||||||
item_mac(mac),
|
item_mac(mac),
|
||||||
|
|
|
@ -2571,11 +2571,11 @@ struct parser {
|
||||||
|
|
||||||
|
|
||||||
// Parse traits, if necessary.
|
// Parse traits, if necessary.
|
||||||
let traits = if self.token == token::COLON {
|
let opt_trait = if self.token == token::COLON {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.parse_trait_ref_list(token::LBRACE)
|
Some(self.parse_trait_ref())
|
||||||
} else {
|
} else {
|
||||||
~[]
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut meths = ~[];
|
let mut meths = ~[];
|
||||||
|
@ -2584,7 +2584,7 @@ struct parser {
|
||||||
let vis = self.parse_visibility();
|
let vis = self.parse_visibility();
|
||||||
vec::push(meths, self.parse_method(vis));
|
vec::push(meths, self.parse_method(vis));
|
||||||
}
|
}
|
||||||
(ident, item_impl(tps, traits, ty, meths), None)
|
(ident, item_impl(tps, opt_trait, ty, meths), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantiates ident <i> with references to <typarams> as arguments.
|
// Instantiates ident <i> with references to <typarams> as arguments.
|
||||||
|
|
|
@ -499,7 +499,7 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||||
print_struct(s, struct_def, tps, item.ident, item.span);
|
print_struct(s, struct_def, tps, item.ident, item.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::item_impl(tps, traits, ty, methods) => {
|
ast::item_impl(tps, opt_trait, ty, methods) => {
|
||||||
head(s, ~"impl");
|
head(s, ~"impl");
|
||||||
if tps.is_not_empty() {
|
if tps.is_not_empty() {
|
||||||
print_type_params(s, tps);
|
print_type_params(s, tps);
|
||||||
|
@ -507,12 +507,13 @@ fn print_item(s: ps, &&item: @ast::item) {
|
||||||
}
|
}
|
||||||
print_type(s, ty);
|
print_type(s, ty);
|
||||||
|
|
||||||
if vec::len(traits) != 0u {
|
match opt_trait {
|
||||||
word_space(s, ~":");
|
Some(t) => {
|
||||||
do commasep(s, inconsistent, traits) |s, p| {
|
word_space(s, ~":");
|
||||||
print_path(s, p.path, false);
|
print_path(s, t.path, false);
|
||||||
}
|
}
|
||||||
}
|
None => ()
|
||||||
|
};
|
||||||
space(s.s);
|
space(s.s);
|
||||||
|
|
||||||
bopen(s);
|
bopen(s);
|
||||||
|
|
|
@ -699,7 +699,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
|
||||||
else { None }, tps);
|
else { None }, tps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_impl(tps, traits, _, methods) => {
|
item_impl(tps, opt_trait, _, methods) => {
|
||||||
add_to_index();
|
add_to_index();
|
||||||
ebml_w.start_tag(tag_items_data_item);
|
ebml_w.start_tag(tag_items_data_item);
|
||||||
encode_def_id(ebml_w, local_def(item.id));
|
encode_def_id(ebml_w, local_def(item.id));
|
||||||
|
@ -714,10 +714,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::Writer, item: @item,
|
||||||
ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
|
ebml_w.writer.write(str::to_bytes(def_to_str(local_def(m.id))));
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
if traits.len() > 1 {
|
do opt_trait.iter() |associated_trait| {
|
||||||
fail ~"multiple traits!!";
|
|
||||||
}
|
|
||||||
for traits.each |associated_trait| {
|
|
||||||
encode_trait_ref(ebml_w, ecx, associated_trait)
|
encode_trait_ref(ebml_w, ecx, associated_trait)
|
||||||
}
|
}
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||||
|
|
|
@ -3532,7 +3532,7 @@ struct Resolver {
|
||||||
fn resolve_implementation(id: node_id,
|
fn resolve_implementation(id: node_id,
|
||||||
span: span,
|
span: span,
|
||||||
type_parameters: ~[ty_param],
|
type_parameters: ~[ty_param],
|
||||||
trait_references: ~[@trait_ref],
|
opt_trait_reference: Option<@trait_ref>,
|
||||||
self_type: @ty,
|
self_type: @ty,
|
||||||
methods: ~[@method],
|
methods: ~[@method],
|
||||||
visitor: ResolveVisitor) {
|
visitor: ResolveVisitor) {
|
||||||
|
@ -3549,10 +3549,10 @@ struct Resolver {
|
||||||
|
|
||||||
// Resolve the trait reference, if necessary.
|
// Resolve the trait reference, if necessary.
|
||||||
let original_trait_refs = self.current_trait_refs;
|
let original_trait_refs = self.current_trait_refs;
|
||||||
if trait_references.len() >= 1 {
|
match opt_trait_reference {
|
||||||
let mut new_trait_refs = @DVec();
|
Some(trait_reference) => {
|
||||||
for trait_references.each |trait_reference| {
|
let new_trait_refs = @DVec();
|
||||||
match self.resolve_path(
|
match self.resolve_path(
|
||||||
trait_reference.path, TypeNS, true, visitor) {
|
trait_reference.path, TypeNS, true, visitor) {
|
||||||
None => {
|
None => {
|
||||||
self.session.span_err(span,
|
self.session.span_err(span,
|
||||||
|
@ -3566,11 +3566,11 @@ struct Resolver {
|
||||||
(*new_trait_refs).push(def_id_of_def(def));
|
(*new_trait_refs).push(def_id_of_def(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Record the current set of trait references.
|
// Record the current set of trait references.
|
||||||
self.current_trait_refs = Some(new_trait_refs);
|
self.current_trait_refs = Some(new_trait_refs);
|
||||||
}
|
}
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
|
||||||
// Resolve the self type.
|
// Resolve the self type.
|
||||||
self.resolve_type(self_type, visitor);
|
self.resolve_type(self_type, visitor);
|
||||||
|
|
|
@ -3121,13 +3121,13 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
|
||||||
debug!("(impl_traits) searching for trait impl %?", id);
|
debug!("(impl_traits) searching for trait impl %?", id);
|
||||||
match cx.items.find(id.node) {
|
match cx.items.find(id.node) {
|
||||||
Some(ast_map::node_item(@{
|
Some(ast_map::node_item(@{
|
||||||
node: ast::item_impl(_, trait_refs, _, _),
|
node: ast::item_impl(_, opt_trait, _, _),
|
||||||
_},
|
_},
|
||||||
_)) => {
|
_)) => {
|
||||||
|
|
||||||
do vec::map(trait_refs) |trait_ref| {
|
do option::map_default(opt_trait, ~[]) |trait_ref| {
|
||||||
node_id_to_type(cx, trait_ref.ref_id)
|
~[node_id_to_type(cx, trait_ref.ref_id)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(ast_map::node_item(@{node: ast::item_class(sd,_),
|
Some(ast_map::node_item(@{node: ast::item_class(sd,_),
|
||||||
_},_)) => {
|
_},_)) => {
|
||||||
|
|
|
@ -231,8 +231,8 @@ struct CoherenceChecker {
|
||||||
self.crate_context.tcx.sess.str_of(item.ident));
|
self.crate_context.tcx.sess.str_of(item.ident));
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
item_impl(_, associated_traits, _, _) => {
|
item_impl(_, opt_trait, _, _) => {
|
||||||
self.check_implementation(item, associated_traits);
|
self.check_implementation(item, opt_trait.to_vec());
|
||||||
}
|
}
|
||||||
item_class(struct_def, _) => {
|
item_class(struct_def, _) => {
|
||||||
self.check_implementation(item, struct_def.traits);
|
self.check_implementation(item, struct_def.traits);
|
||||||
|
@ -432,7 +432,7 @@ struct CoherenceChecker {
|
||||||
// Then visit the module items.
|
// Then visit the module items.
|
||||||
visit_mod(module_, item.span, item.id, (), visitor);
|
visit_mod(module_, item.span, item.id, (), visitor);
|
||||||
}
|
}
|
||||||
item_impl(_, associated_traits, _, _) => {
|
item_impl(_, opt_trait, _, _) => {
|
||||||
match self.base_type_def_ids.find(
|
match self.base_type_def_ids.find(
|
||||||
local_def(item.id)) {
|
local_def(item.id)) {
|
||||||
|
|
||||||
|
@ -453,7 +453,8 @@ struct CoherenceChecker {
|
||||||
// if the traits are defined in the same
|
// if the traits are defined in the same
|
||||||
// crate.
|
// crate.
|
||||||
|
|
||||||
if associated_traits.len() == 0 {
|
match opt_trait {
|
||||||
|
None => {
|
||||||
// There is no trait to implement, so
|
// There is no trait to implement, so
|
||||||
// this is an error.
|
// this is an error.
|
||||||
|
|
||||||
|
@ -470,8 +471,10 @@ struct CoherenceChecker {
|
||||||
or new type \
|
or new type \
|
||||||
instead");
|
instead");
|
||||||
}
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
|
||||||
for associated_traits.each |trait_ref| {
|
do opt_trait.iter() |trait_ref| {
|
||||||
// This is OK if and only if the
|
// This is OK if and only if the
|
||||||
// trait was defined in this
|
// trait was defined in this
|
||||||
// crate.
|
// crate.
|
||||||
|
|
|
@ -243,10 +243,10 @@ fn fold_impl(
|
||||||
let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
|
let (trait_types, self_ty) = do astsrv::exec(srv) |ctxt| {
|
||||||
match ctxt.ast_map.get(doc.id()) {
|
match ctxt.ast_map.get(doc.id()) {
|
||||||
ast_map::node_item(@{
|
ast_map::node_item(@{
|
||||||
node: ast::item_impl(_, trait_types, self_ty, _), _
|
node: ast::item_impl(_, opt_trait_type, self_ty, _), _
|
||||||
}, _) => {
|
}, _) => {
|
||||||
let trait_types = vec::map(trait_types, |p| {
|
let trait_types = opt_trait_type.map_default(~[], |p| {
|
||||||
pprust::path_to_str(p.path, extract::interner())
|
~[pprust::path_to_str(p.path, extract::interner())]
|
||||||
});
|
});
|
||||||
(trait_types, Some(pprust::ty_to_str(self_ty,
|
(trait_types, Some(pprust::ty_to_str(self_ty,
|
||||||
extract::interner())))
|
extract::interner())))
|
||||||
|
|
8
src/test/compile-fail/multitrait.rs
Normal file
8
src/test/compile-fail/multitrait.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
struct S {
|
||||||
|
y: int;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl S: Cmp, ToStr { //~ ERROR: expected `{` but found `,`
|
||||||
|
fn eq(&&other: S) { false }
|
||||||
|
fn to_str() -> ~str { ~"hi" }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue