Whenever a lang_item is required, some relevant message is displayed, often with
a span of what triggered the usage of the lang item
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) => {
// 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]
}
}
}
}
- 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();
}
}
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) {
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;
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,
}
}
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,
use metadata::common::LinkMeta;
use metadata::{csearch, cstore, encoder};
use middle::astencode;
+use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
+use middle::lang_items::{MallocFnLangItem, ClosureExchangeMallocFnLangItem};
use middle::resolve;
use middle::trans::_match;
use middle::trans::adt;
let _icx = push_ctxt("malloc_raw");
let ccx = bcx.ccx();
+ fn require_alloc_fn(bcx: block, t: ty::t, it: LangItem) -> ast::def_id {
+ let li = &bcx.tcx().lang_items;
+ match li.require(it) {
+ Ok(id) => id,
+ Err(s) => {
+ bcx.tcx().sess.fatal(fmt!("allocation of `%s` %s",
+ bcx.ty_to_str(t), s));
+ }
+ }
+ }
+
if heap == heap_exchange {
let llty_value = type_of::type_of(ccx, t);
+
// Allocate space:
let r = callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.exchange_malloc_fn(),
+ require_alloc_fn(bcx, t, ExchangeMallocFnLangItem),
[size],
None);
rslt(r.bcx, PointerCast(r.bcx, r.val, llty_value.ptr_to()))
// we treat ~fn, @fn and @[] as @ here, which isn't ideal
let (mk_fn, langcall) = match heap {
heap_managed | heap_managed_unique => {
- (ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn())
+ (ty::mk_imm_box,
+ require_alloc_fn(bcx, t, MallocFnLangItem))
}
heap_exchange_closure => {
- (ty::mk_imm_box, bcx.tcx().lang_items.closure_exchange_malloc_fn())
+ (ty::mk_imm_box,
+ require_alloc_fn(bcx, t, ClosureExchangeMallocFnLangItem))
}
_ => fail!("heap_exchange already handled")
};
fn create_entry_fn(ccx: @mut CrateContext,
rust_main: ValueRef,
use_start_lang_item: bool) {
- let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], &ccx.int_type);
+ let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()],
+ &ccx.int_type);
// FIXME #4404 android JNI hacks
let llfn = if *ccx.sess.building_library {
unsafe {
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
- let start_def_id = ccx.tcx.lang_items.start_fn();
- if start_def_id.crate != ast::local_crate {
- let start_fn_type = csearch::get_type(ccx.tcx,
- start_def_id).ty;
- trans_external_path(ccx, start_def_id, start_fn_type);
- }
-
let crate_map = ccx.crate_map;
let opaque_crate_map = do "crate_map".as_c_str |buf| {
llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
};
let (start_fn, args) = if use_start_lang_item {
- let start_def_id = ccx.tcx.lang_items.start_fn();
+ let start_def_id = match ccx.tcx.lang_items.require(StartFnLangItem) {
+ Ok(id) => id,
+ Err(s) => { ccx.tcx.sess.fatal(s); }
+ };
let start_fn = if start_def_id.crate == ast::local_crate {
get_item_val(ccx, start_def_id.node)
} else {
let start_fn_type = csearch::get_type(ccx.tcx,
- start_def_id).ty;
+ start_def_id).ty;
trans_external_path(ccx, start_def_id, start_fn_type)
};
(start_fn, args)
} else {
debug!("using user-defined start fn");
- let args = {
- ~[
- C_null(Type::opaque_box(ccx).ptr_to()),
- llvm::LLVMGetParam(llfn, 0 as c_uint),
- llvm::LLVMGetParam(llfn, 1 as c_uint),
- opaque_crate_map
- ]
- };
+ let args = ~[
+ C_null(Type::opaque_box(ccx).ptr_to()),
+ llvm::LLVMGetParam(llfn, 0 as c_uint),
+ llvm::LLVMGetParam(llfn, 1 as c_uint),
+ opaque_crate_map
+ ];
(rust_main, args)
};
}
subcrates.push(C_int(ccx, 0));
- let llannihilatefn;
- let annihilate_def_id = ccx.tcx.lang_items.annihilate_fn();
- if annihilate_def_id.crate == ast::local_crate {
- llannihilatefn = get_item_val(ccx, annihilate_def_id.node);
- } else {
- let annihilate_fn_type = csearch::get_type(ccx.tcx,
- annihilate_def_id).ty;
- llannihilatefn = trans_external_path(ccx,
- annihilate_def_id,
- annihilate_fn_type);
- }
+ let llannihilatefn = match ccx.tcx.lang_items.annihilate_fn() {
+ Some(annihilate_def_id) => {
+ if annihilate_def_id.crate == ast::local_crate {
+ get_item_val(ccx, annihilate_def_id.node)
+ } else {
+ let annihilate_fn_type = csearch::get_type(ccx.tcx,
+ annihilate_def_id).ty;
+ trans_external_path(ccx, annihilate_def_id, annihilate_fn_type)
+ }
+ }
+ None => { C_null(Type::i8p()) }
+ };
unsafe {
let mod_map = create_module_map(ccx);
use back::link::{mangle_internal_name_by_path_and_seq};
use lib::llvm::{llvm, ValueRef};
use middle::moves;
+use middle::lang_items::ClosureExchangeMallocFnLangItem;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
// Allocate memory, update original ptr, and copy existing data
let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p());
let mut bcx = bcx;
+ let alloc_fn = langcall(bcx, None,
+ fmt!("allocation of type with sigil `%s`",
+ sigil.to_str()),
+ ClosureExchangeMallocFnLangItem);
let llresult = unpack_result!(bcx, callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.closure_exchange_malloc_fn(),
+ alloc_fn,
[opaque_tydesc, sz],
None));
let cbox_out = PointerCast(bcx, llresult, llopaquecboxty);
use lib::llvm::{True, False, Bool};
use lib::llvm::{llvm};
use lib;
+use middle::lang_items::LangItem;
use middle::trans::base;
use middle::trans::build;
use middle::trans::datum;
pub fn bool_to_i1(bcx: block, llval: ValueRef) -> ValueRef {
build::ICmp(bcx, lib::llvm::IntNE, llval, C_bool(false))
}
+
+pub fn langcall(bcx: block, span: Option<span>, msg: &str,
+ li: LangItem) -> ast::def_id {
+ match bcx.tcx().lang_items.require(li) {
+ Ok(id) => id,
+ Err(s) => {
+ let msg = fmt!("%s %s", msg, s);
+ match span {
+ Some(span) => { bcx.tcx().sess.span_fatal(span, msg); }
+ None => { bcx.tcx().sess.fatal(msg); }
+ }
+ }
+ }
+}
use back::link;
use lib;
use lib::llvm::*;
+use middle::lang_items::{FailFnLangItem, FailBoundsCheckFnLangItem};
+use middle::lang_items::LogTypeFnLangItem;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
// Call the polymorphic log function
let val = val_datum.to_ref_llval(bcx);
- let did = bcx.tcx().lang_items.log_type_fn();
+ let did = langcall(bcx, Some(e.span), "", LogTypeFnLangItem);
let bcx = callee::trans_lang_call_with_type_params(
bcx, did, [level, val], [val_datum.ty], expr::Ignore);
bcx
let V_str = PointerCast(bcx, V_fail_str, Type::i8p());
let V_filename = PointerCast(bcx, V_filename, Type::i8p());
let args = ~[V_str, V_filename, C_int(ccx, V_line)];
- let bcx = callee::trans_lang_call(
- bcx, bcx.tcx().lang_items.fail_fn(), args, Some(expr::Ignore)).bcx;
+ let did = langcall(bcx, sp_opt, "", FailFnLangItem);
+ let bcx = callee::trans_lang_call(bcx, did, args, Some(expr::Ignore)).bcx;
Unreachable(bcx);
return bcx;
}
let _icx = push_ctxt("trans_fail_bounds_check");
let (filename, line) = filename_and_line_num_from_span(bcx, sp);
let args = ~[filename, line, index, len];
- let bcx = callee::trans_lang_call(
- bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, Some(expr::Ignore)).bcx;
+ let did = langcall(bcx, Some(sp), "", FailBoundsCheckFnLangItem);
+ let bcx = callee::trans_lang_call(bcx, did, args, Some(expr::Ignore)).bcx;
Unreachable(bcx);
return bcx;
}
use driver::session;
use lib;
use lib::llvm::{llvm, ValueRef, True};
+use middle::lang_items::{FreeFnLangItem, ExchangeFreeFnLangItem};
use middle::trans::adt;
use middle::trans::base::*;
use middle::trans::callee;
pub fn trans_free(cx: block, v: ValueRef) -> block {
let _icx = push_ctxt("trans_free");
callee::trans_lang_call(cx,
- cx.tcx().lang_items.free_fn(),
+ langcall(cx, None, "", FreeFnLangItem),
[PointerCast(cx, v, Type::i8p())],
Some(expr::Ignore)).bcx
}
pub fn trans_exchange_free(cx: block, v: ValueRef) -> block {
let _icx = push_ctxt("trans_exchange_free");
callee::trans_lang_call(cx,
- cx.tcx().lang_items.exchange_free_fn(),
+ langcall(cx, None, "", ExchangeFreeFnLangItem),
[PointerCast(cx, v, Type::i8p())],
Some(expr::Ignore)).bcx
}
let _icx = push_ctxt("make_visit_glue");
do with_scope(bcx, None, "visitor cleanup") |bcx| {
let mut bcx = bcx;
- let (visitor_trait, object_ty) = ty::visitor_object_ty(bcx.tcx());
+ let (visitor_trait, object_ty) = match ty::visitor_object_ty(bcx.tcx()){
+ Ok(pair) => pair,
+ Err(s) => {
+ bcx.tcx().sess.fatal(s);
+ }
+ };
let v = PointerCast(bcx, v, type_of::type_of(bcx.ccx(), object_ty).ptr_to());
bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, visitor_trait.def_id);
// The visitor is a boxed object and needs to be dropped
let repr = adt::represent_type(bcx.ccx(), t);
let variants = ty::substd_enum_variants(ccx.tcx, did, substs);
let llptrty = type_of(ccx, t).ptr_to();
- let opaquety = ty::get_opaque_ty(ccx.tcx);
+ let opaquety = ty::get_opaque_ty(ccx.tcx).unwrap();
let opaqueptrty = ty::mk_ptr(ccx.tcx, ty::mt { ty: opaquety, mutbl: ast::m_imm });
let make_get_disr = || {
visitor_trait_id: def_id)
-> block {
let final = sub_block(bcx, "final");
- let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx);
+ let tydesc_ty = ty::get_tydesc_ty(bcx.ccx().tcx).unwrap();
let tydesc_ty = type_of(bcx.ccx(), tydesc_ty);
let mut r = Reflector {
visitor_val: visitor_val,
use back::abi;
use lib;
use lib::llvm::{llvm, ValueRef};
+use middle::lang_items::StrDupUniqFnLangItem;
use middle::trans::base;
use middle::trans::base::*;
use middle::trans::build::*;
heap_exchange => {
match content_expr.node {
ast::expr_lit(@codemap::spanned {
- node: ast::lit_str(s), _
+ node: ast::lit_str(s), span
}) => {
let llptrval = C_cstr(bcx.ccx(), s);
let llptrval = PointerCast(bcx, llptrval, Type::i8p());
let llsizeval = C_uint(bcx.ccx(), s.len());
let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq);
let lldestval = scratch_datum(bcx, typ, "", false);
+ let alloc_fn = langcall(bcx, Some(span), "",
+ StrDupUniqFnLangItem);
let bcx = callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.strdup_uniq_fn(),
+ alloc_fn,
[ llptrval, llsizeval ],
Some(expr::SaveIn(lldestval.to_ref_llval(bcx)))).bcx;
return DatumBlock {
use lib::llvm::ValueRef;
use middle::borrowck::{RootInfo, root_map_key, DynaImm, DynaMut};
+use middle::lang_items::CheckNotBorrowedFnLangItem;
+use middle::lang_items::{BorrowAsImmFnLangItem, BorrowAsMutFnLangItem};
+use middle::lang_items::{RecordBorrowFnLangItem, UnrecordBorrowFnLangItem};
+use middle::lang_items::ReturnToMutFnLangItem;
use middle::trans::base::*;
use middle::trans::build::*;
use middle::trans::callee;
if bcx.tcx().sess.debug_borrows() {
bcx = callee::trans_lang_call( bcx,
- bcx.tcx().lang_items.unrecord_borrow_fn(),
+ langcall(bcx, None, "unborrow", UnrecordBorrowFnLangItem),
[
box_ptr,
bits_val,
callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.return_to_mut_fn(),
+ langcall(bcx, None, "unborrow", ReturnToMutFnLangItem),
[
box_ptr,
bits_val,
let scratch_bits = scratch_datum(bcx, ty::mk_uint(),
"__write_guard_bits", false);
- let freeze_did = match freeze_kind {
- DynaImm => bcx.tcx().lang_items.borrow_as_imm_fn(),
- DynaMut => bcx.tcx().lang_items.borrow_as_mut_fn(),
+ let freeze_item = match freeze_kind {
+ DynaImm => BorrowAsImmFnLangItem,
+ DynaMut => BorrowAsMutFnLangItem,
};
let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to()));
let llresult = unpack_result!(bcx, callee::trans_lang_call(
bcx,
- freeze_did,
+ langcall(bcx, Some(span), "freeze", freeze_item),
[
box_ptr,
filename,
if bcx.tcx().sess.debug_borrows() {
bcx = callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.record_borrow_fn(),
+ langcall(bcx, Some(span), "freeze", RecordBorrowFnLangItem),
[
box_ptr,
llresult,
callee::trans_lang_call(
bcx,
- bcx.tcx().lang_items.check_not_borrowed_fn(),
+ langcall(bcx, Some(span), "write guard", CheckNotBorrowedFnLangItem),
[PointerCast(bcx, llval, Type::i8p()), filename, line],
Some(expr::Ignore)).bcx
}
use metadata::csearch;
use metadata;
use middle::const_eval;
+use middle::lang_items::{TyDescStructLangItem, TyVisitorTraitLangItem};
+use middle::lang_items::OpaqueStructLangItem;
use middle::freevars;
use middle::resolve::{Impl, MethodInfo};
use middle::resolve;
}
}
-pub fn get_tydesc_ty(tcx: ctxt) -> t {
- let tydesc_lang_item = tcx.lang_items.ty_desc();
- tcx.intrinsic_defs.find_copy(&tydesc_lang_item)
- .expect("Failed to resolve TyDesc")
+pub fn get_tydesc_ty(tcx: ctxt) -> Result<t, ~str> {
+ do tcx.lang_items.require(TyDescStructLangItem).map |tydesc_lang_item| {
+ tcx.intrinsic_defs.find_copy(tydesc_lang_item)
+ .expect("Failed to resolve TyDesc")
+ }
}
-pub fn get_opaque_ty(tcx: ctxt) -> t {
- let opaque_lang_item = tcx.lang_items.opaque();
- tcx.intrinsic_defs.find_copy(&opaque_lang_item)
- .expect("Failed to resolve Opaque")
+pub fn get_opaque_ty(tcx: ctxt) -> Result<t, ~str> {
+ do tcx.lang_items.require(OpaqueStructLangItem).map |opaque_lang_item| {
+ tcx.intrinsic_defs.find_copy(opaque_lang_item)
+ .expect("Failed to resolve Opaque")
+ }
}
-pub fn visitor_object_ty(tcx: ctxt) -> (@TraitRef, t) {
+pub fn visitor_object_ty(tcx: ctxt) -> Result<(@TraitRef, t), ~str> {
+ let trait_lang_item = match tcx.lang_items.require(TyVisitorTraitLangItem) {
+ Ok(id) => id,
+ Err(s) => { return Err(s); }
+ };
let substs = substs {
self_r: None,
self_ty: None,
tps: ~[]
};
- let trait_lang_item = tcx.lang_items.ty_visitor();
let trait_ref = @TraitRef { def_id: trait_lang_item, substs: substs };
let mut static_trait_bound = EmptyBuiltinBounds();
static_trait_bound.add(BoundStatic);
- (trait_ref,
- mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
- BoxTraitStore, ast::m_imm, static_trait_bound))
+ Ok((trait_ref,
+ mk_trait(tcx, trait_ref.def_id, copy trait_ref.substs,
+ BoxTraitStore, ast::m_imm, static_trait_bound)))
}
//! is a builtin trait.
let li = &tcx.lang_items;
- if trait_def_id == li.send_trait() {
+ if Some(trait_def_id) == li.send_trait() {
builtin_bounds.add(ty::BoundSend);
true
- } else if trait_def_id == li.copy_trait() {
+ } else if Some(trait_def_id) == li.copy_trait() {
builtin_bounds.add(ty::BoundCopy);
true
- } else if trait_def_id == li.freeze_trait() {
+ } else if Some(trait_def_id) == li.freeze_trait() {
builtin_bounds.add(ty::BoundFreeze);
true
- } else if trait_def_id == li.sized_trait() {
+ } else if Some(trait_def_id) == li.sized_trait() {
builtin_bounds.add(ty::BoundSized);
true
} else {
}
"get_tydesc" => {
- let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
+ let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
+ Ok(t) => t,
+ Err(s) => { tcx.sess.span_fatal(it.span, s); }
+ };
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
ty: tydesc_ty,
mutbl: ast::m_imm
(1u, ~[], td_ptr)
}
"visit_tydesc" => {
- let tydesc_ty = ty::get_tydesc_ty(ccx.tcx);
- let (_, visitor_object_ty) = ty::visitor_object_ty(tcx);
+ let tydesc_ty = match ty::get_tydesc_ty(ccx.tcx) {
+ Ok(t) => t,
+ Err(s) => { tcx.sess.span_fatal(it.span, s); }
+ };
+ let visitor_object_ty = match ty::visitor_object_ty(tcx) {
+ Ok((_, vot)) => vot,
+ Err(s) => { tcx.sess.span_fatal(it.span, s); }
+ };
+
let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt {
ty: tydesc_ty,
mutbl: ast::m_imm
pub fn populate_destructor_table(&self) {
let coherence_info = &self.crate_context.coherence_info;
let tcx = self.crate_context.tcx;
- let drop_trait = tcx.lang_items.drop_trait();
+ let drop_trait = match tcx.lang_items.drop_trait() {
+ Some(id) => id, None => { return }
+ };
let impls_opt = coherence_info.extension_methods.find(&drop_trait);
let impls;
ccx.tcx.intrinsic_defs.insert(lang_item, ty);
}
- collect_intrinsic_type(ccx, ccx.tcx.lang_items.ty_desc());
- collect_intrinsic_type(ccx, ccx.tcx.lang_items.opaque());
+ match ccx.tcx.lang_items.ty_desc() {
+ Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
+ }
+ match ccx.tcx.lang_items.opaque() {
+ Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
+ }
visit::visit_crate(
crate, ((),
--- /dev/null
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// xfail-fast - windows doesn't like this
+
+// Smallest hello world with no runtime
+
+#[no_std];
+
+// This is an unfortunate thing to have to do on linux :(
+#[cfg(target_os = "linux")]
+#[doc(hidden)]
+pub mod linkhack {
+ #[link_args="-lrustrt -lrt"]
+ extern {}
+}
+
+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;
+}
+