Skip to content

Commit 71acc54

Browse files
committed
Make TypeContents consider the type T to be reachable via *T pointers
Fixes #9509
1 parent 3d1f3f4 commit 71acc54

File tree

4 files changed

+128
-12
lines changed

4 files changed

+128
-12
lines changed

src/librustc/middle/ty.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2088,7 +2088,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20882088
let result = match get(ty).sty {
20892089
// Scalar and unique types are sendable, freezable, and durable
20902090
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_uint(_) | ty_float(_) |
2091-
ty_bare_fn(_) | ty_ptr(_) | ty::ty_char => {
2091+
ty_bare_fn(_) | ty::ty_char => {
20922092
TC::None
20932093
}
20942094

@@ -2108,6 +2108,10 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
21082108
object_contents(cx, store, mutbl, bounds)
21092109
}
21102110

2111+
ty_ptr(ref mt) => {
2112+
tc_ty(cx, mt.ty, cache).other_pointer(TC::None)
2113+
}
2114+
21112115
ty_rptr(r, ref mt) => {
21122116
tc_ty(cx, mt.ty, cache).other_pointer(
21132117
borrowed_contents(r, mt.mutbl))

src/librustuv/uvio.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,10 @@ impl UvIoFactory {
414414
/// callback in a situation where the task wil be immediately blocked
415415
/// afterwards. The `FsCallback` yielded must be invoked to reschedule the task
416416
/// (once the result of the operation is known).
417-
fn uv_fs_helper<T>(loop_: &mut Loop,
418-
retfn: extern "Rust" fn(&mut FsRequest) -> T,
419-
cb: &fn(&mut FsRequest, &mut Loop, FsCallback))
420-
-> Result<T, IoError> {
417+
fn uv_fs_helper<T:Send>(loop_: &mut Loop,
418+
retfn: extern "Rust" fn(&mut FsRequest) -> T,
419+
cb: &fn(&mut FsRequest, &mut Loop, FsCallback))
420+
-> Result<T, IoError> {
421421
let result_cell = Cell::new_empty();
422422
let result_cell_ptr: *Cell<Result<T, IoError>> = &result_cell;
423423
do task::unkillable { // FIXME(#8674)
@@ -1025,14 +1025,12 @@ fn read_stream(mut watcher: StreamWatcher,
10251025
let result_cell = Cell::new_empty();
10261026
let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell;
10271027

1028-
let buf_ptr: *&mut [u8] = &buf;
1028+
let uv_buf = slice_to_uv_buf(buf);
10291029
do scheduler.deschedule_running_task_and_then |_sched, task| {
10301030
let task_cell = Cell::new(task);
10311031
// XXX: We shouldn't reallocate these callbacks every
10321032
// call to read
1033-
let alloc: AllocCallback = |_| unsafe {
1034-
slice_to_uv_buf(*buf_ptr)
1035-
};
1033+
let alloc: AllocCallback = |_| uv_buf;
10361034
do watcher.read_start(alloc) |mut watcher, nread, _buf, status| {
10371035

10381036
// Stop reading so that no read callbacks are
@@ -1280,11 +1278,10 @@ impl RtioUdpSocket for UvUdpSocket {
12801278
do self.home_for_io_with_sched |self_, scheduler| {
12811279
let result_cell = Cell::new_empty();
12821280
let result_cell_ptr: *Cell<Result<(uint, SocketAddr), IoError>> = &result_cell;
1283-
1284-
let buf_ptr: *&mut [u8] = &buf;
1281+
let uv_buf = slice_to_uv_buf(buf);
12851282
do scheduler.deschedule_running_task_and_then |_, task| {
12861283
let task_cell = Cell::new(task);
1287-
let alloc: AllocCallback = |_| unsafe { slice_to_uv_buf(*buf_ptr) };
1284+
let alloc: AllocCallback = |_| uv_buf;
12881285
do self_.watcher.recv_start(alloc) |mut watcher, nread, _buf, addr, flags, status| {
12891286
let _ = flags; // /XXX add handling for partials?
12901287

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test which of the builtin types are considered freezeable.
12+
13+
fn assert_freeze<T:Freeze>() { }
14+
trait Dummy { }
15+
16+
fn test<'a,T,U:Freeze>(_: &'a int) {
17+
// lifetime pointers are ok...
18+
assert_freeze::<&'static int>();
19+
assert_freeze::<&'a int>();
20+
assert_freeze::<&'a str>();
21+
assert_freeze::<&'a [int]>();
22+
23+
// ...unless they are mutable
24+
assert_freeze::<&'static mut int>(); //~ ERROR does not fulfill `Freeze`
25+
assert_freeze::<&'a mut int>(); //~ ERROR does not fulfill `Freeze`
26+
27+
// ~ pointers are ok
28+
assert_freeze::<~int>();
29+
assert_freeze::<~str>();
30+
assert_freeze::<~[int]>();
31+
32+
// but not if they own a bad thing
33+
assert_freeze::<~&'a mut int>(); //~ ERROR does not fulfill `Freeze`
34+
35+
// careful with object types, who knows what they close over...
36+
assert_freeze::<&'a Dummy>(); //~ ERROR does not fulfill `Freeze`
37+
assert_freeze::<~Dummy>(); //~ ERROR does not fulfill `Freeze`
38+
39+
// ...unless they are properly bounded
40+
assert_freeze::<&'a Dummy:Freeze>();
41+
assert_freeze::<&'static Dummy:Freeze>();
42+
assert_freeze::<~Dummy:Freeze>();
43+
44+
// ...but even then the pointer overrides
45+
assert_freeze::<&'a mut Dummy:Freeze>(); //~ ERROR does not fulfill `Freeze`
46+
47+
// closures are like an `&mut` object
48+
assert_freeze::<&fn()>(); //~ ERROR does not fulfill `Freeze`
49+
50+
// unsafe ptrs are ok unless they point at unfreezeable things
51+
assert_freeze::<*int>();
52+
assert_freeze::<*&'a mut int>(); //~ ERROR does not fulfill `Freeze`
53+
}
54+
55+
fn main() {
56+
}

src/test/compile-fail/kindck-send.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test which of the builtin types are considered sendable.
12+
13+
fn assert_send<T:Send>() { }
14+
trait Dummy { }
15+
16+
fn test<'a,T,U:Send>(_: &'a int) {
17+
// lifetime pointers with 'static lifetime are ok
18+
assert_send::<&'static int>();
19+
assert_send::<&'static str>();
20+
assert_send::<&'static [int]>();
21+
22+
// whether or not they are mutable
23+
assert_send::<&'static mut int>();
24+
25+
// otherwise lifetime pointers are not ok
26+
assert_send::<&'a int>(); //~ ERROR does not fulfill `Send`
27+
assert_send::<&'a str>(); //~ ERROR does not fulfill `Send`
28+
assert_send::<&'a [int]>(); //~ ERROR does not fulfill `Send`
29+
30+
// ~ pointers are ok
31+
assert_send::<~int>();
32+
assert_send::<~str>();
33+
assert_send::<~[int]>();
34+
35+
// but not if they own a bad thing
36+
assert_send::<~&'a int>(); //~ ERROR does not fulfill `Send`
37+
38+
// careful with object types, who knows what they close over...
39+
assert_send::<&'static Dummy>(); //~ ERROR does not fulfill `Send`
40+
assert_send::<&'a Dummy>(); //~ ERROR does not fulfill `Send`
41+
assert_send::<&'a Dummy:Send>(); //~ ERROR does not fulfill `Send`
42+
assert_send::<~Dummy:>(); //~ ERROR does not fulfill `Send`
43+
44+
// ...unless they are properly bounded
45+
assert_send::<&'static Dummy:Send>();
46+
assert_send::<~Dummy:Send>();
47+
48+
// but closure and object types can have lifetime bounds which make
49+
// them not ok (FIXME #5121)
50+
// assert_send::<~fn:'a()>(); // ERROR does not fulfill `Send`
51+
// assert_send::<~Dummy:'a>(); // ERROR does not fulfill `Send`
52+
53+
// unsafe ptrs are ok unless they point at unsendable things
54+
assert_send::<*int>();
55+
assert_send::<*&'a int>(); //~ ERROR does not fulfill `Send`
56+
}
57+
58+
fn main() {
59+
}

0 commit comments

Comments
 (0)