Skip to content

Commit

Permalink
Use a macro in lang_items to remove duplication.
Browse files Browse the repository at this point in the history
This should make maintenance of lang items simpler and also reduces the
line count by about 201 lines.
  • Loading branch information
chris-morgan committed Dec 6, 2013
1 parent 9fc4806 commit 0b1bbc5
Showing 1 changed file with 77 additions and 276 deletions.
353 changes: 77 additions & 276 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,66 +34,26 @@ use std::hashmap::HashMap;
use std::iter::Enumerate;
use std::vec;

// The actual lang items defined come at the end of this file in one handy table.
// So you probably just want to nip down to the end.
macro_rules! lets_do_this {
(
There are $num_lang_items:expr lang items.
$( $num:pat, $variant:ident, $name:expr, $method:ident; )*
) => {

pub enum LangItem {
FreezeTraitLangItem, // 0
SendTraitLangItem, // 1
SizedTraitLangItem, // 2

DropTraitLangItem, // 3

AddTraitLangItem, // 4
SubTraitLangItem, // 5
MulTraitLangItem, // 6
DivTraitLangItem, // 7
RemTraitLangItem, // 8
NegTraitLangItem, // 9
NotTraitLangItem, // 10
BitXorTraitLangItem, // 11
BitAndTraitLangItem, // 12
BitOrTraitLangItem, // 13
ShlTraitLangItem, // 14
ShrTraitLangItem, // 15
IndexTraitLangItem, // 16

EqTraitLangItem, // 17
OrdTraitLangItem, // 18

StrEqFnLangItem, // 19
UniqStrEqFnLangItem, // 20
FailFnLangItem, // 21
FailBoundsCheckFnLangItem, // 22
ExchangeMallocFnLangItem, // 23
ClosureExchangeMallocFnLangItem, // 24
ExchangeFreeFnLangItem, // 25
MallocFnLangItem, // 26
FreeFnLangItem, // 27
BorrowAsImmFnLangItem, // 28
BorrowAsMutFnLangItem, // 29
ReturnToMutFnLangItem, // 30
CheckNotBorrowedFnLangItem, // 31
StrDupUniqFnLangItem, // 32
RecordBorrowFnLangItem, // 33
UnrecordBorrowFnLangItem, // 34

StartFnLangItem, // 35

TyDescStructLangItem, // 36
TyVisitorTraitLangItem, // 37
OpaqueStructLangItem, // 38

EventLoopFactoryLangItem, // 39

TypeIdLangItem, // 40
$($variant),*
}

pub struct LanguageItems {
items: [Option<ast::DefId>, ..41]
items: [Option<ast::DefId>, ..$num_lang_items]
}

impl LanguageItems {
pub fn new() -> LanguageItems {
LanguageItems {
items: [ None, ..41 ]
items: [ None, ..$num_lang_items ]
}
}

Expand All @@ -103,61 +63,11 @@ impl LanguageItems {

pub fn item_name(index: uint) -> &'static str {
match index {
0 => "freeze",
1 => "send",
2 => "sized",

3 => "drop",

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",

19 => "str_eq",
20 => "uniq_str_eq",
21 => "fail_",
22 => "fail_bounds_check",
23 => "exchange_malloc",
24 => "closure_exchange_malloc",
25 => "exchange_free",
26 => "malloc",
27 => "free",
28 => "borrow_as_imm",
29 => "borrow_as_mut",
30 => "return_to_mut",
31 => "check_not_borrowed",
32 => "strdup_uniq",
33 => "record_borrow",
34 => "unrecord_borrow",

35 => "start",

36 => "ty_desc",
37 => "ty_visitor",
38 => "opaque",

39 => "event_loop_factory",

40 => "type_id",

$( $num => $name, )*
_ => "???"
}
}

// FIXME #4621: Method macros sure would be nice here.

pub fn require(&self, it: LangItem) -> Result<ast::DefId, ~str> {
match self.items[it as uint] {
Some(id) => Ok(id),
Expand All @@ -178,133 +88,11 @@ impl LanguageItems {
}
}

pub fn freeze_trait(&self) -> Option<ast::DefId> {
self.items[FreezeTraitLangItem as uint]
}
pub fn send_trait(&self) -> Option<ast::DefId> {
self.items[SendTraitLangItem as uint]
}
pub fn sized_trait(&self) -> Option<ast::DefId> {
self.items[SizedTraitLangItem as uint]
}

pub fn drop_trait(&self) -> Option<ast::DefId> {
self.items[DropTraitLangItem as uint]
}

pub fn add_trait(&self) -> Option<ast::DefId> {
self.items[AddTraitLangItem as uint]
}
pub fn sub_trait(&self) -> Option<ast::DefId> {
self.items[SubTraitLangItem as uint]
}
pub fn mul_trait(&self) -> Option<ast::DefId> {
self.items[MulTraitLangItem as uint]
}
pub fn div_trait(&self) -> Option<ast::DefId> {
self.items[DivTraitLangItem as uint]
}
pub fn rem_trait(&self) -> Option<ast::DefId> {
self.items[RemTraitLangItem as uint]
}
pub fn neg_trait(&self) -> Option<ast::DefId> {
self.items[NegTraitLangItem as uint]
}
pub fn not_trait(&self) -> Option<ast::DefId> {
self.items[NotTraitLangItem as uint]
}
pub fn bitxor_trait(&self) -> Option<ast::DefId> {
self.items[BitXorTraitLangItem as uint]
}
pub fn bitand_trait(&self) -> Option<ast::DefId> {
self.items[BitAndTraitLangItem as uint]
}
pub fn bitor_trait(&self) -> Option<ast::DefId> {
self.items[BitOrTraitLangItem as uint]
}
pub fn shl_trait(&self) -> Option<ast::DefId> {
self.items[ShlTraitLangItem as uint]
}
pub fn shr_trait(&self) -> Option<ast::DefId> {
self.items[ShrTraitLangItem as uint]
}
pub fn index_trait(&self) -> Option<ast::DefId> {
self.items[IndexTraitLangItem as uint]
}

pub fn eq_trait(&self) -> Option<ast::DefId> {
self.items[EqTraitLangItem as uint]
}
pub fn ord_trait(&self) -> Option<ast::DefId> {
self.items[OrdTraitLangItem as uint]
}

pub fn str_eq_fn(&self) -> Option<ast::DefId> {
self.items[StrEqFnLangItem as uint]
}
pub fn uniq_str_eq_fn(&self) -> Option<ast::DefId> {
self.items[UniqStrEqFnLangItem as uint]
}
pub fn fail_fn(&self) -> Option<ast::DefId> {
self.items[FailFnLangItem as uint]
}
pub fn fail_bounds_check_fn(&self) -> Option<ast::DefId> {
self.items[FailBoundsCheckFnLangItem as uint]
}
pub fn exchange_malloc_fn(&self) -> Option<ast::DefId> {
self.items[ExchangeMallocFnLangItem as uint]
}
pub fn closure_exchange_malloc_fn(&self) -> Option<ast::DefId> {
self.items[ClosureExchangeMallocFnLangItem as uint]
}
pub fn exchange_free_fn(&self) -> Option<ast::DefId> {
self.items[ExchangeFreeFnLangItem as uint]
}
pub fn malloc_fn(&self) -> Option<ast::DefId> {
self.items[MallocFnLangItem as uint]
}
pub fn free_fn(&self) -> Option<ast::DefId> {
self.items[FreeFnLangItem as uint]
}
pub fn borrow_as_imm_fn(&self) -> Option<ast::DefId> {
self.items[BorrowAsImmFnLangItem as uint]
}
pub fn borrow_as_mut_fn(&self) -> Option<ast::DefId> {
self.items[BorrowAsMutFnLangItem as uint]
}
pub fn return_to_mut_fn(&self) -> Option<ast::DefId> {
self.items[ReturnToMutFnLangItem as uint]
}
pub fn check_not_borrowed_fn(&self) -> Option<ast::DefId> {
self.items[CheckNotBorrowedFnLangItem as uint]
}
pub fn strdup_uniq_fn(&self) -> Option<ast::DefId> {
self.items[StrDupUniqFnLangItem as uint]
}
pub fn record_borrow_fn(&self) -> Option<ast::DefId> {
self.items[RecordBorrowFnLangItem as uint]
}
pub fn unrecord_borrow_fn(&self) -> Option<ast::DefId> {
self.items[UnrecordBorrowFnLangItem as uint]
}
pub fn start_fn(&self) -> Option<ast::DefId> {
self.items[StartFnLangItem as uint]
}
pub fn ty_desc(&self) -> Option<ast::DefId> {
self.items[TyDescStructLangItem as uint]
}
pub fn ty_visitor(&self) -> Option<ast::DefId> {
self.items[TyVisitorTraitLangItem as uint]
}
pub fn opaque(&self) -> Option<ast::DefId> {
self.items[OpaqueStructLangItem as uint]
}
pub fn event_loop_factory(&self) -> Option<ast::DefId> {
self.items[EventLoopFactoryLangItem as uint]
}
pub fn type_id(&self) -> Option<ast::DefId> {
self.items[TypeIdLangItem as uint]
}
$(
pub fn $method(&self) -> Option<ast::DefId> {
self.items[$variant as uint]
}
)*
}

struct LanguageItemCollector {
Expand Down Expand Up @@ -343,53 +131,7 @@ impl LanguageItemCollector {
pub fn new(session: Session) -> LanguageItemCollector {
let mut item_refs = HashMap::new();

item_refs.insert("freeze", FreezeTraitLangItem as uint);
item_refs.insert("send", SendTraitLangItem as uint);
item_refs.insert("sized", SizedTraitLangItem as uint);

item_refs.insert("drop", DropTraitLangItem as uint);

item_refs.insert("add", AddTraitLangItem as uint);
item_refs.insert("sub", SubTraitLangItem as uint);
item_refs.insert("mul", MulTraitLangItem as uint);
item_refs.insert("div", DivTraitLangItem as uint);
item_refs.insert("rem", RemTraitLangItem 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);
item_refs.insert("shl", ShlTraitLangItem as uint);
item_refs.insert("shr", ShrTraitLangItem as uint);
item_refs.insert("index", IndexTraitLangItem as uint);

item_refs.insert("eq", EqTraitLangItem as uint);
item_refs.insert("ord", OrdTraitLangItem as uint);

item_refs.insert("str_eq", StrEqFnLangItem as uint);
item_refs.insert("uniq_str_eq", UniqStrEqFnLangItem as uint);
item_refs.insert("fail_", FailFnLangItem as uint);
item_refs.insert("fail_bounds_check",
FailBoundsCheckFnLangItem as uint);
item_refs.insert("exchange_malloc", ExchangeMallocFnLangItem as uint);
item_refs.insert("closure_exchange_malloc", ClosureExchangeMallocFnLangItem as uint);
item_refs.insert("exchange_free", ExchangeFreeFnLangItem as uint);
item_refs.insert("malloc", MallocFnLangItem as uint);
item_refs.insert("free", FreeFnLangItem as uint);
item_refs.insert("borrow_as_imm", BorrowAsImmFnLangItem as uint);
item_refs.insert("borrow_as_mut", BorrowAsMutFnLangItem as uint);
item_refs.insert("return_to_mut", ReturnToMutFnLangItem as uint);
item_refs.insert("check_not_borrowed",
CheckNotBorrowedFnLangItem as uint);
item_refs.insert("strdup_uniq", StrDupUniqFnLangItem as uint);
item_refs.insert("record_borrow", RecordBorrowFnLangItem as uint);
item_refs.insert("unrecord_borrow", UnrecordBorrowFnLangItem as uint);
item_refs.insert("start", StartFnLangItem as uint);
item_refs.insert("ty_desc", TyDescStructLangItem as uint);
item_refs.insert("ty_visitor", TyVisitorTraitLangItem as uint);
item_refs.insert("opaque", OpaqueStructLangItem as uint);
item_refs.insert("event_loop_factory", EventLoopFactoryLangItem as uint);
item_refs.insert("type_id", TypeIdLangItem as uint);
$( item_refs.insert($name, $variant as uint); )*

LanguageItemCollector {
session: session,
Expand Down Expand Up @@ -458,3 +200,62 @@ pub fn collect_language_items(crate: &ast::Crate,
session.abort_if_errors();
items
}

// End of the macro
}
}

lets_do_this! {
There are 41 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;
}

5 comments on commit 0b1bbc5

@bors
Copy link
Contributor

@bors bors commented on 0b1bbc5 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at chris-morgan@0b1bbc5

@bors
Copy link
Contributor

@bors bors commented on 0b1bbc5 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging chris-morgan/rust/let's-lop-lang-item-line-count = 0b1bbc5 into auto

@bors
Copy link
Contributor

@bors bors commented on 0b1bbc5 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chris-morgan/rust/let's-lop-lang-item-line-count = 0b1bbc5 merged ok, testing candidate = aa4455e

@bors
Copy link
Contributor

@bors bors commented on 0b1bbc5 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 0b1bbc5 Dec 6, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = aa4455e

Please sign in to comment.