Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libcore: Move Cell to core and de-~mut core and std #5108

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libstd/cell.rs → src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::option;
use core::prelude::*;
use option;
use prelude::*;

/// A dynamic, mutable location.
///
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/core.rc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue:
#[warn(vecs_implicitly_copyable)];
#[deny(non_camel_case_types)];
#[allow(deprecated_self)];
#[allow(deprecated_mutable_fields)];

/* The Prelude. */

Expand Down Expand Up @@ -142,6 +143,7 @@ pub mod dlist;
#[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"]
pub mod dlist_iter;
pub mod hashmap;
pub mod cell;


/* Tasks and communication */
Expand Down
17 changes: 7 additions & 10 deletions src/libcore/pipes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bounded and unbounded protocols allows for less code duplication.

use cmp::Eq;
use cast::{forget, reinterpret_cast, transmute};
use cell::Cell;
use either::{Either, Left, Right};
use kinds::Owned;
use libc;
Expand Down Expand Up @@ -917,11 +918,9 @@ pub fn spawn_service<T:Owned,Tb:Owned>(

// This is some nasty gymnastics required to safely move the pipe
// into a new task.
let server = ~mut Some(server);
do task::spawn || {
let mut server_ = None;
server_ <-> *server;
service(option::unwrap(server_))
let server = Cell(server);
do task::spawn {
service(server.take());
}

client
Expand All @@ -941,11 +940,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(

// This is some nasty gymnastics required to safely move the pipe
// into a new task.
let server = ~mut Some(server);
do task::spawn || {
let mut server_ = None;
server_ <-> *server;
service(option::unwrap(server_))
let server = Cell(server);
do task::spawn {
service(server.take())
}

client
Expand Down
40 changes: 23 additions & 17 deletions src/libcore/private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,14 @@ fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
* Shared state & exclusive ARC
****************************************************************************/

struct UnwrapProtoInner {
contents: Option<(comm::ChanOne<()>, comm::PortOne<bool>)>,
}

// An unwrapper uses this protocol to communicate with the "other" task that
// drops the last refcount on an arc. Unfortunately this can't be a proper
// pipe protocol because the unwrapper has to access both stages at once.
type UnwrapProto = ~mut Option<(comm::ChanOne<()>, comm::PortOne<bool>)>;
type UnwrapProto = ~UnwrapProtoInner;

struct ArcData<T> {
mut count: libc::intptr_t,
Expand Down Expand Up @@ -139,9 +143,10 @@ struct ArcDestruct<T> {
// reference. In effect, being here means we're the only
// *awake* task with the data.
if data.unwrapper != 0 {
let p: UnwrapProto =
let mut p: UnwrapProto =
cast::reinterpret_cast(&data.unwrapper);
let (message, response) = option::swap_unwrap(p);
let (message, response) =
option::swap_unwrap(&mut p.contents);
// Send 'ready' and wait for a response.
comm::send_one(message, ());
// Unkillable wait. Message guaranteed to come.
Expand Down Expand Up @@ -196,7 +201,9 @@ pub unsafe fn unwrap_shared_mutable_state<T:Owned>(rc: SharedMutableState<T>)
let ptr: ~ArcData<T> = cast::reinterpret_cast(&rc.data);
let (p1,c1) = comm::oneshot(); // ()
let (p2,c2) = comm::oneshot(); // bool
let server: UnwrapProto = ~mut Some((c1,p2));
let mut server: UnwrapProto = ~UnwrapProtoInner {
contents: Some((c1,p2))
};
let serverp: int = cast::transmute(server);
// Try to put our server end in the unwrapper slot.
if compare_and_swap(&mut ptr.unwrapper, 0, serverp) {
Expand Down Expand Up @@ -409,8 +416,9 @@ pub fn unwrap_exclusive<T:Owned>(arc: Exclusive<T>) -> T {
pub mod tests {
use core::option::{None, Some};

use option;
use cell::Cell;
use comm;
use option;
use private::{exclusive, unwrap_exclusive};
use result;
use task;
Expand All @@ -423,7 +431,7 @@ pub mod tests {
let num_tasks = 10;
let count = 10;

let total = exclusive(~mut 0);
let total = exclusive(~0);

for uint::range(0, num_tasks) |_i| {
let total = total.clone();
Expand Down Expand Up @@ -472,21 +480,20 @@ pub mod tests {
#[test]
pub fn exclusive_unwrap_contended() {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
do task::spawn || {
let x2 = option::swap_unwrap(x2);
let x2 = Cell(x.clone());
do task::spawn {
let x2 = option::swap_unwrap(x2.take());
do x2.with |_hello| { }
task::yield();
}
assert unwrap_exclusive(x) == ~~"hello";

// Now try the same thing, but with the child task blocking.
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
let x2 = Cell(x.clone());
let mut res = None;
do task::task().future_result(|+r| res = Some(r)).spawn
|| {
let x2 = option::swap_unwrap(x2);
do task::task().future_result(|+r| res = Some(r)).spawn {
let x2 = x2.take();
assert unwrap_exclusive(x2) == ~~"hello";
}
// Have to get rid of our reference before blocking.
Expand All @@ -498,11 +505,10 @@ pub mod tests {
#[test] #[should_fail] #[ignore(cfg(windows))]
pub fn exclusive_unwrap_conflict() {
let x = exclusive(~~"hello");
let x2 = ~mut Some(x.clone());
let x2 = Cell(x.clone());
let mut res = None;
do task::task().future_result(|+r| res = Some(r)).spawn
|| {
let x2 = option::swap_unwrap(x2);
do task::task().future_result(|+r| res = Some(r)).spawn {
let x2 = x2.take();
assert unwrap_exclusive(x2) == ~~"hello";
}
assert unwrap_exclusive(x) == ~~"hello";
Expand Down
25 changes: 12 additions & 13 deletions src/libcore/private/weak_task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ it is running, sending a notification to the task that the runtime
is trying to shut down.
*/

use cell::Cell;
use comm::{GenericSmartChan, stream};
use comm::{Port, Chan, SharedChan, GenericChan, GenericPort};
use hashmap::linear::LinearMap;
use ops::Drop;
use option::{Some, None, swap_unwrap};
use private::at_exit::at_exit;
use private::global::global_data_clone_create;
use private::finally::Finally;
use comm::{Port, Chan, SharedChan, GenericChan,
GenericPort, GenericSmartChan, stream};
use task::{Task, task, spawn};
use private::global::global_data_clone_create;
use task::rt::{task_id, get_task_id};
use hashmap::linear::LinearMap;
use ops::Drop;
use task::{Task, task, spawn};

type ShutdownMsg = ();

Expand All @@ -37,14 +38,13 @@ pub unsafe fn weaken_task(f: &fn(Port<ShutdownMsg>)) {
let service = global_data_clone_create(global_data_key,
create_global_service);
let (shutdown_port, shutdown_chan) = stream::<ShutdownMsg>();
let shutdown_port = ~mut Some(shutdown_port);
let shutdown_port = Cell(shutdown_port);
let task = get_task_id();
// Expect the weak task service to be alive
assert service.try_send(RegisterWeakTask(task, shutdown_chan));
unsafe { rust_dec_kernel_live_count(); }
do fn&() {
let shutdown_port = swap_unwrap(&mut *shutdown_port);
f(shutdown_port)
f(shutdown_port.take())
}.finally || {
unsafe { rust_inc_kernel_live_count(); }
// Service my have already exited
Expand All @@ -67,16 +67,15 @@ fn create_global_service() -> ~WeakTaskService {

debug!("creating global weak task service");
let (port, chan) = stream::<ServiceMsg>();
let port = ~mut Some(port);
let port = Cell(port);
let chan = SharedChan(chan);
let chan_clone = chan.clone();

do task().unlinked().spawn {
debug!("running global weak task service");
let port = swap_unwrap(&mut *port);
let port = ~mut Some(port);
let port = Cell(port.take());
do fn&() {
let port = swap_unwrap(&mut *port);
let port = port.take();
// The weak task service is itself a weak task
debug!("weakening the weak service task");
unsafe { rust_dec_kernel_live_count(); }
Expand Down
1 change: 0 additions & 1 deletion src/libcore/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,6 @@ fn test_repr() {
exact_test(&(@10), "@10");
exact_test(&(@mut 10), "@10");
exact_test(&(~10), "~10");
exact_test(&(~mut 10), "~mut 10");
exact_test(&(&10), "&10");
let mut x = 10;
exact_test(&(&mut x), "&mut 10");
Expand Down
7 changes: 4 additions & 3 deletions src/libcore/task/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
*/

use cast;
use cell::Cell;
use cmp;
use cmp::Eq;
use iter;
Expand Down Expand Up @@ -397,9 +398,9 @@ impl TaskBuilder {
}
/// Runs a task, while transfering ownership of one argument to the child.
fn spawn_with<A:Owned>(arg: A, f: fn~(v: A)) {
let arg = ~mut Some(arg);
do self.spawn || {
f(option::swap_unwrap(arg))
let arg = Cell(arg);
do self.spawn {
f(arg.take());
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/libcore/task/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#[doc(hidden)]; // FIXME #3538

use cast;
use cell::Cell;
use container::Map;
use option;
use comm::{Chan, GenericChan, GenericPort, Port, stream};
Expand Down Expand Up @@ -530,11 +531,11 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
gen_child_taskgroup(opts.linked, opts.supervised);

unsafe {
let child_data = ~mut Some((child_tg, ancestors, f));
let child_data = Cell((child_tg, ancestors, f));
// Being killed with the unsafe task/closure pointers would leak them.
do unkillable {
// Agh. Get move-mode items into the closure. FIXME (#2829)
let (child_tg, ancestors, f) = option::swap_unwrap(child_data);
let (child_tg, ancestors, f) = child_data.take();
// Create child task.
let new_task = match opts.sched.mode {
DefaultScheduler => rt::new_task(),
Expand Down Expand Up @@ -571,10 +572,10 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
ancestors: AncestorList, is_main: bool,
notify_chan: Option<Chan<TaskResult>>,
f: fn~()) -> fn~() {
let child_data = ~mut Some((child_arc, ancestors));
let child_data = Cell((child_arc, ancestors));
return fn~() {
// Agh. Get move-mode items into the closure. FIXME (#2829)
let mut (child_arc, ancestors) = option::swap_unwrap(child_data);
let mut (child_arc, ancestors) = child_data.take();
// Child task runs this code.

// Even if the below code fails to kick the child off, we must
Expand Down
29 changes: 29 additions & 0 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub enum lint {
type_limits,
default_methods,
deprecated_self,
deprecated_mutable_fields,

managed_heap_memory,
owned_heap_memory,
Expand Down Expand Up @@ -255,6 +256,13 @@ pub fn get_lint_dict() -> LintDict {
default: warn
}),

(@~"deprecated_mutable_fields",
@LintSpec {
lint: deprecated_mutable_fields,
desc: "deprecated mutable fields in structures",
default: deny
}),

/* FIXME(#3266)--make liveness warnings lintable
(@~"unused_variable",
@LintSpec {
Expand Down Expand Up @@ -488,6 +496,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
check_item_type_limits(cx, i);
check_item_default_methods(cx, i);
check_item_deprecated_self(cx, i);
check_item_deprecated_mutable_fields(cx, i);
}

// Take a visitor, and modify it so that it will not proceed past subitems.
Expand Down Expand Up @@ -705,6 +714,26 @@ fn check_item_deprecated_self(cx: ty::ctxt, item: @ast::item) {
}
}

fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
match item.node {
ast::item_struct(struct_def, _) => {
for struct_def.fields.each |field| {
match field.node.kind {
ast::named_field(_, ast::struct_mutable, _) => {
cx.sess.span_lint(deprecated_mutable_fields,
item.id,
item.id,
field.span,
~"mutable fields are deprecated");
}
ast::named_field(*) | ast::unnamed_field => {}
}
}
}
_ => {}
}
}

fn check_item_structural_records(cx: ty::ctxt, it: @ast::item) {
let visit = item_stopping_visitor(
visit::mk_simple_visitor(@visit::SimpleVisitor {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/infer/region_inference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ use syntax::codemap;
use util::common::indenter;
use util::ppaux::note_and_explain_region;

use core::cell::{Cell, empty_cell};
use core::cmp;
use core::dvec::DVec;
use core::to_bytes;
Expand All @@ -557,7 +558,6 @@ use core::vec;
use result::Result;
use result::{Ok, Err};
use std::oldmap::HashMap;
use std::cell::{Cell, empty_cell};
use std::list::{List, Nil, Cons};
use syntax::codemap::span;
use syntax::codemap;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/rustc.rc
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ fails without recording a fatal error then we've encountered a compiler
bug and need to present an error.
*/
pub fn monitor(+f: fn~(diagnostic::Emitter)) {
use core::cell::Cell;
use core::comm::*;
use std::cell::Cell;
let (p, ch) = stream();
let ch = SharedChan(ch);
let ch_capture = ch.clone();
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/astsrv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ use core::prelude::*;

use parse;
use util;
use std::cell::Cell;

use core::cell::Cell;
use core::comm::{stream, Chan, SharedChan, Port};
use core::vec;
use core::ops::Drop;
Expand Down
Loading