@@ -74,7 +74,7 @@ pub fn should_run_pass_for_item<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> bool {
7474 }
7575
7676 let codegen_fn_attrs = tcx. codegen_fn_attrs ( did) ;
77- matches ! ( codegen_fn_attrs. inline, InlineAttr :: Required { .. } | InlineAttr :: Must { .. } )
77+ codegen_fn_attrs. inline . required ( )
7878 || match tcx. sess . mir_opt_level ( ) {
7979 0 | 1 => false ,
8080 2 => {
@@ -219,8 +219,10 @@ impl<'tcx> Inliner<'tcx> {
219219 // Intrinsic fallback bodies are automatically made cross-crate inlineable,
220220 // but at this stage we don't know whether codegen knows the intrinsic,
221221 // so just conservatively don't inline it.
222- if self . tcx . has_attr ( callsite. callee . def_id ( ) , sym:: rustc_intrinsic) {
223- return Err ( "Callee is an intrinsic, do not inline fallback bodies" ) ;
222+ if self . tcx . has_attr ( callsite. callee . def_id ( ) , sym:: rustc_intrinsic)
223+ && !callee_attrs. inline . required ( )
224+ {
225+ return Err ( "callee is an intrinsic" ) ;
224226 }
225227
226228 let terminator = caller_body[ callsite. block ] . terminator . as_ref ( ) . unwrap ( ) ;
@@ -230,7 +232,7 @@ impl<'tcx> Inliner<'tcx> {
230232 if !arg. node . ty ( & caller_body. local_decls , self . tcx ) . is_sized ( self . tcx , self . param_env ) {
231233 // We do not allow inlining functions with unsized params. Inlining these functions
232234 // could create unsized locals, which are unsound and being phased out.
233- return Err ( "Call has unsized argument" ) ;
235+ return Err ( "call has unsized argument" ) ;
234236 }
235237 }
236238
@@ -239,7 +241,8 @@ impl<'tcx> Inliner<'tcx> {
239241
240242 if !self . tcx . consider_optimizing ( || {
241243 format ! ( "Inline {:?} into {:?}" , callsite. callee, caller_body. source)
242- } ) {
244+ } ) && !callee_attrs. inline . required ( )
245+ {
243246 return Err ( "optimization fuel exhausted" ) ;
244247 }
245248
@@ -248,7 +251,8 @@ impl<'tcx> Inliner<'tcx> {
248251 self . param_env ,
249252 ty:: EarlyBinder :: bind ( callee_body. clone ( ) ) ,
250253 ) else {
251- return Err ( "failed to normalize callee body" ) ;
254+ debug ! ( "failed to normalize callee body" ) ;
255+ return Err ( "implementation limitation" ) ;
252256 } ;
253257
254258 // Normally, this shouldn't be required, but trait normalization failure can create a
@@ -262,7 +266,8 @@ impl<'tcx> Inliner<'tcx> {
262266 )
263267 . is_empty ( )
264268 {
265- return Err ( "failed to validate callee body" ) ;
269+ debug ! ( "failed to validate callee body" ) ;
270+ return Err ( "implementation limitation" ) ;
266271 }
267272
268273 // Check call signature compatibility.
@@ -272,14 +277,15 @@ impl<'tcx> Inliner<'tcx> {
272277 if !util:: relate_types ( self . tcx , self . param_env , ty:: Covariant , output_type, destination_ty)
273278 {
274279 trace ! ( ?output_type, ?destination_ty) ;
275- return Err ( "failed to normalize return type" ) ;
280+ debug ! ( "failed to normalize return type" ) ;
281+ return Err ( "implementation limitation" ) ;
276282 }
277283 if callsite. fn_sig . abi ( ) == Abi :: RustCall {
278284 // FIXME: Don't inline user-written `extern "rust-call"` functions,
279285 // since this is generally perf-negative on rustc, and we hope that
280286 // LLVM will inline these functions instead.
281287 if callee_body. spread_arg . is_some ( ) {
282- return Err ( "do not inline user-written rust-call functions" ) ;
288+ return Err ( "user-written rust-call functions" ) ;
283289 }
284290
285291 let ( self_arg, arg_tuple) = match & args[ ..] {
@@ -303,7 +309,8 @@ impl<'tcx> Inliner<'tcx> {
303309 if !util:: relate_types ( self . tcx , self . param_env , ty:: Covariant , input_type, arg_ty)
304310 {
305311 trace ! ( ?arg_ty, ?input_type) ;
306- return Err ( "failed to normalize tuple argument type" ) ;
312+ debug ! ( "failed to normalize tuple argument type" ) ;
313+ return Err ( "implementation limitation" ) ;
307314 }
308315 }
309316 } else {
@@ -313,7 +320,8 @@ impl<'tcx> Inliner<'tcx> {
313320 if !util:: relate_types ( self . tcx , self . param_env , ty:: Covariant , input_type, arg_ty)
314321 {
315322 trace ! ( ?arg_ty, ?input_type) ;
316- return Err ( "failed to normalize argument type" ) ;
323+ debug ! ( "failed to normalize argument type" ) ;
324+ return Err ( "implementation limitation" ) ;
317325 }
318326 }
319327 }
@@ -342,12 +350,14 @@ impl<'tcx> Inliner<'tcx> {
342350 // because it has no MIR because it's an extern function), then the inliner
343351 // won't cause cycles on this.
344352 if !self . tcx . is_mir_available ( callee_def_id) {
345- return Err ( "item MIR unavailable" ) ;
353+ debug ! ( "item MIR unavailable" ) ;
354+ return Err ( "implementation limitation" ) ;
346355 }
347356 }
348357 // These have no own callable MIR.
349358 InstanceKind :: Intrinsic ( _) | InstanceKind :: Virtual ( ..) => {
350- return Err ( "instance without MIR (intrinsic / virtual)" ) ;
359+ debug ! ( "instance without MIR (intrinsic / virtual)" ) ;
360+ return Err ( "implementation limitation" ) ;
351361 }
352362
353363 // FIXME(#127030): `ConstParamHasTy` has bad interactions with
@@ -356,7 +366,8 @@ impl<'tcx> Inliner<'tcx> {
356366 // the MIR for this instance until all of its const params are
357367 // substituted.
358368 InstanceKind :: DropGlue ( _, Some ( ty) ) if ty. has_type_flags ( TypeFlags :: HAS_CT_PARAM ) => {
359- return Err ( "still needs substitution" ) ;
369+ debug ! ( "still needs substitution" ) ;
370+ return Err ( "implementation limitation" ) ;
360371 }
361372
362373 // This cannot result in an immediate cycle since the callee MIR is a shim, which does
@@ -385,7 +396,8 @@ impl<'tcx> Inliner<'tcx> {
385396 // If we know for sure that the function we're calling will itself try to
386397 // call us, then we avoid inlining that function.
387398 if self . tcx . mir_callgraph_reachable ( ( callee, caller_def_id. expect_local ( ) ) ) {
388- return Err ( "caller might be reachable from callee (query cycle avoidance)" ) ;
399+ debug ! ( "query cycle avoidance" ) ;
400+ return Err ( "caller might be reachable from callee" ) ;
389401 }
390402
391403 Ok ( ( ) )
@@ -459,7 +471,7 @@ impl<'tcx> Inliner<'tcx> {
459471 }
460472
461473 if let InlineAttr :: Never = callee_attrs. inline {
462- return Err ( "never inline hint " ) ;
474+ return Err ( "never inline attribute " ) ;
463475 }
464476
465477 // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined
@@ -528,12 +540,12 @@ impl<'tcx> Inliner<'tcx> {
528540 let tcx = self . tcx ;
529541
530542 if let Some ( _) = callee_body. tainted_by_errors {
531- return Err ( "Body is tainted " ) ;
543+ return Err ( "body has errors " ) ;
532544 }
533545
534546 // Callees which require inlining must be inlined to maintain security properties or
535547 // for performance reasons, so skip any heuristics.
536- if matches ! ( callee_attrs. inline, InlineAttr :: Required { .. } | InlineAttr :: Must { .. } ) {
548+ if callee_attrs. inline . required ( ) {
537549 debug ! ( "INLINING {:?} [required]" , callsite) ;
538550 return Ok ( ( ) ) ;
539551 }
@@ -594,7 +606,7 @@ impl<'tcx> Inliner<'tcx> {
594606 // assign one. However, during this stage we require an exact match when any
595607 // inline-asm is detected. LLVM will still possibly do an inline later on
596608 // if the no-attribute function ends up with the same instruction set anyway.
597- return Err ( "Cannot move inline-asm across instruction sets" ) ;
609+ return Err ( "cannot move inline-asm across instruction sets" ) ;
598610 } else if let TerminatorKind :: TailCall { .. } = term. kind {
599611 // FIXME(explicit_tail_calls): figure out how exactly functions containing tail
600612 // calls can be inlined (and if they even should)
0 commit comments