diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 4f812a5ae769..18e049789445 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -104,64 +104,98 @@ pub fn stream() -> (Port, Chan) { (Port_(Port_ { endp: Some(s) }), Chan_(Chan_{ endp: Some(c) })) } +// Add an inherent method so that imports of GenericChan are not +// required. +#[cfg(stage1)] +#[cfg(stage2)] +pub impl Chan { + fn send(&self, x: T) { chan_send(self, x) } + fn try_send(&self, x: T) -> bool { chan_try_send(self, x) } +} + impl GenericChan for Chan { - fn send(&self, x: T) { - let mut endp = None; - endp <-> self.endp; - self.endp = Some( - streamp::client::data(unwrap(endp), x)) - } + fn send(&self, x: T) { chan_send(self, x) } +} + +#[inline(always)] +fn chan_send(self: &Chan, x: T) { + let mut endp = None; + endp <-> self.endp; + self.endp = Some( + streamp::client::data(unwrap(endp), x)) } impl GenericSmartChan for Chan { - fn try_send(&self, x: T) -> bool { - let mut endp = None; - endp <-> self.endp; - match streamp::client::try_data(unwrap(endp), x) { - Some(next) => { - self.endp = Some(next); - true - } - None => false - } + chan_try_send(self, x) } } -impl GenericPort for Port { - fn recv(&self) -> T { - let mut endp = None; - endp <-> self.endp; - let streamp::data(x, endp) = recv(unwrap(endp)); - self.endp = Some(endp); - x +#[inline(always)] +fn chan_try_send(self: &Chan, x: T) -> bool { + let mut endp = None; + endp <-> self.endp; + match streamp::client::try_data(unwrap(endp), x) { + Some(next) => { + self.endp = Some(next); + true + } + None => false } +} - fn try_recv(&self) -> Option { - let mut endp = None; - endp <-> self.endp; - match try_recv(unwrap(endp)) { - Some(streamp::data(x, endp)) => { +// Use an inherent impl so that imports are not required: +#[cfg(stage1)] +#[cfg(stage2)] +pub impl Port { + fn recv(&self) -> T { port_recv(self) } + fn try_recv(&self) -> Option { port_try_recv(self) } + pure fn peek(&self) -> bool { port_peek(self) } +} + +impl GenericPort for Port { + // These two calls will prefer the inherent versions above: + fn recv(&self) -> T { port_recv(self) } + fn try_recv(&self) -> Option { port_try_recv(self) } +} + +#[inline(always)] +fn port_recv(self: &Port) -> T { + let mut endp = None; + endp <-> self.endp; + let streamp::data(x, endp) = recv(unwrap(endp)); + self.endp = Some(endp); + x +} + +#[inline(always)] +fn port_try_recv(self: &Port) -> Option { + let mut endp = None; + endp <-> self.endp; + match try_recv(unwrap(endp)) { + Some(streamp::data(x, endp)) => { self.endp = Some(endp); Some(x) - } - None => None } + None => None } } impl Peekable for Port { - pure fn peek(&self) -> bool { - unsafe { - let mut endp = None; - endp <-> self.endp; - let peek = match &endp { - &Some(ref endp) => peek(endp), - &None => fail!(~"peeking empty stream") - }; - self.endp <-> endp; - peek - } + pure fn peek(&self) -> bool { port_peek(self) } +} + +#[inline(always)] +pure fn port_peek(self: &Port) -> bool { + unsafe { + let mut endp = None; + endp <-> self.endp; + let peek = match &endp { + &Some(ref endp) => peek(endp), + &None => fail!(~"peeking empty stream") + }; + self.endp <-> endp; + peek } } @@ -187,8 +221,16 @@ pub fn PortSet() -> PortSet{ } } -pub impl PortSet { +// Use an inherent impl so that imports are not required: +#[cfg(stage1)] +#[cfg(stage2)] +pub impl PortSet { + fn recv(&self) -> T { port_set_recv(self) } + fn try_recv(&self) -> Option { port_set_try_recv(self) } + pure fn peek(&self) -> bool { port_set_peek(self) } +} +pub impl PortSet { fn add(&self, port: Port) { self.ports.push(port) } @@ -200,69 +242,89 @@ pub impl PortSet { } } -impl GenericPort for PortSet { +impl GenericPort for PortSet { + fn try_recv(&self) -> Option { port_set_try_recv(self) } + fn recv(&self) -> T { port_set_recv(self) } +} - fn try_recv(&self) -> Option { - let mut result = None; - // we have to swap the ports array so we aren't borrowing - // aliasable mutable memory. - let mut ports = ~[]; - ports <-> self.ports; - while result.is_none() && ports.len() > 0 { - let i = wait_many(ports); - match ports[i].try_recv() { - Some(m) => { - result = Some(m); - } - None => { - // Remove this port. - let _ = ports.swap_remove(i); - } +#[inline(always)] +fn port_set_recv(self: &PortSet) -> T { + port_set_try_recv(self).expect("port_set: endpoints closed") +} + +#[inline(always)] +fn port_set_try_recv(self: &PortSet) -> Option { + let mut result = None; + // we have to swap the ports array so we aren't borrowing + // aliasable mutable memory. + let mut ports = ~[]; + ports <-> self.ports; + while result.is_none() && ports.len() > 0 { + let i = wait_many(ports); + match ports[i].try_recv() { + Some(m) => { + result = Some(m); + } + None => { + // Remove this port. + let _ = ports.swap_remove(i); } } - ports <-> self.ports; - result } - - fn recv(&self) -> T { - self.try_recv().expect("port_set: endpoints closed") - } - + ports <-> self.ports; + result } impl Peekable for PortSet { - pure fn peek(&self) -> bool { - // It'd be nice to use self.port.each, but that version isn't - // pure. - for vec::each(self.ports) |p| { - if p.peek() { return true } - } - false - } + pure fn peek(&self) -> bool { port_set_peek(self) } } +#[inline(always)] +pure fn port_set_peek(self: &PortSet) -> bool { + // It'd be nice to use self.port.each, but that version isn't + // pure. + for vec::each(self.ports) |p| { + if p.peek() { return true } + } + false +} + + /// A channel that can be shared between many senders. pub type SharedChan = unstable::Exclusive>; +#[cfg(stage1)] +#[cfg(stage2)] +pub impl SharedChan { + fn send(&self, x: T) { shared_chan_send(self, x) } + fn try_send(&self, x: T) -> bool { shared_chan_try_send(self, x) } +} + impl GenericChan for SharedChan { - fn send(&self, x: T) { - let mut xx = Some(x); - do self.with_imm |chan| { - let mut x = None; - x <-> xx; - chan.send(option::unwrap(x)) - } + fn send(&self, x: T) { shared_chan_send(self, x) } +} + +#[inline(always)] +fn shared_chan_send(self: &SharedChan, x: T) { + let mut xx = Some(x); + do self.with_imm |chan| { + let mut x = None; + x <-> xx; + chan.send(option::unwrap(x)) } } impl GenericSmartChan for SharedChan { - fn try_send(&self, x: T) -> bool { - let mut xx = Some(x); - do self.with_imm |chan| { - let mut x = None; - x <-> xx; - chan.try_send(option::unwrap(x)) - } + fn try_send(&self, x: T) -> bool { shared_chan_try_send(self, x) } +} + +#[inline(always)] +fn shared_chan_try_send(self: &SharedChan, x: T) -> bool { + let mut xx = Some(x); + do self.with_imm |chan| { + let mut x = None; + x <-> xx; + chan.try_send(option::unwrap(x)) } } diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 27456fbe1604..65879f88a5da 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -69,6 +69,26 @@ pub trait Reader { fn tell(&self) -> uint; } +#[cfg(stage1)] +#[cfg(stage2)] +impl Reader for @Reader { + fn read(&self, bytes: &mut [u8], len: uint) -> uint { + self.read(bytes, len) + } + fn read_byte(&self) -> int { + self.read_byte() + } + fn eof(&self) -> bool { + self.eof() + } + fn seek(&self, position: int, style: SeekStyle) { + self.seek(position, style) + } + fn tell(&self) -> uint { + self.tell() + } +} + /// Generic utility functions defined on readers. pub trait ReaderUtil { @@ -631,6 +651,16 @@ pub trait Writer { fn get_type(&self) -> WriterType; } +#[cfg(stage1)] +#[cfg(stage2)] +impl Writer for @Writer { + fn write(&self, v: &[const u8]) { self.write(v) } + fn seek(&self, a: int, b: SeekStyle) { self.seek(a, b) } + fn tell(&self) -> uint { self.tell() } + fn flush(&self) -> int { self.flush() } + fn get_type(&self) -> WriterType { self.get_type() } +} + impl Writer for Wrapper { fn write(&self, bs: &[const u8]) { self.base.write(bs); } fn seek(&self, off: int, style: SeekStyle) { self.base.seek(off, style); } @@ -1067,8 +1097,8 @@ pub fn buffered_file_writer(path: &Path) -> Result { // FIXME (#2004) it would be great if this could be a const // FIXME (#2004) why are these different from the way stdin() is // implemented? -pub fn stdout() -> Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } -pub fn stderr() -> Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } +pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) } +pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) } pub fn print(s: &str) { stdout().write_str(s); } pub fn println(s: &str) { stdout().write_line(s); } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 30ef73bf6705..8e74ec1dc4cb 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -23,6 +23,7 @@ use middle::ty; use util::ppaux; use core::char; +use core::hash::Streaming; use core::hash; use core::io::{Writer, WriterUtil}; use core::libc::{c_int, c_uint, c_char}; diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index c5cb66171302..2c9a824471ce 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -26,7 +26,7 @@ use core::dvec; use core::flate; use core::hash::{Hash, HashUtil}; use core::int; -use core::io::WriterUtil; +use core::io::{Writer, WriterUtil}; use core::io; use core::str; use core::to_bytes::IterBytes; diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index cf88a0eb9024..e418aa35e1e8 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -29,10 +29,11 @@ use core::{dvec, io, option, vec}; use std::ebml::reader; use std::ebml; use std::serialize; -use std::serialize::{Encodable, EncoderHelpers, DecoderHelpers}; -use std::serialize::Decodable; +use std::serialize::{Encoder, Encodable, EncoderHelpers, DecoderHelpers}; +use std::serialize::{Decoder, Decodable}; use syntax::ast; use syntax::ast_map; +use syntax::ast_util::inlined_item_utils; use syntax::ast_util; use syntax::codemap::span; use syntax::codemap; @@ -663,16 +664,6 @@ fn encode_vtable_origin(ecx: @e::EncodeContext, } } } - typeck::vtable_trait(def_id, tys) => { - do ebml_w.emit_enum_variant(~"vtable_trait", 1u, 3u) { - do ebml_w.emit_enum_variant_arg(0u) { - ebml_w.emit_def_id(def_id) - } - do ebml_w.emit_enum_variant_arg(1u) { - ebml_w.emit_tys(ecx, /*bad*/copy tys); - } - } - } } } @@ -719,16 +710,6 @@ impl vtable_decoder_helpers for reader::Decoder { } ) } - 2 => { - typeck::vtable_trait( - do self.read_enum_variant_arg(0u) { - self.read_def_id(xcx) - }, - do self.read_enum_variant_arg(1u) { - self.read_tys(xcx) - } - ) - } // hard to avoid - user input _ => fail!(~"bad enum variant") } diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index f3ac11771975..33b52c6e6b6c 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -1405,7 +1405,6 @@ pub fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, +vt: typeck::vtable_origin) } } } - vt => vt } } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 917960f7a27a..2f4e8d715e0a 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -478,14 +478,6 @@ pub fn trans_monomorphized_callee(bcx: block, }) } } - typeck::vtable_trait(_, _) => { - trans_trait_callee(bcx, - callee_id, - n_method, - base, - ty::vstore_box, - mentry.explicit_self) - } typeck::vtable_param(*) => { fail!(~"vtable_param left in monomorphized function's " + "vtable substs"); @@ -756,13 +748,7 @@ pub fn vtable_id(ccx: @CrateContext, None, None) } - typeck::vtable_trait(trait_id, substs) => { - @mono_id_ { - def: trait_id, - params: vec::map(substs, |t| mono_precise(*t, None)), - impl_did_opt: None - } - } + // can't this be checked at the callee? _ => fail!(~"vtable_id") } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index b269e5943959..5d0b3f948e2d 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -30,7 +30,7 @@ itself (note that inherent impls can only be defined in the same module as the type itself). Inherent candidates are not always derived from impls. If you have a -trait instance, such as a value of type `ToStr`, then the trait +trait instance, such as a value of type `@ToStr`, then the trait methods (`to_str()`, in this case) are inherently associated with it. Another case is type parameters, in which case the methods of their bounds are inherent. @@ -1221,7 +1221,7 @@ pub impl LookupContext { } method_trait(trait_did, _, _) | method_self(trait_did, _) | method_super(trait_did, _) => { - self.report_param_candidate(idx, trait_did) + self.report_trait_candidate(idx, trait_did) } } } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index da2b80364771..fa17c9438a22 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -18,7 +18,7 @@ use middle::typeck::infer::{fixup_err_to_str, InferCtxt}; use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type}; use middle::typeck::infer; use middle::typeck::{CrateCtxt, vtable_origin, vtable_param, vtable_res}; -use middle::typeck::{vtable_static, vtable_trait}; +use middle::typeck::{vtable_static}; use util::common::indenter; use util::ppaux::tys_to_str; use util::ppaux; @@ -81,7 +81,6 @@ pub fn lookup_vtables(vcx: &VtableContext, location_info: &LocationInfo, bounds: @~[ty::param_bounds], substs: &ty::substs, - allow_unsafe: bool, is_early: bool) -> vtable_res { debug!("lookup_vtables(location_info=%?, # bounds=%?, \ @@ -110,8 +109,7 @@ pub fn lookup_vtables(vcx: &VtableContext, debug!("after subst: %?", ppaux::ty_to_str(tcx, trait_ty)); - match lookup_vtable(vcx, location_info, *ty, trait_ty, - allow_unsafe, is_early) { + match lookup_vtable(vcx, location_info, *ty, trait_ty, is_early) { Some(vtable) => result.push(vtable), None => { vcx.tcx().sess.span_fatal( @@ -162,7 +160,6 @@ pub fn lookup_vtable(vcx: &VtableContext, location_info: &LocationInfo, ty: ty::t, trait_ty: ty::t, - allow_unsafe: bool, is_early: bool) -> Option { debug!("lookup_vtable(ty=%s, trait_ty=%s)", @@ -224,30 +221,6 @@ pub fn lookup_vtable(vcx: &VtableContext, } } - ty::ty_trait(did, ref substs, _) if trait_id == did => { - debug!("(checking vtable) @1 relating ty to trait ty with did %?", - did); - - relate_trait_tys(vcx, location_info, trait_ty, ty); - if !allow_unsafe && !is_early { - for vec::each(*ty::trait_methods(tcx, did)) |m| { - if ty::type_has_self(ty::mk_bare_fn(tcx, copy m.fty)) { - tcx.sess.span_err( - location_info.span, - ~"a boxed trait with self types may not be \ - passed as a bounded type"); - } else if (*m.tps).len() > 0u { - tcx.sess.span_err( - location_info.span, - ~"a boxed trait with generic methods may not \ - be passed as a bounded type"); - - } - } - } - return Some(vtable_trait(did, /*bad*/copy (*substs).tps)); - } - _ => { let mut found = ~[]; @@ -411,7 +384,7 @@ pub fn lookup_vtable(vcx: &VtableContext, trait_vstore); let subres = lookup_vtables( vcx, location_info, im_bs, &substs_f, - false, is_early); + is_early); // Finally, we register that we found a // matching impl, and record the def ID of @@ -542,8 +515,7 @@ pub fn early_resolve_expr(ex: @ast::expr, } let vcx = VtableContext { ccx: fcx.ccx, infcx: fcx.infcx() }; let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex), - item_ty.bounds, substs, false, - is_early); + item_ty.bounds, substs, is_early); if !is_early { let vtable_map = cx.vtable_map; vtable_map.insert(ex.id, vtbls); @@ -573,7 +545,7 @@ pub fn early_resolve_expr(ex: @ast::expr, let substs = fcx.node_ty_substs(callee_id); let vcx = VtableContext { ccx: fcx.ccx, infcx: fcx.infcx() }; let vtbls = lookup_vtables(&vcx, &location_info_for_expr(ex), - bounds, &substs, false, is_early); + bounds, &substs, is_early); if !is_early { insert_vtables(cx, callee_id, vtbls); } @@ -607,7 +579,6 @@ pub fn early_resolve_expr(ex: @ast::expr, location_info, mt.ty, target_ty, - true, is_early); match vtable_opt { Some(vtable) => { diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index 00f757412f6a..5cfb7973b96a 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -22,7 +22,7 @@ use middle::typeck::infer::{force_all, resolve_all, resolve_region}; use middle::typeck::infer::{resolve_type}; use middle::typeck::infer; use middle::typeck::method_map_entry; -use middle::typeck::{vtable_param, vtable_trait, write_substs_to_tcx}; +use middle::typeck::{vtable_param, write_substs_to_tcx}; use middle::typeck::{write_ty_to_tcx}; use util::ppaux; diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 2d2be88de7f1..2d1fab5f6a9c 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -902,8 +902,12 @@ pub impl CoherenceChecker { // Nothing to do. } Some(base_type_def_id) => { - self.add_inherent_method(base_type_def_id, - *implementation); + // inherent methods apply to `impl Type` but not + // `impl Trait for Type`: + if associated_traits.len() == 0 { + self.add_inherent_method(base_type_def_id, + *implementation); + } self.base_type_def_ids.insert(implementation.did, base_type_def_id); diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs index b7d60817627f..81094e3fb97e 100644 --- a/src/librustc/middle/typeck/mod.rs +++ b/src/librustc/middle/typeck/mod.rs @@ -150,12 +150,7 @@ pub enum vtable_origin { The first uint is the param number (identifying T in the example), and the second is the bound number (identifying baz) */ - vtable_param(uint, uint), - /* - Dynamic vtable, comes from something known to have a trait - type. def_id refers to the trait item, tys are the substs - */ - vtable_trait(ast::def_id, ~[ty::t]), + vtable_param(uint, uint) } pub impl vtable_origin { @@ -171,12 +166,6 @@ pub impl vtable_origin { vtable_param(x, y) => { fmt!("vtable_param(%?, %?)", x, y) } - - vtable_trait(def_id, ref tys) => { - fmt!("vtable_trait(%?:%s, %?)", - def_id, ty::item_path_str(tcx, def_id), - tys.map(|t| ppaux::ty_to_str(tcx, *t))) - } } } } diff --git a/src/librustpkg/rustpkg.rc b/src/librustpkg/rustpkg.rc index 603480f907c0..0f8463b0b3c9 100644 --- a/src/librustpkg/rustpkg.rc +++ b/src/librustpkg/rustpkg.rc @@ -35,6 +35,7 @@ use std::net::url; use std::{json, semver, getopts}; use syntax::codemap::spanned; use syntax::{ast, attr, codemap, diagnostic, parse, visit}; +use core::container::Map; mod usage; mod util; diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs index 32f9593d9a63..8cfb216d2a2a 100644 --- a/src/librustpkg/util.rs +++ b/src/librustpkg/util.rs @@ -9,6 +9,7 @@ // except according to those terms. use core::*; +use core::hash::{Hash, HashUtil, Streaming}; use core::hashmap::linear::LinearMap; use rustc::driver::{driver, session}; use rustc::metadata::filesearch; diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs index 14a37ecbf520..e3437fc57aae 100644 --- a/src/libstd/comm.rs +++ b/src/libstd/comm.rs @@ -25,6 +25,27 @@ pub struct DuplexStream { priv port: Port, } +// Allow these methods to be used without import: +#[cfg(stage1)] +#[cfg(stage2)] +pub impl DuplexStream { + fn send(x: T) { + self.chan.send(x) + } + fn try_send(x: T) -> bool { + self.chan.try_send(x) + } + fn recv() -> U { + self.port.recv() + } + fn try_recv() -> Option { + self.port.try_recv() + } + pure fn peek() -> bool { + self.port.peek() + } +} + impl GenericChan for DuplexStream { fn send(&self, x: T) { self.chan.send(x) diff --git a/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs b/src/test/auxiliary/coherence_inherent_cc_lib.rs similarity index 66% rename from src/test/run-pass/autoderef-method-on-trait-monomorphized.rs rename to src/test/auxiliary/coherence_inherent_cc_lib.rs index bfde19993e9e..0458636a401e 100644 --- a/src/test/run-pass/autoderef-method-on-trait-monomorphized.rs +++ b/src/test/auxiliary/coherence_inherent_cc_lib.rs @@ -8,19 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait double { - fn double() -> uint; +// See coherence_inherent_cc.rs + +pub trait TheTrait { + fn the_fn(&self); } -impl double for uint { - fn double() -> uint { self * 2u } -} +pub struct TheStruct; -fn is_equal(x: @D, exp: uint) { - assert x.double() == exp; -} - -pub fn main() { - let x = @(@3u as @double); - is_equal(x, 6); +impl TheTrait for TheStruct { + fn the_fn(&self) {} } diff --git a/src/test/compile-fail/coherence_inherent.rs b/src/test/compile-fail/coherence_inherent.rs new file mode 100644 index 000000000000..590c12826e4f --- /dev/null +++ b/src/test/compile-fail/coherence_inherent.rs @@ -0,0 +1,45 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +mod Lib { + pub trait TheTrait { + fn the_fn(&self); + } + + pub struct TheStruct; + + impl TheTrait for TheStruct { + fn the_fn(&self) {} + } +} + +mod Import { + // Trait is in scope here: + use Lib::TheStruct; + use Lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use Lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); //~ ERROR does not implement any method in scope named `the_fn` + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/compile-fail/coherence_inherent_cc.rs b/src/test/compile-fail/coherence_inherent_cc.rs new file mode 100644 index 000000000000..72c6df57c4ff --- /dev/null +++ b/src/test/compile-fail/coherence_inherent_cc.rs @@ -0,0 +1,38 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-fast +// aux-build:coherence_inherent_cc_lib.rs + +// Tests that methods that implement a trait cannot be invoked +// unless the trait is imported. + +extern mod coherence_inherent_cc_lib; + +mod Import { + // Trait is in scope here: + use coherence_inherent_cc_lib::TheStruct; + use coherence_inherent_cc_lib::TheTrait; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); + } +} + +mod NoImport { + // Trait is not in scope here: + use coherence_inherent_cc_lib::TheStruct; + + fn call_the_fn(s: &TheStruct) { + s.the_fn(); //~ ERROR does not implement any method in scope named `the_fn` + } +} + +fn main() {} \ No newline at end of file diff --git a/src/test/run-pass/issue-3305.rs b/src/test/compile-fail/object-does-not-impl-trait.rs similarity index 65% rename from src/test/run-pass/issue-3305.rs rename to src/test/compile-fail/object-does-not-impl-trait.rs index bfde19993e9e..886b849dbefc 100644 --- a/src/test/run-pass/issue-3305.rs +++ b/src/test/compile-fail/object-does-not-impl-trait.rs @@ -8,19 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -trait double { - fn double() -> uint; -} +// Test that an object type `@Foo` is not considered to implement the +// trait `Foo`. Issue #5087. -impl double for uint { - fn double() -> uint { self * 2u } -} - -fn is_equal(x: @D, exp: uint) { - assert x.double() == exp; -} - -pub fn main() { - let x = @(@3u as @double); - is_equal(x, 6); -} +trait Foo {} +fn take_foo(f: F) {} +fn take_object(f: @Foo) { take_foo(f); } //~ ERROR failed to find an implementation of trait +fn main() {} diff --git a/src/test/compile-fail/regions-trait-3.rs b/src/test/compile-fail/regions-trait-3.rs index 0ddaf25710c9..a10c239617ec 100644 --- a/src/test/compile-fail/regions-trait-3.rs +++ b/src/test/compile-fail/regions-trait-3.rs @@ -16,8 +16,16 @@ fn make_gc1(gc: get_ctxt/&a) -> get_ctxt/&b { return gc; //~ ERROR mismatched types: expected `@get_ctxt/&b` but found `@get_ctxt/&a` } -fn make_gc2(gc: get_ctxt/&a) -> get_ctxt/&b { - return @gc as get_ctxt; //~ ERROR cannot infer an appropriate lifetime +struct Foo { + r: &'self uint +} + +impl get_ctxt/&self for Foo/&self { + fn get_ctxt() -> &self/uint { self.r } +} + +fn make_gc2(foo: Foo/&a) -> get_ctxt/&b { + return @foo as get_ctxt; //~ ERROR cannot infer an appropriate lifetime } fn main() { diff --git a/src/test/compile-fail/selftype-astparam.rs b/src/test/compile-fail/selftype-astparam.rs deleted file mode 100644 index 08b6c0f71fe6..000000000000 --- a/src/test/compile-fail/selftype-astparam.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait add { - fn plus(++x: Self) -> Self; -} - -impl add for int { - fn plus(++x: int) -> int { self + x } -} - -fn do_add(x: A, y: A) -> A { x.plus(y) } - -fn main() { - let x = @3 as @add; - let y = @4 as @add; - do_add(x, y); //~ ERROR a boxed trait with self types may not be passed as a bounded type -} diff --git a/src/test/compile-fail/trait-cast.rs b/src/test/compile-fail/trait-cast.rs deleted file mode 100644 index d0738be09c7c..000000000000 --- a/src/test/compile-fail/trait-cast.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -trait foo { } - -fn bar(x: foo) -> foo { - return (@x as foo::); - //~^ ERROR mismatched types: expected `@foo` but found `@foo` - //~^^ ERROR mismatched types: expected `@foo` but found `@foo` - // This is unfortunate -- new handling of parens means the error message - // gets printed twice -} - -fn main() {} diff --git a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs index 1db3d4b38d79..53c50d7fca0c 100644 --- a/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs +++ b/src/test/run-pass/class-cast-to-trait-cross-crate-2.rs @@ -14,7 +14,7 @@ extern mod cci_class_cast; use core::to_str::ToStr; use cci_class_cast::kitty::*; -fn print_out(thing: T, expected: ~str) { +fn print_out(thing: @ToStr, expected: ~str) { let actual = thing.to_str(); debug!("%s", actual); assert(actual == expected); diff --git a/src/test/run-pass/class-cast-to-trait-multiple-types.rs b/src/test/run-pass/class-cast-to-trait-multiple-types.rs index 5cf68174075f..39466bb8c167 100644 --- a/src/test/run-pass/class-cast-to-trait-multiple-types.rs +++ b/src/test/run-pass/class-cast-to-trait-multiple-types.rs @@ -79,7 +79,7 @@ fn cat(in_x : uint, in_y : int, in_name: ~str) -> cat { } -fn annoy_neighbors(critter: T) { +fn annoy_neighbors(critter: @noisy) { for uint::range(0u, 10u) |i| { critter.speak(); } } diff --git a/src/test/run-pass/class-separate-impl.rs b/src/test/run-pass/class-separate-impl.rs index b232be325502..eb0d8de7eab8 100644 --- a/src/test/run-pass/class-separate-impl.rs +++ b/src/test/run-pass/class-separate-impl.rs @@ -56,7 +56,7 @@ impl ToStr for cat { pure fn to_str(&self) -> ~str { copy self.name } } -fn print_out(thing: T, expected: ~str) { +fn print_out(thing: @ToStr, expected: ~str) { let actual = thing.to_str(); debug!("%s", actual); assert(actual == expected); diff --git a/src/test/run-pass/explicit-self-objects-ext-1.rs b/src/test/run-pass/explicit-self-objects-ext-1.rs deleted file mode 100644 index 92f745d7d538..000000000000 --- a/src/test/run-pass/explicit-self-objects-ext-1.rs +++ /dev/null @@ -1,39 +0,0 @@ -pub trait Reader { - // FIXME (#2004): Seekable really should be orthogonal. - - /// Read up to len bytes (or EOF) and put them into bytes (which - /// must be at least len bytes long). Return number of bytes read. - // FIXME (#2982): This should probably return an error. - fn read(&self, bytes: &mut [u8], len: uint) -> uint; -} - -pub trait ReaderUtil { - - /// Read len bytes into a new vec. - fn read_bytes(&self, len: uint); -} - -impl ReaderUtil for T { - - fn read_bytes(&self, len: uint) { - let mut count = self.read(&mut [0], len); - } - -} - -struct S { - x: int, - y: int -} - -impl Reader for S { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - 0 - } -} - -pub fn main() { - let x = S { x: 1, y: 2 }; - let x = @x as @Reader; - x.read_bytes(0); -} diff --git a/src/test/run-pass/explicit-self-objects-ext-2.rs b/src/test/run-pass/explicit-self-objects-ext-2.rs deleted file mode 100644 index 92f745d7d538..000000000000 --- a/src/test/run-pass/explicit-self-objects-ext-2.rs +++ /dev/null @@ -1,39 +0,0 @@ -pub trait Reader { - // FIXME (#2004): Seekable really should be orthogonal. - - /// Read up to len bytes (or EOF) and put them into bytes (which - /// must be at least len bytes long). Return number of bytes read. - // FIXME (#2982): This should probably return an error. - fn read(&self, bytes: &mut [u8], len: uint) -> uint; -} - -pub trait ReaderUtil { - - /// Read len bytes into a new vec. - fn read_bytes(&self, len: uint); -} - -impl ReaderUtil for T { - - fn read_bytes(&self, len: uint) { - let mut count = self.read(&mut [0], len); - } - -} - -struct S { - x: int, - y: int -} - -impl Reader for S { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - 0 - } -} - -pub fn main() { - let x = S { x: 1, y: 2 }; - let x = @x as @Reader; - x.read_bytes(0); -} diff --git a/src/test/run-pass/explicit-self-objects-ext-3.rs b/src/test/run-pass/explicit-self-objects-ext-3.rs deleted file mode 100644 index 2cfd327dc4e5..000000000000 --- a/src/test/run-pass/explicit-self-objects-ext-3.rs +++ /dev/null @@ -1,39 +0,0 @@ -pub trait Reader { - // FIXME (#2004): Seekable really should be orthogonal. - - /// Read up to len bytes (or EOF) and put them into bytes (which - /// must be at least len bytes long). Return number of bytes read. - // FIXME (#2982): This should probably return an error. - fn read(&self, bytes: &mut [u8], len: uint) -> uint; -} - -pub trait ReaderUtil { - - /// Read len bytes into a new vec. - fn read_bytes(len: uint); -} - -impl ReaderUtil for T { - - fn read_bytes(len: uint) { - let mut count = self.read(&mut [0], len); - } - -} - -struct S { - x: int, - y: int -} - -impl Reader for S { - fn read(&self, bytes: &mut [u8], len: uint) -> uint { - 0 - } -} - -pub fn main() { - let x = S { x: 1, y: 2 }; - let x = @x as @Reader; - x.read_bytes(0); -} diff --git a/src/test/run-pass/explicit-self-objects-ext-4.rs b/src/test/run-pass/explicit-self-objects-ext-4.rs deleted file mode 100644 index 3945be779041..000000000000 --- a/src/test/run-pass/explicit-self-objects-ext-4.rs +++ /dev/null @@ -1,39 +0,0 @@ -pub trait Reader { - // FIXME (#2004): Seekable really should be orthogonal. - - /// Read up to len bytes (or EOF) and put them into bytes (which - /// must be at least len bytes long). Return number of bytes read. - // FIXME (#2982): This should probably return an error. - fn read(bytes: &mut [u8], len: uint) -> uint; -} - -pub trait ReaderUtil { - - /// Read len bytes into a new vec. - fn read_bytes(len: uint); -} - -impl ReaderUtil for T { - - fn read_bytes(len: uint) { - let mut count = self.read(&mut [0], len); - } - -} - -struct S { - x: int, - y: int -} - -impl Reader for S { - fn read(bytes: &mut [u8], len: uint) -> uint { - 0 - } -} - -pub fn main() { - let x = S { x: 1, y: 2 }; - let x = @x as @Reader; - x.read_bytes(0); -} diff --git a/src/test/run-pass/issue-2611.rs b/src/test/run-pass/issue-2611.rs index 7b3247fafc7d..83cedc0fe502 100644 --- a/src/test/run-pass/issue-2611.rs +++ b/src/test/run-pass/issue-2611.rs @@ -11,12 +11,12 @@ use core::iter::BaseIter; trait FlatMapToVec { - fn flat_map_to_vec>(op: fn(&A) -> IB) -> ~[B]; + fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B]; } -impl FlatMapToVec for BaseIter { - fn flat_map_to_vec>(op: fn(&A) -> IB) -> ~[B] { - iter::flat_map_to_vec(&self, op) +impl FlatMapToVec for ~[A] { + fn flat_map_to_vec>(&self, op: fn(&A) -> IB) -> ~[B] { + iter::flat_map_to_vec(self, op) } } diff --git a/src/test/run-pass/issue-3168.rs b/src/test/run-pass/issue-3168.rs index e0ec62ff255a..b0a3223bb3bc 100644 --- a/src/test/run-pass/issue-3168.rs +++ b/src/test/run-pass/issue-3168.rs @@ -18,13 +18,13 @@ pub fn main() { p2.recv(); error!("sibling fails"); fail!(); - } + } let (p3,c3) = comm::stream(); c.send(c3); c2.send(()); error!("child blocks"); p3.recv(); - }; + }; error!("parent tries"); assert !p.recv().try_send(()); error!("all done!"); diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs index 8749c1cb1133..01f68929b90a 100644 --- a/src/test/run-pass/pipe-presentation-examples.rs +++ b/src/test/run-pass/pipe-presentation-examples.rs @@ -17,6 +17,7 @@ use double_buffer::client::*; use double_buffer::give_buffer; +use core::comm::Selectable; macro_rules! select_if ( { diff --git a/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs b/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs index f537357d3ce1..f344837a22d7 100644 --- a/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs +++ b/src/test/run-pass/trait-inheritance-cross-trait-call-xc.rs @@ -13,7 +13,9 @@ extern mod aux(name = "trait_inheritance_cross_trait_call_xc_aux"); -trait Bar : aux::Foo { +use aux::Foo; + +trait Bar : Foo { fn g() -> int; }