Merge pull request #4445 from apasel422/notop

Allow logical negation operator (!) to be overloaded
This commit is contained in:
Tim Chevalier 2013-01-11 20:10:51 -08:00
commit 847d30db66
6 changed files with 67 additions and 42 deletions

View File

@ -172,7 +172,7 @@ pub mod util;
pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Drop};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Shl, Shr, Index};

View File

@ -48,6 +48,11 @@ pub trait Neg<Result> {
pure fn neg(&self) -> Result;
}
#[lang="not"]
pub trait Not<Result> {
pure fn not(&self) -> Result;
}
#[lang="bitand"]
pub trait BitAnd<RHS,Result> {
pure fn bitand(&self, rhs: &RHS) -> Result;
@ -77,4 +82,3 @@ pub trait Shr<RHS,Result> {
pub trait Index<Index,Result> {
pure fn index(&self, index: Index) -> Result;
}

View File

@ -4,7 +4,7 @@
pub use kinds::{Const, Copy, Owned, Durable};
pub use ops::{Drop};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg};
pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, Not};
pub use ops::{BitAnd, BitOr, BitXor};
pub use ops::{Shl, Shr, Index};
pub use option::{Option, Some, None};

View File

@ -50,36 +50,37 @@ pub enum LangItem {
DivTraitLangItem, // 8
ModuloTraitLangItem, // 9
NegTraitLangItem, // 10
BitXorTraitLangItem, // 11
BitAndTraitLangItem, // 12
BitOrTraitLangItem, // 13
ShlTraitLangItem, // 14
ShrTraitLangItem, // 15
IndexTraitLangItem, // 16
NotTraitLangItem, // 11
BitXorTraitLangItem, // 12
BitAndTraitLangItem, // 13
BitOrTraitLangItem, // 14
ShlTraitLangItem, // 15
ShrTraitLangItem, // 16
IndexTraitLangItem, // 17
EqTraitLangItem, // 17
OrdTraitLangItem, // 18
EqTraitLangItem, // 18
OrdTraitLangItem, // 19
StrEqFnLangItem, // 19
UniqStrEqFnLangItem, // 20
AnnihilateFnLangItem, // 21
LogTypeFnLangItem, // 22
FailFnLangItem, // 23
FailBoundsCheckFnLangItem, // 24
ExchangeMallocFnLangItem, // 25
ExchangeFreeFnLangItem, // 26
MallocFnLangItem, // 27
FreeFnLangItem, // 28
StrEqFnLangItem, // 20
UniqStrEqFnLangItem, // 21
AnnihilateFnLangItem, // 22
LogTypeFnLangItem, // 23
FailFnLangItem, // 24
FailBoundsCheckFnLangItem, // 25
ExchangeMallocFnLangItem, // 26
ExchangeFreeFnLangItem, // 27
MallocFnLangItem, // 28
FreeFnLangItem, // 29
}
struct LanguageItems {
items: [ Option<def_id> * 29 ]
items: [ Option<def_id> * 30 ]
}
impl LanguageItems {
static pub fn new() -> LanguageItems {
LanguageItems {
items: [ None, ..29 ]
items: [ None, ..30 ]
}
}
@ -106,25 +107,26 @@ impl LanguageItems {
8 => "div",
9 => "modulo",
10 => "neg",
11 => "bitxor",
12 => "bitand",
13 => "bitor",
14 => "shl",
15 => "shr",
16 => "index",
17 => "eq",
18 => "ord",
11 => "not",
12 => "bitxor",
13 => "bitand",
14 => "bitor",
15 => "shl",
16 => "shr",
17 => "index",
18 => "eq",
19 => "ord",
19 => "str_eq",
20 => "uniq_str_eq",
21 => "annihilate",
22 => "log_type",
23 => "fail_",
24 => "fail_bounds_check",
25 => "exchange_malloc",
26 => "exchange_free",
27 => "malloc",
28 => "free",
20 => "str_eq",
21 => "uniq_str_eq",
22 => "annihilate",
23 => "log_type",
24 => "fail_",
25 => "fail_bounds_check",
26 => "exchange_malloc",
27 => "exchange_free",
28 => "malloc",
29 => "free",
_ => "???"
}
@ -167,6 +169,9 @@ impl LanguageItems {
pub fn neg_trait(&const self) -> def_id {
self.items[NegTraitLangItem as uint].get()
}
pub fn not_trait(&const self) -> def_id {
self.items[NotTraitLangItem as uint].get()
}
pub fn bitxor_trait(&const self) -> def_id {
self.items[BitXorTraitLangItem as uint].get()
}
@ -244,6 +249,7 @@ fn LanguageItemCollector(crate: @crate,
item_refs.insert(~"div", DivTraitLangItem as uint);
item_refs.insert(~"modulo", ModuloTraitLangItem as uint);
item_refs.insert(~"neg", NegTraitLangItem as uint);
item_refs.insert(~"not", NotTraitLangItem as uint);
item_refs.insert(~"bitxor", BitXorTraitLangItem as uint);
item_refs.insert(~"bitand", BitAndTraitLangItem as uint);
item_refs.insert(~"bitor", BitOrTraitLangItem as uint);

View File

@ -54,7 +54,7 @@ use syntax::ast::{ty_str, ty_u, ty_u16, ty_u32, ty_u64, ty_u8, ty_uint};
use syntax::ast::{type_value_ns, ty_param_bound, unnamed_field};
use syntax::ast::{variant, view_item, view_item_export, view_item_import};
use syntax::ast::{view_item_use, view_path_glob, view_path_list};
use syntax::ast::{view_path_simple, visibility, anonymous, named};
use syntax::ast::{view_path_simple, visibility, anonymous, named, not};
use syntax::ast_util::{def_id_of_def, dummy_sp, local_def};
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
use syntax::ast_util::{Privacy, Public, Private, visibility_to_privacy};
@ -5217,6 +5217,10 @@ impl Resolver {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.neg_trait());
}
expr_unary(not, _) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.not_trait());
}
expr_index(*) => {
self.add_fixed_trait_for_expr(expr.id,
self.lang_items.index_trait());

View File

@ -34,6 +34,12 @@ impl Point : ops::Neg<Point> {
}
}
impl Point : ops::Not<Point> {
pure fn not(&self) -> Point {
Point {x: !self.x, y: !self.y }
}
}
impl Point : ops::Index<bool,int> {
pure fn index(&self, +x: bool) -> int {
if x { self.x } else { self.y }
@ -55,6 +61,11 @@ fn main() {
assert -p == Point {x: -11, y: -22};
assert p[true] == 11;
assert p[false] == 22;
let q = !p;
assert q.x == !(p.x);
assert q.y == !(p.y);
// Issue #1733
fn~(_x: int){}(p[true]);
}