Skip to content

Commit

Permalink
auto merge of #7828 : alexcrichton/rust/lang-opt, r=graydon
Browse files Browse the repository at this point in the history
Whenever a lang_item is required, some relevant message is displayed, often with
a span of what triggered the usage of the lang item.

Now "hello word" is as small as:

```rust
#[no_std];

extern {
    fn puts(s: *u8);
}

extern "rust-intrinsic" {
    fn transmute<T, U>(t: T) -> U;
}

#[start]
fn main(_: int, _: **u8, _: *u8) -> int {
    unsafe {
        let (ptr, _): (*u8, uint) = transmute("Hello!");
        puts(ptr);
    }
    return 0;
}
```
  • Loading branch information
bors committed Jul 17, 2013
2 parents 4bd716a + 88a1b71 commit af54f63
Show file tree
Hide file tree
Showing 18 changed files with 294 additions and 179 deletions.
2 changes: 1 addition & 1 deletion src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt<Context>)) {
None => cx.tcx.sess.bug("trait ref not in def map!"),
Some(&trait_def) => {
let trait_def_id = ast_util::def_id_of_def(trait_def);
if cx.tcx.lang_items.drop_trait() == trait_def_id {
if cx.tcx.lang_items.drop_trait() == Some(trait_def_id) {
// Yes, it's a destructor.
match self_type.node {
ty_path(_, ref bounds, path_node_id) => {
Expand Down
190 changes: 92 additions & 98 deletions src/librustc/middle/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,135 +153,143 @@ impl LanguageItems {

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

pub fn freeze_trait(&self) -> def_id {
self.items[FreezeTraitLangItem as uint].get()
pub fn require(&self, it: LangItem) -> Result<def_id, ~str> {
match self.items[it as uint] {
Some(id) => Ok(id),
None => Err(fmt!("requires `%s` lang_item",
LanguageItems::item_name(it as uint)))
}
}

pub fn freeze_trait(&self) -> Option<def_id> {
self.items[FreezeTraitLangItem as uint]
}
pub fn copy_trait(&self) -> def_id {
self.items[CopyTraitLangItem as uint].get()
pub fn copy_trait(&self) -> Option<def_id> {
self.items[CopyTraitLangItem as uint]
}
pub fn send_trait(&self) -> def_id {
self.items[SendTraitLangItem as uint].get()
pub fn send_trait(&self) -> Option<def_id> {
self.items[SendTraitLangItem as uint]
}
pub fn sized_trait(&self) -> def_id {
self.items[SizedTraitLangItem as uint].get()
pub fn sized_trait(&self) -> Option<def_id> {
self.items[SizedTraitLangItem as uint]
}

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

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

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

pub fn str_eq_fn(&self) -> def_id {
self.items[StrEqFnLangItem as uint].get()
pub fn str_eq_fn(&self) -> Option<def_id> {
self.items[StrEqFnLangItem as uint]
}
pub fn uniq_str_eq_fn(&self) -> def_id {
self.items[UniqStrEqFnLangItem as uint].get()
pub fn uniq_str_eq_fn(&self) -> Option<def_id> {
self.items[UniqStrEqFnLangItem as uint]
}
pub fn annihilate_fn(&self) -> def_id {
self.items[AnnihilateFnLangItem as uint].get()
pub fn annihilate_fn(&self) -> Option<def_id> {
self.items[AnnihilateFnLangItem as uint]
}
pub fn log_type_fn(&self) -> def_id {
self.items[LogTypeFnLangItem as uint].get()
pub fn log_type_fn(&self) -> Option<def_id> {
self.items[LogTypeFnLangItem as uint]
}
pub fn fail_fn(&self) -> def_id {
self.items[FailFnLangItem as uint].get()
pub fn fail_fn(&self) -> Option<def_id> {
self.items[FailFnLangItem as uint]
}
pub fn fail_bounds_check_fn(&self) -> def_id {
self.items[FailBoundsCheckFnLangItem as uint].get()
pub fn fail_bounds_check_fn(&self) -> Option<def_id> {
self.items[FailBoundsCheckFnLangItem as uint]
}
pub fn exchange_malloc_fn(&self) -> def_id {
self.items[ExchangeMallocFnLangItem as uint].get()
pub fn exchange_malloc_fn(&self) -> Option<def_id> {
self.items[ExchangeMallocFnLangItem as uint]
}
pub fn closure_exchange_malloc_fn(&self) -> def_id {
self.items[ClosureExchangeMallocFnLangItem as uint].get()
pub fn closure_exchange_malloc_fn(&self) -> Option<def_id> {
self.items[ClosureExchangeMallocFnLangItem as uint]
}
pub fn exchange_free_fn(&self) -> def_id {
self.items[ExchangeFreeFnLangItem as uint].get()
pub fn exchange_free_fn(&self) -> Option<def_id> {
self.items[ExchangeFreeFnLangItem as uint]
}
pub fn malloc_fn(&self) -> def_id {
self.items[MallocFnLangItem as uint].get()
pub fn malloc_fn(&self) -> Option<def_id> {
self.items[MallocFnLangItem as uint]
}
pub fn free_fn(&self) -> def_id {
self.items[FreeFnLangItem as uint].get()
pub fn free_fn(&self) -> Option<def_id> {
self.items[FreeFnLangItem as uint]
}
pub fn borrow_as_imm_fn(&self) -> def_id {
self.items[BorrowAsImmFnLangItem as uint].get()
pub fn borrow_as_imm_fn(&self) -> Option<def_id> {
self.items[BorrowAsImmFnLangItem as uint]
}
pub fn borrow_as_mut_fn(&self) -> def_id {
self.items[BorrowAsMutFnLangItem as uint].get()
pub fn borrow_as_mut_fn(&self) -> Option<def_id> {
self.items[BorrowAsMutFnLangItem as uint]
}
pub fn return_to_mut_fn(&self) -> def_id {
self.items[ReturnToMutFnLangItem as uint].get()
pub fn return_to_mut_fn(&self) -> Option<def_id> {
self.items[ReturnToMutFnLangItem as uint]
}
pub fn check_not_borrowed_fn(&self) -> def_id {
self.items[CheckNotBorrowedFnLangItem as uint].get()
pub fn check_not_borrowed_fn(&self) -> Option<def_id> {
self.items[CheckNotBorrowedFnLangItem as uint]
}
pub fn strdup_uniq_fn(&self) -> def_id {
self.items[StrDupUniqFnLangItem as uint].get()
pub fn strdup_uniq_fn(&self) -> Option<def_id> {
self.items[StrDupUniqFnLangItem as uint]
}
pub fn record_borrow_fn(&self) -> def_id {
self.items[RecordBorrowFnLangItem as uint].get()
pub fn record_borrow_fn(&self) -> Option<def_id> {
self.items[RecordBorrowFnLangItem as uint]
}
pub fn unrecord_borrow_fn(&self) -> def_id {
self.items[UnrecordBorrowFnLangItem as uint].get()
pub fn unrecord_borrow_fn(&self) -> Option<def_id> {
self.items[UnrecordBorrowFnLangItem as uint]
}
pub fn start_fn(&self) -> def_id {
self.items[StartFnLangItem as uint].get()
pub fn start_fn(&self) -> Option<def_id> {
self.items[StartFnLangItem as uint]
}
pub fn ty_desc(&const self) -> def_id {
self.items[TyDescStructLangItem as uint].get()
pub fn ty_desc(&self) -> Option<def_id> {
self.items[TyDescStructLangItem as uint]
}
pub fn ty_visitor(&const self) -> def_id {
self.items[TyVisitorTraitLangItem as uint].get()
pub fn ty_visitor(&self) -> Option<def_id> {
self.items[TyVisitorTraitLangItem as uint]
}
pub fn opaque(&const self) -> def_id {
self.items[OpaqueStructLangItem as uint].get()
pub fn opaque(&self) -> Option<def_id> {
self.items[OpaqueStructLangItem as uint]
}
}

Expand Down Expand Up @@ -439,23 +447,9 @@ impl<'self> LanguageItemCollector<'self> {
}
}

pub fn check_completeness(&self) {
for self.item_refs.iter().advance |(&key, &item_ref)| {
match self.items.items[item_ref] {
None => {
self.session.err(fmt!("no item found for `%s`", key));
}
Some(_) => {
// OK.
}
}
}
}

pub fn collect(&mut self) {
self.collect_local_language_items();
self.collect_external_language_items();
self.check_completeness();
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5268,8 +5268,13 @@ impl Resolver {

pub fn add_fixed_trait_for_expr(@mut self,
expr_id: node_id,
trait_id: def_id) {
self.trait_map.insert(expr_id, @mut ~[trait_id]);
trait_id: Option<def_id>) {
match trait_id {
Some(trait_id) => {
self.trait_map.insert(expr_id, @mut ~[trait_id]);
}
None => {}
}
}

pub fn record_def(@mut self, node_id: node_id, def: def) {
Expand Down
9 changes: 7 additions & 2 deletions src/librustc/middle/trans/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ use back::abi;
use lib::llvm::{llvm, ValueRef, BasicBlockRef};
use middle::const_eval;
use middle::borrowck::root_map_key;
use middle::lang_items::{UniqStrEqFnLangItem, StrEqFnLangItem};
use middle::pat_util::*;
use middle::resolve::DefMap;
use middle::trans::adt;
Expand Down Expand Up @@ -1099,15 +1100,19 @@ pub fn compare_values(cx: block,
Store(cx, lhs, scratch_lhs);
let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
Store(cx, rhs, scratch_rhs);
let did = cx.tcx().lang_items.uniq_str_eq_fn();
let did = langcall(cx, None,
fmt!("comparison of `%s`", cx.ty_to_str(rhs_t)),
UniqStrEqFnLangItem);
let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
Result {
bcx: result.bcx,
val: bool_to_i1(result.bcx, result.val)
}
}
ty::ty_estr(_) => {
let did = cx.tcx().lang_items.str_eq_fn();
let did = langcall(cx, None,
fmt!("comparison of `%s`", cx.ty_to_str(rhs_t)),
StrEqFnLangItem);
let result = callee::trans_lang_call(cx, did, [lhs, rhs], None);
Result {
bcx: result.bcx,
Expand Down
Loading

0 comments on commit af54f63

Please sign in to comment.