Skip to content

Commit f73a48e

Browse files
committed
auto merge of #10120 : Kimundi/rust/remove_sys, r=alexcrichton
- `begin_unwind` and `fail!` is now generic over any `T: Any + Send`. - Every value you fail with gets boxed as an `~Any`. - Because of implementation issues, `&'static str` and `~str` are still handled specially behind the scenes. - Changed the big macro source string in libsyntax to a raw string literal, and enabled doc comments there.
2 parents 6789a77 + 54f4dcd commit f73a48e

File tree

16 files changed

+187
-229
lines changed

16 files changed

+187
-229
lines changed

src/libextra/extra.rs

+2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ pub mod extra {
118118
pub use std::clone;
119119
pub use std::condition;
120120
pub use std::cmp;
121+
// NOTE: Remove import after next snapshot
122+
#[cfg(stage0)]
121123
pub use std::sys;
122124
pub use std::unstable;
123125
pub use std::str;

src/libstd/rt/borrowck.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) ->
6565
None => { // not recording borrows
6666
let msg = "borrowed";
6767
do msg.with_c_str |msg_p| {
68-
task::begin_unwind(msg_p, file, line);
68+
task::begin_unwind_raw(msg_p, file, line);
6969
}
7070
}
7171
Some(borrow_list) => { // recording borrows
@@ -81,7 +81,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) ->
8181
}
8282
}
8383
do msg.with_c_str |msg_p| {
84-
task::begin_unwind(msg_p, file, line)
84+
task::begin_unwind_raw(msg_p, file, line)
8585
}
8686
}
8787
}
@@ -180,7 +180,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
180180
if br.box != a || br.file != file || br.line != line {
181181
let err = format!("wrong borrow found, br={:?}", br);
182182
do err.with_c_str |msg_p| {
183-
task::begin_unwind(msg_p, file, line)
183+
task::begin_unwind_raw(msg_p, file, line)
184184
}
185185
}
186186
borrow_list

src/libstd/rt/kill.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ use cell::Cell;
155155
use option::{Option, Some, None};
156156
use prelude::*;
157157
use rt::task::Task;
158-
use rt::task::UnwindReasonLinked;
158+
use rt::task::UnwindMessageLinked;
159159
use rt::task::{UnwindResult, Failure};
160160
use task::spawn::Taskgroup;
161161
use to_bytes::IterBytes;
@@ -597,7 +597,7 @@ impl Death {
597597
}
598598

599599
if !success {
600-
result = Cell::new(Failure(UnwindReasonLinked));
600+
result = Cell::new(Failure(UnwindMessageLinked));
601601
}
602602
}
603603
on_exit(result.take());

src/libstd/rt/task.rs

+52-19
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ pub enum UnwindResult {
9595
/// The task is ending successfully
9696
Success,
9797

98-
/// The Task is failing with reason `UnwindReason`
99-
Failure(UnwindReason),
98+
/// The Task is failing with reason `UnwindMessage`
99+
Failure(UnwindMessage),
100100
}
101101

102102
impl UnwindResult {
@@ -121,20 +121,25 @@ impl UnwindResult {
121121

122122
/// Represents the cause of a task failure
123123
#[deriving(ToStr)]
124-
pub enum UnwindReason {
125-
/// Failed with a string message
126-
UnwindReasonStr(SendStr),
124+
pub enum UnwindMessage {
125+
// FIXME: #9913 - This variant is not neccessary once Any works properly
126+
/// Failed with a static string message
127+
UnwindMessageStrStatic(&'static str),
128+
129+
// FIXME: #9913 - This variant is not neccessary once Any works properly
130+
/// Failed with a owned string message
131+
UnwindMessageStrOwned(~str),
127132

128133
/// Failed with an `~Any`
129-
UnwindReasonAny(~Any),
134+
UnwindMessageAny(~Any),
130135

131136
/// Failed because of linked failure
132-
UnwindReasonLinked
137+
UnwindMessageLinked
133138
}
134139

135140
pub struct Unwinder {
136141
unwinding: bool,
137-
cause: Option<UnwindReason>
142+
cause: Option<UnwindMessage>
138143
}
139144

140145
impl Unwinder {
@@ -527,7 +532,7 @@ impl Unwinder {
527532
}
528533
}
529534

530-
pub fn begin_unwind(&mut self, cause: UnwindReason) -> ! {
535+
pub fn begin_unwind(&mut self, cause: UnwindMessage) -> ! {
531536
#[fixed_stack_segment]; #[inline(never)];
532537

533538
self.unwinding = true;
@@ -622,7 +627,7 @@ pub extern "C" fn rust_stack_exhausted() {
622627
/// This is the entry point of unwinding for things like lang items and such.
623628
/// The arguments are normally generated by the compiler, and need to
624629
/// have static lifetimes.
625-
pub fn begin_unwind(msg: *c_char, file: *c_char, line: size_t) -> ! {
630+
pub fn begin_unwind_raw(msg: *c_char, file: *c_char, line: size_t) -> ! {
626631
use c_str::CString;
627632
use cast::transmute;
628633

@@ -638,11 +643,33 @@ pub fn begin_unwind(msg: *c_char, file: *c_char, line: size_t) -> ! {
638643
let msg = static_char_ptr(msg);
639644
let file = static_char_ptr(file);
640645

641-
begin_unwind_reason(UnwindReasonStr(msg.into_send_str()), file, line as uint)
646+
begin_unwind(msg, file, line as uint)
642647
}
643648

644649
/// This is the entry point of unwinding for fail!() and assert!().
645-
pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint) -> ! {
650+
pub fn begin_unwind<M: Any + Send>(msg: M, file: &'static str, line: uint) -> ! {
651+
// Wrap the fail message in a `Any` box for uniform representation.
652+
let any = ~msg as ~Any;
653+
654+
// FIXME: #9913 - This can be changed to be internal to begin_unwind_internal
655+
// once Any works properly.
656+
// As a workaround, string types need to be special cased right now
657+
// because `Any` does not support dynamically querying whether the
658+
// type implements a trait yet, so without requiring that every `Any`
659+
// also implements `ToStr` there is no way to get a failure message
660+
// out of it again during unwinding.
661+
let msg = if any.is::<&'static str>() {
662+
UnwindMessageStrStatic(*any.move::<&'static str>().unwrap())
663+
} else if any.is::<~str>() {
664+
UnwindMessageStrOwned(*any.move::<~str>().unwrap())
665+
} else {
666+
UnwindMessageAny(any)
667+
};
668+
669+
begin_unwind_internal(msg, file, line)
670+
}
671+
672+
fn begin_unwind_internal(msg: UnwindMessage, file: &'static str, line: uint) -> ! {
646673
use rt::in_green_task_context;
647674
use rt::task::Task;
648675
use rt::local::Local;
@@ -656,15 +683,16 @@ pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint)
656683
let task: *mut Task;
657684

658685
{
659-
let msg = match reason {
660-
UnwindReasonStr(ref s) => s.as_slice(),
661-
UnwindReasonAny(_) => "~Any",
662-
UnwindReasonLinked => "linked failure",
686+
let msg_s = match msg {
687+
UnwindMessageAny(_) => "~Any",
688+
UnwindMessageLinked => "linked failure",
689+
UnwindMessageStrOwned(ref s) => s.as_slice(),
690+
UnwindMessageStrStatic(ref s) => s.as_slice(),
663691
};
664692

665693
if !in_green_task_context() {
666694
rterrln!("failed in non-task context at '{}', {}:{}",
667-
msg, file, line);
695+
msg_s, file, line);
668696
intrinsics::abort();
669697
}
670698

@@ -679,19 +707,20 @@ pub fn begin_unwind_reason(reason: UnwindReason, file: &'static str, line: uint)
679707
// due to mismanagment of its own kill flag, so calling our own
680708
// logger in its current state is a bit of a problem.
681709

682-
rterrln!("task '{}' failed at '{}', {}:{}", n, msg, file, line);
710+
rterrln!("task '{}' failed at '{}', {}:{}", n, msg_s, file, line);
683711

684712
if (*task).unwinder.unwinding {
685713
rtabort!("unwinding again");
686714
}
687715
}
688716

689-
(*task).unwinder.begin_unwind(reason);
717+
(*task).unwinder.begin_unwind(msg);
690718
}
691719
}
692720

693721
#[cfg(test)]
694722
mod test {
723+
use super::*;
695724
use rt::test::*;
696725

697726
#[test]
@@ -804,4 +833,8 @@ mod test {
804833
a.next = Some(b);
805834
}
806835
}
836+
837+
#[test]
838+
#[should_fail]
839+
fn test_begin_unwind() { begin_unwind("cause", file!(), line!()) }
807840
}

src/libstd/std.rs

+5
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ pub mod os;
184184
pub mod path;
185185
pub mod rand;
186186
pub mod run;
187+
// NOTE: Remove module after next snapshot
188+
#[cfg(stage0)]
187189
pub mod sys;
188190
pub mod cast;
189191
pub mod fmt;
@@ -226,7 +228,10 @@ mod std {
226228
pub use logging;
227229
pub use option;
228230
pub use os;
231+
pub use rt;
229232
pub use str;
233+
// NOTE: Remove import after next snapshot
234+
#[cfg(stage0)]
230235
pub use sys;
231236
pub use to_bytes;
232237
pub use to_str;

src/libstd/sys.rs

+5-84
Original file line numberDiff line numberDiff line change
@@ -10,99 +10,20 @@
1010

1111
//! Misc low level stuff
1212
13+
// NOTE: Remove this module after an snapshot
14+
1315
#[allow(missing_doc)];
1416

1517
use any::Any;
1618
use kinds::Send;
17-
use rt::task::{UnwindReasonStr, UnwindReasonAny};
1819
use rt::task;
19-
use send_str::{SendStr, IntoSendStr};
2020

21-
/// Trait for initiating task failure with a sendable cause.
2221
pub trait FailWithCause {
23-
/// Fail the current task with `cause`.
2422
fn fail_with(cause: Self, file: &'static str, line: uint) -> !;
2523
}
2624

27-
impl FailWithCause for ~str {
28-
fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
29-
task::begin_unwind_reason(UnwindReasonStr(cause.into_send_str()), file, line)
30-
}
31-
}
32-
33-
impl FailWithCause for &'static str {
34-
fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
35-
task::begin_unwind_reason(UnwindReasonStr(cause.into_send_str()), file, line)
36-
}
37-
}
38-
39-
impl FailWithCause for SendStr {
40-
fn fail_with(cause: SendStr, file: &'static str, line: uint) -> ! {
41-
task::begin_unwind_reason(UnwindReasonStr(cause), file, line)
42-
}
43-
}
44-
45-
impl FailWithCause for ~Any {
46-
fn fail_with(cause: ~Any, file: &'static str, line: uint) -> ! {
47-
task::begin_unwind_reason(UnwindReasonAny(cause), file, line)
48-
}
49-
}
50-
51-
impl<T: Any + Send + 'static> FailWithCause for ~T {
52-
fn fail_with(cause: ~T, file: &'static str, line: uint) -> ! {
53-
task::begin_unwind_reason(UnwindReasonAny(cause as ~Any), file, line)
54-
}
55-
}
56-
57-
#[cfg(test)]
58-
mod tests {
59-
use super::*;
60-
61-
use any::Any;
62-
use cast;
63-
use send_str::IntoSendStr;
64-
65-
#[test]
66-
fn synthesize_closure() {
67-
use unstable::raw::Closure;
68-
unsafe {
69-
let x = 10;
70-
let f: &fn(int) -> int = |y| x + y;
71-
72-
assert_eq!(f(20), 30);
73-
74-
let original_closure: Closure = cast::transmute(f);
75-
76-
let actual_function_pointer = original_closure.code;
77-
let environment = original_closure.env;
78-
79-
let new_closure = Closure {
80-
code: actual_function_pointer,
81-
env: environment
82-
};
83-
84-
let new_f: &fn(int) -> int = cast::transmute(new_closure);
85-
assert_eq!(new_f(20), 30);
86-
}
25+
impl<T: Any + Send> FailWithCause for T {
26+
fn fail_with(msg: T, file: &'static str, line: uint) -> ! {
27+
task::begin_unwind(msg, file, line)
8728
}
88-
89-
#[test]
90-
#[should_fail]
91-
fn fail_static() { FailWithCause::fail_with("cause", file!(), line!()) }
92-
93-
#[test]
94-
#[should_fail]
95-
fn fail_owned() { FailWithCause::fail_with(~"cause", file!(), line!()) }
96-
97-
#[test]
98-
#[should_fail]
99-
fn fail_send() { FailWithCause::fail_with("cause".into_send_str(), file!(), line!()) }
100-
101-
#[test]
102-
#[should_fail]
103-
fn fail_any() { FailWithCause::fail_with(~612_u16 as ~Any, file!(), line!()) }
104-
105-
#[test]
106-
#[should_fail]
107-
fn fail_any_wrap() { FailWithCause::fail_with(~413_u16, file!(), line!()) }
10829
}

0 commit comments

Comments
 (0)