about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/comm.rs75
-rw-r--r--src/libcore/path.rs21
-rw-r--r--src/librustc/middle/typeck/coherence.rs101
-rw-r--r--src/libstd/future.rs13
-rw-r--r--src/libstd/workcache.rs13
-rw-r--r--src/libsyntax/ext/auto_encode.rs45
-rw-r--r--src/libsyntax/fold.rs6
-rw-r--r--src/test/auxiliary/issue-2526.rs3
8 files changed, 193 insertions, 84 deletions
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<T> = oneshot::client::Oneshot<T>;
+pub struct ChanOne<T> {
+    contents: oneshot::client::Oneshot<T>
+}
+
+impl<T> ChanOne<T> {
+    pub fn new(contents: oneshot::client::Oneshot<T>) -> ChanOne<T> {
+        ChanOne {
+            contents: contents
+        }
+    }
+}
+
 /// The receive end of a oneshot pipe.
-pub type PortOne<T> = oneshot::server::Oneshot<T>;
+pub struct PortOne<T> {
+    contents: oneshot::server::Oneshot<T>
+}
+
+impl<T> PortOne<T> {
+    pub fn new(contents: oneshot::server::Oneshot<T>) -> PortOne<T> {
+        PortOne {
+            contents: contents
+        }
+    }
+}
 
 /// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
 pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
     let (chan, port) = oneshot::init();
-    (port, chan)
+    (PortOne::new(port), ChanOne::new(chan))
 }
 
 pub impl<T: Owned> PortOne<T> {
     fn recv(self) -> T { recv_one(self) }
     fn try_recv(self) -> Option<T> { try_recv_one(self) }
+    fn unwrap(self) -> oneshot::server::Oneshot<T> {
+        match self {
+            PortOne { contents: s } => s
+        }
+    }
 }
 
 pub impl<T: Owned> ChanOne<T> {
     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<T> {
+        match self {
+            ChanOne { contents: s } => s
+        }
+    }
 }
 
 /**
@@ -420,33 +451,47 @@ pub impl<T: Owned> ChanOne<T> {
  * closed.
  */
 pub fn recv_one<T: Owned>(port: PortOne<T>) -> 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<T: Owned> (port: PortOne<T>) -> Option<T> {
-    let message = try_recv(port);
-
-    if message.is_none() { None }
-    else {
-        let oneshot::send(message) = message.unwrap();
-        Some(message)
+    match port {
+        PortOne { contents: port } => {
+            let message = try_recv(port);
+
+            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<T: Owned>(chan: ChanOne<T>, 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<T: Owned>(chan: ChanOne<T>, data: T)
-        -> bool {
-    oneshot::client::try_send(chan, data).is_some()
+pub fn try_send_one<T: Owned>(chan: ChanOne<T>, 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 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");
-                                }
+                            let trait_def_id =
+                                self.trait_ref_to_trait_def_id(trait_ref);
 
-                                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<A>(val: A) -> Future<A> {
     Future {state: Forced(val)}
 }
 
-pub fn from_port<A:Owned>(port: PortOne<A>) ->
-        Future<A> {
+pub fn from_port<A:Owned>(port: PortOne<A>) -> Future<A> {
     /*!
      * Create a future from a port
      *
@@ -131,7 +130,7 @@ pub fn from_port<A:Owned>(port: PortOne<A>) ->
 
     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<A:Owned>(blk: ~fn() -> A) -> Future<A> {
      * 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<T:Owned +
         None => 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::TyParamBound>)
+                 -> 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<context_res>;
 
-pub impl context {
-    fn socket(&self) { }
-}