auto merge of #10924 : pcwalton/rust/pod, r=pcwalton
This will be used for the new `Cell`. r? @nikomatsakis
This commit is contained in:
commit
2c41a823cc
doc
src
librustc
libstd
test
@ -3329,6 +3329,12 @@ The kinds are:
|
||||
This kind includes scalars, owning pointers, owned closures, and
|
||||
structural types containing only other owned types.
|
||||
All `Send` types are `'static`.
|
||||
`Pod`
|
||||
: Types of this kind consist of "Plain Old Data"
|
||||
which can be copied by simply moving bits.
|
||||
All values of this kind can be implicitly copied.
|
||||
This kind includes scalars and immutable references,
|
||||
as well as structural types containing other `Pod` types.
|
||||
`'static`
|
||||
: Types of this kind do not contain any borrowed pointers;
|
||||
this can be a useful guarantee for code
|
||||
|
@ -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 @@ impl LanguageItems {
|
||||
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, PodTraitLangItem, "pod", pod_trait;
|
||||
|
||||
3, DropTraitLangItem, "drop", drop_trait;
|
||||
4, 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;
|
||||
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;
|
||||
|
||||
17, EqTraitLangItem, "eq", eq_trait;
|
||||
18, OrdTraitLangItem, "ord", ord_trait;
|
||||
18, EqTraitLangItem, "eq", eq_trait;
|
||||
19, 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;
|
||||
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;
|
||||
|
||||
35, StartFnLangItem, "start", start_fn;
|
||||
36, StartFnLangItem, "start", start_fn;
|
||||
|
||||
36, TyDescStructLangItem, "ty_desc", ty_desc;
|
||||
37, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
|
||||
38, OpaqueStructLangItem, "opaque", opaque;
|
||||
37, TyDescStructLangItem, "ty_desc", ty_desc;
|
||||
38, TyVisitorTraitLangItem, "ty_visitor", ty_visitor;
|
||||
39, OpaqueStructLangItem, "opaque", opaque;
|
||||
|
||||
39, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
|
||||
40, EventLoopFactoryLangItem, "event_loop_factory", event_loop_factory;
|
||||
|
||||
40, TypeIdLangItem, "type_id", type_id;
|
||||
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 @@ def_type_content_sets!(
|
||||
// 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 @@ impl TypeContents {
|
||||
BoundFreeze => self.is_freezable(cx),
|
||||
BoundSend => self.is_sendable(cx),
|
||||
BoundSized => self.is_sized(cx),
|
||||
BoundPod => self.is_pod(cx),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1859,6 +1864,10 @@ impl TypeContents {
|
||||
!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 @@ impl 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 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
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 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
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 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
}
|
||||
|
||||
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 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
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 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
|
||||
BoundSend => TC::Nonsendable,
|
||||
BoundFreeze => TC::Nonfreezable,
|
||||
BoundSized => TC::Nonsized,
|
||||
BoundPod => TC::Nonpod,
|
||||
};
|
||||
});
|
||||
return tc;
|
||||
|
@ -639,6 +639,7 @@ impl Repr for ty::ParamBounds {
|
||||
ty::BoundSend => ~"Send",
|
||||
ty::BoundFreeze => ~"Freeze",
|
||||
ty::BoundSized => ~"Sized",
|
||||
ty::BoundPod => ~"Pod",
|
||||
});
|
||||
}
|
||||
for t in self.trait_bounds.iter() {
|
||||
@ -926,6 +927,7 @@ impl UserString for ty::BuiltinBound {
|
||||
ty::BoundSend => ~"Send",
|
||||
ty::BoundFreeze => ~"Freeze",
|
||||
ty::BoundSized => ~"Sized",
|
||||
ty::BoundPod => ~"Pod",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,71 @@ use prelude::*;
|
||||
use cast;
|
||||
use util::NonCopyable;
|
||||
|
||||
#[cfg(stage0)]
|
||||
use unstable::intrinsics;
|
||||
|
||||
/// A mutable memory location that admits only `Pod` data.
|
||||
#[no_freeze]
|
||||
#[deriving(Clone)]
|
||||
pub struct Cell<T> {
|
||||
priv value: T,
|
||||
}
|
||||
|
||||
// NB: For `stage0`, we omit the `Pod` bound. This is unsound but will help
|
||||
// us get started on removing `@mut` from `rustc`.
|
||||
|
||||
#[cfg(stage0)]
|
||||
impl<T> Cell<T> {
|
||||
/// Creates a new `Cell` containing the given value.
|
||||
pub fn new(value: T) -> Cell<T> {
|
||||
Cell {
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a copy of the contained value.
|
||||
#[inline]
|
||||
pub fn get(&self) -> T {
|
||||
unsafe {
|
||||
let mut result = intrinsics::uninit();
|
||||
intrinsics::copy_nonoverlapping_memory(&mut result, &self.value, 1);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the contained value.
|
||||
#[inline]
|
||||
pub fn set(&self, value: T) {
|
||||
unsafe {
|
||||
intrinsics::copy_nonoverlapping_memory(cast::transmute_mut(&self.value), &value, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
impl<T: ::kinds::Pod> Cell<T> {
|
||||
/// Creates a new `Cell` containing the given value.
|
||||
pub fn new(value: T) -> Cell<T> {
|
||||
Cell {
|
||||
value: value,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a copy of the contained value.
|
||||
#[inline]
|
||||
pub fn get(&self) -> T {
|
||||
self.value
|
||||
}
|
||||
|
||||
/// Sets the contained value.
|
||||
#[inline]
|
||||
pub fn set(&self, value: T) {
|
||||
unsafe {
|
||||
*cast::transmute_mut(&self.value) = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A mutable memory location with dynamically checked borrow rules
|
||||
#[no_freeze]
|
||||
pub struct RefCell<T> {
|
||||
@ -132,6 +197,30 @@ impl<T> RefCell<T> {
|
||||
let mut ptr = self.borrow_mut();
|
||||
blk(ptr.get())
|
||||
}
|
||||
|
||||
/// Sets the value, replacing what was there.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the value is currently borrowed.
|
||||
#[inline]
|
||||
pub fn set(&self, value: T) {
|
||||
let mut reference = self.borrow_mut();
|
||||
*reference.get() = value
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone> RefCell<T> {
|
||||
/// Returns a copy of the contained value.
|
||||
///
|
||||
/// # Failure
|
||||
///
|
||||
/// Fails if the value is currently mutably borrowed.
|
||||
#[inline]
|
||||
pub fn get(&self) -> T {
|
||||
let reference = self.borrow();
|
||||
(*reference.get()).clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Clone for RefCell<T> {
|
||||
@ -202,6 +291,17 @@ impl<'b, T> RefMut<'b, T> {
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn smoketest_cell() {
|
||||
let x = Cell::new(10);
|
||||
assert_eq!(x.get(), 10);
|
||||
x.set(20);
|
||||
assert_eq!(x.get(), 20);
|
||||
|
||||
let y = Cell::new((30, 40));
|
||||
assert_eq!(y.get(), (30, 40));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn double_imm_borrow() {
|
||||
let x = RefCell::new(0);
|
||||
|
@ -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 ops::{Shl, Shr, Index};
|
||||
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;
|
||||
|
86
src/test/compile-fail/kindck-pod.rs
Normal file
86
src/test/compile-fail/kindck-pod.rs
Normal file
@ -0,0 +1,86 @@
|
||||
// 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.
|
||||
|
||||
#[feature(managed_boxes)];
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
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`
|
||||
|
||||
// managed or ref counted types are not ok
|
||||
assert_pod::<@int>(); //~ ERROR does not fulfill `Pod`
|
||||
assert_pod::<Rc<int>>(); //~ ERROR does not fulfill `Pod`
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
}
|
||||
|
15
src/test/run-pass/can-copy-pod.rs
Normal file
15
src/test/run-pass/can-copy-pod.rs
Normal file
@ -0,0 +1,15 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that type parameters with the `Pod` are implicitly copyable.
|
||||
|
||||
#[allow(dead_code)];
|
||||
|
||||
fn can_copy_pod<T:Pod>(v: T) {
|
||||
let _a = v;
|
||||
let _b = v;
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user