]> git.lizzy.rs Git - rust.git/blob - src/librustc_trans/callee.rs
Rollup merge of #40146 - bjorn3:few-infer-changes, r=pnkfelix
[rust.git] / src / librustc_trans / callee.rs
1 // Copyright 2012 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 //! Handles translation of callees as well as other call-related
12 //! things.  Callees are a superset of normal rust values and sometimes
13 //! have different representations.  In particular, top-level fn items
14 //! and methods are represented as just a fn ptr and not a full
15 //! closure.
16
17 pub use self::CalleeData::*;
18
19 use llvm::{self, ValueRef, get_params};
20 use rustc::hir::def_id::DefId;
21 use rustc::ty::subst::{Substs, Subst};
22 use rustc::traits;
23 use abi::{Abi, FnType};
24 use attributes;
25 use base;
26 use builder::Builder;
27 use common::{self, CrateContext};
28 use cleanup::CleanupScope;
29 use mir::lvalue::LvalueRef;
30 use consts;
31 use common::def_ty;
32 use declare;
33 use value::Value;
34 use meth;
35 use monomorphize::Instance;
36 use trans_item::TransItem;
37 use type_of;
38 use Disr;
39 use rustc::ty::{self, Ty, TypeFoldable};
40 use rustc::hir;
41 use std::iter;
42
43 use syntax_pos::DUMMY_SP;
44
45 use mir::lvalue::Alignment;
46
47 #[derive(Debug)]
48 pub enum CalleeData {
49     /// Constructor for enum variant/tuple-like-struct.
50     NamedTupleConstructor(Disr),
51
52     /// Function pointer.
53     Fn(ValueRef),
54
55     Intrinsic,
56
57     /// Trait object found in the vtable at that index.
58     Virtual(usize)
59 }
60
61 #[derive(Debug)]
62 pub struct Callee<'tcx> {
63     pub data: CalleeData,
64     pub ty: Ty<'tcx>
65 }
66
67 impl<'tcx> Callee<'tcx> {
68     /// Function pointer.
69     pub fn ptr(llfn: ValueRef, ty: Ty<'tcx>) -> Callee<'tcx> {
70         Callee {
71             data: Fn(llfn),
72             ty: ty
73         }
74     }
75
76     /// Function or method definition.
77     pub fn def<'a>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId, substs: &'tcx Substs<'tcx>)
78                    -> Callee<'tcx> {
79         let tcx = ccx.tcx();
80
81         if let Some(trait_id) = tcx.trait_of_item(def_id) {
82             return Callee::trait_method(ccx, trait_id, def_id, substs);
83         }
84
85         let fn_ty = def_ty(ccx.shared(), def_id, substs);
86         if let ty::TyFnDef(.., f) = fn_ty.sty {
87             if f.abi() == Abi::RustIntrinsic || f.abi() == Abi::PlatformIntrinsic {
88                 return Callee {
89                     data: Intrinsic,
90                     ty: fn_ty
91                 };
92             }
93         }
94
95         // FIXME(eddyb) Detect ADT constructors more efficiently.
96         if let Some(adt_def) = fn_ty.fn_ret().skip_binder().ty_adt_def() {
97             if let Some(i) = adt_def.variants.iter().position(|v| def_id == v.did) {
98                 return Callee {
99                     data: NamedTupleConstructor(Disr::for_variant(tcx, adt_def, i)),
100                     ty: fn_ty
101                 };
102             }
103         }
104
105         let (llfn, ty) = get_fn(ccx, def_id, substs);
106         Callee::ptr(llfn, ty)
107     }
108
109     /// Trait method, which has to be resolved to an impl method.
110     pub fn trait_method<'a>(ccx: &CrateContext<'a, 'tcx>,
111                             trait_id: DefId,
112                             def_id: DefId,
113                             substs: &'tcx Substs<'tcx>)
114                             -> Callee<'tcx> {
115         let tcx = ccx.tcx();
116
117         let trait_ref = ty::TraitRef::from_method(tcx, trait_id, substs);
118         let trait_ref = tcx.normalize_associated_type(&ty::Binder(trait_ref));
119         match common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref) {
120             traits::VtableImpl(vtable_impl) => {
121                 let name = tcx.item_name(def_id);
122                 let (def_id, substs) = traits::find_method(tcx, name, substs, &vtable_impl);
123
124                 // Translate the function, bypassing Callee::def.
125                 // That is because default methods have the same ID as the
126                 // trait method used to look up the impl method that ended
127                 // up here, so calling Callee::def would infinitely recurse.
128                 let (llfn, ty) = get_fn(ccx, def_id, substs);
129                 Callee::ptr(llfn, ty)
130             }
131             traits::VtableClosure(vtable_closure) => {
132                 // The substitutions should have no type parameters remaining
133                 // after passing through fulfill_obligation
134                 let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
135                 let instance = Instance::new(def_id, substs);
136                 let llfn = trans_closure_method(
137                     ccx,
138                     vtable_closure.closure_def_id,
139                     vtable_closure.substs,
140                     instance,
141                     trait_closure_kind);
142
143                 let method_ty = def_ty(ccx.shared(), def_id, substs);
144                 Callee::ptr(llfn, method_ty)
145             }
146             traits::VtableFnPointer(vtable_fn_pointer) => {
147                 let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
148                 let instance = Instance::new(def_id, substs);
149                 let llfn = trans_fn_pointer_shim(ccx, instance,
150                                                  trait_closure_kind,
151                                                  vtable_fn_pointer.fn_ty);
152
153                 let method_ty = def_ty(ccx.shared(), def_id, substs);
154                 Callee::ptr(llfn, method_ty)
155             }
156             traits::VtableObject(ref data) => {
157                 Callee {
158                     data: Virtual(tcx.get_vtable_index_of_object_method(data, def_id)),
159                     ty: def_ty(ccx.shared(), def_id, substs)
160                 }
161             }
162             vtable => {
163                 bug!("resolved vtable bad vtable {:?} in trans", vtable);
164             }
165         }
166     }
167
168     /// Get the abi::FnType for a direct call. Mainly deals with the fact
169     /// that a Virtual call doesn't take the vtable, like its shim does.
170     /// The extra argument types are for variadic (extern "C") functions.
171     pub fn direct_fn_type<'a>(&self, ccx: &CrateContext<'a, 'tcx>,
172                               extra_args: &[Ty<'tcx>]) -> FnType {
173         let sig = ccx.tcx().erase_late_bound_regions_and_normalize(&self.ty.fn_sig());
174         let mut fn_ty = FnType::unadjusted(ccx, sig, extra_args);
175         if let Virtual(_) = self.data {
176             // Don't pass the vtable, it's not an argument of the virtual fn.
177             fn_ty.args[1].ignore();
178         }
179         fn_ty.adjust_for_abi(ccx, sig);
180         fn_ty
181     }
182
183     /// Turn the callee into a function pointer.
184     pub fn reify<'a>(self, ccx: &CrateContext<'a, 'tcx>) -> ValueRef {
185         match self.data {
186             Fn(llfn) => llfn,
187             Virtual(_) => meth::trans_object_shim(ccx, self),
188             NamedTupleConstructor(disr) => match self.ty.sty {
189                 ty::TyFnDef(def_id, substs, _) => {
190                     let instance = Instance::new(def_id, substs);
191                     if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
192                         return llfn;
193                     }
194
195                     let sym = ccx.symbol_map().get_or_compute(ccx.shared(),
196                                                               TransItem::Fn(instance));
197                     assert!(!ccx.codegen_unit().contains_item(&TransItem::Fn(instance)));
198                     let lldecl = declare::define_internal_fn(ccx, &sym, self.ty);
199                     base::trans_ctor_shim(ccx, def_id, substs, disr, lldecl);
200                     ccx.instances().borrow_mut().insert(instance, lldecl);
201
202                     lldecl
203                 }
204                 _ => bug!("expected fn item type, found {}", self.ty)
205             },
206             Intrinsic => bug!("intrinsic {} getting reified", self.ty)
207         }
208     }
209 }
210
211 fn trans_closure_method<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
212                                   def_id: DefId,
213                                   substs: ty::ClosureSubsts<'tcx>,
214                                   method_instance: Instance<'tcx>,
215                                   trait_closure_kind: ty::ClosureKind)
216                                   -> ValueRef
217 {
218     // If this is a closure, redirect to it.
219     let (llfn, _) = get_fn(ccx, def_id, substs.substs);
220
221     // If the closure is a Fn closure, but a FnOnce is needed (etc),
222     // then adapt the self type
223     let llfn_closure_kind = ccx.tcx().closure_kind(def_id);
224
225     debug!("trans_closure_adapter_shim(llfn_closure_kind={:?}, \
226            trait_closure_kind={:?}, llfn={:?})",
227            llfn_closure_kind, trait_closure_kind, Value(llfn));
228
229     match needs_fn_once_adapter_shim(llfn_closure_kind, trait_closure_kind) {
230         Ok(true) => trans_fn_once_adapter_shim(ccx,
231                                                def_id,
232                                                substs,
233                                                method_instance,
234                                                llfn),
235         Ok(false) => llfn,
236         Err(()) => {
237             bug!("trans_closure_adapter_shim: cannot convert {:?} to {:?}",
238                  llfn_closure_kind,
239                  trait_closure_kind);
240         }
241     }
242 }
243
244 pub fn needs_fn_once_adapter_shim(actual_closure_kind: ty::ClosureKind,
245                                   trait_closure_kind: ty::ClosureKind)
246                                   -> Result<bool, ()>
247 {
248     match (actual_closure_kind, trait_closure_kind) {
249         (ty::ClosureKind::Fn, ty::ClosureKind::Fn) |
250         (ty::ClosureKind::FnMut, ty::ClosureKind::FnMut) |
251         (ty::ClosureKind::FnOnce, ty::ClosureKind::FnOnce) => {
252             // No adapter needed.
253            Ok(false)
254         }
255         (ty::ClosureKind::Fn, ty::ClosureKind::FnMut) => {
256             // The closure fn `llfn` is a `fn(&self, ...)`.  We want a
257             // `fn(&mut self, ...)`. In fact, at trans time, these are
258             // basically the same thing, so we can just return llfn.
259             Ok(false)
260         }
261         (ty::ClosureKind::Fn, ty::ClosureKind::FnOnce) |
262         (ty::ClosureKind::FnMut, ty::ClosureKind::FnOnce) => {
263             // The closure fn `llfn` is a `fn(&self, ...)` or `fn(&mut
264             // self, ...)`.  We want a `fn(self, ...)`. We can produce
265             // this by doing something like:
266             //
267             //     fn call_once(self, ...) { call_mut(&self, ...) }
268             //     fn call_once(mut self, ...) { call_mut(&mut self, ...) }
269             //
270             // These are both the same at trans time.
271             Ok(true)
272         }
273         _ => Err(()),
274     }
275 }
276
277 fn trans_fn_once_adapter_shim<'a, 'tcx>(
278     ccx: &'a CrateContext<'a, 'tcx>,
279     def_id: DefId,
280     substs: ty::ClosureSubsts<'tcx>,
281     method_instance: Instance<'tcx>,
282     llreffn: ValueRef)
283     -> ValueRef
284 {
285     if let Some(&llfn) = ccx.instances().borrow().get(&method_instance) {
286         return llfn;
287     }
288
289     debug!("trans_fn_once_adapter_shim(def_id={:?}, substs={:?}, llreffn={:?})",
290            def_id, substs, Value(llreffn));
291
292     let tcx = ccx.tcx();
293
294     // Find a version of the closure type. Substitute static for the
295     // region since it doesn't really matter.
296     let closure_ty = tcx.mk_closure_from_closure_substs(def_id, substs);
297     let ref_closure_ty = tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), closure_ty);
298
299     // Make a version with the type of by-ref closure.
300     let sig = tcx.closure_type(def_id).subst(tcx, substs.substs);
301     let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
302     assert_eq!(sig.abi, Abi::RustCall);
303     let llref_fn_ty = tcx.mk_fn_ptr(ty::Binder(tcx.mk_fn_sig(
304         iter::once(ref_closure_ty).chain(sig.inputs().iter().cloned()),
305         sig.output(),
306         sig.variadic,
307         sig.unsafety,
308         Abi::RustCall
309     )));
310     debug!("trans_fn_once_adapter_shim: llref_fn_ty={:?}",
311            llref_fn_ty);
312
313
314     // Make a version of the closure type with the same arguments, but
315     // with argument #0 being by value.
316     let sig = tcx.mk_fn_sig(
317         iter::once(closure_ty).chain(sig.inputs().iter().cloned()),
318         sig.output(),
319         sig.variadic,
320         sig.unsafety,
321         Abi::RustCall
322     );
323
324     let fn_ty = FnType::new(ccx, sig, &[]);
325     let llonce_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig));
326
327     // Create the by-value helper.
328     let function_name = method_instance.symbol_name(ccx.shared());
329     let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty);
330     attributes::set_frame_pointer_elimination(ccx, lloncefn);
331
332     let orig_fn_ty = fn_ty;
333     let mut bcx = Builder::new_block(ccx, lloncefn, "entry-block");
334
335     let callee = Callee {
336         data: Fn(llreffn),
337         ty: llref_fn_ty
338     };
339
340     // the first argument (`self`) will be the (by value) closure env.
341
342     let mut llargs = get_params(lloncefn);
343     let fn_ret = callee.ty.fn_ret();
344     let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
345     let self_idx = fn_ty.ret.is_indirect() as usize;
346     let env_arg = &orig_fn_ty.args[0];
347     let env = if env_arg.is_indirect() {
348         LvalueRef::new_sized_ty(llargs[self_idx], closure_ty, Alignment::AbiAligned)
349     } else {
350         let scratch = LvalueRef::alloca(&bcx, closure_ty, "self");
351         let mut llarg_idx = self_idx;
352         env_arg.store_fn_arg(&bcx, &mut llarg_idx, scratch.llval);
353         scratch
354     };
355
356     debug!("trans_fn_once_adapter_shim: env={:?}", env);
357     // Adjust llargs such that llargs[self_idx..] has the call arguments.
358     // For zero-sized closures that means sneaking in a new argument.
359     if env_arg.is_ignore() {
360         llargs.insert(self_idx, env.llval);
361     } else {
362         llargs[self_idx] = env.llval;
363     }
364
365     // Call the by-ref closure body with `self` in a cleanup scope,
366     // to drop `self` when the body returns, or in case it unwinds.
367     let self_scope = CleanupScope::schedule_drop_mem(&bcx, env);
368
369     let llfn = callee.reify(bcx.ccx);
370     let llret;
371     if let Some(landing_pad) = self_scope.landing_pad {
372         let normal_bcx = bcx.build_sibling_block("normal-return");
373         llret = bcx.invoke(llfn, &llargs[..], normal_bcx.llbb(), landing_pad, None);
374         bcx = normal_bcx;
375     } else {
376         llret = bcx.call(llfn, &llargs[..], None);
377     }
378     fn_ty.apply_attrs_callsite(llret);
379
380     if fn_ret.0.is_never() {
381         bcx.unreachable();
382     } else {
383         self_scope.trans(&bcx);
384
385         if fn_ty.ret.is_indirect() || fn_ty.ret.is_ignore() {
386             bcx.ret_void();
387         } else {
388             bcx.ret(llret);
389         }
390     }
391
392     ccx.instances().borrow_mut().insert(method_instance, lloncefn);
393
394     lloncefn
395 }
396
397 /// Translates an adapter that implements the `Fn` trait for a fn
398 /// pointer. This is basically the equivalent of something like:
399 ///
400 /// ```
401 /// impl<'a> Fn(&'a int) -> &'a int for fn(&int) -> &int {
402 ///     extern "rust-abi" fn call(&self, args: (&'a int,)) -> &'a int {
403 ///         (*self)(args.0)
404 ///     }
405 /// }
406 /// ```
407 ///
408 /// but for the bare function type given.
409 fn trans_fn_pointer_shim<'a, 'tcx>(
410     ccx: &'a CrateContext<'a, 'tcx>,
411     method_instance: Instance<'tcx>,
412     closure_kind: ty::ClosureKind,
413     bare_fn_ty: Ty<'tcx>)
414     -> ValueRef
415 {
416     let tcx = ccx.tcx();
417
418     // Normalize the type for better caching.
419     let bare_fn_ty = tcx.normalize_associated_type(&bare_fn_ty);
420
421     // If this is an impl of `Fn` or `FnMut` trait, the receiver is `&self`.
422     let is_by_ref = match closure_kind {
423         ty::ClosureKind::Fn | ty::ClosureKind::FnMut => true,
424         ty::ClosureKind::FnOnce => false,
425     };
426
427     let llfnpointer = match bare_fn_ty.sty {
428         ty::TyFnDef(def_id, substs, _) => {
429             // Function definitions have to be turned into a pointer.
430             let llfn = Callee::def(ccx, def_id, substs).reify(ccx);
431             if !is_by_ref {
432                 // A by-value fn item is ignored, so the shim has
433                 // the same signature as the original function.
434                 return llfn;
435             }
436             Some(llfn)
437         }
438         _ => None
439     };
440
441     let bare_fn_ty_maybe_ref = if is_by_ref {
442         tcx.mk_imm_ref(tcx.mk_region(ty::ReErased), bare_fn_ty)
443     } else {
444         bare_fn_ty
445     };
446
447     // Check if we already trans'd this shim.
448     if let Some(&llval) = ccx.fn_pointer_shims().borrow().get(&bare_fn_ty_maybe_ref) {
449         return llval;
450     }
451
452     debug!("trans_fn_pointer_shim(bare_fn_ty={:?})",
453            bare_fn_ty);
454
455     // Construct the "tuply" version of `bare_fn_ty`. It takes two arguments: `self`,
456     // which is the fn pointer, and `args`, which is the arguments tuple.
457     let sig = bare_fn_ty.fn_sig();
458     let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
459     assert_eq!(sig.unsafety, hir::Unsafety::Normal);
460     assert_eq!(sig.abi, Abi::Rust);
461     let tuple_input_ty = tcx.intern_tup(sig.inputs(), false);
462     let sig = tcx.mk_fn_sig(
463         [bare_fn_ty_maybe_ref, tuple_input_ty].iter().cloned(),
464         sig.output(),
465         false,
466         hir::Unsafety::Normal,
467         Abi::RustCall
468     );
469     let fn_ty = FnType::new(ccx, sig, &[]);
470     let tuple_fn_ty = tcx.mk_fn_ptr(ty::Binder(sig));
471     debug!("tuple_fn_ty: {:?}", tuple_fn_ty);
472
473     //
474     let function_name = method_instance.symbol_name(ccx.shared());
475     let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
476     attributes::set_frame_pointer_elimination(ccx, llfn);
477     //
478     let bcx = Builder::new_block(ccx, llfn, "entry-block");
479
480     let mut llargs = get_params(llfn);
481
482     let self_arg = llargs.remove(fn_ty.ret.is_indirect() as usize);
483     let llfnpointer = llfnpointer.unwrap_or_else(|| {
484         // the first argument (`self`) will be ptr to the fn pointer
485         if is_by_ref {
486             bcx.load(self_arg, None)
487         } else {
488             self_arg
489         }
490     });
491
492     let callee = Callee {
493         data: Fn(llfnpointer),
494         ty: bare_fn_ty
495     };
496     let fn_ret = callee.ty.fn_ret();
497     let fn_ty = callee.direct_fn_type(ccx, &[]);
498     let llret = bcx.call(llfnpointer, &llargs, None);
499     fn_ty.apply_attrs_callsite(llret);
500
501     if fn_ret.0.is_never() {
502         bcx.unreachable();
503     } else {
504         if fn_ty.ret.is_indirect() || fn_ty.ret.is_ignore() {
505             bcx.ret_void();
506         } else {
507             bcx.ret(llret);
508         }
509     }
510
511     ccx.fn_pointer_shims().borrow_mut().insert(bare_fn_ty_maybe_ref, llfn);
512
513     llfn
514 }
515
516 /// Translates a reference to a fn/method item, monomorphizing and
517 /// inlining as it goes.
518 ///
519 /// # Parameters
520 ///
521 /// - `ccx`: the crate context
522 /// - `def_id`: def id of the fn or method item being referenced
523 /// - `substs`: values for each of the fn/method's parameters
524 fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
525                     def_id: DefId,
526                     substs: &'tcx Substs<'tcx>)
527                     -> (ValueRef, Ty<'tcx>) {
528     let tcx = ccx.tcx();
529
530     debug!("get_fn(def_id={:?}, substs={:?})", def_id, substs);
531
532     assert!(!substs.needs_infer());
533     assert!(!substs.has_escaping_regions());
534     assert!(!substs.has_param_types());
535
536     let substs = tcx.normalize_associated_type(&substs);
537     let instance = Instance::new(def_id, substs);
538     let fn_ty = common::def_ty(ccx.shared(), def_id, substs);
539
540     if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
541         return (llfn, fn_ty);
542     }
543
544     let sym = ccx.symbol_map().get_or_compute(ccx.shared(),
545                                               TransItem::Fn(instance));
546     debug!("get_fn({:?}: {:?}) => {}", instance, fn_ty, sym);
547
548     // This is subtle and surprising, but sometimes we have to bitcast
549     // the resulting fn pointer.  The reason has to do with external
550     // functions.  If you have two crates that both bind the same C
551     // library, they may not use precisely the same types: for
552     // example, they will probably each declare their own structs,
553     // which are distinct types from LLVM's point of view (nominal
554     // types).
555     //
556     // Now, if those two crates are linked into an application, and
557     // they contain inlined code, you can wind up with a situation
558     // where both of those functions wind up being loaded into this
559     // application simultaneously. In that case, the same function
560     // (from LLVM's point of view) requires two types. But of course
561     // LLVM won't allow one function to have two types.
562     //
563     // What we currently do, therefore, is declare the function with
564     // one of the two types (whichever happens to come first) and then
565     // bitcast as needed when the function is referenced to make sure
566     // it has the type we expect.
567     //
568     // This can occur on either a crate-local or crate-external
569     // reference. It also occurs when testing libcore and in some
570     // other weird situations. Annoying.
571
572     // Create a fn pointer with the substituted signature.
573     let fn_ptr_ty = tcx.mk_fn_ptr(common::ty_fn_sig(ccx, fn_ty));
574     let llptrty = type_of::type_of(ccx, fn_ptr_ty);
575
576     let llfn = if let Some(llfn) = declare::get_declared_value(ccx, &sym) {
577         if common::val_ty(llfn) != llptrty {
578             debug!("get_fn: casting {:?} to {:?}", llfn, llptrty);
579             consts::ptrcast(llfn, llptrty)
580         } else {
581             debug!("get_fn: not casting pointer!");
582             llfn
583         }
584     } else {
585         let llfn = declare::declare_fn(ccx, &sym, fn_ty);
586         assert_eq!(common::val_ty(llfn), llptrty);
587         debug!("get_fn: not casting pointer!");
588
589         let attrs = ccx.tcx().get_attrs(def_id);
590         attributes::from_fn_attrs(ccx, &attrs, llfn);
591
592         let is_local_def = ccx.shared().translation_items().borrow()
593                               .contains(&TransItem::Fn(instance));
594         if is_local_def {
595             // FIXME(eddyb) Doubt all extern fn should allow unwinding.
596             attributes::unwind(llfn, true);
597             unsafe {
598                 llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::ExternalLinkage);
599             }
600         }
601         if ccx.use_dll_storage_attrs() && ccx.sess().cstore.is_dllimport_foreign_item(def_id) {
602             unsafe {
603                 llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport);
604             }
605         }
606         llfn
607     };
608
609     ccx.instances().borrow_mut().insert(instance, llfn);
610
611     (llfn, fn_ty)
612 }