Skip to content

Use a macro in lang_items to remove duplication. #10832

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Copy link
Member

Choose a reason for hiding this comment

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

This header could be part of the macro definition, not just a comment.

There are 41 lang items. The lang items follow:

ID, Variant name, Name, Method name;
// ...

:P

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure; we can go for a full-blown literate coding style if we want, too!

(I'll leave that to your imagination.)

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;
}