Skip to content

Commit

Permalink
Emit a lint for small functions without #[inline]
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Nov 4, 2023
1 parent f81d6f0 commit 3edee2b
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/deriving/debug.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub fn expand_deriving_debug(
explicit_self: true,
nonself_args: vec![(fmtr, sym::f)],
ret_ty: Path(path_std!(fmt::Result)),
attributes: ast::AttrVec::new(),
attributes: thin_vec![cx.attr_word(sym::inline, span)],
fieldless_variants_strategy:
FieldlessVariantsStrategy::SpecializeIfAllVariantsFieldless,
combine_substructure: combine_substructure(Box::new(|a, b, c| {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_mir_transform/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in
}
.not_inherited = items do not inherit unsafety from separate enclosing items
mir_transform_small_fn_without_inline = this function looks small ({$statements}) but doesn't have #[inline], consider adding it
.suggestion = add the inline attribute
mir_transform_target_feature_call_label = call to function with `#[target_feature]`
mir_transform_target_feature_call_note = can only be called if the required target features are available
Expand Down
39 changes: 34 additions & 5 deletions compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,37 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
}

let mir = tcx.optimized_mir(def_id);
let mut checker =
CostChecker { tcx, callee_body: mir, calls: 0, statements: 0, landing_pads: 0, resumes: 0 };
let mut checker = CostChecker {
tcx,
callee_body: mir,
calls: 0,
statements: 0,
landing_pads: 0,
resumes: 0,
branches: 0,
asserts: 0,
};
checker.visit_body(mir);
checker.calls == 0
let is_leaf = checker.calls == 0
&& checker.resumes == 0
&& checker.landing_pads == 0
&& checker.statements
<= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100)
<= tcx.sess.opts.unstable_opts.cross_crate_inline_threshold.unwrap_or(100);

let is_trivial_wrapper = checker.calls == 1
&& checker.resumes == 0
&& checker.landing_pads == 0
&& mir.basic_blocks.len() == 2;

if is_trivial_wrapper {
let span = tcx.def_span(def_id);
tcx.sess.emit_warning(crate::errors::SuggestAddingInline {
place: span,
suggest_inline: span.with_hi(span.lo()),
statements: checker.statements,
});
}
is_leaf
}

struct CostChecker<'b, 'tcx> {
Expand All @@ -72,6 +95,8 @@ struct CostChecker<'b, 'tcx> {
statements: usize,
landing_pads: usize,
resumes: usize,
branches: usize,
asserts: usize,
}

impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
Expand Down Expand Up @@ -105,7 +130,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}
}
TerminatorKind::Assert { unwind, .. } => {
self.calls += 1;
self.asserts += 1;
if let UnwindAction::Cleanup(_) = unwind {
self.landing_pads += 1;
}
Expand All @@ -117,6 +142,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
self.landing_pads += 1;
}
}
TerminatorKind::SwitchInt { .. } => {
self.statements += 1;
self.branches += 1;
}
TerminatorKind::Return => {}
_ => self.statements += 1,
}
Expand Down
10 changes: 10 additions & 0 deletions compiler/rustc_mir_transform/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,13 @@ pub(crate) struct MustNotSuspendReason {
pub span: Span,
pub reason: String,
}

#[derive(Diagnostic)]
#[diag(mir_transform_small_fn_without_inline)]
pub struct SuggestAddingInline {
#[primary_span]
pub place: Span,
#[suggestion(code = "#[inline]\n", applicability = "machine-applicable")]
pub suggest_inline: Span,
pub statements: usize,
}

0 comments on commit 3edee2b

Please sign in to comment.