Skip to content

Commit 3ed9fbd

Browse files
committed
impls of traits cannot define methods on the anonymous trait
1 parent 78ee821 commit 3ed9fbd

23 files changed

+87
-84
lines changed

src/libcore/iter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub trait Times {
3737
pub trait CopyableIter<A:Copy> {
3838
pure fn filter_to_vec(pred: fn(a: A) -> bool) -> ~[A];
3939
pure fn map_to_vec<B>(op: fn(v: A) -> B) -> ~[B];
40+
pure fn flat_map_to_vec<B:Copy,IB: BaseIter<B>>(op: fn(A) -> IB) -> ~[B];
4041
pure fn to_vec() -> ~[A];
4142
pure fn find(p: fn(a: A) -> bool) -> Option<A>;
4243
}

src/libcore/path.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ pub trait GenericPath {
4444
pure fn with_filestem((&str)) -> self;
4545
pure fn with_filetype((&str)) -> self;
4646

47+
pure fn dir_path() -> self;
48+
pure fn file_path() -> self;
49+
4750
pure fn push((&str)) -> self;
4851
pure fn push_rel((&self)) -> self;
4952
pure fn push_many((&[~str])) -> self;

src/libcore/pipes.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -811,13 +811,22 @@ pub struct RecvPacketBuffered<T: Send, Tbuffer: Send> {
811811
}
812812
}
813813

814-
impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
814+
impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> {
815815
fn unwrap() -> *Packet<T> {
816816
let mut p = None;
817817
p <-> self.p;
818818
option::unwrap(move p)
819819
}
820820

821+
fn reuse_buffer() -> BufferResource<Tbuffer> {
822+
//error!("recv reuse_buffer");
823+
let mut tmp = None;
824+
tmp <-> self.buffer;
825+
option::unwrap(move tmp)
826+
}
827+
}
828+
829+
impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
821830
pure fn header() -> *PacketHeader {
822831
match self.p {
823832
Some(packet) => unsafe {
@@ -829,13 +838,6 @@ impl<T: Send, Tbuffer: Send> RecvPacketBuffered<T, Tbuffer> : Selectable {
829838
None => fail ~"packet already consumed"
830839
}
831840
}
832-
833-
fn reuse_buffer() -> BufferResource<Tbuffer> {
834-
//error!("recv reuse_buffer");
835-
let mut tmp = None;
836-
tmp <-> self.buffer;
837-
option::unwrap(move tmp)
838-
}
839841
}
840842

841843
pub fn RecvPacketBuffered<T: Send, Tbuffer: Send>(p: *Packet<T>)
@@ -1046,7 +1048,7 @@ pub fn PortSet<T: Send>() -> PortSet<T>{
10461048
}
10471049
}
10481050

1049-
impl<T: Send> PortSet<T> : Recv<T> {
1051+
impl<T: Send> PortSet<T> {
10501052

10511053
fn add(port: pipes::Port<T>) {
10521054
self.ports.push(move port)
@@ -1057,6 +1059,9 @@ impl<T: Send> PortSet<T> : Recv<T> {
10571059
self.add(move po);
10581060
move ch
10591061
}
1062+
}
1063+
1064+
impl<T: Send> PortSet<T> : Recv<T> {
10601065

10611066
fn try_recv() -> Option<T> {
10621067
let mut result = None;

src/libcore/reflect.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ pub fn MovePtrAdaptor<V: TyVisitor MovePtr>(v: V) -> MovePtrAdaptor<V> {
3434
MovePtrAdaptor { inner: move v }
3535
}
3636

37-
/// Abstract type-directed pointer-movement using the MovePtr trait
38-
impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
39-
37+
impl<V: TyVisitor MovePtr> MovePtrAdaptor<V> {
4038
#[inline(always)]
4139
fn bump(sz: uint) {
4240
do self.inner.move_ptr() |p| {
@@ -60,7 +58,10 @@ impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
6058
fn bump_past<T>() {
6159
self.bump(sys::size_of::<T>());
6260
}
61+
}
6362

63+
/// Abstract type-directed pointer-movement using the MovePtr trait
64+
impl<V: TyVisitor MovePtr> MovePtrAdaptor<V>: TyVisitor {
6465
fn visit_bot() -> bool {
6566
self.align_to::<()>();
6667
if ! self.inner.visit_bot() { return false; }

src/librustc/middle/astencode.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ trait tr {
7272
fn tr(xcx: extended_decode_ctxt) -> self;
7373
}
7474

75+
trait tr_intern {
76+
fn tr_intern(xcx: extended_decode_ctxt) -> ast::def_id;
77+
}
78+
7579
// ______________________________________________________________________
7680
// Top-level methods.
7781

@@ -168,13 +172,16 @@ impl extended_decode_ctxt {
168172
}
169173
}
170174

175+
impl ast::def_id: tr_intern {
176+
fn tr_intern(xcx: extended_decode_ctxt) -> ast::def_id {
177+
xcx.tr_intern_def_id(self)
178+
}
179+
}
180+
171181
impl ast::def_id: tr {
172182
fn tr(xcx: extended_decode_ctxt) -> ast::def_id {
173183
xcx.tr_def_id(self)
174184
}
175-
fn tr_intern(xcx: extended_decode_ctxt) -> ast::def_id {
176-
xcx.tr_intern_def_id(self)
177-
}
178185
}
179186

180187
impl span: tr {

src/librustc/middle/typeck/check/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,6 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
549549
}
550550

551551
impl @fn_ctxt: ast_conv {
552-
fn infcx() -> infer::infer_ctxt { self.inh.infcx }
553552
fn tcx() -> ty::ctxt { self.ccx.tcx }
554553
fn ccx() -> @crate_ctxt { self.ccx }
555554

@@ -563,6 +562,7 @@ impl @fn_ctxt: ast_conv {
563562
}
564563

565564
impl @fn_ctxt {
565+
fn infcx() -> infer::infer_ctxt { self.inh.infcx }
566566
fn search_in_scope_regions(br: ty::bound_region)
567567
-> Result<ty::Region, ~str>
568568
{

src/librustc/middle/typeck/collect.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -465,22 +465,27 @@ fn check_methods_against_trait(ccx: @crate_ctxt,
465465
}
466466
}
467467
468-
for vec::each(*ty::trait_methods(tcx, did)) |trait_m| {
469-
match vec::find(impl_ms, |impl_m| trait_m.ident == impl_m.mty.ident) {
470-
Some(ref cm) => {
468+
// Check that each method we impl is a method on the trait
469+
// Trait methods we don't implement must be default methods, but if not
470+
// we'll catch it in coherence
471+
let trait_ms = ty::trait_methods(tcx, did);
472+
for impl_ms.each |impl_m| {
473+
match trait_ms.find(|trait_m| trait_m.ident == impl_m.mty.ident) {
474+
Some(ref trait_m) => {
471475
compare_impl_method(
472-
ccx.tcx, vec::len(tps), cm, trait_m,
476+
ccx.tcx, tps.len(), impl_m, trait_m,
473477
&tpt.substs, selfty);
474478
}
475479
None => {
476-
// If we couldn't find an implementation for trait_m in
477-
// the impl, then either this method has a default
478-
// implementation or we're using the trait-provided
479-
// version. Either way, we handle this later, during the
480-
// coherence phase.
480+
// This method is not part of the trait
481+
tcx.sess.span_err(
482+
impl_m.span,
483+
fmt!("method `%s` is not a member of trait `%s`",
484+
tcx.sess.str_of(impl_m.mty.ident),
485+
path_to_str(a_trait_ty.path, tcx.sess.intr())));
481486
}
482-
} // match
483-
} // |trait_m|
487+
}
488+
}
484489
} // fn
485490

486491
fn convert_field(ccx: @crate_ctxt,

src/librustc/middle/typeck/infer/lub.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ fn macros() { include!("macros.rs"); } // FIXME(#3114): Macro import/export.
77

88
enum Lub = combine_fields; // "subtype", "subregion" etc
99

10+
impl Lub {
11+
fn bot_ty(b: ty::t) -> cres<ty::t> { Ok(b) }
12+
fn ty_bot(b: ty::t) -> cres<ty::t> { self.bot_ty(b) } // commutative
13+
}
14+
1015
impl Lub: combine {
1116
fn infcx() -> infer_ctxt { self.infcx }
1217
fn tag() -> ~str { ~"lub" }
@@ -16,9 +21,6 @@ impl Lub: combine {
1621
fn lub() -> Lub { Lub(*self) }
1722
fn glb() -> Glb { Glb(*self) }
1823

19-
fn bot_ty(b: ty::t) -> cres<ty::t> { Ok(b) }
20-
fn ty_bot(b: ty::t) -> cres<ty::t> { self.bot_ty(b) } // commutative
21-
2224
fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
2325
let tcx = self.infcx.tcx;
2426

src/libstd/map.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ pub mod chained {
390390
}
391391
}
392392

393-
impl<K:Eq IterBytes Hash Copy ToStr, V: ToStr Copy> T<K, V>: ToStr {
393+
impl<K:Eq IterBytes Hash Copy ToStr, V: ToStr Copy> T<K, V> {
394394
fn to_writer(wr: io::Writer) {
395395
if self.count == 0u {
396396
wr.write_str(~"{}");
@@ -410,7 +410,9 @@ pub mod chained {
410410
};
411411
wr.write_str(~" }");
412412
}
413+
}
413414

415+
impl<K:Eq IterBytes Hash Copy ToStr, V: ToStr Copy> T<K, V>: ToStr {
414416
pure fn to_str() -> ~str unsafe {
415417
// Meh -- this should be safe
416418
do io::with_str_writer |wr| { self.to_writer(wr) }

src/libstd/net_tcp.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,9 +824,6 @@ impl TcpSocketBuf: io::Reader {
824824
bytes[0] as int
825825
}
826826
}
827-
fn unread_byte(amt: int) {
828-
self.data.buf.unshift(amt as u8);
829-
}
830827
fn eof() -> bool {
831828
self.end_of_stream
832829
}

src/libstd/smallintmap.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ impl<V: Copy> SmallIntMap<V>: map::Map<uint, V> {
101101
}
102102
pure fn get(key: uint) -> V { get(self, key) }
103103
pure fn find(key: uint) -> Option<V> { find(self, key) }
104-
fn rehash() { fail }
105104

106105
fn update_with_key(key: uint, val: V, ff: fn(uint, V, V) -> V) -> bool {
107106
match self.find(key) {

src/libsyntax/ext/pipes/ast_builder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ trait ext_ctxt_ast_builder {
7979
fn stmt_let(ident: ident, e: @ast::expr) -> @ast::stmt;
8080
fn stmt_expr(e: @ast::expr) -> @ast::stmt;
8181
fn block_expr(b: ast::blk) -> @ast::expr;
82+
fn move_expr(e: @ast::expr) -> @ast::expr;
8283
fn ty_option(ty: @ast::Ty) -> @ast::Ty;
84+
fn ty_infer() -> @ast::Ty;
85+
fn ty_nil_ast_builder() -> @ast::Ty;
8386
}
8487

8588
impl ext_ctxt: ext_ctxt_ast_builder {

src/libsyntax/ext/pipes/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ use ext::base::ext_ctxt;
3838
use ast::tt_delim;
3939
use parse::lexer::{new_tt_reader, reader};
4040
use parse::parser::Parser;
41-
use parse::common::parser_common;
4241

4342
use pipes::parse_proto::proto_parser;
4443

src/libsyntax/ext/pipes/parse_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use pipec::*;
88
trait proto_parser {
99
fn parse_proto(id: ~str) -> protocol;
1010
fn parse_state(proto: protocol);
11+
fn parse_message(state: state);
1112
}
1213

1314
impl parser::Parser: proto_parser {

src/libsyntax/ext/pipes/pipec.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mod syntax {
2424

2525
trait gen_send {
2626
fn gen_send(cx: ext_ctxt, try: bool) -> @ast::item;
27+
fn to_ty(cx: ext_ctxt) -> @ast::Ty;
2728
}
2829

2930
trait to_type_decls {
@@ -34,6 +35,10 @@ trait to_type_decls {
3435
trait gen_init {
3536
fn gen_init(cx: ext_ctxt) -> @ast::item;
3637
fn compile(cx: ext_ctxt) -> @ast::item;
38+
fn buffer_ty_path(cx: ext_ctxt) -> @ast::Ty;
39+
fn gen_buffer_type(cx: ext_ctxt) -> @ast::item;
40+
fn gen_buffer_init(ext_cx: ext_ctxt) -> @ast::expr;
41+
fn gen_init_bounded(ext_cx: ext_ctxt) -> @ast::expr;
3742
}
3843

3944
impl message: gen_send {

src/libsyntax/ext/trace_macros.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use ext::base::ext_ctxt;
33
use ast::tt_delim;
44
use parse::lexer::{new_tt_reader, reader};
55
use parse::parser::Parser;
6-
use parse::common::parser_common;
76

87
fn expand_trace_macros(cx: ext_ctxt, sp: span,
98
tt: ~[ast::token_tree]) -> base::mac_result

src/libsyntax/parse/common.rs

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,7 @@ fn token_to_str(reader: reader, ++token: token::Token) -> ~str {
2222
token::to_str(reader.interner(), token)
2323
}
2424

25-
trait parser_common {
26-
fn unexpected_last(t: token::Token) -> !;
27-
fn unexpected() -> !;
28-
fn expect(t: token::Token);
29-
fn parse_ident() -> ast::ident;
30-
fn parse_path_list_ident() -> ast::path_list_ident;
31-
fn parse_value_ident() -> ast::ident;
32-
fn eat(tok: token::Token) -> bool;
33-
// A sanity check that the word we are asking for is a known keyword
34-
fn require_keyword(word: ~str);
35-
fn token_is_keyword(word: ~str, ++tok: token::Token) -> bool;
36-
fn is_keyword(word: ~str) -> bool;
37-
fn is_any_keyword(tok: token::Token) -> bool;
38-
fn eat_keyword(word: ~str) -> bool;
39-
fn expect_keyword(word: ~str);
40-
fn expect_gt();
41-
fn parse_seq_to_before_gt<T: Copy>(sep: Option<token::Token>,
42-
f: fn(Parser) -> T) -> ~[T];
43-
fn parse_seq_to_gt<T: Copy>(sep: Option<token::Token>,
44-
f: fn(Parser) -> T) -> ~[T];
45-
fn parse_seq_lt_gt<T: Copy>(sep: Option<token::Token>,
46-
f: fn(Parser) -> T) -> spanned<~[T]>;
47-
fn parse_seq_to_end<T: Copy>(ket: token::Token, sep: seq_sep,
48-
f: fn(Parser) -> T) -> ~[T];
49-
fn parse_seq_to_before_end<T: Copy>(ket: token::Token, sep: seq_sep,
50-
f: fn(Parser) -> T) -> ~[T];
51-
fn parse_unspanned_seq<T: Copy>(bra: token::Token,
52-
ket: token::Token,
53-
sep: seq_sep,
54-
f: fn(Parser) -> T) -> ~[T];
55-
fn parse_seq<T: Copy>(bra: token::Token, ket: token::Token, sep: seq_sep,
56-
f: fn(Parser) -> T) -> spanned<~[T]>;
57-
}
58-
59-
impl Parser: parser_common {
25+
impl Parser {
6026
fn unexpected_last(t: token::Token) -> ! {
6127
self.span_fatal(
6228
copy self.last_span,

src/libsyntax/parse/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export parse_from_source_str;
2727

2828
use parser::Parser;
2929
use attr::parser_attr;
30-
use common::parser_common;
3130
use ast::node_id;
3231
use util::interner;
3332
use diagnostic::{span_handler, mk_span_handler, mk_handler, emitter};

src/libsyntax/parse/obsolete.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,7 @@ impl ObsoleteSyntax: to_bytes::IterBytes {
5252
}
5353
}
5454

55-
pub trait ObsoleteReporter {
56-
fn obsolete(sp: span, kind: ObsoleteSyntax);
57-
fn obsolete_expr(sp: span, kind: ObsoleteSyntax) -> @expr;
58-
}
59-
60-
impl Parser : ObsoleteReporter {
55+
impl Parser {
6156
/// Reports an obsolete syntax non-fatal error.
6257
fn obsolete(sp: span, kind: ObsoleteSyntax) {
6358
let (kind_str, desc) = match kind {

src/libsyntax/parse/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed,
1616
use dvec::DVec;
1717
use vec::{push};
1818
use obsolete::{
19-
ObsoleteReporter, ObsoleteSyntax,
19+
ObsoleteSyntax,
2020
ObsoleteLowerCaseKindBounds, ObsoleteLet,
2121
ObsoleteFieldTerminator, ObsoleteStructCtor,
2222
ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits,

src/test/compile-fail/issue-3953.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ trait Hahaha: Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, Eq, //
99

1010
enum Lol = int;
1111

12-
pub impl Lol: Hahaha {
13-
pure fn eq(other: &Lol) -> bool { *self != **other }
14-
pure fn ne(other: &Lol) -> bool { *self == **other }
12+
pub impl Lol: Hahaha { }
13+
14+
impl Lol: Eq {
15+
pure fn eq(&self, other: &Lol) -> bool { **self != **other }
16+
pure fn ne(&self, other: &Lol) -> bool { **self == **other }
1517
}
1618

1719
fn main() {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
trait A { }
2+
3+
impl int: A {
4+
fn foo() { } //~ ERROR method `foo` is not a member of trait `A`
5+
}
6+
7+
fn main() { }

0 commit comments

Comments
 (0)