diff --git a/src/compiletest/errors.rs b/src/compiletest/errors.rs index 63b5c64c6d4a6..5a5c091d9570a 100644 --- a/src/compiletest/errors.rs +++ b/src/compiletest/errors.rs @@ -30,36 +30,34 @@ pub fn load_errors(testfile: &Path) -> ~[ExpectedError] { } fn parse_expected(line_num: uint, line: ~str) -> ~[ExpectedError] { - unsafe { - let error_tag = ~"//~"; - let mut idx; - match str::find_str(line, error_tag) { - None => return ~[], - Some(nn) => { idx = (nn as uint) + str::len(error_tag); } - } + let error_tag = ~"//~"; + let mut idx; + match str::find_str(line, error_tag) { + None => return ~[], + Some(nn) => { idx = (nn as uint) + str::len(error_tag); } + } - // "//~^^^ kind msg" denotes a message expected - // three lines above current line: - let mut adjust_line = 0u; - let len = str::len(line); - while idx < len && line[idx] == ('^' as u8) { - adjust_line += 1u; - idx += 1u; - } + // "//~^^^ kind msg" denotes a message expected + // three lines above current line: + let mut adjust_line = 0u; + let len = str::len(line); + while idx < len && line[idx] == ('^' as u8) { + adjust_line += 1u; + idx += 1u; + } - // Extract kind: - while idx < len && line[idx] == (' ' as u8) { idx += 1u; } - let start_kind = idx; - while idx < len && line[idx] != (' ' as u8) { idx += 1u; } - let kind = str::to_lower(str::slice(line, start_kind, idx).to_owned()); + // Extract kind: + while idx < len && line[idx] == (' ' as u8) { idx += 1u; } + let start_kind = idx; + while idx < len && line[idx] != (' ' as u8) { idx += 1u; } + let kind = str::to_lower(str::slice(line, start_kind, idx).to_owned()); - // Extract msg: - while idx < len && line[idx] == (' ' as u8) { idx += 1u; } - let msg = str::slice(line, idx, len).to_owned(); + // Extract msg: + while idx < len && line[idx] == (' ' as u8) { idx += 1u; } + let msg = str::slice(line, idx, len).to_owned(); - debug!("line=%u kind=%s msg=%s", line_num - adjust_line, kind, msg); + debug!("line=%u kind=%s msg=%s", line_num - adjust_line, kind, msg); - return ~[ExpectedError{line: line_num - adjust_line, kind: kind, - msg: msg}]; - } + return ~[ExpectedError{line: line_num - adjust_line, kind: kind, + msg: msg}]; } diff --git a/src/compiletest/header.rs b/src/compiletest/header.rs index 5a35c56c075a7..2b36518833888 100644 --- a/src/compiletest/header.rs +++ b/src/compiletest/header.rs @@ -171,16 +171,14 @@ fn parse_name_directive(line: ~str, directive: ~str) -> bool { fn parse_name_value_directive(line: ~str, directive: ~str) -> Option<~str> { - unsafe { - let keycolon = directive + ~":"; - match str::find_str(line, keycolon) { - Some(colon) => { - let value = str::slice(line, colon + str::len(keycolon), - str::len(line)).to_owned(); - debug!("%s: %s", directive, value); - Some(value) - } - None => None + let keycolon = directive + ~":"; + match str::find_str(line, keycolon) { + Some(colon) => { + let value = str::slice(line, colon + str::len(keycolon), + str::len(line)).to_owned(); + debug!("%s: %s", directive, value); + Some(value) } + None => None } } diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs index 9fd6f1db793b0..d665bf311f362 100644 --- a/src/libcore/comm.rs +++ b/src/libcore/comm.rs @@ -188,16 +188,14 @@ impl Peekable for Port { #[inline(always)] 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 - } + 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 } impl Selectable for Port { diff --git a/src/libcore/io.rs b/src/libcore/io.rs index 3853e7c8f2b0e..3c5900f51a247 100644 --- a/src/libcore/io.rs +++ b/src/libcore/io.rs @@ -1536,11 +1536,8 @@ pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] { pub fn with_str_writer(f: &fn(@Writer)) -> ~str { let mut v = with_bytes_writer(f); - // FIXME (#3758): This should not be needed. - unsafe { - // Make sure the vector has a trailing null and is proper utf8. - v.push(0); - } + // Make sure the vector has a trailing null and is proper utf8. + v.push(0); assert!(str::is_utf8(v)); unsafe { ::cast::transmute(v) } @@ -1640,16 +1637,14 @@ pub mod fsync { // outer res pub fn FILE_res_sync(file: &FILERes, opt_level: Option, blk: &fn(v: Res<*libc::FILE>)) { - unsafe { - blk(Res(Arg { - val: file.f, opt_level: opt_level, - fsync_fn: |file, l| { - unsafe { - os::fsync_fd(libc::fileno(file), l) as int - } + blk(Res(Arg { + val: file.f, opt_level: opt_level, + fsync_fn: |file, l| { + unsafe { + os::fsync_fd(libc::fileno(file), l) as int } - })); - } + } + })); } // fsync fd after executing blk diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs index 234b710d238b0..2bd3959acf4de 100644 --- a/src/libcore/managed.rs +++ b/src/libcore/managed.rs @@ -38,13 +38,13 @@ pub mod raw { #[inline(always)] pub fn ptr_eq(a: @T, b: @T) -> bool { //! Determine if two shared boxes point to the same object - unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } + ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } #[inline(always)] pub fn mut_ptr_eq(a: @mut T, b: @mut T) -> bool { //! Determine if two mutable shared boxes point to the same object - unsafe { ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } + ptr::addr_of(&(*a)) == ptr::addr_of(&(*b)) } #[cfg(notest)] diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs index 1ab0e24f62dc9..87d04b05087c2 100644 --- a/src/libcore/num/float.rs +++ b/src/libcore/num/float.rs @@ -369,27 +369,27 @@ pub fn is_NaN(x: float) -> bool { f64::is_NaN(x as f64) } #[inline(always)] pub fn abs(x: float) -> float { - unsafe { f64::abs(x as f64) as float } + f64::abs(x as f64) as float } #[inline(always)] pub fn sqrt(x: float) -> float { - unsafe { f64::sqrt(x as f64) as float } + f64::sqrt(x as f64) as float } #[inline(always)] pub fn atan(x: float) -> float { - unsafe { f64::atan(x as f64) as float } + f64::atan(x as f64) as float } #[inline(always)] pub fn sin(x: float) -> float { - unsafe { f64::sin(x as f64) as float } + f64::sin(x as f64) as float } #[inline(always)] pub fn cos(x: float) -> float { - unsafe { f64::cos(x as f64) as float } + f64::cos(x as f64) as float } #[inline(always)] pub fn tan(x: float) -> float { - unsafe { f64::tan(x as f64) as float } + f64::tan(x as f64) as float } #[cfg(notest)] diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 7de0f355dd21d..0e8dbd144b143 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -389,13 +389,11 @@ impl GenericPath for PosixPath { } fn dirname(&self) -> ~str { - unsafe { - let s = self.dir_path().to_str(); - if s.len() == 0 { - ~"." - } else { - s - } + let s = self.dir_path().to_str(); + if s.len() == 0 { + ~"." + } else { + s } } @@ -439,10 +437,8 @@ impl GenericPath for PosixPath { } fn with_filename(&self, f: &str) -> PosixPath { - unsafe { - assert!(! str::any(f, |c| windows::is_sep(c as u8))); - self.dir_path().push(f) - } + assert!(! str::any(f, |c| windows::is_sep(c as u8))); + self.dir_path().push(f) } fn with_filestem(&self, s: &str) -> PosixPath { @@ -509,7 +505,7 @@ impl GenericPath for PosixPath { for str::each_split_nonempty(*e, |c| windows::is_sep(c as u8)) |s| { ss.push(s.to_owned()) } - unsafe { v.push_all_move(ss); } + v.push_all_move(ss); } PosixPath { is_absolute: self.is_absolute, components: v } @@ -521,14 +517,14 @@ impl GenericPath for PosixPath { for str::each_split_nonempty(s, |c| windows::is_sep(c as u8)) |s| { ss.push(s.to_owned()) } - unsafe { v.push_all_move(ss); } + v.push_all_move(ss); PosixPath { components: v, ..copy *self } } fn pop(&self) -> PosixPath { let mut cs = copy self.components; if cs.len() != 0 { - unsafe { cs.pop(); } + cs.pop(); } return PosixPath { is_absolute: self.is_absolute, @@ -607,13 +603,11 @@ impl GenericPath for WindowsPath { } fn dirname(&self) -> ~str { - unsafe { - let s = self.dir_path().to_str(); - if s.len() == 0 { - ~"." - } else { - s - } + let s = self.dir_path().to_str(); + if s.len() == 0 { + ~"." + } else { + s } } @@ -770,7 +764,7 @@ impl GenericPath for WindowsPath { for str::each_split_nonempty(*e, |c| windows::is_sep(c as u8)) |s| { ss.push(s.to_owned()) } - unsafe { v.push_all_move(ss); } + v.push_all_move(ss); } // tedious, but as-is, we can't use ..self return WindowsPath { @@ -787,14 +781,14 @@ impl GenericPath for WindowsPath { for str::each_split_nonempty(s, |c| windows::is_sep(c as u8)) |s| { ss.push(s.to_owned()) } - unsafe { v.push_all_move(ss); } + v.push_all_move(ss); return WindowsPath { components: v, ..copy *self } } fn pop(&self) -> WindowsPath { let mut cs = copy self.components; if cs.len() != 0 { - unsafe { cs.pop(); } + cs.pop(); } return WindowsPath { host: copy self.host, @@ -820,18 +814,14 @@ impl GenericPath for WindowsPath { pub fn normalize(components: &[~str]) -> ~[~str] { let mut cs = ~[]; - unsafe { - for components.each |c| { - unsafe { - if *c == ~"." && components.len() > 1 { loop; } - if *c == ~"" { loop; } - if *c == ~".." && cs.len() != 0 { - cs.pop(); - loop; - } - cs.push(copy *c); - } + for components.each |c| { + if *c == ~"." && components.len() > 1 { loop; } + if *c == ~"" { loop; } + if *c == ~".." && cs.len() != 0 { + cs.pop(); + loop; } + cs.push(copy *c); } cs } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 70bdb6f41d8ba..14e17de4fbda0 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -55,17 +55,13 @@ pub fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } } /// Calculate the offset from a pointer #[inline(always)] pub fn offset(ptr: *T, count: uint) -> *T { - unsafe { - (ptr as uint + count * sys::size_of::()) as *T - } + (ptr as uint + count * sys::size_of::()) as *T } /// Calculate the offset from a const pointer #[inline(always)] pub fn const_offset(ptr: *const T, count: uint) -> *const T { - unsafe { - (ptr as uint + count * sys::size_of::()) as *T - } + (ptr as uint + count * sys::size_of::()) as *T } /// Calculate the offset from a mut pointer diff --git a/src/libcore/rt/context.rs b/src/libcore/rt/context.rs index 9dc9f5da8c1da..4714be9e3d520 100644 --- a/src/libcore/rt/context.rs +++ b/src/libcore/rt/context.rs @@ -205,8 +205,6 @@ fn align_down(sp: *mut uint) -> *mut uint { #[inline(always)] pub fn mut_offset(ptr: *mut T, count: int) -> *mut T { use core::sys::size_of; - unsafe { - (ptr as int + count * (size_of::() as int)) as *mut T - } + (ptr as int + count * (size_of::() as int)) as *mut T } diff --git a/src/libcore/rt/thread_local_storage.rs b/src/libcore/rt/thread_local_storage.rs index c8a9689bbc67a..366996fb93560 100644 --- a/src/libcore/rt/thread_local_storage.rs +++ b/src/libcore/rt/thread_local_storage.rs @@ -21,17 +21,17 @@ pub type Key = pthread_key_t; #[cfg(unix)] pub unsafe fn create(key: &mut Key) { - unsafe { assert!(0 == pthread_key_create(key, null())); } + assert!(0 == pthread_key_create(key, null())); } #[cfg(unix)] pub unsafe fn set(key: Key, value: *mut c_void) { - unsafe { assert!(0 == pthread_setspecific(key, value)); } + assert!(0 == pthread_setspecific(key, value)); } #[cfg(unix)] pub unsafe fn get(key: Key) -> *mut c_void { - unsafe { pthread_getspecific(key) } + pthread_getspecific(key) } #[cfg(target_os="macos")] diff --git a/src/libcore/run.rs b/src/libcore/run.rs index f6f4b9a397d81..49df2938afd40 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -382,64 +382,62 @@ pub struct ProgramOutput {status: int, out: ~str, err: ~str} * the contents of stdout and the contents of stderr. */ pub fn program_output(prog: &str, args: &[~str]) -> ProgramOutput { - unsafe { - let pipe_in = os::pipe(); - let pipe_out = os::pipe(); - let pipe_err = os::pipe(); - let pid = spawn_process(prog, args, &None, &None, - pipe_in.in, pipe_out.out, pipe_err.out); - - os::close(pipe_in.in); - os::close(pipe_out.out); - os::close(pipe_err.out); - if pid == -1i32 { - os::close(pipe_in.out); - os::close(pipe_out.in); - os::close(pipe_err.in); - fail!(); - } + let pipe_in = os::pipe(); + let pipe_out = os::pipe(); + let pipe_err = os::pipe(); + let pid = spawn_process(prog, args, &None, &None, + pipe_in.in, pipe_out.out, pipe_err.out); + os::close(pipe_in.in); + os::close(pipe_out.out); + os::close(pipe_err.out); + if pid == -1i32 { os::close(pipe_in.out); + os::close(pipe_out.in); + os::close(pipe_err.in); + fail!(); + } - // Spawn two entire schedulers to read both stdout and sterr - // in parallel so we don't deadlock while blocking on one - // or the other. FIXME (#2625): Surely there's a much more - // clever way to do this. - let (p, ch) = stream(); - let ch = SharedChan(ch); - let ch_clone = ch.clone(); - do task::spawn_sched(task::SingleThreaded) { - let errput = readclose(pipe_err.in); - ch.send((2, errput)); - }; - do task::spawn_sched(task::SingleThreaded) { - let output = readclose(pipe_out.in); - ch_clone.send((1, output)); - }; - let status = run::waitpid(pid); - let mut errs = ~""; - let mut outs = ~""; - let mut count = 2; - while count > 0 { - let stream = p.recv(); - match stream { - (1, copy s) => { - outs = s; - } - (2, copy s) => { - errs = s; - } - (n, _) => { - fail!(fmt!("program_output received an unexpected file \ - number: %u", n)); - } - }; - count -= 1; + os::close(pipe_in.out); + + // Spawn two entire schedulers to read both stdout and sterr + // in parallel so we don't deadlock while blocking on one + // or the other. FIXME (#2625): Surely there's a much more + // clever way to do this. + let (p, ch) = stream(); + let ch = SharedChan(ch); + let ch_clone = ch.clone(); + do task::spawn_sched(task::SingleThreaded) { + let errput = readclose(pipe_err.in); + ch.send((2, errput)); + }; + do task::spawn_sched(task::SingleThreaded) { + let output = readclose(pipe_out.in); + ch_clone.send((1, output)); + }; + let status = run::waitpid(pid); + let mut errs = ~""; + let mut outs = ~""; + let mut count = 2; + while count > 0 { + let stream = p.recv(); + match stream { + (1, copy s) => { + outs = s; + } + (2, copy s) => { + errs = s; + } + (n, _) => { + fail!(fmt!("program_output received an unexpected file \ + number: %u", n)); + } }; - return ProgramOutput {status: status, - out: outs, - err: errs}; - } + count -= 1; + }; + return ProgramOutput {status: status, + out: outs, + err: errs}; } pub fn writeclose(fd: c_int, s: ~str) { diff --git a/src/libcore/str.rs b/src/libcore/str.rs index 521c8266e0505..b0653db365e03 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -170,18 +170,16 @@ pub fn push_char(s: &mut ~str, ch: char) { /// Convert a char to a string pub fn from_char(ch: char) -> ~str { let mut buf = ~""; - unsafe { push_char(&mut buf, ch); } + push_char(&mut buf, ch); buf } /// Convert a vector of chars to a string pub fn from_chars(chs: &[char]) -> ~str { let mut buf = ~""; - unsafe { - reserve(&mut buf, chs.len()); - for vec::each(chs) |ch| { - push_char(&mut buf, *ch); - } + reserve(&mut buf, chs.len()); + for vec::each(chs) |ch| { + push_char(&mut buf, *ch); } buf } @@ -226,9 +224,7 @@ pub fn push_str(lhs: &mut ~str, rhs: &str) { #[inline(always)] pub fn append(lhs: ~str, rhs: &str) -> ~str { let mut v = lhs; - unsafe { - push_str_no_overallocate(&mut v, rhs); - } + push_str_no_overallocate(&mut v, rhs); v } @@ -236,7 +232,7 @@ pub fn append(lhs: ~str, rhs: &str) -> ~str { pub fn concat(v: &[~str]) -> ~str { let mut s: ~str = ~""; for vec::each(v) |ss| { - unsafe { push_str(&mut s, *ss) }; + push_str(&mut s, *ss); } s } @@ -245,8 +241,8 @@ pub fn concat(v: &[~str]) -> ~str { pub fn connect(v: &[~str], sep: &str) -> ~str { let mut s = ~"", first = true; for vec::each(v) |ss| { - if first { first = false; } else { unsafe { push_str(&mut s, sep); } } - unsafe { push_str(&mut s, *ss) }; + if first { first = false; } else { push_str(&mut s, sep); } + push_str(&mut s, *ss); } s } @@ -255,8 +251,8 @@ pub fn connect(v: &[~str], sep: &str) -> ~str { pub fn connect_slices(v: &[&str], sep: &str) -> ~str { let mut s = ~"", first = true; for vec::each(v) |ss| { - if first { first = false; } else { unsafe { push_str(&mut s, sep); } } - unsafe { push_str(&mut s, *ss) }; + if first { first = false; } else { push_str(&mut s, sep); } + push_str(&mut s, *ss); } s } @@ -2251,16 +2247,14 @@ pub mod raw { assert!((end <= n)); let mut v = vec::with_capacity(end - begin + 1u); - unsafe { - do vec::as_imm_buf(v) |vbuf, _vlen| { - let vbuf = ::cast::transmute_mut_unsafe(vbuf); - let src = ptr::offset(sbuf, begin); - ptr::copy_memory(vbuf, src, end - begin); - } - vec::raw::set_len(&mut v, end - begin); - v.push(0u8); - ::cast::transmute(v) + do vec::as_imm_buf(v) |vbuf, _vlen| { + let vbuf = ::cast::transmute_mut_unsafe(vbuf); + let src = ptr::offset(sbuf, begin); + ptr::copy_memory(vbuf, src, end - begin); } + vec::raw::set_len(&mut v, end - begin); + v.push(0u8); + ::cast::transmute(v) } } @@ -2304,7 +2298,7 @@ pub mod raw { } /// Removes the last byte from a string and returns it. (Not UTF-8 safe). - pub unsafe fn pop_byte(s: &mut ~str) -> u8 { + pub fn pop_byte(s: &mut ~str) -> u8 { let len = len(*s); assert!((len > 0u)); let b = s[len - 1u]; @@ -2313,7 +2307,7 @@ pub mod raw { } /// Removes the first byte from a string and returns it. (Not UTF-8 safe). - pub unsafe fn shift_byte(s: &mut ~str) -> u8 { + pub fn shift_byte(s: &mut ~str) -> u8 { let len = len(*s); assert!((len > 0u)); let b = s[0]; diff --git a/src/libcore/sys.rs b/src/libcore/sys.rs index 52ca020412676..678005ce06f96 100644 --- a/src/libcore/sys.rs +++ b/src/libcore/sys.rs @@ -127,10 +127,8 @@ pub fn refcount(t: @T) -> uint { } pub fn log_str(t: &T) -> ~str { - unsafe { - do io::with_str_writer |wr| { - repr::write_repr(wr, t) - } + do io::with_str_writer |wr| { + repr::write_repr(wr, t) } } @@ -157,10 +155,8 @@ pub fn begin_unwind_(msg: *c_char, file: *c_char, line: size_t) -> ! { } pub fn fail_assert(msg: &str, file: &str, line: uint) -> ! { - unsafe { - let (msg, file) = (msg.to_owned(), file.to_owned()); - begin_unwind(~"assertion failed: " + msg, file, line) - } + let (msg, file) = (msg.to_owned(), file.to_owned()); + begin_unwind(~"assertion failed: " + msg, file, line) } #[cfg(test)] diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs index e4ee430cdda64..d712bf8f98f44 100644 --- a/src/libcore/task/mod.rs +++ b/src/libcore/task/mod.rs @@ -39,10 +39,9 @@ use result::Result; use comm::{stream, Chan, GenericChan, GenericPort, Port}; use prelude::*; use result; -use task::rt::{task_id, sched_id}; +use task::rt::{task_id, sched_id, rust_task}; use util; use util::replace; -use unstable::finally::Finally; #[cfg(test)] use comm::SharedChan; @@ -566,28 +565,48 @@ pub fn get_scheduler() -> Scheduler { * ~~~ */ pub unsafe fn unkillable(f: &fn() -> U) -> U { - unsafe { - let t = rt::rust_get_task(); - rt::rust_task_inhibit_kill(t); - do (|| { - f() - }).finally { - rt::rust_task_allow_kill(t); + struct AllowFailure { + t: *rust_task, + drop { + unsafe { + rt::rust_task_allow_kill(self.t); + } + } + } + + fn AllowFailure(t: *rust_task) -> AllowFailure{ + AllowFailure { + t: t } } + + let t = rt::rust_get_task(); + let _allow_failure = AllowFailure(t); + rt::rust_task_inhibit_kill(t); + f() } /// The inverse of unkillable. Only ever to be used nested in unkillable(). pub unsafe fn rekillable(f: &fn() -> U) -> U { - unsafe { - let t = rt::rust_get_task(); - rt::rust_task_allow_kill(t); - do (|| { - f() - }).finally { - rt::rust_task_inhibit_kill(t); + struct DisallowFailure { + t: *rust_task, + drop { + unsafe { + rt::rust_task_inhibit_kill(self.t); + } } } + + fn DisallowFailure(t: *rust_task) -> DisallowFailure { + DisallowFailure { + t: t + } + } + + let t = rt::rust_get_task(); + let _allow_failure = DisallowFailure(t); + rt::rust_task_allow_kill(t); + f() } /** @@ -595,17 +614,27 @@ pub unsafe fn rekillable(f: &fn() -> U) -> U { * For use with exclusive ARCs, which use pthread mutexes directly. */ pub unsafe fn atomically(f: &fn() -> U) -> U { - unsafe { - let t = rt::rust_get_task(); - rt::rust_task_inhibit_kill(t); - rt::rust_task_inhibit_yield(t); - do (|| { - f() - }).finally { - rt::rust_task_allow_yield(t); - rt::rust_task_allow_kill(t); + struct DeferInterrupts { + t: *rust_task, + drop { + unsafe { + rt::rust_task_allow_yield(self.t); + rt::rust_task_allow_kill(self.t); + } } } + + fn DeferInterrupts(t: *rust_task) -> DeferInterrupts { + DeferInterrupts { + t: t + } + } + + let t = rt::rust_get_task(); + let _interrupts = DeferInterrupts(t); + rt::rust_task_inhibit_kill(t); + rt::rust_task_inhibit_yield(t); + f() } #[test] #[should_fail] #[ignore(cfg(windows))] diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index e1b645cd56272..c71f7d26d40f1 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -157,13 +157,13 @@ struct AncestorList(Option>); // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety. #[inline(always)] fn access_group(x: &TaskGroupArc, blk: &fn(TaskGroupInner) -> U) -> U { - unsafe { x.with(blk) } + x.with(blk) } #[inline(always)] fn access_ancestors(x: &unstable::Exclusive, blk: &fn(x: &mut AncestorNode) -> U) -> U { - unsafe { x.with(blk) } + x.with(blk) } // Iterates over an ancestor list. diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs index 9ccce0cfe7654..e43d321dc4d05 100644 --- a/src/libcore/unstable.rs +++ b/src/libcore/unstable.rs @@ -152,45 +152,37 @@ pub type SharedMutableState = ArcDestruct; pub unsafe fn shared_mutable_state(data: T) -> SharedMutableState { let data = ~ArcData { count: 1, data: Some(data) }; - unsafe { - let ptr = cast::transmute(data); - ArcDestruct(ptr) - } + let ptr = cast::transmute(data); + ArcDestruct(ptr) } #[inline(always)] pub unsafe fn get_shared_mutable_state( rc: *SharedMutableState) -> *mut T { - unsafe { - let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); - assert!(ptr.count > 0); - let r = cast::transmute(ptr.data.get_ref()); - cast::forget(ptr); - return r; - } + let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); + assert!(ptr.count > 0); + let r = cast::transmute(ptr.data.get_ref()); + cast::forget(ptr); + return r; } #[inline(always)] pub unsafe fn get_shared_immutable_state<'a,T:Owned>( rc: &'a SharedMutableState) -> &'a T { - unsafe { - let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); - assert!(ptr.count > 0); - // Cast us back into the correct region - let r = cast::transmute_region(ptr.data.get_ref()); - cast::forget(ptr); - return r; - } + let ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); + assert!(ptr.count > 0); + // Cast us back into the correct region + let r = cast::transmute_region(ptr.data.get_ref()); + cast::forget(ptr); + return r; } pub unsafe fn clone_shared_mutable_state(rc: &SharedMutableState) -> SharedMutableState { - unsafe { - let mut ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); - let new_count = intrinsics::atomic_xadd(&mut ptr.count, 1) + 1; - assert!(new_count >= 2); - cast::forget(ptr); - } + let mut ptr: ~ArcData = cast::reinterpret_cast(&(*rc).data); + let new_count = intrinsics::atomic_xadd(&mut ptr.count, 1) + 1; + assert!(new_count >= 2); + cast::forget(ptr); ArcDestruct((*rc).data) } diff --git a/src/libcore/unstable/exchange_alloc.rs b/src/libcore/unstable/exchange_alloc.rs index fdf99e9dffea6..8ca5486d92992 100644 --- a/src/libcore/unstable/exchange_alloc.rs +++ b/src/libcore/unstable/exchange_alloc.rs @@ -19,27 +19,25 @@ use ptr::null; use intrinsic::TyDesc; pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void { - unsafe { - assert!(td.is_not_null()); + assert!(td.is_not_null()); - let total_size = get_box_size(size, (*td).align); - let p = c_malloc(total_size as size_t); - assert!(p.is_not_null()); + let total_size = get_box_size(size, (*td).align); + let p = c_malloc(total_size as size_t); + assert!(p.is_not_null()); - // FIXME #3475: Converting between our two different tydesc types - let td: *TyDesc = transmute(td); + // FIXME #3475: Converting between our two different tydesc types + let td: *TyDesc = transmute(td); - let box: &mut BoxRepr = transmute(p); - box.header.ref_count = -1; // Exchange values not ref counted - box.header.type_desc = td; - box.header.prev = null(); - box.header.next = null(); + let box: &mut BoxRepr = transmute(p); + box.header.ref_count = -1; // Exchange values not ref counted + box.header.type_desc = td; + box.header.prev = null(); + box.header.next = null(); - let exchange_count = &mut *rust_get_exchange_count_ptr(); - atomic_xadd(exchange_count, 1); + let exchange_count = &mut *rust_get_exchange_count_ptr(); + atomic_xadd(exchange_count, 1); - return transmute(box); - } + return transmute(box); } /** Thin wrapper around libc::malloc, none of the box header diff --git a/src/libcore/unstable/extfmt.rs b/src/libcore/unstable/extfmt.rs index be2aecf0c2a3b..ad3dce0a74992 100644 --- a/src/libcore/unstable/extfmt.rs +++ b/src/libcore/unstable/extfmt.rs @@ -512,7 +512,7 @@ pub mod rt { None } } else { Some('-') }; - unsafe { pad(cv, s, head, PadSigned, buf) }; + pad(cv, s, head, PadSigned, buf); } pub fn conv_uint(cv: Conv, u: uint, buf: &mut ~str) { let prec = get_int_precision(cv); @@ -524,7 +524,7 @@ pub mod rt { TyBits => uint_to_str_prec(u, 2, prec), TyOctal => uint_to_str_prec(u, 8, prec) }; - unsafe { pad(cv, rs, None, PadUnsigned, buf) }; + pad(cv, rs, None, PadUnsigned, buf); } pub fn conv_bool(cv: Conv, b: bool, buf: &mut ~str) { let s = if b { "true" } else { "false" }; @@ -533,7 +533,7 @@ pub mod rt { conv_str(cv, s, buf); } pub fn conv_char(cv: Conv, c: char, buf: &mut ~str) { - unsafe { pad(cv, "", Some(c), PadNozero, buf) }; + pad(cv, "", Some(c), PadNozero, buf); } pub fn conv_str(cv: Conv, s: &str, buf: &mut ~str) { // For strings, precision is the maximum characters @@ -546,14 +546,14 @@ pub mod rt { s } }; - unsafe { pad(cv, unpadded, None, PadNozero, buf) }; + pad(cv, unpadded, None, PadNozero, buf); } pub fn conv_float(cv: Conv, f: float, buf: &mut ~str) { let (to_str, digits) = match cv.precision { CountIs(c) => (float::to_str_exact, c as uint), CountImplied => (float::to_str_digits, 6u) }; - let mut s = unsafe { to_str(f, digits) }; + let mut s = to_str(f, digits); let head = if 0.0 <= f { if have_flag(cv.flags, flag_sign_always) { Some('+') @@ -563,7 +563,7 @@ pub mod rt { None } } else { None }; - unsafe { pad(cv, s, head, PadFloat, buf) }; + pad(cv, s, head, PadFloat, buf); } pub fn conv_poly(cv: Conv, v: &T, buf: &mut ~str) { let s = sys::log_str(v); diff --git a/src/libcore/unstable/lang.rs b/src/libcore/unstable/lang.rs index dad990c0f97cf..be776a39742f0 100644 --- a/src/libcore/unstable/lang.rs +++ b/src/libcore/unstable/lang.rs @@ -44,7 +44,7 @@ pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! { } #[lang="fail_bounds_check"] -pub unsafe fn fail_bounds_check(file: *c_char, line: size_t, +pub fn fail_bounds_check(file: *c_char, line: size_t, index: size_t, len: size_t) { let msg = fmt!("index out of bounds: the len is %d but the index is %d", len as int, index as int); @@ -53,7 +53,7 @@ pub unsafe fn fail_bounds_check(file: *c_char, line: size_t, } } -pub unsafe fn fail_borrowed() { +pub fn fail_borrowed() { let msg = "borrowed"; do str::as_buf(msg) |msg_p, _| { do str::as_buf("???") |file_p, _| { diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index fae56aac38f3c..1c99566280815 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -615,9 +615,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, } pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str { - unsafe { - symbol_hasher.result_str() - } + symbol_hasher.result_str() } diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 721bb99626249..116b70bf7e320 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -33,6 +33,7 @@ use util::ppaux::ty_to_str; use core::hashmap::HashSet; use core::uint; +use core::util::with; use syntax::ast::m_mutbl; use syntax::ast; use syntax::ast_util; @@ -40,13 +41,18 @@ use syntax::codemap::span; use syntax::print::pprust; use syntax::visit; +struct PurityState { + def: ast::node_id, + purity: ast::purity +} + struct CheckLoanCtxt { bccx: @BorrowckCtxt, req_maps: ReqMaps, reported: HashSet, - declared_purity: @mut ast::purity, + declared_purity: @mut PurityState, fn_args: @mut @~[ast::node_id] } @@ -62,6 +68,16 @@ enum purity_cause { pc_cmt(bckerr) } +// if we're not pure, why? +#[deriving(Eq)] +enum impurity_cause { + // some surrounding block was marked as 'unsafe' + pc_unsafe, + + // nothing was unsafe, and nothing was pure + pc_default, +} + pub fn check_loans(bccx: @BorrowckCtxt, +req_maps: ReqMaps, crate: @ast::crate) { @@ -69,7 +85,8 @@ pub fn check_loans(bccx: @BorrowckCtxt, bccx: bccx, req_maps: req_maps, reported: HashSet::new(), - declared_purity: @mut ast::impure_fn, + declared_purity: @mut PurityState { purity: ast::impure_fn, + def: 0 }, fn_args: @mut @~[] }; let vt = visit::mk_vt(@visit::Visitor {visit_expr: check_loans_in_expr, @@ -106,16 +123,18 @@ pub impl assignment_type { pub impl CheckLoanCtxt { fn tcx(&self) -> ty::ctxt { self.bccx.tcx } - fn purity(&mut self, scope_id: ast::node_id) -> Option { - let default_purity = match *self.declared_purity { + fn purity(&mut self, scope_id: ast::node_id) + -> Either + { + let default_purity = match self.declared_purity.purity { // an unsafe declaration overrides all - ast::unsafe_fn => return None, + ast::unsafe_fn => return Right(pc_unsafe), // otherwise, remember what was declared as the // default, but we must scan for requirements // imposed by the borrow check - ast::pure_fn => Some(pc_pure_fn), - ast::extern_fn | ast::impure_fn => None + ast::pure_fn => Left(pc_pure_fn), + ast::extern_fn | ast::impure_fn => Right(pc_default) }; // scan to see if this scope or any enclosing scope requires @@ -125,7 +144,7 @@ pub impl CheckLoanCtxt { loop { match self.req_maps.pure_map.find(&scope_id) { None => (), - Some(e) => return Some(pc_cmt(*e)) + Some(e) => return Left(pc_cmt(*e)) } match self.tcx().region_maps.opt_encl_scope(scope_id) { @@ -171,7 +190,7 @@ pub impl CheckLoanCtxt { // overloaded operators the callee has an id but no expr. // annoying. fn check_pure_callee_or_arg(&mut self, - pc: purity_cause, + pc: Either, opt_expr: Option<@ast::expr>, callee_id: ast::node_id, callee_span: span) { @@ -196,7 +215,7 @@ pub impl CheckLoanCtxt { match opt_expr { Some(expr) => { match expr.node { - ast::expr_path(_) if pc == pc_pure_fn => { + ast::expr_path(_) if pc == Left(pc_pure_fn) => { let def = *self.tcx().def_map.get(&expr.id); let did = ast_util::def_id_of_def(def); let is_fn_arg = @@ -361,10 +380,10 @@ pub impl CheckLoanCtxt { // if this is a pure function, only loan-able state can be // assigned, because it is uniquely tied to this function and // is not visible from the outside - match self.purity(ex.id) { - None => (), - Some(pc_cmt(_)) => { - let purity = self.purity(ex.id).get(); + let purity = self.purity(ex.id); + match purity { + Right(_) => (), + Left(pc_cmt(_)) => { // Subtle: Issue #3162. If we are enforcing purity // because there is a reference to aliasable, mutable data // that we require to be immutable, we can't allow writes @@ -376,10 +395,10 @@ pub impl CheckLoanCtxt { ex.span, at.ing_form(self.bccx.cmt_to_str(cmt))); } - Some(pc_pure_fn) => { + Left(pc_pure_fn) => { if cmt.lp.is_none() { self.report_purity_error( - pc_pure_fn, ex.span, + purity, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt))); } } @@ -462,14 +481,23 @@ pub impl CheckLoanCtxt { } } - fn report_purity_error(&mut self, pc: purity_cause, sp: span, msg: ~str) { + fn report_purity_error(&mut self, pc: Either, + sp: span, msg: ~str) { match pc { - pc_pure_fn => { + Right(pc_default) => { fail!(~"pc_default should be filtered sooner") } + Right(pc_unsafe) => { + // this error was prevented by being marked as unsafe, so flag the + // definition as having contributed to the validity of the program + let def = self.declared_purity.def; + debug!("flagging %? as a used unsafe source", def); + self.tcx().used_unsafe.insert(def); + } + Left(pc_pure_fn) => { self.tcx().sess.span_err( sp, fmt!("%s prohibited in pure context", msg)); } - pc_cmt(ref e) => { + Left(pc_cmt(ref e)) => { if self.reported.insert((*e).cmt.id) { self.tcx().sess.span_err( (*e).cmt.span, @@ -556,16 +584,32 @@ pub impl CheckLoanCtxt { callee_id: ast::node_id, callee_span: span, args: &[@ast::expr]) { - match self.purity(expr.id) { - None => {} - Some(ref pc) => { - self.check_pure_callee_or_arg( - (*pc), callee, callee_id, callee_span); - for args.each |arg| { - self.check_pure_callee_or_arg( - (*pc), Some(*arg), arg.id, arg.span); + let pc = self.purity(expr.id); + match pc { + // no purity, no need to check for anything + Right(pc_default) => return, + + // some form of purity, definitely need to check + Left(_) => (), + + // Unsafe trumped. To see if the unsafe is necessary, see what the + // purity would have been without a trump, and if it's some form + // of purity then we need to go ahead with the check + Right(pc_unsafe) => { + match do with(&mut self.declared_purity.purity, + ast::impure_fn) { self.purity(expr.id) } { + Right(pc_unsafe) => fail!(~"unsafe can't trump twice"), + Right(pc_default) => return, + Left(_) => () + } } - } + + } + self.check_pure_callee_or_arg( + pc, callee, callee_id, callee_span); + for args.each |arg| { + self.check_pure_callee_or_arg( + pc, Some(*arg), arg.id, arg.span); } } } @@ -580,27 +624,32 @@ fn check_loans_in_fn(fk: &visit::fn_kind, let is_stack_closure = self.is_stack_closure(id); let fty = ty::node_id_to_type(self.tcx(), id); - let declared_purity; + let declared_purity, src; match *fk { visit::fk_item_fn(*) | visit::fk_method(*) | visit::fk_dtor(*) => { declared_purity = ty::ty_fn_purity(fty); + src = id; } visit::fk_anon(*) | visit::fk_fn_block(*) => { let fty_sigil = ty::ty_closure_sigil(fty); check_moves_from_captured_variables(self, id, fty_sigil); - declared_purity = ty::determine_inherited_purity( - *self.declared_purity, - ty::ty_fn_purity(fty), + let pair = ty::determine_inherited_purity( + (self.declared_purity.purity, self.declared_purity.def), + (ty::ty_fn_purity(fty), id), fty_sigil); + declared_purity = pair.first(); + src = pair.second(); } } debug!("purity on entry=%?", copy self.declared_purity); do save_and_restore_managed(self.declared_purity) { do save_and_restore_managed(self.fn_args) { - *self.declared_purity = declared_purity; + self.declared_purity = @mut PurityState { + purity: declared_purity, def: src + }; match *fk { visit::fk_anon(*) | @@ -754,7 +803,10 @@ fn check_loans_in_block(blk: &ast::blk, ast::default_blk => { } ast::unsafe_blk => { - *self.declared_purity = ast::unsafe_fn; + *self.declared_purity = PurityState { + purity: ast::unsafe_fn, + def: blk.node.id, + }; } } diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0dd28e5ca7ca1..bacbeb851aa82 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -369,7 +369,7 @@ pub impl<'self> LanguageItemCollector<'self> { } fn collect_local_language_items(&self) { - let this = unsafe { ptr::addr_of(&self) }; + let this = ptr::addr_of(&self); visit_crate(*self.crate, (), mk_simple_visitor(@SimpleVisitor { visit_item: |item| { for item.attrs.each |attribute| { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6f8992bf1ca4a..876ed76f98741 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -75,6 +75,7 @@ pub enum lint { default_methods, deprecated_mutable_fields, deprecated_drop, + unused_unsafe, foreign_mode, managed_heap_memory, @@ -256,6 +257,13 @@ pub fn get_lint_dict() -> LintDict { default: deny }), + (~"unused_unsafe", + LintSpec { + lint: unused_unsafe, + desc: "unnecessary use of an \"unsafe\" block or function", + default: warn + }), + (~"unused_variable", LintSpec { lint: unused_variable, @@ -490,6 +498,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_default_methods(cx, i); check_item_deprecated_mutable_fields(cx, i); check_item_deprecated_drop(cx, i); + check_item_unused_unsafe(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -923,19 +932,55 @@ fn check_item_non_camel_case_types(cx: ty::ctxt, it: @ast::item) { } } +fn check_item_unused_unsafe(cx: ty::ctxt, it: @ast::item) { + let visit_expr: @fn(@ast::expr) = |e| { + match e.node { + ast::expr_block(ref blk) if blk.node.rules == ast::unsafe_blk => { + if !cx.used_unsafe.contains(&blk.node.id) { + cx.sess.span_lint(unused_unsafe, blk.node.id, it.id, + blk.span, + ~"unnecessary \"unsafe\" block"); + } + } + _ => () + } + }; + + let visit = item_stopping_visitor( + visit::mk_simple_visitor(@visit::SimpleVisitor { + visit_expr: visit_expr, + .. *visit::default_simple_visitor() + })); + visit::visit_item(it, (), visit); +} + fn check_fn(tcx: ty::ctxt, fk: &visit::fn_kind, decl: &ast::fn_decl, _body: &ast::blk, span: span, id: ast::node_id) { debug!("lint check_fn fk=%? id=%?", fk, id); - // don't complain about blocks, since they tend to get their modes - // specified from the outside + // Check for an 'unsafe fn' which doesn't need to be unsafe + match *fk { + visit::fk_item_fn(_, _, ast::unsafe_fn, _) => { + if !tcx.used_unsafe.contains(&id) { + tcx.sess.span_lint(unused_unsafe, id, id, span, + ~"unnecessary \"unsafe\" function"); + } + } + _ => () + } + + // Check for deprecated modes match *fk { - visit::fk_fn_block(*) => { return; } - _ => {} + // don't complain about blocks, since they tend to get their modes + // specified from the outside + visit::fk_fn_block(*) => {} + + _ => { + let fn_ty = ty::node_id_to_type(tcx, id); + check_fn_deprecated_modes(tcx, fn_ty, decl, span, id); + } } - let fn_ty = ty::node_id_to_type(tcx, id); - check_fn_deprecated_modes(tcx, fn_ty, decl, span, id); } fn check_fn_deprecated_modes(tcx: ty::ctxt, fn_ty: ty::t, decl: &ast::fn_decl, diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index fa902b7bf56a4..b2225963d2c33 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -19,7 +19,7 @@ use metadata::csearch::get_type_name_if_impl; use metadata::cstore::find_extern_mod_stmt_cnum; use metadata::decoder::{def_like, dl_def, dl_field, dl_impl}; use middle::lang_items::LanguageItems; -use middle::lint::{deny, allow, forbid, level, unused_imports, warn}; +use middle::lint::{allow, level, unused_imports}; use middle::lint::{get_lint_level, get_lint_settings_level}; use middle::pat_util::pat_bindings; @@ -5212,17 +5212,11 @@ pub impl Resolver { import_resolution.span != dummy_sp() && import_resolution.privacy != Public { import_resolution.state.warned = true; - match self.unused_import_lint_level(module_) { - warn => { - self.session.span_warn(copy import_resolution.span, - ~"unused import"); - } - deny | forbid => { - self.session.span_err(copy import_resolution.span, - ~"unused import"); - } - allow => () - } + let span = import_resolution.span; + self.session.span_lint_level( + self.unused_import_lint_level(module_), + span, + ~"unused import"); } } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7e64a219ecdd0..f58e066526c24 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -91,10 +91,8 @@ pub struct icx_popper { #[unsafe_destructor] impl Drop for icx_popper { fn finalize(&self) { - unsafe { - if self.ccx.sess.count_llvm_insns() { - self.ccx.stats.llvm_insn_ctxt.pop(); - } + if self.ccx.sess.count_llvm_insns() { + self.ccx.stats.llvm_insn_ctxt.pop(); } } } @@ -145,9 +143,7 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, llvm::LLVMGetOrInsertFunction(llmod, buf, llty) } }); - unsafe { - lib::llvm::SetFunctionCallConv(llfn, cc); - } + lib::llvm::SetFunctionCallConv(llfn, cc); return llfn; } @@ -730,11 +726,9 @@ pub fn cast_shift_expr_rhs(cx: block, op: ast::binop, pub fn cast_shift_const_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef) -> ValueRef { - unsafe { - cast_shift_rhs(op, lhs, rhs, - |a, b| unsafe { llvm::LLVMConstTrunc(a, b) }, - |a, b| unsafe { llvm::LLVMConstZExt(a, b) }) - } + cast_shift_rhs(op, lhs, rhs, + |a, b| unsafe { llvm::LLVMConstTrunc(a, b) }, + |a, b| unsafe { llvm::LLVMConstZExt(a, b) }) } pub fn cast_shift_rhs(op: ast::binop, @@ -2865,9 +2859,7 @@ pub fn create_module_map(ccx: @CrateContext) -> ValueRef { llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) } }); - unsafe { - lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage); - } + lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage); let mut elts: ~[ValueRef] = ~[]; for ccx.module_data.each |key, &val| { let elt = C_struct(~[p2i(ccx, C_cstr(ccx, @/*bad*/ copy *key)), diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index fa2be2f415f95..d6c045bb1158b 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -27,9 +27,7 @@ use core::str; use core::vec; pub fn terminate(cx: block, _: &str) { - unsafe { - cx.terminated = true; - } + cx.terminated = true; } pub fn check_not_terminated(cx: block) { diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 8c40142335e38..c02417aca8b12 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -172,17 +172,15 @@ fn cast_safely(val: T) -> U { } fn md_from_metadata(val: debug_metadata) -> T { - unsafe { - match val { - file_metadata(md) => cast_safely(md), - compile_unit_metadata(md) => cast_safely(md), - subprogram_metadata(md) => cast_safely(md), - local_var_metadata(md) => cast_safely(md), - tydesc_metadata(md) => cast_safely(md), - block_metadata(md) => cast_safely(md), - argument_metadata(md) => cast_safely(md), - retval_metadata(md) => cast_safely(md) - } + match val { + file_metadata(md) => cast_safely(md), + compile_unit_metadata(md) => cast_safely(md), + subprogram_metadata(md) => cast_safely(md), + local_var_metadata(md) => cast_safely(md), + tydesc_metadata(md) => cast_safely(md), + block_metadata(md) => cast_safely(md), + argument_metadata(md) => cast_safely(md), + retval_metadata(md) => cast_safely(md) } } @@ -190,56 +188,52 @@ fn cached_metadata(cache: metadata_cache, mdtag: int, eq_fn: &fn(md: T) -> bool) -> Option { - unsafe { - if cache.contains_key(&mdtag) { - let items = cache.get(&mdtag); - for items.each |item| { - let md: T = md_from_metadata::(*item); - if eq_fn(md) { - return option::Some(md); - } + if cache.contains_key(&mdtag) { + let items = cache.get(&mdtag); + for items.each |item| { + let md: T = md_from_metadata::(*item); + if eq_fn(md) { + return option::Some(md); } } - return option::None; } + return option::None; } fn create_compile_unit(cx: @CrateContext) -> @Metadata { - unsafe { - let cache = get_cache(cx); - let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file; - let tg = CompileUnitTag; - match cached_metadata::<@Metadata>(cache, tg, - |md| md.data.name == crate_name) { - option::Some(md) => return md, - option::None => () - } + let cache = get_cache(cx); + let crate_name = /*bad*/copy (/*bad*/copy cx.dbg_cx).get().crate_file; + let tg = CompileUnitTag; + match cached_metadata::<@Metadata>(cache, tg, + |md| md.data.name == crate_name) { + option::Some(md) => return md, + option::None => () + } - let (_, work_dir) = get_file_path_and_dir( - cx.sess.working_dir.to_str(), crate_name); - let unit_metadata = ~[lltag(tg), - llunused(), - lli32(DW_LANG_RUST), - llstr(crate_name), - llstr(work_dir), - llstr(env!("CFG_VERSION")), - lli1(true), // deprecated: main compile unit - lli1(cx.sess.opts.optimize != session::No), - llstr(~""), // flags (???) - lli32(0) // runtime version (???) - ]; - let unit_node = llmdnode(unit_metadata); - add_named_metadata(cx, ~"llvm.dbg.cu", unit_node); - let mdval = @Metadata { - node: unit_node, - data: CompileUnitMetadata { - name: crate_name - } - }; - update_cache(cache, tg, compile_unit_metadata(mdval)); + let (_, work_dir) = get_file_path_and_dir( + cx.sess.working_dir.to_str(), crate_name); + let unit_metadata = ~[lltag(tg), + llunused(), + lli32(DW_LANG_RUST), + llstr(crate_name), + llstr(work_dir), + llstr(env!("CFG_VERSION")), + lli1(true), // deprecated: main compile unit + lli1(cx.sess.opts.optimize != session::No), + llstr(~""), // flags (???) + lli32(0) // runtime version (???) + ]; + let unit_node = llmdnode(unit_metadata); + add_named_metadata(cx, ~"llvm.dbg.cu", unit_node); + let mdval = @Metadata { + node: unit_node, + data: CompileUnitMetadata { + name: crate_name + } + }; + update_cache(cache, tg, compile_unit_metadata(mdval)); - return mdval; - } + return mdval; } fn get_cache(cx: @CrateContext) -> metadata_cache { @@ -710,113 +704,109 @@ fn create_var(type_tag: int, context: ValueRef, name: &str, file: ValueRef, pub fn create_local_var(bcx: block, local: @ast::local) -> @Metadata { - unsafe { - let cx = bcx.ccx(); - let cache = get_cache(cx); - let tg = AutoVariableTag; - match cached_metadata::<@Metadata>( - cache, tg, |md| md.data.id == local.node.id) { - option::Some(md) => return md, - option::None => () + let cx = bcx.ccx(); + let cache = get_cache(cx); + let tg = AutoVariableTag; + match cached_metadata::<@Metadata>( + cache, tg, |md| md.data.id == local.node.id) { + option::Some(md) => return md, + option::None => () + } + + let name = match local.node.pat.node { + ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), + // FIXME this should be handled (#2533) + _ => fail!(~"no single variable name for local") + }; + let loc = cx.sess.codemap.lookup_char_pos(local.span.lo); + let ty = node_id_type(bcx, local.node.id); + let tymd = create_ty(cx, ty, local.node.ty.span); + let filemd = create_file(cx, /*bad*/copy loc.file.name); + let context = match bcx.parent { + None => create_function(bcx.fcx).node, + Some(_) => create_block(bcx).node + }; + let mdnode = create_var(tg, context, *cx.sess.str_of(name), + filemd.node, loc.line as int, tymd.node); + let mdval = @Metadata { + node: mdnode, + data: LocalVarMetadata { + id: local.node.id } + }; + update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); - let name = match local.node.pat.node { - ast::pat_ident(_, pth, _) => ast_util::path_to_ident(pth), - // FIXME this should be handled (#2533) - _ => fail!(~"no single variable name for local") - }; - let loc = cx.sess.codemap.lookup_char_pos(local.span.lo); - let ty = node_id_type(bcx, local.node.id); - let tymd = create_ty(cx, ty, local.node.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); - let context = match bcx.parent { - None => create_function(bcx.fcx).node, - Some(_) => create_block(bcx).node - }; - let mdnode = create_var(tg, context, *cx.sess.str_of(name), - filemd.node, loc.line as int, tymd.node); - let mdval = @Metadata { - node: mdnode, - data: LocalVarMetadata { - id: local.node.id - } - }; - update_cache(cache, AutoVariableTag, local_var_metadata(mdval)); - - let llptr = match bcx.fcx.lllocals.find(&local.node.id) { - option::Some(&local_mem(v)) => v, - option::Some(_) => { - bcx.tcx().sess.span_bug(local.span, ~"local is bound to \ - something weird"); - } - option::None => { - match *bcx.fcx.lllocals.get(&local.node.pat.id) { - local_imm(v) => v, - _ => bcx.tcx().sess.span_bug(local.span, ~"local is bound to \ - something weird") - } - } - }; - let declargs = ~[llmdnode(~[llptr]), mdnode]; - trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), - declargs); - return mdval; - } + let llptr = match bcx.fcx.lllocals.find(&local.node.id) { + option::Some(&local_mem(v)) => v, + option::Some(_) => { + bcx.tcx().sess.span_bug(local.span, ~"local is bound to \ + something weird"); + } + option::None => { + match *bcx.fcx.lllocals.get(&local.node.pat.id) { + local_imm(v) => v, + _ => bcx.tcx().sess.span_bug(local.span, ~"local is bound to \ + something weird") + } + } + }; + let declargs = ~[llmdnode(~[llptr]), mdnode]; + trans::build::Call(bcx, *cx.intrinsics.get(&~"llvm.dbg.declare"), + declargs); + return mdval; } pub fn create_arg(bcx: block, arg: ast::arg, sp: span) -> Option<@Metadata> { - unsafe { - let fcx = bcx.fcx, cx = *fcx.ccx; - let cache = get_cache(cx); - let tg = ArgVariableTag; - match cached_metadata::<@Metadata>( - cache, ArgVariableTag, |md| md.data.id == arg.id) { - option::Some(md) => return Some(md), - option::None => () - } + let fcx = bcx.fcx, cx = *fcx.ccx; + let cache = get_cache(cx); + let tg = ArgVariableTag; + match cached_metadata::<@Metadata>( + cache, ArgVariableTag, |md| md.data.id == arg.id) { + option::Some(md) => return Some(md), + option::None => () + } - let loc = cx.sess.codemap.lookup_char_pos(sp.lo); - if loc.file.name == ~"" { - return None; + let loc = cx.sess.codemap.lookup_char_pos(sp.lo); + if loc.file.name == ~"" { + return None; + } + let ty = node_id_type(bcx, arg.id); + let tymd = create_ty(cx, ty, arg.ty.span); + let filemd = create_file(cx, /*bad*/copy loc.file.name); + let context = create_function(bcx.fcx); + + match arg.pat.node { + ast::pat_ident(_, path, _) => { + // XXX: This is wrong; it should work for multiple bindings. + let mdnode = create_var( + tg, + context.node, + *cx.sess.str_of(*path.idents.last()), + filemd.node, + loc.line as int, + tymd.node + ); + + let mdval = @Metadata { + node: mdnode, + data: ArgumentMetadata { + id: arg.id + } + }; + update_cache(cache, tg, argument_metadata(mdval)); + + let llptr = match *fcx.llargs.get(&arg.id) { + local_mem(v) | local_imm(v) => v, + }; + let declargs = ~[llmdnode(~[llptr]), mdnode]; + trans::build::Call(bcx, + *cx.intrinsics.get(&~"llvm.dbg.declare"), + declargs); + return Some(mdval); } - let ty = node_id_type(bcx, arg.id); - let tymd = create_ty(cx, ty, arg.ty.span); - let filemd = create_file(cx, /*bad*/copy loc.file.name); - let context = create_function(bcx.fcx); - - match arg.pat.node { - ast::pat_ident(_, path, _) => { - // XXX: This is wrong; it should work for multiple bindings. - let mdnode = create_var( - tg, - context.node, - *cx.sess.str_of(*path.idents.last()), - filemd.node, - loc.line as int, - tymd.node - ); - - let mdval = @Metadata { - node: mdnode, - data: ArgumentMetadata { - id: arg.id - } - }; - update_cache(cache, tg, argument_metadata(mdval)); - - let llptr = match *fcx.llargs.get(&arg.id) { - local_mem(v) | local_imm(v) => v, - }; - let declargs = ~[llmdnode(~[llptr]), mdnode]; - trans::build::Call(bcx, - *cx.intrinsics.get(&~"llvm.dbg.declare"), - declargs); - return Some(mdval); - } - _ => { - return None; - } + _ => { + return None; } } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index a26c1c1e76635..f62e366ebdcaa 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -300,7 +300,11 @@ struct ctxt_ { destructors: @mut HashSet, // Maps a trait onto a mapping from self-ty to impl - trait_impls: @mut HashMap> + trait_impls: @mut HashMap>, + + // Set of used unsafe nodes (functions or blocks). Unsafe nodes not + // present in this set can be warned about. + used_unsafe: @mut HashSet, } enum tbox_flag { @@ -885,7 +889,8 @@ pub fn mk_ctxt(s: session::Session, supertraits: @mut HashMap::new(), destructor_for_type: @mut HashMap::new(), destructors: @mut HashSet::new(), - trait_impls: @mut HashMap::new() + trait_impls: @mut HashMap::new(), + used_unsafe: @mut HashSet::new(), } } @@ -4309,16 +4314,16 @@ pub fn eval_repeat_count(tcx: ctxt, count_expr: @ast::expr) -> uint { } // Determine what purity to check a nested function under -pub fn determine_inherited_purity(parent_purity: ast::purity, - child_purity: ast::purity, - child_sigil: ast::Sigil) - -> ast::purity { +pub fn determine_inherited_purity(parent: (ast::purity, ast::node_id), + child: (ast::purity, ast::node_id), + child_sigil: ast::Sigil) + -> (ast::purity, ast::node_id) { // If the closure is a stack closure and hasn't had some non-standard // purity inferred for it, then check it under its parent's purity. // Otherwise, use its own match child_sigil { - ast::BorrowedSigil if child_purity == ast::impure_fn => parent_purity, - _ => child_purity + ast::BorrowedSigil if child.first() == ast::impure_fn => parent, + _ => child } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 2d1c940103a7a..5ec4c233bc0d2 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -179,6 +179,11 @@ pub enum FnKind { Vanilla } +struct PurityState { + purity: ast::purity, + from: ast::node_id, +} + pub struct FnCtxt { // var_bindings, locals and next_var_id are shared // with any nested functions that capture the environment @@ -187,7 +192,7 @@ pub struct FnCtxt { ret_ty: ty::t, // Used by loop bodies that return from the outer function indirect_ret_ty: Option, - purity: ast::purity, + ps: PurityState, // Sometimes we generate region pointers where the precise region // to use is not known. For example, an expression like `&x.f` @@ -238,7 +243,7 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, @mut FnCtxt { ret_ty: rty, indirect_ret_ty: None, - purity: ast::pure_fn, + ps: PurityState { purity: ast::pure_fn, from: 0 }, region_lb: region_bnd, in_scope_regions: @Nil, fn_kind: Vanilla, @@ -265,7 +270,7 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt, ty::ty_bare_fn(ref fn_ty) => { let fcx = check_fn(ccx, self_info, fn_ty.purity, - &fn_ty.sig, decl, body, Vanilla, + &fn_ty.sig, decl, id, body, Vanilla, @Nil, blank_inherited(ccx));; vtable::resolve_in_block(fcx, body); @@ -282,6 +287,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, purity: ast::purity, fn_sig: &ty::FnSig, decl: &ast::fn_decl, + id: ast::node_id, body: &ast::blk, fn_kind: FnKind, inherited_isr: isr_alist, @@ -342,7 +348,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, @mut FnCtxt { ret_ty: ret_ty, indirect_ret_ty: indirect_ret_ty, - purity: purity, + ps: PurityState { purity: purity, from: id }, region_lb: body.node.id, in_scope_regions: isr, fn_kind: fn_kind, @@ -867,8 +873,12 @@ pub impl FnCtxt { } fn require_unsafe(&self, sp: span, op: ~str) { - match self.purity { - ast::unsafe_fn => {/*ok*/} + match self.ps.purity { + ast::unsafe_fn => { + // ok, but flag that we used the source of unsafeness + debug!("flagging %? as a used unsafe source", self.ps.from); + self.tcx().used_unsafe.insert(self.ps.from); + } _ => { self.ccx.tcx.sess.span_err( sp, @@ -1679,12 +1689,13 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(expr.id, fty); - let inherited_purity = - ty::determine_inherited_purity(copy fcx.purity, purity, + let (inherited_purity, id) = + ty::determine_inherited_purity((fcx.ps.purity, fcx.ps.from), + (purity, expr.id), sigil); check_fn(fcx.ccx, None, inherited_purity, &fty_sig, - decl, body, fn_kind, fcx.in_scope_regions, fcx.inh); + decl, id, body, fn_kind, fcx.in_scope_regions, fcx.inh); } @@ -2923,8 +2934,11 @@ pub fn check_block_with_expected(fcx0: @mut FnCtxt, blk: &ast::blk, expected: Option) { let fcx = match blk.node.rules { - ast::unsafe_blk => @mut FnCtxt {purity: ast::unsafe_fn,.. copy *fcx0}, - ast::default_blk => fcx0 + ast::unsafe_blk => @mut FnCtxt { + ps: PurityState { purity: ast::unsafe_fn, from: blk.node.id }, + .. copy *fcx0 + }, + ast::default_blk => fcx0 }; do fcx.with_region_lb(blk.node.id) { let mut warned = false; diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 113c8130349ff..a59c76c809b13 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -57,11 +57,9 @@ struct DtorRes { #[unsafe_destructor] impl Drop for DtorRes { fn finalize(&self) { - unsafe { - match self.dtor { - option::None => (), - option::Some(f) => f() - } + match self.dtor { + option::None => (), + option::Some(f) => f() } } } @@ -84,7 +82,7 @@ fn DtorRes(dtor: Option<@fn()>) -> DtorRes { * * base - A foreign pointer to a buffer * * len - The number of elements in the buffer */ -pub unsafe fn CVec(base: *mut T, len: uint) -> CVec { +pub fn CVec(base: *mut T, len: uint) -> CVec { return CVec{ base: base, len: len, @@ -103,7 +101,7 @@ pub unsafe fn CVec(base: *mut T, len: uint) -> CVec { * * dtor - A function to run when the value is destructed, useful * for freeing the buffer, etc. */ -pub unsafe fn c_vec_with_dtor(base: *mut T, len: uint, dtor: @fn()) +pub fn c_vec_with_dtor(base: *mut T, len: uint, dtor: @fn()) -> CVec { return CVec{ base: base, @@ -144,7 +142,7 @@ pub fn set(t: CVec, ofs: uint, v: T) { pub fn len(t: CVec) -> uint { t.len } /// Returns a pointer to the first element of the vector -pub unsafe fn ptr(t: CVec) -> *mut T { t.base } +pub fn ptr(t: CVec) -> *mut T { t.base } #[cfg(test)] mod tests { diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs index df37c48ebe8b8..b1e80718d8f74 100644 --- a/src/libstd/getopts.rs +++ b/src/libstd/getopts.rs @@ -223,128 +223,126 @@ pub type Result = result::Result; * Use to get an error message. */ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result { - unsafe { - let n_opts = opts.len(); - fn f(_x: uint) -> ~[Optval] { return ~[]; } - let mut vals = vec::from_fn(n_opts, f); - let mut free: ~[~str] = ~[]; - let l = args.len(); - let mut i = 0; - while i < l { - let cur = args[i]; - let curlen = cur.len(); - if !is_arg(cur) { - free.push(cur); - } else if cur == ~"--" { - let mut j = i + 1; - while j < l { free.push(args[j]); j += 1; } - break; - } else { - let mut names; - let mut i_arg = None; - if cur[1] == '-' as u8 { - let tail = str::slice(cur, 2, curlen).to_owned(); - let mut tail_eq = ~[]; - for str::each_splitn_char(tail, '=', 1) |s| { tail_eq.push(s.to_owned()) } - if tail_eq.len() <= 1 { - names = ~[Long(tail)]; - } else { - names = - ~[Long(tail_eq[0])]; - i_arg = Some(tail_eq[1]); - } + let n_opts = opts.len(); + fn f(_x: uint) -> ~[Optval] { return ~[]; } + let mut vals = vec::from_fn(n_opts, f); + let mut free: ~[~str] = ~[]; + let l = args.len(); + let mut i = 0; + while i < l { + let cur = args[i]; + let curlen = cur.len(); + if !is_arg(cur) { + free.push(cur); + } else if cur == ~"--" { + let mut j = i + 1; + while j < l { free.push(args[j]); j += 1; } + break; + } else { + let mut names; + let mut i_arg = None; + if cur[1] == '-' as u8 { + let tail = str::slice(cur, 2, curlen).to_owned(); + let mut tail_eq = ~[]; + for str::each_splitn_char(tail, '=', 1) |s| { tail_eq.push(s.to_owned()) } + if tail_eq.len() <= 1 { + names = ~[Long(tail)]; } else { - let mut j = 1; - let mut last_valid_opt_id = None; - names = ~[]; - while j < curlen { - let range = str::char_range_at(cur, j); - let opt = Short(range.ch); - - /* In a series of potential options (eg. -aheJ), if we - see one which takes an argument, we assume all - subsequent characters make up the argument. This - allows options such as -L/usr/local/lib/foo to be - interpreted correctly - */ - - match find_opt(opts, opt) { - Some(id) => last_valid_opt_id = Some(id), - None => { - let arg_follows = - last_valid_opt_id.is_some() && - match opts[last_valid_opt_id.get()] - .hasarg { - - Yes | Maybe => true, - No => false - }; - if arg_follows && j < curlen { - i_arg = Some(cur.slice(j, curlen).to_owned()); - break; - } else { - last_valid_opt_id = None; - } - } - } - names.push(opt); - j = range.next; - } + names = + ~[Long(tail_eq[0])]; + i_arg = Some(tail_eq[1]); } - let mut name_pos = 0; - for names.each() |nm| { - name_pos += 1; - let optid = match find_opt(opts, *nm) { - Some(id) => id, - None => return Err(UnrecognizedOption(name_str(nm))) - }; - match opts[optid].hasarg { - No => { - if !i_arg.is_none() { - return Err(UnexpectedArgument(name_str(nm))); + } else { + let mut j = 1; + let mut last_valid_opt_id = None; + names = ~[]; + while j < curlen { + let range = str::char_range_at(cur, j); + let opt = Short(range.ch); + + /* In a series of potential options (eg. -aheJ), if we + see one which takes an argument, we assume all + subsequent characters make up the argument. This + allows options such as -L/usr/local/lib/foo to be + interpreted correctly + */ + + match find_opt(opts, opt) { + Some(id) => last_valid_opt_id = Some(id), + None => { + let arg_follows = + last_valid_opt_id.is_some() && + match opts[last_valid_opt_id.get()] + .hasarg { + + Yes | Maybe => true, + No => false + }; + if arg_follows && j < curlen { + i_arg = Some(cur.slice(j, curlen).to_owned()); + break; + } else { + last_valid_opt_id = None; } - vals[optid].push(Given); - } - Maybe => { - if !i_arg.is_none() { - vals[optid].push(Val(i_arg.get())); - } else if name_pos < names.len() || - i + 1 == l || is_arg(args[i + 1]) { - vals[optid].push(Given); - } else { i += 1; vals[optid].push(Val(args[i])); } - } - Yes => { - if !i_arg.is_none() { - vals[optid].push(Val(i_arg.get())); - } else if i + 1 == l { - return Err(ArgumentMissing(name_str(nm))); - } else { i += 1; vals[optid].push(Val(args[i])); } } } + names.push(opt); + j = range.next; } } - i += 1; - } - i = 0u; - while i < n_opts { - let n = vals[i].len(); - let occ = opts[i].occur; - if occ == Req { - if n == 0 { - return Err(OptionMissing(name_str(&(opts[i].name)))); + let mut name_pos = 0; + for names.each() |nm| { + name_pos += 1; + let optid = match find_opt(opts, *nm) { + Some(id) => id, + None => return Err(UnrecognizedOption(name_str(nm))) + }; + match opts[optid].hasarg { + No => { + if !i_arg.is_none() { + return Err(UnexpectedArgument(name_str(nm))); + } + vals[optid].push(Given); + } + Maybe => { + if !i_arg.is_none() { + vals[optid].push(Val(i_arg.get())); + } else if name_pos < names.len() || + i + 1 == l || is_arg(args[i + 1]) { + vals[optid].push(Given); + } else { i += 1; vals[optid].push(Val(args[i])); } + } + Yes => { + if !i_arg.is_none() { + vals[optid].push(Val(i_arg.get())); + } else if i + 1 == l { + return Err(ArgumentMissing(name_str(nm))); + } else { i += 1; vals[optid].push(Val(args[i])); } + } } } - if occ != Multi { - if n > 1 { - return Err(OptionDuplicated(name_str(&(opts[i].name)))); - } + } + i += 1; + } + i = 0u; + while i < n_opts { + let n = vals[i].len(); + let occ = opts[i].occur; + if occ == Req { + if n == 0 { + return Err(OptionMissing(name_str(&(opts[i].name)))); + } + } + if occ != Multi { + if n > 1 { + return Err(OptionDuplicated(name_str(&(opts[i].name)))); } - i += 1; } - return Ok(Matches {opts: vec::from_slice(opts), - vals: vals, - free: free}); + i += 1; } + return Ok(Matches {opts: vec::from_slice(opts), + vals: vals, + free: free}); } fn opt_vals(mm: &Matches, nm: &str) -> ~[Optval] { diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs index 6403e0eb5c47a..e920ff20ac5dc 100644 --- a/src/libstd/net_ip.rs +++ b/src/libstd/net_ip.rs @@ -116,35 +116,33 @@ pub fn get_addr(node: &str, iotask: &iotask) let mut output_ch = Some(SharedChan(output_ch)); do str::as_buf(node) |node_ptr, len| { let output_ch = output_ch.swap_unwrap(); - unsafe { - debug!("slice len %?", len); - let handle = create_uv_getaddrinfo_t(); - let handle_ptr = ptr::addr_of(&handle); - let handle_data = GetAddrData { - output_ch: output_ch.clone() - }; - let handle_data_ptr = ptr::addr_of(&handle_data); - do interact(iotask) |loop_ptr| { - unsafe { - let result = uv_getaddrinfo( - loop_ptr, - handle_ptr, - get_addr_cb, - node_ptr, - ptr::null(), - ptr::null()); - match result { - 0i32 => { - set_data_for_req(handle_ptr, handle_data_ptr); - } - _ => { - output_ch.send(result::Err(GetAddrUnknownError)); - } + debug!("slice len %?", len); + let handle = create_uv_getaddrinfo_t(); + let handle_ptr = ptr::addr_of(&handle); + let handle_data = GetAddrData { + output_ch: output_ch.clone() + }; + let handle_data_ptr = ptr::addr_of(&handle_data); + do interact(iotask) |loop_ptr| { + unsafe { + let result = uv_getaddrinfo( + loop_ptr, + handle_ptr, + get_addr_cb, + node_ptr, + ptr::null(), + ptr::null()); + match result { + 0i32 => { + set_data_for_req(handle_ptr, handle_data_ptr); + } + _ => { + output_ch.send(result::Err(GetAddrUnknownError)); } } - }; - output_po.recv() - } + } + }; + output_po.recv() } } diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs index 9630351b5c9be..a8b2723bcfbc4 100644 --- a/src/libstd/net_tcp.rs +++ b/src/libstd/net_tcp.rs @@ -57,9 +57,7 @@ pub struct TcpSocket { #[unsafe_destructor] impl Drop for TcpSocket { fn finalize(&self) { - unsafe { - tear_down_socket_data(self.socket_data) - } + tear_down_socket_data(self.socket_data) } } @@ -302,11 +300,10 @@ pub fn connect(input_ip: ip::IpAddr, port: uint, * `TcpErrData` value as the `Err` variant */ pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) - -> result::Result<(), TcpErrData> { - unsafe { - let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); - write_common_impl(socket_data_ptr, raw_write_data) - } + -> result::Result<(), TcpErrData> +{ + let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); + write_common_impl(socket_data_ptr, raw_write_data) } /** @@ -341,13 +338,12 @@ pub fn write(sock: &TcpSocket, raw_write_data: ~[u8]) * value as the `Err` variant */ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) - -> future::Future> { - unsafe { - let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); - do future_spawn { - let data_copy = copy(raw_write_data); - write_common_impl(socket_data_ptr, data_copy) - } + -> future::Future> +{ + let socket_data_ptr = ptr::addr_of(&(*(sock.socket_data))); + do future_spawn { + let data_copy = copy(raw_write_data); + write_common_impl(socket_data_ptr, data_copy) } } @@ -369,10 +365,8 @@ pub fn write_future(sock: &TcpSocket, raw_write_data: ~[u8]) pub fn read_start(sock: &TcpSocket) -> result::Result<@Port< result::Result<~[u8], TcpErrData>>, TcpErrData> { - unsafe { - let socket_data = ptr::addr_of(&(*(sock.socket_data))); - read_start_common_impl(socket_data) - } + let socket_data = ptr::addr_of(&(*(sock.socket_data))); + read_start_common_impl(socket_data) } /** @@ -382,12 +376,9 @@ pub fn read_start(sock: &TcpSocket) * * * `sock` - a `net::tcp::TcpSocket` that you wish to stop reading on */ -pub fn read_stop(sock: &TcpSocket) -> - result::Result<(), TcpErrData> { - unsafe { - let socket_data = ptr::addr_of(&(*sock.socket_data)); - read_stop_common_impl(socket_data) - } +pub fn read_stop(sock: &TcpSocket) -> result::Result<(), TcpErrData> { + let socket_data = ptr::addr_of(&(*sock.socket_data)); + read_stop_common_impl(socket_data) } /** @@ -654,150 +645,148 @@ fn listen_common(host_ip: ip::IpAddr, on_establish_cb: ~fn(SharedChan>), on_connect_cb: ~fn(*uv::ll::uv_tcp_t)) -> result::Result<(), TcpListenErrData> { - unsafe { - let (stream_closed_po, stream_closed_ch) = stream::<()>(); - let stream_closed_ch = SharedChan(stream_closed_ch); - let (kill_po, kill_ch) = stream::>(); - let kill_ch = SharedChan(kill_ch); - let server_stream = uv::ll::tcp_t(); - let server_stream_ptr = ptr::addr_of(&server_stream); - let server_data: TcpListenFcData = TcpListenFcData { - server_stream_ptr: server_stream_ptr, - stream_closed_ch: stream_closed_ch, - kill_ch: kill_ch.clone(), - on_connect_cb: on_connect_cb, - iotask: iotask.clone(), - ipv6: match &host_ip { - &ip::Ipv4(_) => { false } - &ip::Ipv6(_) => { true } - }, - mut active: true - }; - let server_data_ptr = ptr::addr_of(&server_data); - - let (setup_po, setup_ch) = stream(); - - // this is to address a compiler warning about - // an implicit copy.. it seems that double nested - // will defeat a move sigil, as is done to the host_ip - // arg above.. this same pattern works w/o complaint in - // tcp::connect (because the iotask::interact cb isn't - // nested within a core::comm::listen block) - let loc_ip = copy(host_ip); - do iotask::interact(iotask) |loop_ptr| { - unsafe { - match uv::ll::tcp_init(loop_ptr, server_stream_ptr) { - 0i32 => { - uv::ll::set_data_for_uv_handle( - server_stream_ptr, - server_data_ptr); - let addr_str = ip::format_addr(&loc_ip); - let bind_result = match loc_ip { - ip::Ipv4(ref addr) => { - debug!("addr: %?", addr); - let in_addr = uv::ll::ip4_addr( - addr_str, - port as int); - uv::ll::tcp_bind(server_stream_ptr, - ptr::addr_of(&in_addr)) - } - ip::Ipv6(ref addr) => { - debug!("addr: %?", addr); - let in_addr = uv::ll::ip6_addr( - addr_str, - port as int); - uv::ll::tcp_bind6(server_stream_ptr, - ptr::addr_of(&in_addr)) - } - }; - match bind_result { - 0i32 => { - match uv::ll::listen( - server_stream_ptr, - backlog as libc::c_int, - tcp_lfc_on_connection_cb) { - 0i32 => setup_ch.send(None), - _ => { - debug!( - "failure to uv_tcp_init"); - let err_data = - uv::ll::get_last_err_data( - loop_ptr); - setup_ch.send(Some(err_data)); - } + let (stream_closed_po, stream_closed_ch) = stream::<()>(); + let stream_closed_ch = SharedChan(stream_closed_ch); + let (kill_po, kill_ch) = stream::>(); + let kill_ch = SharedChan(kill_ch); + let server_stream = uv::ll::tcp_t(); + let server_stream_ptr = ptr::addr_of(&server_stream); + let server_data: TcpListenFcData = TcpListenFcData { + server_stream_ptr: server_stream_ptr, + stream_closed_ch: stream_closed_ch, + kill_ch: kill_ch.clone(), + on_connect_cb: on_connect_cb, + iotask: iotask.clone(), + ipv6: match &host_ip { + &ip::Ipv4(_) => { false } + &ip::Ipv6(_) => { true } + }, + mut active: true + }; + let server_data_ptr = ptr::addr_of(&server_data); + + let (setup_po, setup_ch) = stream(); + + // this is to address a compiler warning about + // an implicit copy.. it seems that double nested + // will defeat a move sigil, as is done to the host_ip + // arg above.. this same pattern works w/o complaint in + // tcp::connect (because the iotask::interact cb isn't + // nested within a core::comm::listen block) + let loc_ip = copy(host_ip); + do iotask::interact(iotask) |loop_ptr| { + unsafe { + match uv::ll::tcp_init(loop_ptr, server_stream_ptr) { + 0i32 => { + uv::ll::set_data_for_uv_handle( + server_stream_ptr, + server_data_ptr); + let addr_str = ip::format_addr(&loc_ip); + let bind_result = match loc_ip { + ip::Ipv4(ref addr) => { + debug!("addr: %?", addr); + let in_addr = uv::ll::ip4_addr( + addr_str, + port as int); + uv::ll::tcp_bind(server_stream_ptr, + ptr::addr_of(&in_addr)) + } + ip::Ipv6(ref addr) => { + debug!("addr: %?", addr); + let in_addr = uv::ll::ip6_addr( + addr_str, + port as int); + uv::ll::tcp_bind6(server_stream_ptr, + ptr::addr_of(&in_addr)) + } + }; + match bind_result { + 0i32 => { + match uv::ll::listen( + server_stream_ptr, + backlog as libc::c_int, + tcp_lfc_on_connection_cb) { + 0i32 => setup_ch.send(None), + _ => { + debug!( + "failure to uv_tcp_init"); + let err_data = + uv::ll::get_last_err_data( + loop_ptr); + setup_ch.send(Some(err_data)); } } - _ => { - debug!("failure to uv_tcp_bind"); - let err_data = uv::ll::get_last_err_data( - loop_ptr); - setup_ch.send(Some(err_data)); - } } - } - _ => { - debug!("failure to uv_tcp_bind"); - let err_data = uv::ll::get_last_err_data( - loop_ptr); - setup_ch.send(Some(err_data)); + _ => { + debug!("failure to uv_tcp_bind"); + let err_data = uv::ll::get_last_err_data( + loop_ptr); + setup_ch.send(Some(err_data)); + } } } + _ => { + debug!("failure to uv_tcp_bind"); + let err_data = uv::ll::get_last_err_data( + loop_ptr); + setup_ch.send(Some(err_data)); + } } } + } - let setup_result = setup_po.recv(); + let setup_result = setup_po.recv(); - match setup_result { - Some(ref err_data) => { - do iotask::interact(iotask) |loop_ptr| { - unsafe { - debug!( - "tcp::listen post-kill recv hl interact %?", - loop_ptr); - (*server_data_ptr).active = false; - uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); - } - }; - stream_closed_po.recv(); - match err_data.err_name { - ~"EACCES" => { - debug!("Got EACCES error"); - result::Err(AccessDenied) - } - ~"EADDRINUSE" => { - debug!("Got EADDRINUSE error"); - result::Err(AddressInUse) - } - _ => { - debug!("Got '%s' '%s' libuv error", - err_data.err_name, err_data.err_msg); - result::Err( - GenericListenErr(err_data.err_name, - err_data.err_msg)) - } + match setup_result { + Some(ref err_data) => { + do iotask::interact(iotask) |loop_ptr| { + unsafe { + debug!( + "tcp::listen post-kill recv hl interact %?", + loop_ptr); + (*server_data_ptr).active = false; + uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); + } + }; + stream_closed_po.recv(); + match err_data.err_name { + ~"EACCES" => { + debug!("Got EACCES error"); + result::Err(AccessDenied) + } + ~"EADDRINUSE" => { + debug!("Got EADDRINUSE error"); + result::Err(AddressInUse) + } + _ => { + debug!("Got '%s' '%s' libuv error", + err_data.err_name, err_data.err_msg); + result::Err( + GenericListenErr(err_data.err_name, + err_data.err_msg)) } } - None => { - on_establish_cb(kill_ch.clone()); - let kill_result = kill_po.recv(); - do iotask::interact(iotask) |loop_ptr| { - unsafe { - debug!( - "tcp::listen post-kill recv hl interact %?", - loop_ptr); - (*server_data_ptr).active = false; - uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); - } - }; - stream_closed_po.recv(); - match kill_result { - // some failure post bind/listen - Some(ref err_data) => result::Err(GenericListenErr( - err_data.err_name, - err_data.err_msg)), - // clean exit - None => result::Ok(()) + } + None => { + on_establish_cb(kill_ch.clone()); + let kill_result = kill_po.recv(); + do iotask::interact(iotask) |loop_ptr| { + unsafe { + debug!( + "tcp::listen post-kill recv hl interact %?", + loop_ptr); + (*server_data_ptr).active = false; + uv::ll::close(server_stream_ptr, tcp_lfc_close_cb); } + }; + stream_closed_po.recv(); + match kill_result { + // some failure post bind/listen + Some(ref err_data) => result::Err(GenericListenErr( + err_data.err_name, + err_data.err_msg)), + // clean exit + None => result::Ok(()) } } } @@ -1382,9 +1371,7 @@ extern fn stream_error_close_cb(handle: *uv::ll::uv_tcp_t) { } extern fn tcp_connect_close_cb(handle: *uv::ll::uv_tcp_t) { - unsafe { - debug!("closed client tcp handle %?", handle); - } + debug!("closed client tcp handle %?", handle); } extern fn tcp_connect_on_connect_cb(connect_req_ptr: *uv::ll::uv_connect_t, diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs index b8e0d9d9b2ac4..9b8b0f9be0bcd 100644 --- a/src/libstd/net_url.rs +++ b/src/libstd/net_url.rs @@ -118,8 +118,7 @@ fn encode_inner(s: &str, full_url: bool) -> ~str { * This function is compliant with RFC 3986. */ pub fn encode(s: &str) -> ~str { - // FIXME(#3722): unsafe only because encode_inner does (string) IO - unsafe {encode_inner(s, true)} + encode_inner(s, true) } /** @@ -130,8 +129,7 @@ pub fn encode(s: &str) -> ~str { */ pub fn encode_component(s: &str) -> ~str { - // FIXME(#3722): unsafe only because encode_inner does (string) IO - unsafe {encode_inner(s, false)} + encode_inner(s, false) } fn decode_inner(s: &str, full_url: bool) -> ~str { @@ -178,16 +176,14 @@ fn decode_inner(s: &str, full_url: bool) -> ~str { * This will only decode escape sequences generated by encode. */ pub fn decode(s: &str) -> ~str { - // FIXME(#3722): unsafe only because decode_inner does (string) IO - unsafe {decode_inner(s, true)} + decode_inner(s, true) } /** * Decode a string encoded with percent encoding. */ pub fn decode_component(s: &str) -> ~str { - // FIXME(#3722): unsafe only because decode_inner does (string) IO - unsafe {decode_inner(s, false)} + decode_inner(s, false) } fn encode_plus(s: &str) -> ~str { @@ -301,18 +297,15 @@ fn split_char_first(s: &str, c: char) -> (~str, ~str) { let len = str::len(s); let mut index = len; let mut mat = 0; - // FIXME(#3722): unsafe only because decode_inner does (string) IO - unsafe { - do io::with_str_reader(s) |rdr| { - let mut ch; - while !rdr.eof() { - ch = rdr.read_byte() as char; - if ch == c { - // found a match, adjust markers - index = rdr.tell()-1; - mat = 1; - break; - } + do io::with_str_reader(s) |rdr| { + let mut ch; + while !rdr.eof() { + ch = rdr.read_byte() as char; + if ch == c { + // found a match, adjust markers + index = rdr.tell()-1; + mat = 1; + break; } } } @@ -346,29 +339,25 @@ fn query_from_str(rawquery: &str) -> Query { if str::len(rawquery) != 0 { for str::each_split_char(rawquery, '&') |p| { let (k, v) = split_char_first(p, '='); - // FIXME(#3722): unsafe only because decode_inner does (string) IO - unsafe {query.push((decode_component(k), decode_component(v)));} + query.push((decode_component(k), decode_component(v))); }; } return query; } pub fn query_to_str(query: &Query) -> ~str { - unsafe { - // FIXME(#3722): unsafe only because decode_inner does (string) IO - let mut strvec = ~[]; - for query.each |kv| { - match kv { - &(ref k, ref v) => { - strvec.push(fmt!("%s=%s", - encode_component(*k), - encode_component(*v)) - ); - } + let mut strvec = ~[]; + for query.each |kv| { + match kv { + &(ref k, ref v) => { + strvec.push(fmt!("%s=%s", + encode_component(*k), + encode_component(*v)) + ); } } - return str::connect(strvec, ~"&"); } + return str::connect(strvec, ~"&"); } // returns the scheme and the rest of the url, or a parsing error diff --git a/src/libstd/rl.rs b/src/libstd/rl.rs index a8b25767ce595..9f9f2323d271b 100644 --- a/src/libstd/rl.rs +++ b/src/libstd/rl.rs @@ -59,12 +59,10 @@ pub unsafe fn load_history(file: ~str) -> bool { /// Print out a prompt and then wait for input and return it pub unsafe fn read(prompt: ~str) -> Option<~str> { do str::as_c_str(prompt) |buf| { - unsafe { - let line = rustrt::linenoise(buf); + let line = rustrt::linenoise(buf); - if line.is_null() { None } - else { Some(str::raw::from_c_str(line)) } - } + if line.is_null() { None } + else { Some(str::raw::from_c_str(line)) } } } @@ -74,22 +72,20 @@ fn complete_key(_v: @CompletionCb) {} /// Bind to the main completion callback pub unsafe fn complete(cb: CompletionCb) { - unsafe { - task::local_data::local_data_set(complete_key, @(cb)); - - extern fn callback(line: *c_char, completions: *()) { - unsafe { - let cb = *task::local_data::local_data_get(complete_key) - .get(); - - do cb(str::raw::from_c_str(line)) |suggestion| { - do str::as_c_str(suggestion) |buf| { - rustrt::linenoiseAddCompletion(completions, buf); - } + task::local_data::local_data_set(complete_key, @(cb)); + + extern fn callback(line: *c_char, completions: *()) { + unsafe { + let cb = *task::local_data::local_data_get(complete_key) + .get(); + + do cb(str::raw::from_c_str(line)) |suggestion| { + do str::as_c_str(suggestion) |buf| { + rustrt::linenoiseAddCompletion(completions, buf); } } } - - rustrt::linenoiseSetCompletionCallback(callback); } + + rustrt::linenoiseSetCompletionCallback(callback); } diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 232f46b6676df..653283f2e78b9 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -862,17 +862,15 @@ pub mod node { * This function executes in linear time. */ pub fn flatten(node: @Node) -> @Node { - unsafe { - match (*node) { - Leaf(_) => node, - Concat(ref x) => { - @Leaf(Leaf { - byte_offset: 0u, - byte_len: x.byte_len, - char_len: x.char_len, - content: @serialize_node(node), - }) - } + match (*node) { + Leaf(_) => node, + Concat(ref x) => { + @Leaf(Leaf { + byte_offset: 0u, + byte_len: x.byte_len, + char_len: x.char_len, + content: @serialize_node(node), + }) } } } diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs index 1bfdd7f99d501..f2de8213a1b9e 100644 --- a/src/libstd/sync.rs +++ b/src/libstd/sync.rs @@ -101,17 +101,15 @@ fn new_sem_and_signal(count: int, num_condvars: uint) pub impl Sem { fn acquire(&self) { let mut waiter_nobe = None; - unsafe { - do (**self).with |state| { - state.count -= 1; - if state.count < 0 { - // Create waiter nobe. - let (WaitEnd, SignalEnd) = comm::oneshot(); - // Tell outer scope we need to block. - waiter_nobe = Some(WaitEnd); - // Enqueue ourself. - state.waiters.tail.send(SignalEnd); - } + do (**self).with |state| { + state.count -= 1; + if state.count < 0 { + // Create waiter nobe. + let (WaitEnd, SignalEnd) = comm::oneshot(); + // Tell outer scope we need to block. + waiter_nobe = Some(WaitEnd); + // Enqueue ourself. + state.waiters.tail.send(SignalEnd); } } // Uncomment if you wish to test for sem races. Not valgrind-friendly. @@ -122,12 +120,10 @@ pub impl Sem { } } fn release(&self) { - unsafe { - do (**self).with |state| { - state.count += 1; - if state.count <= 0 { - signal_waitqueue(&state.waiters); - } + do (**self).with |state| { + state.count += 1; + if state.count <= 0 { + signal_waitqueue(&state.waiters); } } } @@ -169,9 +165,7 @@ struct SemReleaseGeneric<'self, Q> { sem: &'self Sem } #[unsafe_destructor] impl<'self, Q:Owned> Drop for SemReleaseGeneric<'self, Q> { fn finalize(&self) { - unsafe { - self.sem.release(); - } + self.sem.release(); } } @@ -291,13 +285,11 @@ pub impl<'self> Condvar<'self> { fn signal_on(&self, condvar_id: uint) -> bool { let mut out_of_bounds = None; let mut result = false; - unsafe { - do (**self.sem).with |state| { - if condvar_id < vec::len(state.blocked) { - result = signal_waitqueue(&state.blocked[condvar_id]); - } else { - out_of_bounds = Some(vec::len(state.blocked)); - } + do (**self.sem).with |state| { + if condvar_id < vec::len(state.blocked) { + result = signal_waitqueue(&state.blocked[condvar_id]); + } else { + out_of_bounds = Some(vec::len(state.blocked)); } } do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { @@ -312,17 +304,15 @@ pub impl<'self> Condvar<'self> { fn broadcast_on(&self, condvar_id: uint) -> uint { let mut out_of_bounds = None; let mut queue = None; - unsafe { - do (**self.sem).with |state| { - if condvar_id < vec::len(state.blocked) { - // To avoid :broadcast_heavy, we make a new waitqueue, - // swap it out with the old one, and broadcast on the - // old one outside of the little-lock. - queue = Some(util::replace(&mut state.blocked[condvar_id], - new_waitqueue())); - } else { - out_of_bounds = Some(vec::len(state.blocked)); - } + do (**self.sem).with |state| { + if condvar_id < vec::len(state.blocked) { + // To avoid :broadcast_heavy, we make a new waitqueue, + // swap it out with the old one, and broadcast on the + // old one outside of the little-lock. + queue = Some(util::replace(&mut state.blocked[condvar_id], + new_waitqueue())); + } else { + out_of_bounds = Some(vec::len(state.blocked)); } } do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs index 229d1a07caaab..99e772b0c95a3 100644 --- a/src/libstd/timer.rs +++ b/src/libstd/timer.rs @@ -42,47 +42,45 @@ pub fn delayed_send(iotask: &IoTask, msecs: uint, ch: &Chan, val: T) { + let (timer_done_po, timer_done_ch) = stream::<()>(); + let timer_done_ch = SharedChan(timer_done_ch); + let timer = uv::ll::timer_t(); + let timer_ptr = ptr::addr_of(&timer); + do iotask::interact(iotask) |loop_ptr| { unsafe { - let (timer_done_po, timer_done_ch) = stream::<()>(); - let timer_done_ch = SharedChan(timer_done_ch); - let timer = uv::ll::timer_t(); - let timer_ptr = ptr::addr_of(&timer); - do iotask::interact(iotask) |loop_ptr| { - unsafe { - let init_result = uv::ll::timer_init(loop_ptr, timer_ptr); - if (init_result == 0i32) { - let start_result = uv::ll::timer_start( - timer_ptr, delayed_send_cb, msecs, 0u); - if (start_result == 0i32) { - // Note: putting the channel into a ~ - // to cast to *c_void - let timer_done_ch_clone = ~timer_done_ch.clone(); - let timer_done_ch_ptr = transmute::< - ~SharedChan<()>, *c_void>( - timer_done_ch_clone); - uv::ll::set_data_for_uv_handle( - timer_ptr, - timer_done_ch_ptr); - } else { - let error_msg = uv::ll::get_last_err_info( - loop_ptr); - fail!(~"timer::delayed_send() start failed: " + - error_msg); - } - } else { - let error_msg = uv::ll::get_last_err_info(loop_ptr); - fail!(~"timer::delayed_send() init failed: " + - error_msg); - } + let init_result = uv::ll::timer_init(loop_ptr, timer_ptr); + if (init_result == 0i32) { + let start_result = uv::ll::timer_start( + timer_ptr, delayed_send_cb, msecs, 0u); + if (start_result == 0i32) { + // Note: putting the channel into a ~ + // to cast to *c_void + let timer_done_ch_clone = ~timer_done_ch.clone(); + let timer_done_ch_ptr = transmute::< + ~SharedChan<()>, *c_void>( + timer_done_ch_clone); + uv::ll::set_data_for_uv_handle( + timer_ptr, + timer_done_ch_ptr); + } else { + let error_msg = uv::ll::get_last_err_info( + loop_ptr); + fail!(~"timer::delayed_send() start failed: " + + error_msg); } - }; - // delayed_send_cb has been processed by libuv - timer_done_po.recv(); - // notify the caller immediately - ch.send(val); - // uv_close for this timer has been processed - timer_done_po.recv(); + } else { + let error_msg = uv::ll::get_last_err_info(loop_ptr); + fail!(~"timer::delayed_send() init failed: " + + error_msg); + } + } }; + // delayed_send_cb has been processed by libuv + timer_done_po.recv(); + // notify the caller immediately + ch.send(val); + // uv_close for this timer has been processed + timer_done_po.recv(); } /** diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs index fe40fc6a78b41..7a9d2438e6ada 100644 --- a/src/libstd/uv_iotask.rs +++ b/src/libstd/uv_iotask.rs @@ -75,7 +75,7 @@ pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask { * module. It is not safe to send the `loop_ptr` param to this callback out * via ports/chans. */ -pub unsafe fn interact(iotask: &IoTask, cb: ~fn(*c_void)) { +pub fn interact(iotask: &IoTask, cb: ~fn(*c_void)) { send_msg(iotask, Interaction(cb)); } @@ -87,9 +87,7 @@ pub unsafe fn interact(iotask: &IoTask, cb: ~fn(*c_void)) { * closed, causing a failure otherwise. */ pub fn exit(iotask: &IoTask) { - unsafe { - send_msg(iotask, TeardownLoop); - } + send_msg(iotask, TeardownLoop); } diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs index 7582a7cff513c..3bf297027d4d6 100644 --- a/src/libstd/uv_ll.rs +++ b/src/libstd/uv_ll.rs @@ -1111,22 +1111,22 @@ pub unsafe fn freeaddrinfo(res: *addrinfo) { } // libuv struct initializers -pub unsafe fn tcp_t() -> uv_tcp_t { +pub fn tcp_t() -> uv_tcp_t { return uv_ll_struct_stubgen::gen_stub_uv_tcp_t(); } -pub unsafe fn connect_t() -> uv_connect_t { +pub fn connect_t() -> uv_connect_t { return uv_ll_struct_stubgen::gen_stub_uv_connect_t(); } -pub unsafe fn write_t() -> uv_write_t { +pub fn write_t() -> uv_write_t { return uv_ll_struct_stubgen::gen_stub_uv_write_t(); } -pub unsafe fn async_t() -> uv_async_t { +pub fn async_t() -> uv_async_t { return uv_ll_struct_stubgen::gen_stub_uv_async_t(); } -pub unsafe fn timer_t() -> uv_timer_t { +pub fn timer_t() -> uv_timer_t { return uv_ll_struct_stubgen::gen_stub_uv_timer_t(); } -pub unsafe fn getaddrinfo_t() -> uv_getaddrinfo_t { +pub fn getaddrinfo_t() -> uv_getaddrinfo_t { return uv_ll_struct_stubgen::gen_stub_uv_getaddrinfo_t(); } diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 37fed113382a2..a848f97d2e09e 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -274,13 +274,11 @@ impl ToStr for Abi { impl ToStr for AbiSet { fn to_str(&self) -> ~str { - unsafe { // so we can push to strs. - let mut strs = ~[]; - for self.each |abi| { - strs.push(abi.data().name); - } - fmt!("\"%s\"", str::connect_slices(strs, " ")) + let mut strs = ~[]; + for self.each |abi| { + strs.push(abi.data().name); } + fmt!("\"%s\"", str::connect_slices(strs, " ")) } } diff --git a/src/test/compile-fail/unused-unsafe.rs b/src/test/compile-fail/unused-unsafe.rs new file mode 100644 index 0000000000000..368a0fbe9bece --- /dev/null +++ b/src/test/compile-fail/unused-unsafe.rs @@ -0,0 +1,44 @@ +// Copyright 2013 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. + +// Exercise the unused_unsafe attribute in some positive and negative cases + +#[deny(unused_unsafe)]; + +use core::libc; + +fn callback(_f: &fn() -> T) -> T { fail!() } + +fn bad1() { unsafe {} } //~ ERROR: unnecessary "unsafe" block +fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary "unsafe" block +unsafe fn bad3() {} //~ ERROR: unnecessary "unsafe" function +unsafe fn bad4() { unsafe {} } //~ ERROR: unnecessary "unsafe" function + //~^ ERROR: unnecessary "unsafe" block +fn bad5() { unsafe { do callback {} } } //~ ERROR: unnecessary "unsafe" block + +unsafe fn good0() { libc::exit(1) } +fn good1() { unsafe { libc::exit(1) } } +fn good2() { + /* bug uncovered when implementing warning about unused unsafe blocks. Be + sure that when purity is inherited that the source of the unsafe-ness + is tracked correctly */ + unsafe { + unsafe fn what() -> ~[~str] { libc::exit(2) } + + do callback { + what(); + } + } +} + +#[allow(unused_unsafe)] unsafe fn allowed0() {} +#[allow(unused_unsafe)] fn allowed1() { unsafe {} } + +fn main() { }