44//! and methods are represented as just a fn ptr and not a full
55//! closure.
66
7+ use crate :: abi:: FnAbi ;
78use crate :: attributes;
89use crate :: llvm;
910use crate :: context:: CodegenCx ;
1011use crate :: value:: Value ;
1112use rustc_codegen_ssa:: traits:: * ;
1213
13- use rustc:: ty:: { TypeFoldable , Instance } ;
14- use rustc:: ty:: layout:: { LayoutOf , HasTyCtxt } ;
14+ use rustc:: ty:: { self , TypeFoldable , Instance } ;
15+ use rustc:: ty:: layout:: { FnAbiExt , LayoutOf , HasTyCtxt } ;
1516
1617/// Codegens a reference to a fn/method item, monomorphizing and
1718/// inlining as it goes.
@@ -32,19 +33,19 @@ pub fn get_fn(
3233 assert ! ( !instance. substs. has_escaping_bound_vars( ) ) ;
3334 assert ! ( !instance. substs. has_param_types( ) ) ;
3435
35- let sig = instance. fn_sig ( cx. tcx ( ) ) ;
3636 if let Some ( & llfn) = cx. instances . borrow ( ) . get ( & instance) {
3737 return llfn;
3838 }
3939
40+ let sig = instance. fn_sig ( cx. tcx ( ) ) ;
4041 let sym = tcx. symbol_name ( instance) . name . as_str ( ) ;
4142 debug ! ( "get_fn({:?}: {:?}) => {}" , instance, sig, sym) ;
4243
43- // Create a fn pointer with the substituted signature.
44- let fn_ptr_ty = tcx. mk_fn_ptr ( sig) ;
45- let llptrty = cx. backend_type ( cx. layout_of ( fn_ptr_ty) ) ;
46-
4744 let llfn = if let Some ( llfn) = cx. get_declared_value ( & sym) {
45+ // Create a fn pointer with the substituted signature.
46+ let fn_ptr_ty = tcx. mk_fn_ptr ( sig) ;
47+ let llptrty = cx. backend_type ( cx. layout_of ( fn_ptr_ty) ) ;
48+
4849 // This is subtle and surprising, but sometimes we have to bitcast
4950 // the resulting fn pointer. The reason has to do with external
5051 // functions. If you have two crates that both bind the same C
@@ -76,14 +77,15 @@ pub fn get_fn(
7677 llfn
7778 }
7879 } else {
79- let llfn = cx. declare_fn ( & sym, sig) ;
80- assert_eq ! ( cx. val_ty( llfn) , llptrty) ;
80+ let sig = tcx. normalize_erasing_late_bound_regions ( ty:: ParamEnv :: reveal_all ( ) , & sig) ;
81+ let fn_abi = FnAbi :: new ( cx, sig, & [ ] ) ;
82+ let llfn = cx. declare_fn ( & sym, & fn_abi) ;
8183 debug ! ( "get_fn: not casting pointer!" ) ;
8284
8385 if instance. def . is_inline ( tcx) {
8486 attributes:: inline ( cx, llfn, attributes:: InlineAttr :: Hint ) ;
8587 }
86- attributes:: from_fn_attrs ( cx, llfn, Some ( instance. def . def_id ( ) ) , sig) ;
88+ attributes:: from_fn_attrs ( cx, llfn, Some ( instance. def . def_id ( ) ) , sig. abi ) ;
8789
8890 let instance_def_id = instance. def_id ( ) ;
8991
0 commit comments