Skip to content

Commit 6ca9ca8

Browse files
committed
Introduce special types for driving kind inference
Closes rust-lang#10834
1 parent 28beb06 commit 6ca9ca8

28 files changed

+335
-163
lines changed

src/libextra/arc.rs

+11-8
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,11 @@
4444
use sync;
4545
use sync::{Mutex, RWLock};
4646

47+
use std::kinds::NotFreeze;
48+
use std::borrow;
4749
use std::cast;
4850
use std::sync::arc::UnsafeArc;
4951
use std::task;
50-
use std::borrow;
5152

5253
/// As sync::condvar, a mechanism for unlock-and-descheduling and signaling.
5354
pub struct Condvar<'a> {
@@ -151,8 +152,10 @@ impl<T:Freeze + Send> Clone for Arc<T> {
151152
struct MutexArcInner<T> { priv lock: Mutex, priv failed: bool, priv data: T }
152153

153154
/// An Arc with mutable data protected by a blocking mutex.
154-
#[no_freeze]
155-
pub struct MutexArc<T> { priv x: UnsafeArc<MutexArcInner<T>> }
155+
pub struct MutexArc<T> {
156+
priv x: UnsafeArc<MutexArcInner<T>>,
157+
priv nf: NotFreeze,
158+
}
156159

157160

158161
impl<T:Send> Clone for MutexArc<T> {
@@ -161,7 +164,7 @@ impl<T:Send> Clone for MutexArc<T> {
161164
fn clone(&self) -> MutexArc<T> {
162165
// NB: Cloning the underlying mutex is not necessary. Its reference
163166
// count would be exactly the same as the shared state's.
164-
MutexArc { x: self.x.clone() }
167+
MutexArc { x: self.x.clone(), nf: NotFreeze }
165168
}
166169
}
167170

@@ -180,7 +183,7 @@ impl<T:Send> MutexArc<T> {
180183
lock: Mutex::new_with_condvars(num_condvars),
181184
failed: false, data: user_data
182185
};
183-
MutexArc { x: UnsafeArc::new(data) }
186+
MutexArc { x: UnsafeArc::new(data), nf: NotFreeze }
184187
}
185188

186189
/**
@@ -319,16 +322,16 @@ struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
319322
*
320323
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
321324
*/
322-
#[no_freeze]
323325
pub struct RWArc<T> {
324326
priv x: UnsafeArc<RWArcInner<T>>,
327+
priv nf: NotFreeze,
325328
}
326329

327330
impl<T:Freeze + Send> Clone for RWArc<T> {
328331
/// Duplicate a rwlock-protected Arc. See arc::clone for more details.
329332
#[inline]
330333
fn clone(&self) -> RWArc<T> {
331-
RWArc { x: self.x.clone() }
334+
RWArc { x: self.x.clone(), nf: NotFreeze }
332335
}
333336

334337
}
@@ -348,7 +351,7 @@ impl<T:Freeze + Send> RWArc<T> {
348351
lock: RWLock::new_with_condvars(num_condvars),
349352
failed: false, data: user_data
350353
};
351-
RWArc { x: UnsafeArc::new(data), }
354+
RWArc { x: UnsafeArc::new(data), nf: NotFreeze }
352355
}
353356

354357
/**

src/libextra/arena.rs

-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ struct Chunk {
6464
// different chunks than objects without destructors. This reduces
6565
// overhead when initializing plain-old-data and means we don't need
6666
// to waste time running the destructors of POD.
67-
#[no_freeze]
6867
pub struct Arena {
6968
// The head is separated out from the list as a unbenchmarked
7069
// microoptimization, to avoid needing to case on the list to

src/libextra/sync.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020

2121
use std::borrow;
2222
use std::comm;
23-
use std::unstable::sync::Exclusive;
23+
use std::kinds::NotPod;
2424
use std::sync::arc::UnsafeArc;
2525
use std::sync::atomics;
2626
use std::unstable::finally::Finally;
27+
use std::unstable::sync::Exclusive;
2728
use std::util;
28-
use std::util::NonCopyable;
2929

3030
/****************************************************************************
3131
* Internals
@@ -179,7 +179,7 @@ pub struct Condvar<'a> {
179179
// See the comment in write_cond for more detail.
180180
priv order: ReacquireOrderLock<'a>,
181181
// Make sure condvars are non-copyable.
182-
priv token: util::NonCopyable,
182+
priv token: NotPod,
183183
}
184184

185185
impl<'a> Condvar<'a> {
@@ -325,7 +325,7 @@ impl Sem<~[WaitQueue]> {
325325
blk(&Condvar {
326326
sem: self,
327327
order: Nothing,
328-
token: NonCopyable
328+
token: NotPod
329329
})
330330
})
331331
}
@@ -565,7 +565,7 @@ impl RWLock {
565565
(&self.order_lock).release();
566566
let opt_lock = Just(&self.order_lock);
567567
blk(&Condvar { sem: cond.sem, order: opt_lock,
568-
token: NonCopyable })
568+
token: NotPod })
569569
})
570570
}
571571

@@ -600,7 +600,7 @@ impl RWLock {
600600
(&self.access_lock).acquire();
601601
(&self.order_lock).release();
602602
(|| {
603-
blk(RWLockWriteMode { lock: self, token: NonCopyable })
603+
blk(RWLockWriteMode { lock: self, token: NotPod })
604604
}).finally(|| {
605605
let writer_or_last_reader;
606606
// Check if we're releasing from read mode or from write mode.
@@ -653,16 +653,16 @@ impl RWLock {
653653
(&self.access_lock).release();
654654
}
655655
}
656-
RWLockReadMode { lock: token.lock, token: NonCopyable }
656+
RWLockReadMode { lock: token.lock, token: NotPod }
657657
}
658658
}
659659

660660
/// The "write permission" token used for rwlock.write_downgrade().
661661
662-
pub struct RWLockWriteMode<'a> { priv lock: &'a RWLock, priv token: NonCopyable }
662+
pub struct RWLockWriteMode<'a> { priv lock: &'a RWLock, priv token: NotPod }
663663
/// The "read permission" token used for rwlock.write_downgrade().
664664
pub struct RWLockReadMode<'a> { priv lock: &'a RWLock,
665-
priv token: NonCopyable }
665+
priv token: NotPod }
666666

667667
impl<'a> RWLockWriteMode<'a> {
668668
/// Access the pre-downgrade rwlock in write mode.
@@ -673,7 +673,7 @@ impl<'a> RWLockWriteMode<'a> {
673673
// access lock. See comment in RWLock::write_cond for why.
674674
blk(&Condvar { sem: &self.lock.access_lock,
675675
order: Just(&self.lock.order_lock),
676-
token: NonCopyable })
676+
token: NotPod })
677677
}
678678
}
679679

src/librustc/middle/lang_items.rs

+4
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ lets_do_this! {
215215
SizedTraitLangItem, "sized", sized_trait;
216216
PodTraitLangItem, "pod", pod_trait;
217217

218+
NotPodLangItem, "not_pod", notpod_struct;
219+
NotFreezeLangItem, "not_freeze", notfreeze_struct;
220+
NotSend, "not_send", notsend_struct;
221+
218222
DropTraitLangItem, "drop", drop_trait;
219223

220224
AddTraitLangItem, "add", add_trait;

src/librustc/middle/lint.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -923,8 +923,8 @@ static other_attrs: &'static [&'static str] = &[
923923
"thread_local", // for statics
924924
"allow", "deny", "forbid", "warn", // lint options
925925
"deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability
926-
"crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze",
927-
"no_mangle", "no_send", "static_assert", "unsafe_no_drop_flag", "packed",
926+
"crate_map", "cfg", "doc", "export_name", "link_section",
927+
"no_mangle", "static_assert", "unsafe_no_drop_flag", "packed",
928928
"simd", "repr", "deriving", "unsafe_destructor", "link", "phase",
929929
"macro_export",
930930

src/librustc/middle/ty.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -2062,13 +2062,21 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20622062
}
20632063

20642064
ty_struct(did, ref substs) => {
2065-
let flds = struct_fields(cx, did, substs);
2066-
let mut res =
2067-
TypeContents::union(flds, |f| tc_mt(cx, f.mt, cache));
2068-
if ty::has_dtor(cx, did) {
2069-
res = res | TC::OwnsDtor;
2065+
if Some(did) == cx.lang_items.notfreeze_struct() {
2066+
TC::ReachesMutable
2067+
} else if Some(did) == cx.lang_items.notsend_struct() {
2068+
TC::ReachesNonsendAnnot
2069+
} else if Some(did) == cx.lang_items.notpod_struct() {
2070+
TC::OwnsOwned
2071+
} else {
2072+
let flds = struct_fields(cx, did, substs);
2073+
let mut res =
2074+
TypeContents::union(flds, |f| tc_mt(cx, f.mt, cache));
2075+
if ty::has_dtor(cx, did) {
2076+
res = res | TC::OwnsDtor;
2077+
}
2078+
res
20702079
}
2071-
apply_attributes(cx, did, res)
20722080
}
20732081

20742082
ty_tup(ref tys) => {
@@ -2083,7 +2091,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
20832091
tc_ty(cx, *arg_ty, cache)
20842092
})
20852093
});
2086-
apply_attributes(cx, did, res)
2094+
res
20872095
}
20882096

20892097
ty_param(p) => {
@@ -2145,15 +2153,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
21452153
mc | tc_ty(cx, mt.ty, cache)
21462154
}
21472155

2148-
fn apply_attributes(cx: ctxt,
2149-
did: ast::DefId,
2150-
tc: TypeContents)
2151-
-> TypeContents {
2152-
tc |
2153-
TC::ReachesMutable.when(has_attr(cx, did, "no_freeze")) |
2154-
TC::ReachesNonsendAnnot.when(has_attr(cx, did, "no_send"))
2155-
}
2156-
21572156
fn borrowed_contents(region: ty::Region,
21582157
mutbl: ast::Mutability)
21592158
-> TypeContents {

src/libstd/cell.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,23 @@
1111
//! Types dealing with dynamic mutability
1212
1313
use prelude::*;
14+
use kinds::NotFreeze;
1415
use cast;
15-
use util::NonCopyable;
16+
use kinds::NotPod;
1617

1718
/// A mutable memory location that admits only `Pod` data.
18-
#[no_freeze]
1919
#[deriving(Clone)]
2020
pub struct Cell<T> {
2121
priv value: T,
22+
priv nf: NotFreeze,
2223
}
2324

2425
impl<T: ::kinds::Pod> Cell<T> {
2526
/// Creates a new `Cell` containing the given value.
2627
pub fn new(value: T) -> Cell<T> {
2728
Cell {
2829
value: value,
30+
nf: NotFreeze,
2931
}
3032
}
3133

@@ -45,11 +47,11 @@ impl<T: ::kinds::Pod> Cell<T> {
4547
}
4648

4749
/// A mutable memory location with dynamically checked borrow rules
48-
#[no_freeze]
4950
pub struct RefCell<T> {
5051
priv value: T,
5152
priv borrow: BorrowFlag,
52-
priv nc: NonCopyable
53+
priv nc: NotPod,
54+
priv nf: NotFreeze,
5355
}
5456

5557
// Values [1, MAX-1] represent the number of `Ref` active
@@ -64,7 +66,8 @@ impl<T> RefCell<T> {
6466
RefCell {
6567
value: value,
6668
borrow: UNUSED,
67-
nc: NonCopyable
69+
nc: NotPod,
70+
nf: NotFreeze,
6871
}
6972
}
7073

src/libstd/comm/mod.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ use clone::Clone;
230230
use container::Container;
231231
use int;
232232
use iter::Iterator;
233-
use kinds::Send;
233+
use kinds::{Send, NotFreeze};
234234
use ops::Drop;
235235
use option::{Option, Some, None};
236236
use result::{Ok, Err};
@@ -297,9 +297,9 @@ impl<T: Send> Consumer<T>{
297297

298298
/// The receiving-half of Rust's channel type. This half can only be owned by
299299
/// one task
300-
#[no_freeze] // can't share ports in an arc
301300
pub struct Port<T> {
302301
priv queue: Consumer<T>,
302+
priv nf: NotFreeze,
303303
}
304304

305305
/// An iterator over messages received on a port, this iterator will block
@@ -311,17 +311,16 @@ pub struct Messages<'a, T> {
311311

312312
/// The sending-half of Rust's channel type. This half can only be owned by one
313313
/// task
314-
#[no_freeze] // can't share chans in an arc
315314
pub struct Chan<T> {
316315
priv queue: spsc::Producer<T, Packet>,
316+
priv nf: NotFreeze,
317317
}
318318

319319
/// The sending-half of Rust's channel type. This half can be shared among many
320320
/// tasks by creating copies of itself through the `clone` method.
321-
#[no_freeze] // technically this implementation is shareable, but it shouldn't
322-
// be required to be shareable in an arc
323321
pub struct SharedChan<T> {
324322
priv queue: mpsc::Producer<T, Packet>,
323+
priv nf: NotFreeze,
325324
}
326325

327326
/// This enumeration is the list of the possible reasons that try_recv could not
@@ -545,7 +544,7 @@ impl<T: Send> Chan<T> {
545544
// maximum buffer size
546545
let (c, p) = spsc::queue(128, Packet::new());
547546
let c = SPSC(c);
548-
(Port { queue: c }, Chan { queue: p })
547+
(Port { queue: c, nf: NotFreeze }, Chan { queue: p, nf: NotFreeze })
549548
}
550549

551550
/// Sends a value along this channel to be received by the corresponding
@@ -640,7 +639,7 @@ impl<T: Send> SharedChan<T> {
640639
pub fn new() -> (Port<T>, SharedChan<T>) {
641640
let (c, p) = mpsc::queue(Packet::new());
642641
let c = MPSC(c);
643-
(Port { queue: c }, SharedChan { queue: p })
642+
(Port { queue: c, nf: NotFreeze }, SharedChan { queue: p, nf: NotFreeze })
644643
}
645644

646645
/// Equivalent method to `send` on the `Chan` type (using the same
@@ -706,7 +705,7 @@ impl<T: Send> SharedChan<T> {
706705
impl<T: Send> Clone for SharedChan<T> {
707706
fn clone(&self) -> SharedChan<T> {
708707
unsafe { (*self.queue.packet()).channels.fetch_add(1, SeqCst); }
709-
SharedChan { queue: self.queue.clone() }
708+
SharedChan { queue: self.queue.clone(), nf: NotFreeze }
710709
}
711710
}
712711

src/libstd/comm/select.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
use cast;
4848
use comm;
4949
use iter::Iterator;
50-
use kinds::Send;
50+
use kinds::{Send, NotFreeze, NotSend};
5151
use ops::Drop;
5252
use option::{Some, None, Option};
5353
use ptr::RawPtr;
@@ -77,12 +77,12 @@ macro_rules! select {
7777

7878
/// The "port set" of the select interface. This structure is used to manage a
7979
/// set of ports which are being selected over.
80-
#[no_freeze]
81-
#[no_send]
8280
pub struct Select {
8381
priv head: *mut Packet,
8482
priv tail: *mut Packet,
8583
priv next_id: uint,
84+
priv nf: NotFreeze,
85+
priv ns: NotSend,
8686
}
8787

8888
/// A handle to a port which is currently a member of a `Select` set of ports.
@@ -107,6 +107,8 @@ impl Select {
107107
head: 0 as *mut Packet,
108108
tail: 0 as *mut Packet,
109109
next_id: 1,
110+
nf: NotFreeze,
111+
ns: NotSend,
110112
}
111113
}
112114

0 commit comments

Comments
 (0)