提交 caf34b41 编写于 作者: P Patrick Walton

librustc: Implement a `Pod` kind for types that can be `memcpy`'d.

This will be used for the new `Cell`.
上级 c2c2c4d6
......@@ -395,6 +395,7 @@ fn enc_bounds(w: @mut MemWriter, cx: @ctxt, bs: &ty::ParamBounds) {
ty::BoundFreeze => mywrite!(w, "K"),
ty::BoundStatic => mywrite!(w, "O"),
ty::BoundSized => mywrite!(w, "Z"),
ty::BoundPod => mywrite!(w, "P"),
}
}
......
......@@ -23,7 +23,7 @@
use driver::session::Session;
use metadata::csearch::each_lang_item;
use metadata::cstore::iter_crate_data;
use middle::ty::{BuiltinBound, BoundFreeze, BoundSend, BoundSized};
use middle::ty::{BuiltinBound, BoundFreeze, BoundPod, BoundSend, BoundSized};
use syntax::ast;
use syntax::ast_util::local_def;
use syntax::attr::AttrMetaMethods;
......@@ -83,6 +83,8 @@ pub fn to_builtin_kind(&self, id: ast::DefId) -> Option<BuiltinBound> {
Some(BoundSend)
} else if Some(id) == self.sized_trait() {
Some(BoundSized)
} else if Some(id) == self.pod_trait() {
Some(BoundPod)
} else {
None
}
......@@ -206,56 +208,58 @@ pub fn collect_language_items(crate: &ast::Crate,
}
lets_do_this! {
There are 41 lang items.
There are 42 lang items.
// ID, Variant name, Name, Method name;
0, FreezeTraitLangItem, "freeze", freeze_trait;
1, SendTraitLangItem, "send", send_trait;
2, SizedTraitLangItem, "sized", sized_trait;
3, DropTraitLangItem, "drop", drop_trait;
4, AddTraitLangItem, "add", add_trait;
5, SubTraitLangItem, "sub", sub_trait;
6, MulTraitLangItem, "mul", mul_trait;
7, DivTraitLangItem, "div", div_trait;
8, RemTraitLangItem, "rem", rem_trait;
9, NegTraitLangItem, "neg", neg_trait;
10, NotTraitLangItem, "not", not_trait;
11, BitXorTraitLangItem, "bitxor", bitxor_trait;
12, BitAndTraitLangItem, "bitand", bitand_trait;
13, BitOrTraitLangItem, "bitor", bitor_trait;
14, ShlTraitLangItem, "shl", shl_trait;
15, ShrTraitLangItem, "shr", shr_trait;
16, IndexTraitLangItem, "index", index_trait;
17, EqTraitLangItem, "eq", eq_trait;
18, OrdTraitLangItem, "ord", ord_trait;
19, StrEqFnLangItem, "str_eq", str_eq_fn;
20, UniqStrEqFnLangItem, "uniq_str_eq", uniq_str_eq_fn;
21, FailFnLangItem, "fail_", fail_fn;
22, FailBoundsCheckFnLangItem, "fail_bounds_check", fail_bounds_check_fn;
23, ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
24, ClosureExchangeMallocFnLangItem, "closure_exchange_malloc", closure_exchange_malloc_fn;
25, ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
26, MallocFnLangItem, "malloc", malloc_fn;
27, FreeFnLangItem, "free", free_fn;
28, BorrowAsImmFnLangItem, "borrow_as_imm", borrow_as_imm_fn;
29, BorrowAsMutFnLangItem, "borrow_as_mut", borrow_as_mut_fn;
30, ReturnToMutFnLangItem, "return_to_mut", return_to_mut_fn;
31, CheckNotBorrowedFnLangItem, "check_not_borrowed", check_not_borrowed_fn;
32, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
33, RecordBorrowFnLangItem, "record_borrow", record_borrow_fn;
34, UnrecordBorrowFnLangItem, "unrecord_borrow", unrecord_borrow_fn;
35, StartFnLangItem, "start", start_fn;
36, TyDescStructLangItem, "ty_desc", ty_desc;
37, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
38, OpaqueStructLangItem, "opaque", opaque;
39, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
40, TypeIdLangItem, "type_id", type_id;
3, PodTraitLangItem, "pod", pod_trait;
4, DropTraitLangItem, "drop", drop_trait;
5, AddTraitLangItem, "add", add_trait;
6, SubTraitLangItem, "sub", sub_trait;
7, MulTraitLangItem, "mul", mul_trait;
8, DivTraitLangItem, "div", div_trait;
9, RemTraitLangItem, "rem", rem_trait;
10, NegTraitLangItem, "neg", neg_trait;
11, NotTraitLangItem, "not", not_trait;
12, BitXorTraitLangItem, "bitxor", bitxor_trait;
13, BitAndTraitLangItem, "bitand", bitand_trait;
14, BitOrTraitLangItem, "bitor", bitor_trait;
15, ShlTraitLangItem, "shl", shl_trait;
16, ShrTraitLangItem, "shr", shr_trait;
17, IndexTraitLangItem, "index", index_trait;
18, EqTraitLangItem, "eq", eq_trait;
19, OrdTraitLangItem, "ord", ord_trait;
20, StrEqFnLangItem, "str_eq", str_eq_fn;
21, UniqStrEqFnLangItem, "uniq_str_eq", uniq_str_eq_fn;
22, FailFnLangItem, "fail_", fail_fn;
23, FailBoundsCheckFnLangItem, "fail_bounds_check", fail_bounds_check_fn;
24, ExchangeMallocFnLangItem, "exchange_malloc", exchange_malloc_fn;
25, ClosureExchangeMallocFnLangItem, "closure_exchange_malloc", closure_exchange_malloc_fn;
26, ExchangeFreeFnLangItem, "exchange_free", exchange_free_fn;
27, MallocFnLangItem, "malloc", malloc_fn;
28, FreeFnLangItem, "free", free_fn;
29, BorrowAsImmFnLangItem, "borrow_as_imm", borrow_as_imm_fn;
30, BorrowAsMutFnLangItem, "borrow_as_mut", borrow_as_mut_fn;
31, ReturnToMutFnLangItem, "return_to_mut", return_to_mut_fn;
32, CheckNotBorrowedFnLangItem, "check_not_borrowed", check_not_borrowed_fn;
33, StrDupUniqFnLangItem, "strdup_uniq", strdup_uniq_fn;
34, RecordBorrowFnLangItem, "record_borrow", record_borrow_fn;
35, UnrecordBorrowFnLangItem, "unrecord_borrow", unrecord_borrow_fn;
36, StartFnLangItem, "start", start_fn;
37, TyDescStructLangItem, "ty_desc", ty_desc;
38, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
39, OpaqueStructLangItem, "opaque", opaque;
40, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
41, TypeIdLangItem, "type_id", type_id;
}
......@@ -737,6 +737,7 @@ pub enum BuiltinBound {
BoundSend,
BoundFreeze,
BoundSized,
BoundPod,
}
pub fn EmptyBuiltinBounds() -> BuiltinBounds {
......@@ -1805,6 +1806,9 @@ mod TC {
// Things that prevent values from being considered sized
Nonsized = 0b0000__00000000__0001,
// Things that make values considered not POD (same as `Moves`)
Nonpod = 0b0000__00001111__0000,
// Bits to set when a managed value is encountered
//
// [1] Do not set the bits TC::OwnsManaged or
......@@ -1828,6 +1832,7 @@ pub fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool {
BoundFreeze => self.is_freezable(cx),
BoundSend => self.is_sendable(cx),
BoundSized => self.is_sized(cx),
BoundPod => self.is_pod(cx),
}
}
......@@ -1859,6 +1864,10 @@ pub fn is_sized(&self, _: ctxt) -> bool {
!self.intersects(TC::Nonsized)
}
pub fn is_pod(&self, _: ctxt) -> bool {
!self.intersects(TC::Nonpod)
}
pub fn moves_by_default(&self, _: ctxt) -> bool {
self.intersects(TC::Moves)
}
......@@ -1876,15 +1885,32 @@ pub fn owned_pointer(&self) -> TypeContents {
*self & (TC::OwnsAll | TC::ReachesAll))
}
pub fn other_pointer(&self, bits: TypeContents) -> TypeContents {
pub fn reference(&self, bits: TypeContents) -> TypeContents {
/*!
* Includes only those bits that still apply
* when indirected through a non-owning pointer (`&`, `@`)
* when indirected through a reference (`&`)
*/
bits | (
*self & TC::ReachesAll)
}
pub fn managed_pointer(&self) -> TypeContents {
/*!
* Includes only those bits that still apply
* when indirected through a managed pointer (`@`)
*/
TC::Managed | (
*self & TC::ReachesAll)
}
pub fn unsafe_pointer(&self) -> TypeContents {
/*!
* Includes only those bits that still apply
* when indirected through an unsafe pointer (`*`)
*/
*self & TC::ReachesAll
}
pub fn union<T>(v: &[T], f: |&T| -> TypeContents) -> TypeContents {
v.iter().fold(TC::None, |tc, t| tc | f(t))
}
......@@ -1994,7 +2020,7 @@ fn tc_ty(cx: ctxt,
}
ty_box(mt) => {
tc_mt(cx, mt, cache).other_pointer(TC::Managed)
tc_mt(cx, mt, cache).managed_pointer()
}
ty_trait(_, _, store, mutbl, bounds) => {
......@@ -2002,11 +2028,11 @@ fn tc_ty(cx: ctxt,
}
ty_ptr(ref mt) => {
tc_ty(cx, mt.ty, cache).other_pointer(TC::None)
tc_ty(cx, mt.ty, cache).unsafe_pointer()
}
ty_rptr(r, ref mt) => {
tc_ty(cx, mt.ty, cache).other_pointer(
tc_ty(cx, mt.ty, cache).reference(
borrowed_contents(r, mt.mutbl))
}
......@@ -2019,11 +2045,11 @@ fn tc_ty(cx: ctxt,
}
ty_evec(mt, vstore_box) => {
tc_mt(cx, mt, cache).other_pointer(TC::Managed)
tc_mt(cx, mt, cache).managed_pointer()
}
ty_evec(ref mt, vstore_slice(r)) => {
tc_ty(cx, mt.ty, cache).other_pointer(
tc_ty(cx, mt.ty, cache).reference(
borrowed_contents(r, mt.mutbl))
}
......@@ -2193,10 +2219,10 @@ fn object_contents(cx: ctxt,
contents.owned_pointer()
}
BoxTraitStore => {
contents.other_pointer(TC::Managed)
contents.managed_pointer()
}
RegionTraitStore(r) => {
contents.other_pointer(borrowed_contents(r, mutbl))
contents.reference(borrowed_contents(r, mutbl))
}
}
}
......@@ -2213,6 +2239,7 @@ fn kind_bounds_to_contents(cx: ctxt,
BoundSend => TC::Nonsendable,
BoundFreeze => TC::Nonfreezable,
BoundSized => TC::Nonsized,
BoundPod => TC::Nonpod,
};
});
return tc;
......
......@@ -639,6 +639,7 @@ fn repr(&self, tcx: ctxt) -> ~str {
ty::BoundSend => ~"Send",
ty::BoundFreeze => ~"Freeze",
ty::BoundSized => ~"Sized",
ty::BoundPod => ~"Pod",
});
}
for t in self.trait_bounds.iter() {
......@@ -926,6 +927,7 @@ fn user_string(&self, _tcx: ctxt) -> ~str {
ty::BoundSend => ~"Send",
ty::BoundFreeze => ~"Freeze",
ty::BoundSized => ~"Sized",
ty::BoundPod => ~"Pod",
}
}
}
......
......@@ -37,3 +37,13 @@ pub trait Freeze {
pub trait Sized {
// Empty.
}
/// Types that can be copied by simply copying bits (i.e. `memcpy`).
///
/// The name "POD" stands for "Plain Old Data" and is borrowed from C++.
#[cfg(not(stage0))]
#[lang="pod"]
pub trait Pod {
// Empty.
}
......@@ -37,6 +37,9 @@
pub use option::{Option, Some, None};
pub use result::{Result, Ok, Err};
#[cfg(not(stage0))]
pub use kinds::Pod;
// Reexported functions
pub use from_str::from_str;
pub use iter::range;
......
// Copyright 2012 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test which of the builtin types are considered POD.
fn assert_pod<T:Pod>() { }
trait Dummy { }
struct MyStruct {
x: int,
y: int,
}
struct MyNonpodStruct {
x: ~int,
}
fn test<'a,T,U:Pod>(_: &'a int) {
// lifetime pointers are ok...
assert_pod::<&'static int>();
assert_pod::<&'a int>();
assert_pod::<&'a str>();
assert_pod::<&'a [int]>();
// ...unless they are mutable
assert_pod::<&'static mut int>(); //~ ERROR does not fulfill `Pod`
assert_pod::<&'a mut int>(); //~ ERROR does not fulfill `Pod`
// ~ pointers are not ok
assert_pod::<~int>(); //~ ERROR does not fulfill `Pod`
assert_pod::<~str>(); //~ ERROR does not fulfill `Pod`
assert_pod::<~[int]>(); //~ ERROR does not fulfill `Pod`
assert_pod::<~&'a mut int>(); //~ ERROR does not fulfill `Pod`
// borrowed object types are generally ok
assert_pod::<&'a Dummy>();
assert_pod::<&'a Dummy:Pod>();
assert_pod::<&'static Dummy:Pod>();
// owned object types are not ok
assert_pod::<~Dummy>(); //~ ERROR does not fulfill `Pod`
assert_pod::<~Dummy:Pod>(); //~ ERROR does not fulfill `Pod`
// mutable object types are not ok
assert_pod::<&'a mut Dummy:Pod>(); //~ ERROR does not fulfill `Pod`
// closures are like an `&mut` object
assert_pod::<||>(); //~ ERROR does not fulfill `Pod`
// unsafe ptrs are ok
assert_pod::<*int>();
assert_pod::<*&'a mut int>();
// regular old ints and such are ok
assert_pod::<int>();
assert_pod::<bool>();
assert_pod::<()>();
// tuples are ok
assert_pod::<(int,int)>();
// structs of POD are ok
assert_pod::<MyStruct>();
// structs containing non-POD are not ok
assert_pod::<MyNonpodStruct>(); //~ ERROR does not fulfill `Pod`
}
fn main() {
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册