Skip to content

Commit b9ff86e

Browse files
committed
auto merge of #13835 : alexcrichton/rust/localdata, r=brson
This commit brings the local_data api up to modern rust standards with a few key improvements: * All functionality is now exposed as a method on the keys themselves. Instead of importing std::local_data, you now use "key.set()" and "key.get()". * All closures have been removed in favor of RAII functionality. This means that get() and get_mut() no long require closures, but rather return Option<SmartPointer> where the smart pointer takes care of relinquishing the borrow and also implements the necessary Deref traits * The modify() function was removed to cut the local_data interface down to its bare essentials (similarly to how RefCell removed set/get). [breaking-change]
2 parents c39b1cb + ab92ea5 commit b9ff86e

File tree

22 files changed

+442
-658
lines changed

22 files changed

+442
-658
lines changed

src/libcollections/hashmap.rs

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,8 +1617,7 @@ mod test_map {
16171617
use std::cmp::Equiv;
16181618
use std::hash::Hash;
16191619
use std::iter::{Iterator,range_inclusive,range_step_inclusive};
1620-
use std::local_data;
1621-
use std::vec;
1620+
use std::cell::RefCell;
16221621

16231622
struct KindaIntLike(int);
16241623

@@ -1657,7 +1656,7 @@ mod test_map {
16571656
assert_eq!(*m.find(&2).unwrap(), 4);
16581657
}
16591658

1660-
local_data_key!(drop_vector: vec::Vec<int>)
1659+
local_data_key!(drop_vector: RefCell<Vec<int>>)
16611660

16621661
#[deriving(Hash, Eq, TotalEq)]
16631662
struct Dropable {
@@ -1667,75 +1666,72 @@ mod test_map {
16671666

16681667
impl Dropable {
16691668
fn new(k: uint) -> Dropable {
1670-
local_data::get_mut(drop_vector,
1671-
|v| { v.unwrap().as_mut_slice()[k] += 1; });
1669+
let v = drop_vector.get().unwrap();
1670+
v.borrow_mut().as_mut_slice()[k] += 1;
16721671

16731672
Dropable { k: k }
16741673
}
16751674
}
16761675

16771676
impl Drop for Dropable {
16781677
fn drop(&mut self) {
1679-
local_data::get_mut(drop_vector, |v|
1680-
{ v.unwrap().as_mut_slice()[self.k] -= 1; });
1678+
let v = drop_vector.get().unwrap();
1679+
v.borrow_mut().as_mut_slice()[self.k] -= 1;
16811680
}
16821681
}
16831682

16841683
#[test]
16851684
fn test_drops() {
1686-
local_data::set(drop_vector, vec::Vec::from_elem(200, 0));
1685+
drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0))));
16871686

16881687
{
16891688
let mut m = HashMap::new();
16901689

1691-
local_data::get(drop_vector, |v| {
1692-
for i in range(0u, 200) {
1693-
assert_eq!(v.unwrap().as_slice()[i], 0);
1694-
}
1695-
});
1690+
let v = drop_vector.get().unwrap();
1691+
for i in range(0u, 200) {
1692+
assert_eq!(v.borrow().as_slice()[i], 0);
1693+
}
1694+
drop(v);
16961695

16971696
for i in range(0u, 100) {
16981697
let d1 = Dropable::new(i);
16991698
let d2 = Dropable::new(i+100);
17001699
m.insert(d1, d2);
17011700
}
17021701

1703-
local_data::get(drop_vector, |v| {
1704-
for i in range(0u, 200) {
1705-
assert_eq!(v.unwrap().as_slice()[i], 1);
1706-
}
1707-
});
1702+
let v = drop_vector.get().unwrap();
1703+
for i in range(0u, 200) {
1704+
assert_eq!(v.borrow().as_slice()[i], 1);
1705+
}
1706+
drop(v);
17081707

17091708
for i in range(0u, 50) {
17101709
let k = Dropable::new(i);
17111710
let v = m.pop(&k);
17121711

17131712
assert!(v.is_some());
17141713

1715-
local_data::get(drop_vector, |v| {
1716-
assert_eq!(v.unwrap().as_slice()[i], 1);
1717-
assert_eq!(v.unwrap().as_slice()[i+100], 1);
1718-
});
1714+
let v = drop_vector.get().unwrap();
1715+
assert_eq!(v.borrow().as_slice()[i], 1);
1716+
assert_eq!(v.borrow().as_slice()[i+100], 1);
17191717
}
17201718

1721-
local_data::get(drop_vector, |v| {
1722-
for i in range(0u, 50) {
1723-
assert_eq!(v.unwrap().as_slice()[i], 0);
1724-
assert_eq!(v.unwrap().as_slice()[i+100], 0);
1725-
}
1719+
let v = drop_vector.get().unwrap();
1720+
for i in range(0u, 50) {
1721+
assert_eq!(v.borrow().as_slice()[i], 0);
1722+
assert_eq!(v.borrow().as_slice()[i+100], 0);
1723+
}
17261724

1727-
for i in range(50u, 100) {
1728-
assert_eq!(v.unwrap().as_slice()[i], 1);
1729-
assert_eq!(v.unwrap().as_slice()[i+100], 1);
1730-
}
1731-
});
1725+
for i in range(50u, 100) {
1726+
assert_eq!(v.borrow().as_slice()[i], 1);
1727+
assert_eq!(v.borrow().as_slice()[i+100], 1);
1728+
}
17321729
}
17331730

1734-
local_data::get(drop_vector, |v| {
1735-
for i in range(0u, 200) {
1736-
assert_eq!(v.unwrap().as_slice()[i], 0);
1737-
}
1738-
});
1731+
let v = drop_vector.get().unwrap();
1732+
for i in range(0u, 200) {
1733+
assert_eq!(v.borrow().as_slice()[i], 0);
1734+
}
17391735
}
17401736

17411737
#[test]

src/liblog/lib.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ use std::cast;
122122
use std::fmt;
123123
use std::io::LineBufferedWriter;
124124
use std::io;
125-
use std::local_data;
126125
use std::os;
127126
use std::rt;
128127
use std::slice;
@@ -228,7 +227,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
228227
// Completely remove the local logger from TLS in case anyone attempts to
229228
// frob the slot while we're doing the logging. This will destroy any logger
230229
// set during logging.
231-
let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
230+
let mut logger = local_logger.replace(None).unwrap_or_else(|| {
232231
box DefaultLogger { handle: io::stderr() } as Box<Logger:Send>
233232
});
234233
logger.log(&LogRecord {
@@ -238,7 +237,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
238237
module_path: loc.module_path,
239238
line: loc.line,
240239
});
241-
local_data::set(local_logger, logger);
240+
local_logger.replace(Some(logger));
242241
}
243242

244243
/// Getter for the global log level. This is a function so that it can be called
@@ -250,9 +249,7 @@ pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
250249
/// Replaces the task-local logger with the specified logger, returning the old
251250
/// logger.
252251
pub fn set_logger(logger: Box<Logger:Send>) -> Option<Box<Logger:Send>> {
253-
let prev = local_data::pop(local_logger);
254-
local_data::set(local_logger, logger);
255-
return prev;
252+
local_logger.replace(Some(logger))
256253
}
257254

258255
/// A LogRecord is created by the logging macros, and passed as the only

src/librand/lib.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ println!("{:?}", tuple_ptr)
7979
use std::cast;
8080
use std::io::IoResult;
8181
use std::kinds::marker;
82-
use std::local_data;
8382
use std::strbuf::StrBuf;
8483

8584
pub use isaac::{IsaacRng, Isaac64Rng};
@@ -581,9 +580,6 @@ pub struct TaskRng {
581580
marker: marker::NoSend,
582581
}
583582

584-
// used to make space in TLS for a random number generator
585-
local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
586-
587583
/// Retrieve the lazily-initialized task-local random number
588584
/// generator, seeded by the system. Intended to be used in method
589585
/// chaining style, e.g. `task_rng().gen::<int>()`.
@@ -596,7 +592,10 @@ local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
596592
/// the same sequence always. If absolute consistency is required,
597593
/// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
598594
pub fn task_rng() -> TaskRng {
599-
local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
595+
// used to make space in TLS for a random number generator
596+
local_data_key!(TASK_RNG_KEY: Box<TaskRngInner>)
597+
598+
match TASK_RNG_KEY.get() {
600599
None => {
601600
let r = match StdRng::new() {
602601
Ok(r) => r,
@@ -607,12 +606,15 @@ pub fn task_rng() -> TaskRng {
607606
TaskRngReseeder);
608607
let ptr = &mut *rng as *mut TaskRngInner;
609608

610-
local_data::set(TASK_RNG_KEY, rng);
609+
TASK_RNG_KEY.replace(Some(rng));
611610

612611
TaskRng { rng: ptr, marker: marker::NoSend }
613612
}
614-
Some(rng) => TaskRng { rng: &mut **rng, marker: marker::NoSend }
615-
})
613+
Some(rng) => TaskRng {
614+
rng: &**rng as *_ as *mut TaskRngInner,
615+
marker: marker::NoSend
616+
}
617+
}
616618
}
617619

618620
impl Rng for TaskRng {

src/librustc/middle/trans/base.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ use arena::TypedArena;
7474
use libc::c_uint;
7575
use std::c_str::ToCStr;
7676
use std::cell::{Cell, RefCell};
77-
use std::local_data;
7877
use std::rc::Rc;
7978
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
8079
use syntax::ast_util::{local_def, is_local};
@@ -88,43 +87,37 @@ use syntax::{ast, ast_util, ast_map};
8887

8988
use time;
9089

91-
local_data_key!(task_local_insn_key: Vec<&'static str> )
90+
local_data_key!(task_local_insn_key: RefCell<Vec<&'static str>>)
9291

9392
pub fn with_insn_ctxt(blk: |&[&'static str]|) {
94-
local_data::get(task_local_insn_key, |c| {
95-
match c {
96-
Some(ctx) => blk(ctx.as_slice()),
97-
None => ()
98-
}
99-
})
93+
match task_local_insn_key.get() {
94+
Some(ctx) => blk(ctx.borrow().as_slice()),
95+
None => ()
96+
}
10097
}
10198

10299
pub fn init_insn_ctxt() {
103-
local_data::set(task_local_insn_key, Vec::new());
100+
task_local_insn_key.replace(Some(RefCell::new(Vec::new())));
104101
}
105102

106103
pub struct _InsnCtxt { _x: () }
107104

108105
#[unsafe_destructor]
109106
impl Drop for _InsnCtxt {
110107
fn drop(&mut self) {
111-
local_data::modify(task_local_insn_key, |c| {
112-
c.map(|mut ctx| {
113-
ctx.pop();
114-
ctx
115-
})
116-
})
108+
match task_local_insn_key.get() {
109+
Some(ctx) => { ctx.borrow_mut().pop(); }
110+
None => {}
111+
}
117112
}
118113
}
119114

120115
pub fn push_ctxt(s: &'static str) -> _InsnCtxt {
121116
debug!("new InsnCtxt: {}", s);
122-
local_data::modify(task_local_insn_key, |c| {
123-
c.map(|mut ctx| {
124-
ctx.push(s);
125-
ctx
126-
})
127-
});
117+
match task_local_insn_key.get() {
118+
Some(ctx) => ctx.borrow_mut().push(s),
119+
None => {}
120+
}
128121
_InsnCtxt { _x: () }
129122
}
130123

src/librustc/util/common.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,21 @@ use syntax::ast;
1414
use syntax::visit;
1515
use syntax::visit::Visitor;
1616

17-
use std::local_data;
18-
1917
use time;
2018

2119
pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
2220
local_data_key!(depth: uint);
2321
if !do_it { return f(u); }
2422

25-
let old = local_data::get(depth, |d| d.map(|a| *a).unwrap_or(0));
26-
local_data::set(depth, old + 1);
23+
let old = depth.get().map(|d| *d).unwrap_or(0);
24+
depth.replace(Some(old + 1));
2725

2826
let start = time::precise_time_s();
2927
let rv = f(u);
3028
let end = time::precise_time_s();
3129

3230
println!("{}time: {:3.3f} s\t{}", " ".repeat(old), end - start, what);
33-
local_data::set(depth, old);
31+
depth.replace(Some(old));
3432

3533
rv
3634
}

src/librustdoc/clean.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use rustc::metadata::cstore;
2626
use rustc::metadata::csearch;
2727
use rustc::metadata::decoder;
2828

29-
use std::local_data;
3029
use std::strbuf::StrBuf;
3130

3231
use core;
@@ -77,7 +76,7 @@ pub struct Crate {
7776

7877
impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
7978
fn clean(&self) -> Crate {
80-
let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
79+
let cx = super::ctxtkey.get().unwrap();
8180

8281
let mut externs = Vec::new();
8382
cx.sess().cstore.iter_crate_data(|n, meta| {
@@ -251,7 +250,7 @@ impl Clean<Item> for doctree::Module {
251250
// determine if we should display the inner contents or
252251
// the outer `mod` item for the source code.
253252
let where = {
254-
let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
253+
let ctxt = super::ctxtkey.get().unwrap();
255254
let cm = ctxt.sess().codemap();
256255
let outer = cm.lookup_char_pos(self.where_outer.lo);
257256
let inner = cm.lookup_char_pos(self.where_inner.lo);
@@ -726,7 +725,7 @@ impl Clean<Type> for ast::Ty {
726725
fn clean(&self) -> Type {
727726
use syntax::ast::*;
728727
debug!("cleaning type `{:?}`", self);
729-
let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
728+
let ctxt = super::ctxtkey.get().unwrap();
730729
let codemap = ctxt.sess().codemap();
731730
debug!("span corresponds to `{}`", codemap.span_to_str(self.span));
732731
match self.node {
@@ -909,7 +908,7 @@ pub struct Span {
909908

910909
impl Clean<Span> for syntax::codemap::Span {
911910
fn clean(&self) -> Span {
912-
let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
911+
let ctxt = super::ctxtkey.get().unwrap();
913912
let cm = ctxt.sess().codemap();
914913
let filename = cm.span_to_filename(*self);
915914
let lo = cm.lookup_char_pos(self.lo);
@@ -1237,7 +1236,7 @@ trait ToSource {
12371236
impl ToSource for syntax::codemap::Span {
12381237
fn to_src(&self) -> ~str {
12391238
debug!("converting span {:?} to snippet", self.clean());
1240-
let ctxt = local_data::get(super::ctxtkey, |x| x.unwrap().clone());
1239+
let ctxt = super::ctxtkey.get().unwrap();
12411240
let cm = ctxt.sess().codemap().clone();
12421241
let sn = match cm.span_to_snippet(*self) {
12431242
Some(x) => x,
@@ -1292,7 +1291,7 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
12921291
/// Given a Type, resolve it using the def_map
12931292
fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound> >,
12941293
id: ast::NodeId) -> Type {
1295-
let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
1294+
let cx = super::ctxtkey.get().unwrap();
12961295
let tycx = match cx.maybe_typed {
12971296
core::Typed(ref tycx) => tycx,
12981297
// If we're extracting tests, this return value doesn't matter.
@@ -1351,7 +1350,7 @@ fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
13511350
}
13521351

13531352
fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
1354-
let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
1353+
let cx = super::ctxtkey.get().unwrap();
13551354
match cx.maybe_typed {
13561355
core::Typed(ref tcx) => {
13571356
tcx.def_map.borrow().find(&id).map(|&d| ast_util::def_id_of_def(d))

src/librustdoc/core.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use syntax;
2020

2121
use std::cell::RefCell;
2222
use std::os;
23-
use std::local_data;
2423
use collections::HashSet;
2524

2625
use visit_ast::RustdocVisitor;
@@ -109,7 +108,7 @@ pub fn run_core(libs: HashSet<Path>, cfgs: Vec<~str>, path: &Path)
109108
-> (clean::Crate, CrateAnalysis) {
110109
let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs);
111110
let ctxt = @ctxt;
112-
local_data::set(super::ctxtkey, ctxt);
111+
super::ctxtkey.replace(Some(ctxt));
113112

114113
let krate = {
115114
let mut v = RustdocVisitor::new(ctxt, Some(&analysis));

0 commit comments

Comments
 (0)