]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/trans/common.rs
8ec65639b5227d6fff4c0264294ddda8319fdf15
[rust.git] / src / librustc_trans / trans / common.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![allow(non_camel_case_types, non_snake_case)]
12
13 //! Code that is useful in various trans modules.
14
15 pub use self::ExprOrMethodCall::*;
16
17 use session::Session;
18 use llvm;
19 use llvm::{ValueRef, BasicBlockRef, BuilderRef, ContextRef};
20 use llvm::{True, False, Bool};
21 use middle::cfg;
22 use middle::def;
23 use middle::infer;
24 use middle::lang_items::LangItem;
25 use middle::subst::{self, Substs};
26 use trans::base;
27 use trans::build;
28 use trans::callee;
29 use trans::cleanup;
30 use trans::consts;
31 use trans::datum;
32 use trans::debuginfo::{self, DebugLoc};
33 use trans::declare;
34 use trans::machine;
35 use trans::monomorphize;
36 use trans::type_::Type;
37 use trans::type_of;
38 use middle::traits;
39 use middle::ty::{self, HasTypeFlags, Ty};
40 use middle::ty_fold;
41 use middle::ty_fold::{TypeFolder, TypeFoldable};
42 use rustc::ast_map::{PathElem, PathName};
43 use util::nodemap::{FnvHashMap, NodeMap};
44
45 use arena::TypedArena;
46 use libc::{c_uint, c_char};
47 use std::ffi::CString;
48 use std::cell::{Cell, RefCell};
49 use std::result::Result as StdResult;
50 use std::vec::Vec;
51 use syntax::ast;
52 use syntax::codemap::{DUMMY_SP, Span};
53 use syntax::parse::token::InternedString;
54 use syntax::parse::token;
55
56 pub use trans::context::CrateContext;
57
58 /// Returns an equivalent value with all free regions removed (note
59 /// that late-bound regions remain, because they are important for
60 /// subtyping, but they are anonymized and normalized as well). This
61 /// is a stronger, caching version of `ty_fold::erase_regions`.
62 pub fn erase_regions<'tcx,T>(cx: &ty::ctxt<'tcx>, value: &T) -> T
63     where T : TypeFoldable<'tcx>
64 {
65     let value1 = value.fold_with(&mut RegionEraser(cx));
66     debug!("erase_regions({:?}) = {:?}",
67            value, value1);
68     return value1;
69
70     struct RegionEraser<'a, 'tcx: 'a>(&'a ty::ctxt<'tcx>);
71
72     impl<'a, 'tcx> TypeFolder<'tcx> for RegionEraser<'a, 'tcx> {
73         fn tcx(&self) -> &ty::ctxt<'tcx> { self.0 }
74
75         fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
76             match self.tcx().normalized_cache.borrow().get(&ty).cloned() {
77                 None => {}
78                 Some(u) => return u
79             }
80
81             let t_norm = ty_fold::super_fold_ty(self, ty);
82             self.tcx().normalized_cache.borrow_mut().insert(ty, t_norm);
83             return t_norm;
84         }
85
86         fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
87             where T : TypeFoldable<'tcx>
88         {
89             let u = self.tcx().anonymize_late_bound_regions(t);
90             ty_fold::super_fold_binder(self, &u)
91         }
92
93         fn fold_region(&mut self, r: ty::Region) -> ty::Region {
94             // because late-bound regions affect subtyping, we can't
95             // erase the bound/free distinction, but we can replace
96             // all free regions with 'static.
97             //
98             // Note that we *CAN* replace early-bound regions -- the
99             // type system never "sees" those, they get substituted
100             // away. In trans, they will always be erased to 'static
101             // whenever a substitution occurs.
102             match r {
103                 ty::ReLateBound(..) => r,
104                 _ => ty::ReStatic
105             }
106         }
107
108         fn fold_substs(&mut self,
109                        substs: &subst::Substs<'tcx>)
110                        -> subst::Substs<'tcx> {
111             subst::Substs { regions: subst::ErasedRegions,
112                             types: substs.types.fold_with(self) }
113         }
114     }
115 }
116
117 /// Is the type's representation size known at compile time?
118 pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
119     ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP)
120 }
121
122 pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
123     match ty.sty {
124         ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
125         ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
126         ty::TyBox(ty) => {
127             !type_is_sized(cx, ty)
128         }
129         _ => {
130             false
131         }
132     }
133 }
134
135 /// If `type_needs_drop` returns true, then `ty` is definitely
136 /// non-copy and *might* have a destructor attached; if it returns
137 /// false, then `ty` definitely has no destructor (i.e. no drop glue).
138 ///
139 /// (Note that this implies that if `ty` has a destructor attached,
140 /// then `type_needs_drop` will definitely return `true` for `ty`.)
141 pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
142     type_needs_drop_given_env(cx, ty, &cx.empty_parameter_environment())
143 }
144
145 /// Core implementation of type_needs_drop, potentially making use of
146 /// and/or updating caches held in the `param_env`.
147 fn type_needs_drop_given_env<'a,'tcx>(cx: &ty::ctxt<'tcx>,
148                                       ty: Ty<'tcx>,
149                                       param_env: &ty::ParameterEnvironment<'a,'tcx>) -> bool {
150     // Issue #22536: We first query type_moves_by_default.  It sees a
151     // normalized version of the type, and therefore will definitely
152     // know whether the type implements Copy (and thus needs no
153     // cleanup/drop/zeroing) ...
154     let implements_copy = !ty.moves_by_default(param_env, DUMMY_SP);
155
156     if implements_copy { return false; }
157
158     // ... (issue #22536 continued) but as an optimization, still use
159     // prior logic of asking if the `needs_drop` bit is set; we need
160     // not zero non-Copy types if they have no destructor.
161
162     // FIXME(#22815): Note that calling `ty::type_contents` is a
163     // conservative heuristic; it may report that `needs_drop` is set
164     // when actual type does not actually have a destructor associated
165     // with it. But since `ty` absolutely did not have the `Copy`
166     // bound attached (see above), it is sound to treat it as having a
167     // destructor (e.g. zero its memory on move).
168
169     let contents = ty.type_contents(cx);
170     debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
171     contents.needs_drop(cx)
172 }
173
174 fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
175     match ty.sty {
176         ty::TyStruct(def_id, substs) => {
177             let fields = ccx.tcx().lookup_struct_fields(def_id);
178             fields.len() == 1 && {
179                 let ty = ccx.tcx().lookup_field_type(def_id, fields[0].id, substs);
180                 let ty = monomorphize::normalize_associated_type(ccx.tcx(), &ty);
181                 type_is_immediate(ccx, ty)
182             }
183         }
184         _ => false
185     }
186 }
187
188 pub fn type_is_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
189     use trans::machine::llsize_of_alloc;
190     use trans::type_of::sizing_type_of;
191
192     let tcx = ccx.tcx();
193     let simple = ty.is_scalar() ||
194         ty.is_unique() || ty.is_region_ptr() ||
195         type_is_newtype_immediate(ccx, ty) ||
196         ty.is_simd(tcx);
197     if simple && !type_is_fat_ptr(tcx, ty) {
198         return true;
199     }
200     if !type_is_sized(tcx, ty) {
201         return false;
202     }
203     match ty.sty {
204         ty::TyStruct(..) | ty::TyEnum(..) | ty::TyTuple(..) | ty::TyArray(_, _) |
205         ty::TyClosure(..) => {
206             let llty = sizing_type_of(ccx, ty);
207             llsize_of_alloc(ccx, llty) <= llsize_of_alloc(ccx, ccx.int_type())
208         }
209         _ => type_is_zero_size(ccx, ty)
210     }
211 }
212
213 /// Identify types which have size zero at runtime.
214 pub fn type_is_zero_size<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
215     use trans::machine::llsize_of_alloc;
216     use trans::type_of::sizing_type_of;
217     let llty = sizing_type_of(ccx, ty);
218     llsize_of_alloc(ccx, llty) == 0
219 }
220
221 /// Identifies types which we declare to be equivalent to `void` in C for the purpose of function
222 /// return types. These are `()`, bot, and uninhabited enums. Note that all such types are also
223 /// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI
224 /// compatibility).
225 pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
226     ty.is_nil() || ty.is_empty(ccx.tcx())
227 }
228
229 /// Generates a unique symbol based off the name given. This is used to create
230 /// unique symbols for things like closures.
231 pub fn gensym_name(name: &str) -> PathElem {
232     let num = token::gensym(name).usize();
233     // use one colon which will get translated to a period by the mangler, and
234     // we're guaranteed that `num` is globally unique for this crate.
235     PathName(token::gensym(&format!("{}:{}", name, num)))
236 }
237
238 /*
239 * A note on nomenclature of linking: "extern", "foreign", and "upcall".
240 *
241 * An "extern" is an LLVM symbol we wind up emitting an undefined external
242 * reference to. This means "we don't have the thing in this compilation unit,
243 * please make sure you link it in at runtime". This could be a reference to
244 * C code found in a C library, or rust code found in a rust crate.
245 *
246 * Most "externs" are implicitly declared (automatically) as a result of a
247 * user declaring an extern _module_ dependency; this causes the rust driver
248 * to locate an extern crate, scan its compilation metadata, and emit extern
249 * declarations for any symbols used by the declaring crate.
250 *
251 * A "foreign" is an extern that references C (or other non-rust ABI) code.
252 * There is no metadata to scan for extern references so in these cases either
253 * a header-digester like bindgen, or manual function prototypes, have to
254 * serve as declarators. So these are usually given explicitly as prototype
255 * declarations, in rust code, with ABI attributes on them noting which ABI to
256 * link via.
257 *
258 * An "upcall" is a foreign call generated by the compiler (not corresponding
259 * to any user-written call in the code) into the runtime library, to perform
260 * some helper task such as bringing a task to life, allocating memory, etc.
261 *
262 */
263
264 #[derive(Copy, Clone)]
265 pub struct NodeIdAndSpan {
266     pub id: ast::NodeId,
267     pub span: Span,
268 }
269
270 pub fn expr_info(expr: &ast::Expr) -> NodeIdAndSpan {
271     NodeIdAndSpan { id: expr.id, span: expr.span }
272 }
273
274 pub struct BuilderRef_res {
275     pub b: BuilderRef,
276 }
277
278 impl Drop for BuilderRef_res {
279     fn drop(&mut self) {
280         unsafe {
281             llvm::LLVMDisposeBuilder(self.b);
282         }
283     }
284 }
285
286 pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
287     BuilderRef_res {
288         b: b
289     }
290 }
291
292 pub type ExternMap = FnvHashMap<String, ValueRef>;
293
294 pub fn validate_substs(substs: &Substs) {
295     assert!(!substs.types.needs_infer());
296 }
297
298 // work around bizarre resolve errors
299 type RvalueDatum<'tcx> = datum::Datum<'tcx, datum::Rvalue>;
300 pub type LvalueDatum<'tcx> = datum::Datum<'tcx, datum::Lvalue>;
301
302 // Function context.  Every LLVM function we create will have one of
303 // these.
304 pub struct FunctionContext<'a, 'tcx: 'a> {
305     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
306     // address of the first instruction in the sequence of
307     // instructions for this function that will go in the .text
308     // section of the executable we're generating.
309     pub llfn: ValueRef,
310
311     // always an empty parameter-environment NOTE: @jroesch another use of ParamEnv
312     pub param_env: ty::ParameterEnvironment<'a, 'tcx>,
313
314     // The environment argument in a closure.
315     pub llenv: Option<ValueRef>,
316
317     // A pointer to where to store the return value. If the return type is
318     // immediate, this points to an alloca in the function. Otherwise, it's a
319     // pointer to the hidden first parameter of the function. After function
320     // construction, this should always be Some.
321     pub llretslotptr: Cell<Option<ValueRef>>,
322
323     // These pub elements: "hoisted basic blocks" containing
324     // administrative activities that have to happen in only one place in
325     // the function, due to LLVM's quirks.
326     // A marker for the place where we want to insert the function's static
327     // allocas, so that LLVM will coalesce them into a single alloca call.
328     pub alloca_insert_pt: Cell<Option<ValueRef>>,
329     pub llreturn: Cell<Option<BasicBlockRef>>,
330
331     // If the function has any nested return's, including something like:
332     // fn foo() -> Option<Foo> { Some(Foo { x: return None }) }, then
333     // we use a separate alloca for each return
334     pub needs_ret_allocas: bool,
335
336     // The a value alloca'd for calls to upcalls.rust_personality. Used when
337     // outputting the resume instruction.
338     pub personality: Cell<Option<ValueRef>>,
339
340     // True if the caller expects this fn to use the out pointer to
341     // return. Either way, your code should write into the slot llretslotptr
342     // points to, but if this value is false, that slot will be a local alloca.
343     pub caller_expects_out_pointer: bool,
344
345     // Maps the DefId's for local variables to the allocas created for
346     // them in llallocas.
347     pub lllocals: RefCell<NodeMap<LvalueDatum<'tcx>>>,
348
349     // Same as above, but for closure upvars
350     pub llupvars: RefCell<NodeMap<ValueRef>>,
351
352     // The NodeId of the function, or -1 if it doesn't correspond to
353     // a user-defined function.
354     pub id: ast::NodeId,
355
356     // If this function is being monomorphized, this contains the type
357     // substitutions used.
358     pub param_substs: &'tcx Substs<'tcx>,
359
360     // The source span and nesting context where this function comes from, for
361     // error reporting and symbol generation.
362     pub span: Option<Span>,
363
364     // The arena that blocks are allocated from.
365     pub block_arena: &'a TypedArena<BlockS<'a, 'tcx>>,
366
367     // This function's enclosing crate context.
368     pub ccx: &'a CrateContext<'a, 'tcx>,
369
370     // Used and maintained by the debuginfo module.
371     pub debug_context: debuginfo::FunctionDebugContext,
372
373     // Cleanup scopes.
374     pub scopes: RefCell<Vec<cleanup::CleanupScope<'a, 'tcx>>>,
375
376     pub cfg: Option<cfg::CFG>,
377 }
378
379 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
380     pub fn arg_offset(&self) -> usize {
381         self.env_arg_pos() + if self.llenv.is_some() { 1 } else { 0 }
382     }
383
384     pub fn env_arg_pos(&self) -> usize {
385         if self.caller_expects_out_pointer {
386             1
387         } else {
388             0
389         }
390     }
391
392     pub fn cleanup(&self) {
393         unsafe {
394             llvm::LLVMInstructionEraseFromParent(self.alloca_insert_pt
395                                                      .get()
396                                                      .unwrap());
397         }
398     }
399
400     pub fn get_llreturn(&self) -> BasicBlockRef {
401         if self.llreturn.get().is_none() {
402
403             self.llreturn.set(Some(unsafe {
404                 llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn,
405                                                     "return\0".as_ptr() as *const _)
406             }))
407         }
408
409         self.llreturn.get().unwrap()
410     }
411
412     pub fn get_ret_slot(&self, bcx: Block<'a, 'tcx>,
413                         output: ty::FnOutput<'tcx>,
414                         name: &str) -> ValueRef {
415         if self.needs_ret_allocas {
416             base::alloca_no_lifetime(bcx, match output {
417                 ty::FnConverging(output_type) => type_of::type_of(bcx.ccx(), output_type),
418                 ty::FnDiverging => Type::void(bcx.ccx())
419             }, name)
420         } else {
421             self.llretslotptr.get().unwrap()
422         }
423     }
424
425     pub fn new_block(&'a self,
426                      is_lpad: bool,
427                      name: &str,
428                      opt_node_id: Option<ast::NodeId>)
429                      -> Block<'a, 'tcx> {
430         unsafe {
431             let name = CString::new(name).unwrap();
432             let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
433                                                            self.llfn,
434                                                            name.as_ptr());
435             BlockS::new(llbb, is_lpad, opt_node_id, self)
436         }
437     }
438
439     pub fn new_id_block(&'a self,
440                         name: &str,
441                         node_id: ast::NodeId)
442                         -> Block<'a, 'tcx> {
443         self.new_block(false, name, Some(node_id))
444     }
445
446     pub fn new_temp_block(&'a self,
447                           name: &str)
448                           -> Block<'a, 'tcx> {
449         self.new_block(false, name, None)
450     }
451
452     pub fn join_blocks(&'a self,
453                        id: ast::NodeId,
454                        in_cxs: &[Block<'a, 'tcx>])
455                        -> Block<'a, 'tcx> {
456         let out = self.new_id_block("join", id);
457         let mut reachable = false;
458         for bcx in in_cxs {
459             if !bcx.unreachable.get() {
460                 build::Br(*bcx, out.llbb, DebugLoc::None);
461                 reachable = true;
462             }
463         }
464         if !reachable {
465             build::Unreachable(out);
466         }
467         return out;
468     }
469
470     pub fn monomorphize<T>(&self, value: &T) -> T
471         where T : TypeFoldable<'tcx> + HasTypeFlags
472     {
473         monomorphize::apply_param_substs(self.ccx.tcx(),
474                                          self.param_substs,
475                                          value)
476     }
477
478     /// This is the same as `common::type_needs_drop`, except that it
479     /// may use or update caches within this `FunctionContext`.
480     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
481         type_needs_drop_given_env(self.ccx.tcx(), ty, &self.param_env)
482     }
483
484     pub fn eh_personality(&self) -> ValueRef {
485         // The exception handling personality function.
486         //
487         // If our compilation unit has the `eh_personality` lang item somewhere
488         // within it, then we just need to translate that. Otherwise, we're
489         // building an rlib which will depend on some upstream implementation of
490         // this function, so we just codegen a generic reference to it. We don't
491         // specify any of the types for the function, we just make it a symbol
492         // that LLVM can later use.
493         //
494         // Note that MSVC is a little special here in that we don't use the
495         // `eh_personality` lang item at all. Currently LLVM has support for
496         // both Dwarf and SEH unwind mechanisms for MSVC targets and uses the
497         // *name of the personality function* to decide what kind of unwind side
498         // tables/landing pads to emit. It looks like Dwarf is used by default,
499         // injecting a dependency on the `_Unwind_Resume` symbol for resuming
500         // an "exception", but for MSVC we want to force SEH. This means that we
501         // can't actually have the personality function be our standard
502         // `rust_eh_personality` function, but rather we wired it up to the
503         // CRT's custom personality function, which forces LLVM to consider
504         // landing pads as "landing pads for SEH".
505         let target = &self.ccx.sess().target.target;
506         match self.ccx.tcx().lang_items.eh_personality() {
507             Some(def_id) if !target.options.is_like_msvc => {
508                 callee::trans_fn_ref(self.ccx, def_id, ExprId(0),
509                                      self.param_substs).val
510             }
511             _ => {
512                 let mut personality = self.ccx.eh_personality().borrow_mut();
513                 match *personality {
514                     Some(llpersonality) => llpersonality,
515                     None => {
516                         let name = if !target.options.is_like_msvc {
517                             "rust_eh_personality"
518                         } else if target.arch == "x86" {
519                             "_except_handler3"
520                         } else {
521                             "__C_specific_handler"
522                         };
523                         let fty = Type::variadic_func(&[], &Type::i32(self.ccx));
524                         let f = declare::declare_cfn(self.ccx, name, fty,
525                                                      self.ccx.tcx().types.i32);
526                         *personality = Some(f);
527                         f
528                     }
529                 }
530             }
531         }
532     }
533 }
534
535 // Basic block context.  We create a block context for each basic block
536 // (single-entry, single-exit sequence of instructions) we generate from Rust
537 // code.  Each basic block we generate is attached to a function, typically
538 // with many basic blocks per function.  All the basic blocks attached to a
539 // function are organized as a directed graph.
540 pub struct BlockS<'blk, 'tcx: 'blk> {
541     // The BasicBlockRef returned from a call to
542     // llvm::LLVMAppendBasicBlock(llfn, name), which adds a basic
543     // block to the function pointed to by llfn.  We insert
544     // instructions into that block by way of this block context.
545     // The block pointing to this one in the function's digraph.
546     pub llbb: BasicBlockRef,
547     pub terminated: Cell<bool>,
548     pub unreachable: Cell<bool>,
549
550     // Is this block part of a landing pad?
551     pub is_lpad: bool,
552
553     // AST node-id associated with this block, if any. Used for
554     // debugging purposes only.
555     pub opt_node_id: Option<ast::NodeId>,
556
557     // The function context for the function to which this block is
558     // attached.
559     pub fcx: &'blk FunctionContext<'blk, 'tcx>,
560 }
561
562 pub type Block<'blk, 'tcx> = &'blk BlockS<'blk, 'tcx>;
563
564 impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
565     pub fn new(llbb: BasicBlockRef,
566                is_lpad: bool,
567                opt_node_id: Option<ast::NodeId>,
568                fcx: &'blk FunctionContext<'blk, 'tcx>)
569                -> Block<'blk, 'tcx> {
570         fcx.block_arena.alloc(BlockS {
571             llbb: llbb,
572             terminated: Cell::new(false),
573             unreachable: Cell::new(false),
574             is_lpad: is_lpad,
575             opt_node_id: opt_node_id,
576             fcx: fcx
577         })
578     }
579
580     pub fn ccx(&self) -> &'blk CrateContext<'blk, 'tcx> {
581         self.fcx.ccx
582     }
583     pub fn tcx(&self) -> &'blk ty::ctxt<'tcx> {
584         self.fcx.ccx.tcx()
585     }
586     pub fn sess(&self) -> &'blk Session { self.fcx.ccx.sess() }
587
588     pub fn name(&self, name: ast::Name) -> String {
589         token::get_name(name).to_string()
590     }
591
592     pub fn node_id_to_string(&self, id: ast::NodeId) -> String {
593         self.tcx().map.node_to_string(id).to_string()
594     }
595
596     pub fn def(&self, nid: ast::NodeId) -> def::Def {
597         match self.tcx().def_map.borrow().get(&nid) {
598             Some(v) => v.full_def(),
599             None => {
600                 self.tcx().sess.bug(&format!(
601                     "no def associated with node id {}", nid));
602             }
603         }
604     }
605
606     pub fn val_to_string(&self, val: ValueRef) -> String {
607         self.ccx().tn().val_to_string(val)
608     }
609
610     pub fn llty_str(&self, ty: Type) -> String {
611         self.ccx().tn().type_to_string(ty)
612     }
613
614     pub fn to_str(&self) -> String {
615         format!("[block {:p}]", self)
616     }
617
618     pub fn monomorphize<T>(&self, value: &T) -> T
619         where T : TypeFoldable<'tcx> + HasTypeFlags
620     {
621         monomorphize::apply_param_substs(self.tcx(),
622                                          self.fcx.param_substs,
623                                          value)
624     }
625 }
626
627 pub struct Result<'blk, 'tcx: 'blk> {
628     pub bcx: Block<'blk, 'tcx>,
629     pub val: ValueRef
630 }
631
632 impl<'b, 'tcx> Result<'b, 'tcx> {
633     pub fn new(bcx: Block<'b, 'tcx>, val: ValueRef) -> Result<'b, 'tcx> {
634         Result {
635             bcx: bcx,
636             val: val,
637         }
638     }
639 }
640
641 pub fn val_ty(v: ValueRef) -> Type {
642     unsafe {
643         Type::from_ref(llvm::LLVMTypeOf(v))
644     }
645 }
646
647 // LLVM constant constructors.
648 pub fn C_null(t: Type) -> ValueRef {
649     unsafe {
650         llvm::LLVMConstNull(t.to_ref())
651     }
652 }
653
654 pub fn C_undef(t: Type) -> ValueRef {
655     unsafe {
656         llvm::LLVMGetUndef(t.to_ref())
657     }
658 }
659
660 pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
661     unsafe {
662         llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool)
663     }
664 }
665
666 pub fn C_floating(s: &str, t: Type) -> ValueRef {
667     unsafe {
668         let s = CString::new(s).unwrap();
669         llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
670     }
671 }
672
673 pub fn C_nil(ccx: &CrateContext) -> ValueRef {
674     C_struct(ccx, &[], false)
675 }
676
677 pub fn C_bool(ccx: &CrateContext, val: bool) -> ValueRef {
678     C_integral(Type::i1(ccx), val as u64, false)
679 }
680
681 pub fn C_i32(ccx: &CrateContext, i: i32) -> ValueRef {
682     C_integral(Type::i32(ccx), i as u64, true)
683 }
684
685 pub fn C_u32(ccx: &CrateContext, i: u32) -> ValueRef {
686     C_integral(Type::i32(ccx), i as u64, false)
687 }
688
689 pub fn C_u64(ccx: &CrateContext, i: u64) -> ValueRef {
690     C_integral(Type::i64(ccx), i, false)
691 }
692
693 pub fn C_int<I: AsI64>(ccx: &CrateContext, i: I) -> ValueRef {
694     let v = i.as_i64();
695
696     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
697         32 => assert!(v < (1<<31) && v >= -(1<<31)),
698         64 => {},
699         n => panic!("unsupported target size: {}", n)
700     }
701
702     C_integral(ccx.int_type(), v as u64, true)
703 }
704
705 pub fn C_uint<I: AsU64>(ccx: &CrateContext, i: I) -> ValueRef {
706     let v = i.as_u64();
707
708     match machine::llbitsize_of_real(ccx, ccx.int_type()) {
709         32 => assert!(v < (1<<32)),
710         64 => {},
711         n => panic!("unsupported target size: {}", n)
712     }
713
714     C_integral(ccx.int_type(), v, false)
715 }
716
717 pub trait AsI64 { fn as_i64(self) -> i64; }
718 pub trait AsU64 { fn as_u64(self) -> u64; }
719
720 // FIXME: remove the intptr conversions, because they
721 // are host-architecture-dependent
722 impl AsI64 for i64 { fn as_i64(self) -> i64 { self as i64 }}
723 impl AsI64 for i32 { fn as_i64(self) -> i64 { self as i64 }}
724 impl AsI64 for isize { fn as_i64(self) -> i64 { self as i64 }}
725
726 impl AsU64 for u64  { fn as_u64(self) -> u64 { self as u64 }}
727 impl AsU64 for u32  { fn as_u64(self) -> u64 { self as u64 }}
728 impl AsU64 for usize { fn as_u64(self) -> u64 { self as u64 }}
729
730 pub fn C_u8(ccx: &CrateContext, i: usize) -> ValueRef {
731     C_integral(Type::i8(ccx), i as u64, false)
732 }
733
734
735 // This is a 'c-like' raw string, which differs from
736 // our boxed-and-length-annotated strings.
737 pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> ValueRef {
738     unsafe {
739         match cx.const_cstr_cache().borrow().get(&s) {
740             Some(&llval) => return llval,
741             None => ()
742         }
743
744         let sc = llvm::LLVMConstStringInContext(cx.llcx(),
745                                                 s.as_ptr() as *const c_char,
746                                                 s.len() as c_uint,
747                                                 !null_terminated as Bool);
748
749         let gsym = token::gensym("str");
750         let sym = format!("str{}", gsym.usize());
751         let g = declare::define_global(cx, &sym[..], val_ty(sc)).unwrap_or_else(||{
752             cx.sess().bug(&format!("symbol `{}` is already defined", sym));
753         });
754         llvm::LLVMSetInitializer(g, sc);
755         llvm::LLVMSetGlobalConstant(g, True);
756         llvm::SetLinkage(g, llvm::InternalLinkage);
757
758         cx.const_cstr_cache().borrow_mut().insert(s, g);
759         g
760     }
761 }
762
763 // NB: Do not use `do_spill_noroot` to make this into a constant string, or
764 // you will be kicked off fast isel. See issue #4352 for an example of this.
765 pub fn C_str_slice(cx: &CrateContext, s: InternedString) -> ValueRef {
766     let len = s.len();
767     let cs = consts::ptrcast(C_cstr(cx, s, false), Type::i8p(cx));
768     C_named_struct(cx.tn().find_type("str_slice").unwrap(), &[cs, C_uint(cx, len)])
769 }
770
771 pub fn C_struct(cx: &CrateContext, elts: &[ValueRef], packed: bool) -> ValueRef {
772     C_struct_in_context(cx.llcx(), elts, packed)
773 }
774
775 pub fn C_struct_in_context(llcx: ContextRef, elts: &[ValueRef], packed: bool) -> ValueRef {
776     unsafe {
777         llvm::LLVMConstStructInContext(llcx,
778                                        elts.as_ptr(), elts.len() as c_uint,
779                                        packed as Bool)
780     }
781 }
782
783 pub fn C_named_struct(t: Type, elts: &[ValueRef]) -> ValueRef {
784     unsafe {
785         llvm::LLVMConstNamedStruct(t.to_ref(), elts.as_ptr(), elts.len() as c_uint)
786     }
787 }
788
789 pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
790     unsafe {
791         return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
792     }
793 }
794
795 pub fn C_vector(elts: &[ValueRef]) -> ValueRef {
796     unsafe {
797         return llvm::LLVMConstVector(elts.as_ptr(), elts.len() as c_uint);
798     }
799 }
800
801 pub fn C_bytes(cx: &CrateContext, bytes: &[u8]) -> ValueRef {
802     C_bytes_in_context(cx.llcx(), bytes)
803 }
804
805 pub fn C_bytes_in_context(llcx: ContextRef, bytes: &[u8]) -> ValueRef {
806     unsafe {
807         let ptr = bytes.as_ptr() as *const c_char;
808         return llvm::LLVMConstStringInContext(llcx, ptr, bytes.len() as c_uint, True);
809     }
810 }
811
812 pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint])
813               -> ValueRef {
814     unsafe {
815         let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
816
817         debug!("const_get_elt(v={}, us={:?}, r={})",
818                cx.tn().val_to_string(v), us, cx.tn().val_to_string(r));
819
820         return r;
821     }
822 }
823
824 pub fn const_to_int(v: ValueRef) -> i64 {
825     unsafe {
826         llvm::LLVMConstIntGetSExtValue(v)
827     }
828 }
829
830 pub fn const_to_uint(v: ValueRef) -> u64 {
831     unsafe {
832         llvm::LLVMConstIntGetZExtValue(v)
833     }
834 }
835
836 fn is_const_integral(v: ValueRef) -> bool {
837     unsafe {
838         !llvm::LLVMIsAConstantInt(v).is_null()
839     }
840 }
841
842 pub fn const_to_opt_int(v: ValueRef) -> Option<i64> {
843     unsafe {
844         if is_const_integral(v) {
845             Some(llvm::LLVMConstIntGetSExtValue(v))
846         } else {
847             None
848         }
849     }
850 }
851
852 pub fn const_to_opt_uint(v: ValueRef) -> Option<u64> {
853     unsafe {
854         if is_const_integral(v) {
855             Some(llvm::LLVMConstIntGetZExtValue(v))
856         } else {
857             None
858         }
859     }
860 }
861
862 pub fn is_undef(val: ValueRef) -> bool {
863     unsafe {
864         llvm::LLVMIsUndef(val) != False
865     }
866 }
867
868 #[allow(dead_code)] // potentially useful
869 pub fn is_null(val: ValueRef) -> bool {
870     unsafe {
871         llvm::LLVMIsNull(val) != False
872     }
873 }
874
875 pub fn monomorphize_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, t: Ty<'tcx>) -> Ty<'tcx> {
876     bcx.fcx.monomorphize(&t)
877 }
878
879 pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> {
880     let tcx = bcx.tcx();
881     let t = tcx.node_id_to_type(id);
882     monomorphize_type(bcx, t)
883 }
884
885 pub fn expr_ty<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
886     node_id_type(bcx, ex.id)
887 }
888
889 pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
890     monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex))
891 }
892
893 /// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
894 /// do not (necessarily) resolve all nested obligations on the impl. Note that type check should
895 /// guarantee to us that all nested obligations *could be* resolved if we wanted to.
896 pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
897                                     span: Span,
898                                     trait_ref: ty::PolyTraitRef<'tcx>)
899                                     -> traits::Vtable<'tcx, ()>
900 {
901     let tcx = ccx.tcx();
902
903     // Remove any references to regions; this helps improve caching.
904     let trait_ref = erase_regions(tcx, &trait_ref);
905
906     // First check the cache.
907     match ccx.trait_cache().borrow().get(&trait_ref) {
908         Some(vtable) => {
909             info!("Cache hit: {:?}", trait_ref);
910             return (*vtable).clone();
911         }
912         None => { }
913     }
914
915     debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}",
916            trait_ref, trait_ref.def_id());
917
918
919     // Do the initial selection for the obligation. This yields the
920     // shallow result we are looking for -- that is, what specific impl.
921     let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
922     let mut selcx = traits::SelectionContext::new(&infcx);
923
924     let obligation =
925         traits::Obligation::new(traits::ObligationCause::misc(span, ast::DUMMY_NODE_ID),
926                                 trait_ref.to_poly_trait_predicate());
927     let selection = match selcx.select(&obligation) {
928         Ok(Some(selection)) => selection,
929         Ok(None) => {
930             // Ambiguity can happen when monomorphizing during trans
931             // expands to some humongo type that never occurred
932             // statically -- this humongo type can then overflow,
933             // leading to an ambiguous result. So report this as an
934             // overflow bug, since I believe this is the only case
935             // where ambiguity can result.
936             debug!("Encountered ambiguity selecting `{:?}` during trans, \
937                     presuming due to overflow",
938                    trait_ref);
939             ccx.sess().span_fatal(
940                 span,
941                 "reached the recursion limit during monomorphization");
942         }
943         Err(e) => {
944             tcx.sess.span_bug(
945                 span,
946                 &format!("Encountered error `{:?}` selecting `{:?}` during trans",
947                         e,
948                         trait_ref))
949         }
950     };
951
952     // Currently, we use a fulfillment context to completely resolve
953     // all nested obligations. This is because they can inform the
954     // inference of the impl's type parameters.
955     let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
956     let vtable = selection.map(|predicate| {
957         fulfill_cx.register_predicate_obligation(&infcx, predicate);
958     });
959     let vtable = erase_regions(tcx,
960         &drain_fulfillment_cx_or_panic(span, &infcx, &mut fulfill_cx, &vtable)
961     );
962
963     info!("Cache miss: {:?} => {:?}", trait_ref, vtable);
964
965     ccx.trait_cache().borrow_mut().insert(trait_ref, vtable.clone());
966
967     vtable
968 }
969
970 /// Normalizes the predicates and checks whether they hold.  If this
971 /// returns false, then either normalize encountered an error or one
972 /// of the predicates did not hold. Used when creating vtables to
973 /// check for unsatisfiable methods.
974 pub fn normalize_and_test_predicates<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
975                                                predicates: Vec<ty::Predicate<'tcx>>)
976                                                -> bool
977 {
978     debug!("normalize_and_test_predicates(predicates={:?})",
979            predicates);
980
981     let tcx = ccx.tcx();
982     let infcx = infer::normalizing_infer_ctxt(tcx, &tcx.tables);
983     let mut selcx = traits::SelectionContext::new(&infcx);
984     let mut fulfill_cx = infcx.fulfillment_cx.borrow_mut();
985     let cause = traits::ObligationCause::dummy();
986     let traits::Normalized { value: predicates, obligations } =
987         traits::normalize(&mut selcx, cause.clone(), &predicates);
988     for obligation in obligations {
989         fulfill_cx.register_predicate_obligation(&infcx, obligation);
990     }
991     for predicate in predicates {
992         let obligation = traits::Obligation::new(cause.clone(), predicate);
993         fulfill_cx.register_predicate_obligation(&infcx, obligation);
994     }
995     drain_fulfillment_cx(&infcx, &mut fulfill_cx, &()).is_ok()
996 }
997
998 pub fn drain_fulfillment_cx_or_panic<'a,'tcx,T>(span: Span,
999                                                 infcx: &infer::InferCtxt<'a,'tcx>,
1000                                                 fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
1001                                                 result: &T)
1002                                                 -> T
1003     where T : TypeFoldable<'tcx>
1004 {
1005     match drain_fulfillment_cx(infcx, fulfill_cx, result) {
1006         Ok(v) => v,
1007         Err(errors) => {
1008             infcx.tcx.sess.span_bug(
1009                 span,
1010                 &format!("Encountered errors `{:?}` fulfilling during trans",
1011                          errors));
1012         }
1013     }
1014 }
1015
1016 /// Finishes processes any obligations that remain in the fulfillment
1017 /// context, and then "freshens" and returns `result`. This is
1018 /// primarily used during normalization and other cases where
1019 /// processing the obligations in `fulfill_cx` may cause type
1020 /// inference variables that appear in `result` to be unified, and
1021 /// hence we need to process those obligations to get the complete
1022 /// picture of the type.
1023 pub fn drain_fulfillment_cx<'a,'tcx,T>(infcx: &infer::InferCtxt<'a,'tcx>,
1024                                        fulfill_cx: &mut traits::FulfillmentContext<'tcx>,
1025                                        result: &T)
1026                                        -> StdResult<T,Vec<traits::FulfillmentError<'tcx>>>
1027     where T : TypeFoldable<'tcx>
1028 {
1029     debug!("drain_fulfillment_cx(result={:?})",
1030            result);
1031
1032     // In principle, we only need to do this so long as `result`
1033     // contains unbound type parameters. It could be a slight
1034     // optimization to stop iterating early.
1035     match fulfill_cx.select_all_or_error(infcx) {
1036         Ok(()) => { }
1037         Err(errors) => {
1038             return Err(errors);
1039         }
1040     }
1041
1042     // Use freshen to simultaneously replace all type variables with
1043     // their bindings and replace all regions with 'static.  This is
1044     // sort of overkill because we do not expect there to be any
1045     // unbound type variables, hence no `TyFresh` types should ever be
1046     // inserted.
1047     Ok(result.fold_with(&mut infcx.freshener()))
1048 }
1049
1050 // Key used to lookup values supplied for type parameters in an expr.
1051 #[derive(Copy, Clone, PartialEq, Debug)]
1052 pub enum ExprOrMethodCall {
1053     // Type parameters for a path like `None::<int>`
1054     ExprId(ast::NodeId),
1055
1056     // Type parameters for a method call like `a.foo::<int>()`
1057     MethodCallKey(ty::MethodCall)
1058 }
1059
1060 pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1061                             node: ExprOrMethodCall,
1062                             param_substs: &subst::Substs<'tcx>)
1063                             -> subst::Substs<'tcx> {
1064     let tcx = ccx.tcx();
1065
1066     let substs = match node {
1067         ExprId(id) => {
1068             tcx.node_id_item_substs(id).substs
1069         }
1070         MethodCallKey(method_call) => {
1071             tcx.tables.borrow().method_map[&method_call].substs.clone()
1072         }
1073     };
1074
1075     if substs.types.needs_infer() {
1076             tcx.sess.bug(&format!("type parameters for node {:?} include inference types: {:?}",
1077                                  node, substs));
1078         }
1079
1080         monomorphize::apply_param_substs(tcx,
1081                                          param_substs,
1082                                          &substs.erase_regions())
1083 }
1084
1085 pub fn langcall(bcx: Block,
1086                 span: Option<Span>,
1087                 msg: &str,
1088                 li: LangItem)
1089                 -> ast::DefId {
1090     match bcx.tcx().lang_items.require(li) {
1091         Ok(id) => id,
1092         Err(s) => {
1093             let msg = format!("{} {}", msg, s);
1094             match span {
1095                 Some(span) => bcx.tcx().sess.span_fatal(span, &msg[..]),
1096                 None => bcx.tcx().sess.fatal(&msg[..]),
1097             }
1098         }
1099     }
1100 }