@@ -10,6 +10,7 @@ use rustc_middle::mir::*;
10
10
use rustc_middle:: ty:: subst:: Subst ;
11
11
use rustc_middle:: ty:: { self , ConstKind , Instance , InstanceDef , ParamEnv , Ty , TyCtxt } ;
12
12
use rustc_session:: config:: OptLevel ;
13
+ use rustc_span:: def_id:: DefId ;
13
14
use rustc_span:: { hygiene:: ExpnKind , ExpnData , LocalExpnId , Span } ;
14
15
use rustc_target:: spec:: abi:: Abi ;
15
16
@@ -103,8 +104,12 @@ struct Inliner<'tcx> {
103
104
param_env : ParamEnv < ' tcx > ,
104
105
/// Caller codegen attributes.
105
106
codegen_fn_attrs : & ' tcx CodegenFnAttrs ,
106
- /// Stack of inlined Instances.
107
- history : Vec < ty:: Instance < ' tcx > > ,
107
+ /// Stack of inlined instances.
108
+ /// We only check the `DefId` and not the substs because we want to
109
+ /// avoid inlining cases of polymorphic recursion.
110
+ /// The number of `DefId`s is finite, so checking history is enough
111
+ /// to ensure that we do not loop endlessly while inlining.
112
+ history : Vec < DefId > ,
108
113
/// Indicates that the caller body has been modified.
109
114
changed : bool ,
110
115
}
@@ -132,7 +137,7 @@ impl<'tcx> Inliner<'tcx> {
132
137
Ok ( new_blocks) => {
133
138
debug ! ( "inlined {}" , callsite. callee) ;
134
139
self . changed = true ;
135
- self . history . push ( callsite. callee ) ;
140
+ self . history . push ( callsite. callee . def_id ( ) ) ;
136
141
self . process_blocks ( caller_body, new_blocks) ;
137
142
self . history . pop ( ) ;
138
143
}
@@ -308,7 +313,7 @@ impl<'tcx> Inliner<'tcx> {
308
313
return None ;
309
314
}
310
315
311
- if self . history . contains ( & callee) {
316
+ if self . history . contains ( & callee. def_id ( ) ) {
312
317
return None ;
313
318
}
314
319
0 commit comments