Skip to content

Commit 6267339

Browse files
committed
Fix bug in coherence that causes all cross-crate impls to be regarded as
inherent impls, not just those of the `impl Type` variety.
1 parent 959e483 commit 6267339

File tree

13 files changed

+292
-94
lines changed

13 files changed

+292
-94
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/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;

src/librustc/middle/astencode.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ use core::{dvec, io, option, vec};
2929
use std::ebml::reader;
3030
use std::ebml;
3131
use std::serialize;
32-
use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers};
33-
use std::serialize::Decodable;
32+
use std::serialize::{Encoder, Encodable, EncoderHelpers, DecoderHelpers};
33+
use std::serialize::{Decoder, Decodable};
3434
use syntax::ast;
3535
use syntax::ast_map;
36+
use syntax::ast_util::inlined_item_utils;
3637
use syntax::ast_util;
3738
use syntax::codemap::span;
3839
use syntax::codemap;

src/librustc/middle/typeck/coherence.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,12 @@ pub impl CoherenceChecker {
902902
// Nothing to do.
903903
}
904904
Some(base_type_def_id) => {
905-
self.add_inherent_method(base_type_def_id,
906-
*implementation);
905+
// inherent methods apply to `impl Type` but not
906+
// `impl Trait for Type`:
907+
if associated_traits.len() == 0 {
908+
self.add_inherent_method(base_type_def_id,
909+
*implementation);
910+
}
907911

908912
self.base_type_def_ids.insert(implementation.did,
909913
base_type_def_id);

src/librustpkg/rustpkg.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::net::url;
3535
use std::{json, semver, getopts};
3636
use syntax::codemap::spanned;
3737
use syntax::{ast, attr, codemap, diagnostic, parse, visit};
38+
use core::container::Map;
3839

3940
mod usage;
4041
mod util;

src/librustpkg/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
// except according to those terms.
1010

1111
use core::*;
12+
use core::hash::{Hash, HashUtil, Streaming};
1213
use core::hashmap::linear::LinearMap;
1314
use rustc::driver::{driver, session};
1415
use rustc::metadata::filesearch;

src/libstd/comm.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,27 @@ pub struct DuplexStream<T, U> {
2525
priv port: Port<U>,
2626
}
2727

28+
// Allow these methods to be used without import:
29+
#[cfg(stage1)]
30+
#[cfg(stage2)]
31+
pub impl<T:Owned,U:Owned> DuplexStream<T, U> {
32+
fn send(x: T) {
33+
self.chan.send(x)
34+
}
35+
fn try_send(x: T) -> bool {
36+
self.chan.try_send(x)
37+
}
38+
fn recv() -> U {
39+
self.port.recv()
40+
}
41+
fn try_recv() -> Option<U> {
42+
self.port.try_recv()
43+
}
44+
pure fn peek() -> bool {
45+
self.port.peek()
46+
}
47+
}
48+
2849
impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
2950
fn send(&self, x: T) {
3051
self.chan.send(x)

0 commit comments

Comments
 (0)