4
4
//! and methods are represented as just a fn ptr and not a full
5
5
//! closure.
6
6
7
+ use crate :: abi:: FnAbi ;
7
8
use crate :: attributes;
8
9
use crate :: llvm;
9
10
use crate :: context:: CodegenCx ;
10
11
use crate :: value:: Value ;
11
12
use rustc_codegen_ssa:: traits:: * ;
12
13
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 } ;
15
16
16
17
/// Codegens a reference to a fn/method item, monomorphizing and
17
18
/// inlining as it goes.
@@ -32,19 +33,19 @@ pub fn get_fn(
32
33
assert ! ( !instance. substs. has_escaping_bound_vars( ) ) ;
33
34
assert ! ( !instance. substs. has_param_types( ) ) ;
34
35
35
- let sig = instance. fn_sig ( cx. tcx ( ) ) ;
36
36
if let Some ( & llfn) = cx. instances . borrow ( ) . get ( & instance) {
37
37
return llfn;
38
38
}
39
39
40
+ let sig = instance. fn_sig ( cx. tcx ( ) ) ;
40
41
let sym = tcx. symbol_name ( instance) . name . as_str ( ) ;
41
42
debug ! ( "get_fn({:?}: {:?}) => {}" , instance, sig, sym) ;
42
43
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
-
47
44
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
+
48
49
// This is subtle and surprising, but sometimes we have to bitcast
49
50
// the resulting fn pointer. The reason has to do with external
50
51
// functions. If you have two crates that both bind the same C
@@ -76,14 +77,15 @@ pub fn get_fn(
76
77
llfn
77
78
}
78
79
} 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) ;
81
83
debug ! ( "get_fn: not casting pointer!" ) ;
82
84
83
85
if instance. def . is_inline ( tcx) {
84
86
attributes:: inline ( cx, llfn, attributes:: InlineAttr :: Hint ) ;
85
87
}
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 ) ;
87
89
88
90
let instance_def_id = instance. def_id ( ) ;
89
91
0 commit comments