diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index abe8bd7c8d1..522eebaf327 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -395,24 +395,55 @@ pub mod oneshot { } /// The send end of a oneshot pipe. -pub type ChanOne = oneshot::client::Oneshot; +pub struct ChanOne { + contents: oneshot::client::Oneshot +} + +impl ChanOne { + pub fn new(contents: oneshot::client::Oneshot) -> ChanOne { + ChanOne { + contents: contents + } + } +} + /// The receive end of a oneshot pipe. -pub type PortOne = oneshot::server::Oneshot; +pub struct PortOne { + contents: oneshot::server::Oneshot +} + +impl PortOne { + pub fn new(contents: oneshot::server::Oneshot) -> PortOne { + PortOne { + contents: contents + } + } +} /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair. pub fn oneshot() -> (PortOne, ChanOne) { let (chan, port) = oneshot::init(); - (port, chan) + (PortOne::new(port), ChanOne::new(chan)) } pub impl PortOne { fn recv(self) -> T { recv_one(self) } fn try_recv(self) -> Option { try_recv_one(self) } + fn unwrap(self) -> oneshot::server::Oneshot { + match self { + PortOne { contents: s } => s + } + } } pub impl ChanOne { fn send(self, data: T) { send_one(self, data) } fn try_send(self, data: T) -> bool { try_send_one(self, data) } + fn unwrap(self) -> oneshot::client::Oneshot { + match self { + ChanOne { contents: s } => s + } + } } /** @@ -420,33 +451,47 @@ pub impl ChanOne { * closed. */ pub fn recv_one(port: PortOne) -> T { - let oneshot::send(message) = recv(port); - message + match port { + PortOne { contents: port } => { + let oneshot::send(message) = recv(port); + message + } + } } /// Receive a message from a oneshot pipe unless the connection was closed. pub fn try_recv_one (port: PortOne) -> Option { - let message = try_recv(port); + match port { + PortOne { contents: port } => { + let message = try_recv(port); - if message.is_none() { None } - else { - let oneshot::send(message) = message.unwrap(); - Some(message) + if message.is_none() { + None + } else { + let oneshot::send(message) = message.unwrap(); + Some(message) + } + } } } /// Send a message on a oneshot pipe, failing if the connection was closed. pub fn send_one(chan: ChanOne, data: T) { - oneshot::client::send(chan, data); + match chan { + ChanOne { contents: chan } => oneshot::client::send(chan, data), + } } /** * Send a message on a oneshot pipe, or return false if the connection was * closed. */ -pub fn try_send_one(chan: ChanOne, data: T) - -> bool { - oneshot::client::try_send(chan, data).is_some() +pub fn try_send_one(chan: ChanOne, data: T) -> bool { + match chan { + ChanOne { contents: chan } => { + oneshot::client::try_send(chan, data).is_some() + } + } } diff --git a/src/libcore/path.rs b/src/libcore/path.rs index edc61299af9..462c5be3bcf 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -21,6 +21,11 @@ use str; use to_str::ToStr; use ascii::{AsciiCast, AsciiStr}; +#[cfg(windows)] +pub use Path = self::WindowsPath; +#[cfg(unix)] +pub use Path = self::PosixPath; + #[deriving(Clone, Eq)] pub struct WindowsPath { host: Option<~str>, @@ -72,22 +77,6 @@ pub trait GenericPath { fn is_absolute(&self) -> bool; } -#[cfg(windows)] -pub type Path = WindowsPath; - -#[cfg(windows)] -pub fn Path(s: &str) -> Path { - WindowsPath(s) -} - -#[cfg(unix)] -pub type Path = PosixPath; - -#[cfg(unix)] -pub fn Path(s: &str) -> Path { - PosixPath(s) -} - #[cfg(target_os = "linux")] #[cfg(target_os = "android")] mod stat { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index 14c9bc36d7f..05b2f6f577b 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -38,8 +38,9 @@ use middle::typeck::infer::combine::Combine; use middle::typeck::infer::InferCtxt; use middle::typeck::infer::{new_infer_ctxt, resolve_ivar}; use middle::typeck::infer::{resolve_nested_tvar, resolve_type}; -use syntax::ast::{crate, def_id, def_mod, def_trait}; -use syntax::ast::{item, item_impl, item_mod, local_crate, method, trait_ref}; +use syntax::ast::{crate, def_id, def_mod, def_struct, def_trait, def_ty}; +use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct}; +use syntax::ast::{local_crate, method, trait_ref, ty_path}; use syntax::ast; use syntax::ast_map::node_item; use syntax::ast_map; @@ -661,7 +662,19 @@ pub impl CoherenceChecker { // Then visit the module items. visit_mod(module_, item.span, item.id, (), visitor); } - item_impl(_, opt_trait, _, _) => { + item_impl(_, None, ast_ty, _) => { + if !self.ast_type_is_defined_in_local_crate(ast_ty) { + // This is an error. + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot associate methods with \ + a type outside the crate the \ + type is defined in; define \ + and implement a trait or new \ + type instead"); + } + } + item_impl(_, Some(trait_ref), _, _) => { // `for_ty` is `Type` in `impl Trait for Type` let for_ty = ty::node_id_to_type(self.crate_context.tcx, @@ -671,40 +684,16 @@ pub impl CoherenceChecker { // type. This still might be OK if the trait is // defined in the same crate. - match opt_trait { - None => { - // There is no trait to implement, so - // this is an error. + let trait_def_id = + self.trait_ref_to_trait_def_id(trait_ref); - let session = self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot implement \ - inherent methods for a \ - type outside the crate \ - the type was defined \ - in; define and \ - implement a trait or \ - new type instead"); - } - - Some(trait_ref) => { - // This is OK if and only if the trait was - // defined in this crate. - - let trait_def_id = - self.trait_ref_to_trait_def_id( - trait_ref); - - if trait_def_id.crate != local_crate { - let session = self.crate_context.tcx.sess; - session.span_err(item.span, - ~"cannot provide an \ - extension \ - implementation for a \ - trait not defined in \ - this crate"); - } - } + if trait_def_id.crate != local_crate { + let session = self.crate_context.tcx.sess; + session.span_err(item.span, + ~"cannot provide an \ + extension implementation \ + for a trait not defined \ + in this crate"); } } @@ -754,6 +743,46 @@ pub impl CoherenceChecker { } } + /// For coherence, when we have `impl Type`, we need to guarantee that + /// `Type` is "local" to the crate. For our purposes, this means that it + /// must precisely name some nominal type defined in this crate. + pub fn ast_type_is_defined_in_local_crate(&self, original_type: @ast::Ty) + -> bool { + match original_type.node { + ty_path(_, path_id) => { + match *self.crate_context.tcx.def_map.get(&path_id) { + def_ty(def_id) | def_struct(def_id) => { + if def_id.crate != local_crate { + return false; + } + + // Make sure that this type precisely names a nominal + // type. + match self.crate_context + .tcx + .items + .find(&def_id.node) { + None => { + self.crate_context.tcx.sess.span_bug( + original_type.span, + ~"resolve didn't resolve this type?!"); + } + Some(&node_item(item, _)) => { + match item.node { + item_struct(*) | item_enum(*) => true, + _ => false, + } + } + Some(_) => false, + } + } + _ => false + } + } + _ => false + } + } + // Converts an implementation in the AST to an Impl structure. fn create_impl_from_item(&self, item: @item) -> @Impl { fn add_provided_methods(all_methods: &mut ~[@MethodInfo], diff --git a/src/libstd/future.rs b/src/libstd/future.rs index 264f3072cb1..c6c593d7b4a 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -23,7 +23,7 @@ use core::cast; use core::cell::Cell; -use core::comm::{oneshot, PortOne, send_one}; +use core::comm::{ChanOne, PortOne, oneshot, send_one}; use core::pipes::recv; use core::task; @@ -120,8 +120,7 @@ pub fn from_value(val: A) -> Future { Future {state: Forced(val)} } -pub fn from_port(port: PortOne) -> - Future { +pub fn from_port(port: PortOne) -> Future { /*! * Create a future from a port * @@ -131,7 +130,7 @@ pub fn from_port(port: PortOne) -> let port = Cell(port); do from_fn || { - let port = port.take(); + let port = port.take().unwrap(); match recv(port) { oneshot::send(data) => data } @@ -158,10 +157,10 @@ pub fn spawn(blk: ~fn() -> A) -> Future { * value of the future. */ - let (chan, port) = oneshot::init(); + let (port, chan) = oneshot(); let chan = Cell(chan); - do task::spawn || { + do task::spawn { let chan = chan.take(); send_one(chan, blk()); } @@ -186,7 +185,7 @@ mod test { #[test] fn test_from_port() { - let (ch, po) = oneshot::init(); + let (ch, po) = oneshot(); send_one(ch, ~"whale"); let f = from_port(po); assert!(f.get() == ~"whale"); diff --git a/src/libstd/workcache.rs b/src/libstd/workcache.rs index ae09b9b9026..bb4a9e97ea1 100644 --- a/src/libstd/workcache.rs +++ b/src/libstd/workcache.rs @@ -16,10 +16,13 @@ use serialize::{Encoder, Encodable, Decoder, Decodable}; use sort; use core::cell::Cell; -use core::comm::{oneshot, PortOne, send_one}; +use core::cmp; +use core::comm::{ChanOne, PortOne, oneshot, send_one}; +use core::either::{Either, Left, Right}; +use core::hashmap::HashMap; +use core::io; use core::pipes::recv; use core::run; -use core::hashmap::HashMap; use core::to_bytes; /** @@ -340,13 +343,13 @@ impl TPrep for Prep { } _ => { - let (chan, port) = oneshot::init(); + let (port, chan) = oneshot(); let mut blk = None; blk <-> bo; let blk = blk.unwrap(); let chan = Cell(chan); - do task::spawn || { + do task::spawn { let exe = Exec { discovered_inputs: WorkMap::new(), discovered_outputs: WorkMap::new(), @@ -383,7 +386,7 @@ fn unwrap fail!(), Some(Left(v)) => v, Some(Right(port)) => { - let (exe, v) = match recv(port) { + let (exe, v) = match recv(port.unwrap()) { oneshot::send(data) => data }; diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index da7b9570131..2ceb6f0c4bb 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -215,7 +215,50 @@ pub fn expand_auto_decode( } } -priv impl @ext_ctxt { +trait ExtCtxtMethods { + fn bind_path(&self, + span: span, + ident: ast::ident, + path: @ast::Path, + bounds: @OptVec) + -> ast::TyParam; + fn expr(&self, span: span, node: ast::expr_) -> @ast::expr; + fn path(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; + fn path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::Path; + fn path_tps(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty]) + -> @ast::Path; + fn path_tps_global(&self, + span: span, + strs: ~[ast::ident], + tps: ~[@ast::Ty]) + -> @ast::Path; + fn ty_path(&self, span: span, strs: ~[ast::ident], tps: ~[@ast::Ty]) + -> @ast::Ty; + fn binder_pat(&self, span: span, nm: ast::ident) -> @ast::pat; + fn stmt(&self, expr: @ast::expr) -> @ast::stmt; + fn lit_str(&self, span: span, s: @~str) -> @ast::expr; + fn lit_uint(&self, span: span, i: uint) -> @ast::expr; + fn lambda(&self, blk: ast::blk) -> @ast::expr; + fn blk(&self, span: span, stmts: ~[@ast::stmt]) -> ast::blk; + fn expr_blk(&self, expr: @ast::expr) -> ast::blk; + fn expr_path(&self, span: span, strs: ~[ast::ident]) -> @ast::expr; + fn expr_path_global(&self, span: span, strs: ~[ast::ident]) -> @ast::expr; + fn expr_var(&self, span: span, var: ~str) -> @ast::expr; + fn expr_field(&self, span: span, expr: @ast::expr, ident: ast::ident) + -> @ast::expr; + fn expr_call(&self, span: span, expr: @ast::expr, args: ~[@ast::expr]) + -> @ast::expr; + fn expr_method_call(&self, + span: span, + expr: @ast::expr, + ident: ast::ident, + args: ~[@ast::expr]) + -> @ast::expr; + fn lambda_expr(&self, expr: @ast::expr) -> @ast::expr; + fn lambda_stmts(&self, span: span, stmts: ~[@ast::stmt]) -> @ast::expr; +} + +impl ExtCtxtMethods for @ext_ctxt { fn bind_path( &self, _span: span, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cee1f531176..d82608846ab 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -867,7 +867,11 @@ impl ast_fold for AstFoldFns { } } -pub impl @ast_fold { +pub trait AstFoldExtensions { + fn fold_attributes(&self, attrs: ~[attribute]) -> ~[attribute]; +} + +impl AstFoldExtensions for @ast_fold { fn fold_attributes(&self, attrs: ~[attribute]) -> ~[attribute] { attrs.map(|x| fold_attribute_(*x, *self)) } diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs index 775955ff38c..fa32b9603a5 100644 --- a/src/test/auxiliary/issue-2526.rs +++ b/src/test/auxiliary/issue-2526.rs @@ -56,6 +56,3 @@ fn context_res() -> context_res { pub type context = arc_destruct; -pub impl context { - fn socket(&self) { } -}