librustc: Remove the Copy bound from the language.

This commit is contained in:
Patrick Walton 2013-07-10 17:31:53 -07:00
parent d57e8f8419
commit 88fe4ae09c
18 changed files with 95 additions and 183 deletions

View file

@ -87,7 +87,6 @@ mod tests {
use std::rand::RngUtil;
#[test]
#[allow(non_implicitly_copyable_typarams)]
fn test_flate_round_trip() {
let mut r = rand::rng();
let mut words = ~[];

View file

@ -145,7 +145,6 @@ pub fn spawn<A:Send>(blk: ~fn() -> A) -> Future<A> {
return from_port(port);
}
#[allow(non_implicitly_copyable_typarams)]
#[cfg(test)]
mod test {
use future::*;

View file

@ -1,4 +1,4 @@
// Cloneright 2012 The Rust Project Developers. See the COPYRIGHT
// 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.
//

View file

@ -671,7 +671,6 @@ fn get_concurrency() -> uint {
else { threads * SCHED_OVERCOMMIT }
}
#[allow(non_implicitly_copyable_typarams)]
pub fn filter_tests(
opts: &TestOpts,
tests: ~[TestDescAndFn]) -> ~[TestDescAndFn]

View file

@ -561,9 +561,6 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
'S' => {
param_bounds.builtin_bounds.add(ty::BoundSend);
}
'C' => {
param_bounds.builtin_bounds.add(ty::BoundCopy);
}
'K' => {
param_bounds.builtin_bounds.add(ty::BoundFreeze);
}

View file

@ -400,7 +400,6 @@ fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: &ty::ParamBounds) {
for bs.builtin_bounds.each |bound| {
match bound {
ty::BoundSend => w.write_char('S'),
ty::BoundCopy => w.write_char('C'),
ty::BoundFreeze => w.write_char('K'),
ty::BoundStatic => w.write_char('O'),
ty::BoundSized => w.write_char('Z'),

View file

@ -586,7 +586,7 @@ impl BorrowckCtxt {
ty::ty_closure(ref cty) if cty.sigil == ast::BorrowedSigil =>
"a non-copyable stack closure (capture it in a new closure, \
e.g. `|x| f(x)`, to override)",
_ if !ty::type_is_copyable(tcx, ty) =>
_ if ty::type_moves_by_default(tcx, ty) =>
"non-copyable (perhaps you meant to use clone()?)",
_ => default_msg,
}

View file

@ -29,7 +29,6 @@ use syntax::{visit, ast_util};
// of the following attributes.
//
// send: Things that can be sent on channels or included in spawned closures.
// copy: Things that can be copied.
// freeze: Things thare are deeply immutable. They are guaranteed never to
// change, and can be safely shared without copying between tasks.
// 'static: Things that do not contain borrowed pointers.
@ -37,14 +36,12 @@ use syntax::{visit, ast_util};
// Send includes scalar types as well as classes and unique types containing
// only sendable types.
//
// Copy includes boxes, closure and unique types containing copyable types.
//
// Freeze include scalar types, things without non-const fields, and pointers
// to freezable things.
//
// This pass ensures that type parameters are only instantiated with types
// whose kinds are equal or less general than the way the type parameter was
// annotated (with the `Send`, `Copy` or `Freeze` bound).
// annotated (with the `Send` or `Freeze` bound).
//
// It also verifies that noncopyable kinds are not copied. Sendability is not
// applied, since none of our language primitives send. Instead, the sending

View file

@ -13,7 +13,7 @@
// Language items are items that represent concepts intrinsic to the language
// itself. Examples are:
//
// * Traits that specify "kinds"; e.g. "Freeze", "Copy", "Send".
// * Traits that specify "kinds"; e.g. "Freeze", "Send".
//
// * Traits that represent operators; e.g. "Add", "Sub", "Index".
//
@ -33,63 +33,62 @@ use std::hashmap::HashMap;
pub enum LangItem {
FreezeTraitLangItem, // 0
CopyTraitLangItem, // 1
SendTraitLangItem, // 2
SizedTraitLangItem, // 3
SendTraitLangItem, // 1
SizedTraitLangItem, // 2
DropTraitLangItem, // 4
DropTraitLangItem, // 3
AddTraitLangItem, // 5
SubTraitLangItem, // 6
MulTraitLangItem, // 7
DivTraitLangItem, // 8
RemTraitLangItem, // 9
NegTraitLangItem, // 10
NotTraitLangItem, // 11
AddTraitLangItem, // 4
SubTraitLangItem, // 5
MulTraitLangItem, // 6
DivTraitLangItem, // 7
RemTraitLangItem, // 8
NegTraitLangItem, // 9
NotTraitLangItem, // 10
BitXorTraitLangItem, // 11
BitAndTraitLangItem, // 13
BitOrTraitLangItem, // 14
ShlTraitLangItem, // 15
ShrTraitLangItem, // 16
IndexTraitLangItem, // 17
BitAndTraitLangItem, // 12
BitOrTraitLangItem, // 13
ShlTraitLangItem, // 14
ShrTraitLangItem, // 15
IndexTraitLangItem, // 16
EqTraitLangItem, // 18
OrdTraitLangItem, // 19
EqTraitLangItem, // 17
OrdTraitLangItem, // 18
StrEqFnLangItem, // 20
UniqStrEqFnLangItem, // 21
AnnihilateFnLangItem, // 22
LogTypeFnLangItem, // 23
FailFnLangItem, // 24
FailBoundsCheckFnLangItem, // 25
ExchangeMallocFnLangItem, // 26
ClosureExchangeMallocFnLangItem, // 27
ExchangeFreeFnLangItem, // 28
MallocFnLangItem, // 29
FreeFnLangItem, // 30
BorrowAsImmFnLangItem, // 31
BorrowAsMutFnLangItem, // 32
ReturnToMutFnLangItem, // 33
CheckNotBorrowedFnLangItem, // 34
StrDupUniqFnLangItem, // 35
RecordBorrowFnLangItem, // 36
UnrecordBorrowFnLangItem, // 37
StrEqFnLangItem, // 19
UniqStrEqFnLangItem, // 20
AnnihilateFnLangItem, // 21
LogTypeFnLangItem, // 22
FailFnLangItem, // 23
FailBoundsCheckFnLangItem, // 24
ExchangeMallocFnLangItem, // 25
ClosureExchangeMallocFnLangItem, // 26
ExchangeFreeFnLangItem, // 27
MallocFnLangItem, // 28
FreeFnLangItem, // 29
BorrowAsImmFnLangItem, // 30
BorrowAsMutFnLangItem, // 31
ReturnToMutFnLangItem, // 32
CheckNotBorrowedFnLangItem, // 33
StrDupUniqFnLangItem, // 34
RecordBorrowFnLangItem, // 35
UnrecordBorrowFnLangItem, // 36
StartFnLangItem, // 38
StartFnLangItem, // 37
TyDescStructLangItem, // 39
TyVisitorTraitLangItem, // 40
OpaqueStructLangItem, // 41
TyDescStructLangItem, // 38
TyVisitorTraitLangItem, // 39
OpaqueStructLangItem, // 40
}
pub struct LanguageItems {
items: [Option<def_id>, ..42]
items: [Option<def_id>, ..41]
}
impl LanguageItems {
pub fn new() -> LanguageItems {
LanguageItems {
items: [ None, ..42 ]
items: [ None, ..41 ]
}
}
@ -100,52 +99,51 @@ impl LanguageItems {
pub fn item_name(index: uint) -> &'static str {
match index {
0 => "freeze",
1 => "copy",
2 => "send",
3 => "sized",
1 => "send",
2 => "sized",
4 => "drop",
3 => "drop",
5 => "add",
6 => "sub",
7 => "mul",
8 => "div",
9 => "rem",
10 => "neg",
11 => "not",
12 => "bitxor",
13 => "bitand",
14 => "bitor",
15 => "shl",
16 => "shr",
17 => "index",
18 => "eq",
19 => "ord",
4 => "add",
5 => "sub",
6 => "mul",
7 => "div",
8 => "rem",
9 => "neg",
10 => "not",
11 => "bitxor",
12 => "bitand",
13 => "bitor",
14 => "shl",
15 => "shr",
16 => "index",
17 => "eq",
18 => "ord",
20 => "str_eq",
21 => "uniq_str_eq",
22 => "annihilate",
23 => "log_type",
24 => "fail_",
25 => "fail_bounds_check",
26 => "exchange_malloc",
27 => "closure_exchange_malloc",
28 => "exchange_free",
29 => "malloc",
30 => "free",
31 => "borrow_as_imm",
32 => "borrow_as_mut",
33 => "return_to_mut",
34 => "check_not_borrowed",
35 => "strdup_uniq",
36 => "record_borrow",
37 => "unrecord_borrow",
19 => "str_eq",
20 => "uniq_str_eq",
21 => "annihilate",
22 => "log_type",
23 => "fail_",
24 => "fail_bounds_check",
25 => "exchange_malloc",
26 => "closure_exchange_malloc",
27 => "exchange_free",
28 => "malloc",
29 => "free",
30 => "borrow_as_imm",
31 => "borrow_as_mut",
32 => "return_to_mut",
33 => "check_not_borrowed",
34 => "strdup_uniq",
35 => "record_borrow",
36 => "unrecord_borrow",
38 => "start",
37 => "start",
39 => "ty_desc",
40 => "ty_visitor",
41 => "opaque",
38 => "ty_desc",
39 => "ty_visitor",
40 => "opaque",
_ => "???"
}
@ -164,9 +162,6 @@ impl LanguageItems {
pub fn freeze_trait(&self) -> Option<def_id> {
self.items[FreezeTraitLangItem as uint]
}
pub fn copy_trait(&self) -> Option<def_id> {
self.items[CopyTraitLangItem as uint]
}
pub fn send_trait(&self) -> Option<def_id> {
self.items[SendTraitLangItem as uint]
}
@ -308,7 +303,6 @@ impl<'self> LanguageItemCollector<'self> {
let mut item_refs = HashMap::new();
item_refs.insert(@"freeze", FreezeTraitLangItem as uint);
item_refs.insert(@"copy", CopyTraitLangItem as uint);
item_refs.insert(@"send", SendTraitLangItem as uint);
item_refs.insert(@"sized", SizedTraitLangItem as uint);

View file

@ -76,7 +76,6 @@ pub enum lint {
path_statement,
implicit_copies,
unrecognized_lint,
non_implicitly_copyable_typarams,
deprecated_pattern,
non_camel_case_types,
non_uppercase_statics,
@ -182,13 +181,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
default: warn
}),
("non_implicitly_copyable_typarams",
LintSpec {
lint: non_implicitly_copyable_typarams,
desc: "passing non implicitly copyable types as copy type params",
default: warn
}),
("implicit_copies",
LintSpec {
lint: implicit_copies,

View file

@ -666,7 +666,6 @@ pub type BuiltinBounds = EnumSet<BuiltinBound>;
#[deriving(Clone, Eq, IterBytes)]
pub enum BuiltinBound {
BoundCopy,
BoundStatic,
BoundSend,
BoundFreeze,
@ -679,7 +678,6 @@ pub fn EmptyBuiltinBounds() -> BuiltinBounds {
pub fn AllBuiltinBounds() -> BuiltinBounds {
let mut set = EnumSet::empty();
set.add(BoundCopy);
set.add(BoundStatic);
set.add(BoundSend);
set.add(BoundFreeze);
@ -1798,7 +1796,6 @@ impl TypeContents {
pub fn meets_bound(&self, cx: ctxt, bb: BuiltinBound) -> bool {
match bb {
BoundCopy => self.is_copy(cx),
BoundStatic => self.is_static(cx),
BoundFreeze => self.is_freezable(cx),
BoundSend => self.is_sendable(cx),
@ -1810,10 +1807,6 @@ impl TypeContents {
(self.bits & tc.bits) != 0
}
pub fn is_copy(&self, cx: ctxt) -> bool {
!self.intersects(TypeContents::noncopyable(cx))
}
pub fn noncopyable(_cx: ctxt) -> TypeContents {
TC_DTOR + TC_BORROWED_MUT + TC_ONCE_CLOSURE + TC_NONCOPY_TRAIT +
TC_EMPTY_ENUM
@ -1942,10 +1935,6 @@ static TC_DYNAMIC_SIZE: TypeContents = TypeContents{bits: 0b1000_0000_0000};
/// All possible contents.
static TC_ALL: TypeContents = TypeContents{bits: 0b1111_1111_1111};
pub fn type_is_copyable(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_copy(cx)
}
pub fn type_is_static(cx: ctxt, t: ty::t) -> bool {
type_contents(cx, t).is_static(cx)
}
@ -2237,8 +2226,7 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
ast::Many => TC_NONE
};
// Prevent noncopyable types captured in the environment from being copied.
let ct = if cty.bounds.contains_elem(BoundCopy) ||
cty.sigil == ast::ManagedSigil {
let ct = if cty.sigil == ast::ManagedSigil {
TC_NONE
} else {
TC_NONCOPY_TRAIT
@ -2261,9 +2249,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
let mut bt = TC_NONE;
for (AllBuiltinBounds() - bounds).each |bound| {
bt = bt + match bound {
BoundCopy if store == UniqTraitStore
=> TC_NONCOPY_TRAIT,
BoundCopy => TC_NONE, // @Trait/&Trait are copyable either way
BoundStatic if bounds.contains_elem(BoundSend)
=> TC_NONE, // Send bound implies static bound.
BoundStatic => TC_BORROWED_POINTER, // Useful for "@Trait:'static"
@ -2285,7 +2270,6 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents {
for type_param_def.bounds.builtin_bounds.each |bound| {
debug!("tc = %s, bound = %?", tc.to_str(), bound);
tc = tc - match bound {
BoundCopy => TypeContents::noncopyable(cx),
BoundStatic => TypeContents::nonstatic(cx),
BoundSend => TypeContents::nonsendable(cx),
BoundFreeze => TypeContents::nonfreezable(cx),

View file

@ -757,7 +757,7 @@ fn conv_builtin_bounds(tcx: ty::ctxt, ast_bounds: &Option<OptVec<ast::TyParamBou
//! Converts a list of bounds from the AST into a `BuiltinBounds`
//! struct. Reports an error if any of the bounds that appear
//! in the AST refer to general traits and not the built-in traits
//! like `Copy` or `Send`. Used to translate the bounds that
//! like `Send`. Used to translate the bounds that
//! appear in closure and trait types, where only builtin bounds are
//! legal.
//! If no bounds were specified, we choose a "default" bound based on
@ -811,7 +811,7 @@ pub fn try_add_builtin_trait(tcx: ty::ctxt,
trait_def_id: ast::def_id,
builtin_bounds: &mut ty::BuiltinBounds) -> bool {
//! Checks whether `trait_ref` refers to one of the builtin
//! traits, like `Copy` or `Send`, and adds the corresponding
//! traits, like `Send`, and adds the corresponding
//! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
//! is a builtin trait.
@ -819,9 +819,6 @@ pub fn try_add_builtin_trait(tcx: ty::ctxt,
if Some(trait_def_id) == li.send_trait() {
builtin_bounds.add(ty::BoundSend);
true
} else if Some(trait_def_id) == li.copy_trait() {
builtin_bounds.add(ty::BoundCopy);
true
} else if Some(trait_def_id) == li.freeze_trait() {
builtin_bounds.add(ty::BoundFreeze);
true

View file

@ -34,8 +34,7 @@ use middle::ty;
use middle::typeck::CrateCtxt;
use middle::typeck::infer::combine::Combine;
use middle::typeck::infer::InferCtxt;
use middle::typeck::infer::{new_infer_ctxt, resolve_ivar};
use middle::typeck::infer::{resolve_nested_tvar, resolve_type};
use middle::typeck::infer::{new_infer_ctxt, resolve_ivar, resolve_type};
use middle::typeck::infer;
use syntax::ast::{crate, def_id, def_struct, def_ty};
use syntax::ast::{item, item_enum, item_impl, item_mod, item_struct};
@ -584,45 +583,9 @@ impl CoherenceChecker {
b: &'a
UniversalQuantificationResult)
-> bool {
match infer::can_mk_subty(self.inference_context,
a.monotype, b.monotype) {
Ok(_) => {
// Check to ensure that each parameter binding respected its
// kind bounds.
let xs = [a, b];
for xs.iter().advance |result| {
for result.type_variables.iter()
.zip(result.type_param_defs.iter())
.advance |(ty_var, type_param_def)|
{
if type_param_def.bounds.builtin_bounds.contains_elem(
ty::BoundCopy)
{
match resolve_type(self.inference_context,
*ty_var,
resolve_nested_tvar) {
Ok(resolved_ty) => {
if !ty::type_is_copyable(
self.inference_context.tcx,
resolved_ty)
{
return false;
}
}
Err(*) => {
// Conservatively assume it might unify.
}
}
}
}
}
true
}
Err(_) => {
false
}
}
infer::can_mk_subty(self.inference_context,
a.monotype,
b.monotype).is_ok()
}
pub fn get_self_type_for_implementation(&self, implementation: @Impl)

View file

@ -1189,8 +1189,8 @@ pub fn ty_generics(ccx: &CrateCtxt,
* Translate the AST's notion of ty param bounds (which are an
* enum consisting of a newtyped Ty or a region) to ty's
* notion of ty param bounds, which can either be user-defined
* traits, or one of the four built-in traits (formerly known
* as kinds): Freeze, Copy, and Send.
* traits, or one of the two built-in traits (formerly known
* as kinds): Freeze and Send.
*/
let mut param_bounds = ty::ParamBounds {

View file

@ -569,7 +569,6 @@ impl Repr for ty::ParamBounds {
let mut res = ~[];
for self.builtin_bounds.each |b| {
res.push(match b {
ty::BoundCopy => ~"Copy",
ty::BoundStatic => ~"'static",
ty::BoundSend => ~"Send",
ty::BoundFreeze => ~"Freeze",
@ -787,7 +786,6 @@ impl Repr for ty::BuiltinBound {
impl UserString for ty::BuiltinBound {
fn user_string(&self, _tcx: ctxt) -> ~str {
match *self {
ty::BoundCopy => ~"Copy",
ty::BoundStatic => ~"'static",
ty::BoundSend => ~"Send",
ty::BoundFreeze => ~"Freeze",

View file

@ -1559,7 +1559,6 @@ impl<T:Writer> WriterUtil for T {
}
#[allow(non_implicitly_copyable_typarams)]
pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
mk_file_writer(path, flags).chain(|w| result::Ok(w))
}
@ -1727,7 +1726,6 @@ pub fn seek_in_buf(offset: int, pos: uint, len: uint, whence: SeekStyle) ->
return bpos as uint;
}
#[allow(non_implicitly_copyable_typarams)]
pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
result::chain(read_whole_file(file), |bytes| {
if str::is_utf8(bytes) {
@ -1740,7 +1738,6 @@ pub fn read_whole_file_str(file: &Path) -> Result<~str, ~str> {
// FIXME (#2004): implement this in a low-level way. Going through the
// abstractions is pointless.
#[allow(non_implicitly_copyable_typarams)]
pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
result::chain(file_reader(file), |rdr| {
result::Ok(rdr.read_whole_stream())

View file

@ -29,6 +29,7 @@ The 2 kinds are
#[allow(missing_doc)];
#[cfg(stage0)]
#[lang="copy"]
pub trait Copy {
// Empty.

View file

@ -577,13 +577,11 @@ pub fn tmpdir() -> Path {
}
#[cfg(unix)]
#[allow(non_implicitly_copyable_typarams)]
fn lookup() -> Path {
getenv_nonempty("TMPDIR").get_or_default(Path("/tmp"))
}
#[cfg(windows)]
#[allow(non_implicitly_copyable_typarams)]
fn lookup() -> Path {
getenv_nonempty("TMP").or(
getenv_nonempty("TEMP").or(
@ -688,7 +686,6 @@ pub fn mkdir_recursive(p: &Path, mode: c_int) -> bool {
}
/// Lists the contents of a directory
#[allow(non_implicitly_copyable_typarams)]
pub fn list_dir(p: &Path) -> ~[~str] {
if p.components.is_empty() && !p.is_absolute() {
// Not sure what the right behavior is here, but this
@ -1732,7 +1729,6 @@ pub mod consts {
}
#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
use libc::{c_int, c_void, size_t};
use libc;