Skip to content

Commit 4b79a58

Browse files
committed
auto merge of #5252 : nikomatsakis/rust/issue-5087-make-trait-not-impl-self, r=pcwalton
Two changes: - The first fixes an inconsistency in coherence whereby extension methods were added to the inherent methods table, but only in cross-crate scenarios. This causes some minor fallout in tests and so forth. In one case (comm) I added inherent and trait methods so as to avoid the need to import traits like `GenericPort` just to use a port. - The second makes objects not implement the associated trait, as discussed in #5087. r? @pcwalton
2 parents 67100dd + 5653fe6 commit 4b79a58

33 files changed

+344
-420
lines changed

src/libcore/comm.rs

Lines changed: 150 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -104,64 +104,98 @@ pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
104104
(Port_(Port_ { endp: Some(s) }), Chan_(Chan_{ endp: Some(c) }))
105105
}
106106
107+
// Add an inherent method so that imports of GenericChan are not
108+
// required.
109+
#[cfg(stage1)]
110+
#[cfg(stage2)]
111+
pub impl<T: Owned> Chan<T> {
112+
fn send(&self, x: T) { chan_send(self, x) }
113+
fn try_send(&self, x: T) -> bool { chan_try_send(self, x) }
114+
}
115+
107116
impl<T: Owned> GenericChan<T> for Chan<T> {
108-
fn send(&self, x: T) {
109-
let mut endp = None;
110-
endp <-> self.endp;
111-
self.endp = Some(
112-
streamp::client::data(unwrap(endp), x))
113-
}
117+
fn send(&self, x: T) { chan_send(self, x) }
114118
}
115119
116-
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
120+
#[inline(always)]
121+
fn chan_send<T:Owned>(self: &Chan<T>, x: T) {
122+
let mut endp = None;
123+
endp <-> self.endp;
124+
self.endp = Some(
125+
streamp::client::data(unwrap(endp), x))
126+
}
117127
128+
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
118129
fn try_send(&self, x: T) -> bool {
119-
let mut endp = None;
120-
endp <-> self.endp;
121-
match streamp::client::try_data(unwrap(endp), x) {
122-
Some(next) => {
123-
self.endp = Some(next);
124-
true
125-
}
126-
None => false
127-
}
130+
chan_try_send(self, x)
128131
}
129132
}
130133
131-
impl<T: Owned> GenericPort<T> for Port<T> {
132-
fn recv(&self) -> T {
133-
let mut endp = None;
134-
endp <-> self.endp;
135-
let streamp::data(x, endp) = recv(unwrap(endp));
136-
self.endp = Some(endp);
137-
x
134+
#[inline(always)]
135+
fn chan_try_send<T:Owned>(self: &Chan<T>, x: T) -> bool {
136+
let mut endp = None;
137+
endp <-> self.endp;
138+
match streamp::client::try_data(unwrap(endp), x) {
139+
Some(next) => {
140+
self.endp = Some(next);
141+
true
142+
}
143+
None => false
138144
}
145+
}
139146
140-
fn try_recv(&self) -> Option<T> {
141-
let mut endp = None;
142-
endp <-> self.endp;
143-
match try_recv(unwrap(endp)) {
144-
Some(streamp::data(x, endp)) => {
147+
// Use an inherent impl so that imports are not required:
148+
#[cfg(stage1)]
149+
#[cfg(stage2)]
150+
pub impl<T: Owned> Port<T> {
151+
fn recv(&self) -> T { port_recv(self) }
152+
fn try_recv(&self) -> Option<T> { port_try_recv(self) }
153+
pure fn peek(&self) -> bool { port_peek(self) }
154+
}
155+
156+
impl<T: Owned> GenericPort<T> for Port<T> {
157+
// These two calls will prefer the inherent versions above:
158+
fn recv(&self) -> T { port_recv(self) }
159+
fn try_recv(&self) -> Option<T> { port_try_recv(self) }
160+
}
161+
162+
#[inline(always)]
163+
fn port_recv<T:Owned>(self: &Port<T>) -> T {
164+
let mut endp = None;
165+
endp <-> self.endp;
166+
let streamp::data(x, endp) = recv(unwrap(endp));
167+
self.endp = Some(endp);
168+
x
169+
}
170+
171+
#[inline(always)]
172+
fn port_try_recv<T:Owned>(self: &Port<T>) -> Option<T> {
173+
let mut endp = None;
174+
endp <-> self.endp;
175+
match try_recv(unwrap(endp)) {
176+
Some(streamp::data(x, endp)) => {
145177
self.endp = Some(endp);
146178
Some(x)
147-
}
148-
None => None
149179
}
180+
None => None
150181
}
151182
}
152183
153184
impl<T: Owned> Peekable<T> for Port<T> {
154-
pure fn peek(&self) -> bool {
155-
unsafe {
156-
let mut endp = None;
157-
endp <-> self.endp;
158-
let peek = match &endp {
159-
&Some(ref endp) => peek(endp),
160-
&None => fail!(~"peeking empty stream")
161-
};
162-
self.endp <-> endp;
163-
peek
164-
}
185+
pure fn peek(&self) -> bool { port_peek(self) }
186+
}
187+
188+
#[inline(always)]
189+
pure fn port_peek<T:Owned>(self: &Port<T>) -> bool {
190+
unsafe {
191+
let mut endp = None;
192+
endp <-> self.endp;
193+
let peek = match &endp {
194+
&Some(ref endp) => peek(endp),
195+
&None => fail!(~"peeking empty stream")
196+
};
197+
self.endp <-> endp;
198+
peek
165199
}
166200
}
167201
@@ -187,8 +221,16 @@ pub fn PortSet<T: Owned>() -> PortSet<T>{
187221
}
188222
}
189223
190-
pub impl<T: Owned> PortSet<T> {
224+
// Use an inherent impl so that imports are not required:
225+
#[cfg(stage1)]
226+
#[cfg(stage2)]
227+
pub impl<T:Owned> PortSet<T> {
228+
fn recv(&self) -> T { port_set_recv(self) }
229+
fn try_recv(&self) -> Option<T> { port_set_try_recv(self) }
230+
pure fn peek(&self) -> bool { port_set_peek(self) }
231+
}
191232
233+
pub impl<T: Owned> PortSet<T> {
192234
fn add(&self, port: Port<T>) {
193235
self.ports.push(port)
194236
}
@@ -200,69 +242,89 @@ pub impl<T: Owned> PortSet<T> {
200242
}
201243
}
202244
203-
impl<T: Owned> GenericPort<T> for PortSet<T> {
204-
205-
fn try_recv(&self) -> Option<T> {
206-
let mut result = None;
207-
// we have to swap the ports array so we aren't borrowing
208-
// aliasable mutable memory.
209-
let mut ports = ~[];
210-
ports <-> self.ports;
211-
while result.is_none() && ports.len() > 0 {
212-
let i = wait_many(ports);
213-
match ports[i].try_recv() {
214-
Some(m) => {
215-
result = Some(m);
216-
}
217-
None => {
218-
// Remove this port.
219-
let _ = ports.swap_remove(i);
220-
}
245+
impl<T:Owned> GenericPort<T> for PortSet<T> {
246+
fn try_recv(&self) -> Option<T> { port_set_try_recv(self) }
247+
fn recv(&self) -> T { port_set_recv(self) }
248+
}
249+
250+
#[inline(always)]
251+
fn port_set_recv<T:Owned>(self: &PortSet<T>) -> T {
252+
port_set_try_recv(self).expect("port_set: endpoints closed")
253+
}
254+
255+
#[inline(always)]
256+
fn port_set_try_recv<T:Owned>(self: &PortSet<T>) -> Option<T> {
257+
let mut result = None;
258+
// we have to swap the ports array so we aren't borrowing
259+
// aliasable mutable memory.
260+
let mut ports = ~[];
261+
ports <-> self.ports;
262+
while result.is_none() && ports.len() > 0 {
263+
let i = wait_many(ports);
264+
match ports[i].try_recv() {
265+
Some(m) => {
266+
result = Some(m);
267+
}
268+
None => {
269+
// Remove this port.
270+
let _ = ports.swap_remove(i);
221271
}
222272
}
223-
ports <-> self.ports;
224-
result
225273
}
226-
227-
fn recv(&self) -> T {
228-
self.try_recv().expect("port_set: endpoints closed")
229-
}
230-
274+
ports <-> self.ports;
275+
result
231276
}
232277
233278
impl<T: Owned> Peekable<T> for PortSet<T> {
234-
pure fn peek(&self) -> bool {
235-
// It'd be nice to use self.port.each, but that version isn't
236-
// pure.
237-
for vec::each(self.ports) |p| {
238-
if p.peek() { return true }
239-
}
240-
false
279+
pure fn peek(&self) -> bool { port_set_peek(self) }
280+
}
281+
282+
#[inline(always)]
283+
pure fn port_set_peek<T:Owned>(self: &PortSet<T>) -> bool {
284+
// It'd be nice to use self.port.each, but that version isn't
285+
// pure.
286+
for vec::each(self.ports) |p| {
287+
if p.peek() { return true }
241288
}
289+
false
242290
}
243291
292+
244293
/// A channel that can be shared between many senders.
245294
pub type SharedChan<T> = unstable::Exclusive<Chan<T>>;
246295
296+
#[cfg(stage1)]
297+
#[cfg(stage2)]
298+
pub impl<T: Owned> SharedChan<T> {
299+
fn send(&self, x: T) { shared_chan_send(self, x) }
300+
fn try_send(&self, x: T) -> bool { shared_chan_try_send(self, x) }
301+
}
302+
247303
impl<T: Owned> GenericChan<T> for SharedChan<T> {
248-
fn send(&self, x: T) {
249-
let mut xx = Some(x);
250-
do self.with_imm |chan| {
251-
let mut x = None;
252-
x <-> xx;
253-
chan.send(option::unwrap(x))
254-
}
304+
fn send(&self, x: T) { shared_chan_send(self, x) }
305+
}
306+
307+
#[inline(always)]
308+
fn shared_chan_send<T:Owned>(self: &SharedChan<T>, x: T) {
309+
let mut xx = Some(x);
310+
do self.with_imm |chan| {
311+
let mut x = None;
312+
x <-> xx;
313+
chan.send(option::unwrap(x))
255314
}
256315
}
257316
258317
impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
259-
fn try_send(&self, x: T) -> bool {
260-
let mut xx = Some(x);
261-
do self.with_imm |chan| {
262-
let mut x = None;
263-
x <-> xx;
264-
chan.try_send(option::unwrap(x))
265-
}
318+
fn try_send(&self, x: T) -> bool { shared_chan_try_send(self, x) }
319+
}
320+
321+
#[inline(always)]
322+
fn shared_chan_try_send<T:Owned>(self: &SharedChan<T>, x: T) -> bool {
323+
let mut xx = Some(x);
324+
do self.with_imm |chan| {
325+
let mut x = None;
326+
x <-> xx;
327+
chan.try_send(option::unwrap(x))
266328
}
267329
}
268330

src/libcore/io.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,26 @@ pub trait Reader {
6969
fn tell(&self) -> uint;
7070
}
7171

72+
#[cfg(stage1)]
73+
#[cfg(stage2)]
74+
impl Reader for @Reader {
75+
fn read(&self, bytes: &mut [u8], len: uint) -> uint {
76+
self.read(bytes, len)
77+
}
78+
fn read_byte(&self) -> int {
79+
self.read_byte()
80+
}
81+
fn eof(&self) -> bool {
82+
self.eof()
83+
}
84+
fn seek(&self, position: int, style: SeekStyle) {
85+
self.seek(position, style)
86+
}
87+
fn tell(&self) -> uint {
88+
self.tell()
89+
}
90+
}
91+
7292
/// Generic utility functions defined on readers.
7393
pub trait ReaderUtil {
7494

@@ -631,6 +651,16 @@ pub trait Writer {
631651
fn get_type(&self) -> WriterType;
632652
}
633653
654+
#[cfg(stage1)]
655+
#[cfg(stage2)]
656+
impl Writer for @Writer {
657+
fn write(&self, v: &[const u8]) { self.write(v) }
658+
fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) }
659+
fn tell(&self) -> uint { self.tell() }
660+
fn flush(&self) -> int { self.flush() }
661+
fn get_type(&self) -> WriterType { self.get_type() }
662+
}
663+
634664
impl<W:Writer,C> Writer for Wrapper<W, C> {
635665
fn write(&self, bs: &[const u8]) { self.base.write(bs); }
636666
fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); }
@@ -1067,8 +1097,8 @@ pub fn buffered_file_writer(path: &Path) -> Result<Writer, ~str> {
10671097
// FIXME (#2004) it would be great if this could be a const
10681098
// FIXME (#2004) why are these different from the way stdin() is
10691099
// implemented?
1070-
pub fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1071-
pub fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
1100+
pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
1101+
pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
10721102
10731103
pub fn print(s: &str) { stdout().write_str(s); }
10741104
pub fn println(s: &str) { stdout().write_line(s); }

src/librustc/back/link.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use middle::ty;
2323
use util::ppaux;
2424

2525
use core::char;
26+
use core::hash::Streaming;
2627
use core::hash;
2728
use core::io::{Writer, WriterUtil};
2829
use core::libc::{c_int, c_uint, c_char};

src/librustc/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use core::dvec;
2626
use core::flate;
2727
use core::hash::{Hash, HashUtil};
2828
use core::int;
29-
use core::io::WriterUtil;
29+
use core::io::{Writer, WriterUtil};
3030
use core::io;
3131
use core::str;
3232
use core::to_bytes::IterBytes;

0 commit comments

Comments
 (0)