mir_transform: implement forced inlining
Adds `#[rustc_force_inline]` which is similar to always inlining but reports an error if the inlining was not possible, and which always attempts to inline annotated items, regardless of optimisation levels. It can only be applied to free functions to guarantee that the MIR inliner will be able to resolve calls.
This commit is contained in:
parent
336209eef1
commit
f86169a58f
47 changed files with 2130 additions and 709 deletions
|
@ -656,6 +656,14 @@ passes_rustc_allow_const_fn_unstable =
|
|||
passes_rustc_dirty_clean =
|
||||
attribute requires -Z query-dep-graph to be enabled
|
||||
|
||||
passes_rustc_force_inline =
|
||||
attribute should be applied to a function
|
||||
.label = not a function definition
|
||||
|
||||
passes_rustc_force_inline_coro =
|
||||
attribute cannot be applied to a `async`, `gen` or `async gen` function
|
||||
.label = `async`, `gen` or `async gen` function
|
||||
|
||||
passes_rustc_layout_scalar_valid_range_arg =
|
||||
expected exactly one integer literal argument
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
self.check_coroutine(attr, target);
|
||||
}
|
||||
[sym::linkage, ..] => self.check_linkage(attr, span, target),
|
||||
[sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent( attr.span, span, attrs),
|
||||
[sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent(attr.span, span, attrs),
|
||||
[
|
||||
// ok
|
||||
sym::allow
|
||||
|
@ -332,6 +332,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
|
||||
self.check_repr(attrs, span, target, item, hir_id);
|
||||
self.check_used(attrs, target, span);
|
||||
self.check_rustc_force_inline(hir_id, attrs, span, target);
|
||||
}
|
||||
|
||||
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr: &Attribute, sym: &str) {
|
||||
|
@ -2480,6 +2481,45 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_rustc_force_inline(
|
||||
&self,
|
||||
hir_id: HirId,
|
||||
attrs: &[Attribute],
|
||||
span: Span,
|
||||
target: Target,
|
||||
) {
|
||||
let force_inline_attr = attrs.iter().find(|attr| attr.has_name(sym::rustc_force_inline));
|
||||
match (target, force_inline_attr) {
|
||||
(Target::Closure, None) => {
|
||||
let is_coro = matches!(
|
||||
self.tcx.hir().expect_expr(hir_id).kind,
|
||||
hir::ExprKind::Closure(hir::Closure {
|
||||
kind: hir::ClosureKind::Coroutine(..)
|
||||
| hir::ClosureKind::CoroutineClosure(..),
|
||||
..
|
||||
})
|
||||
);
|
||||
let parent_did = self.tcx.hir().get_parent_item(hir_id).to_def_id();
|
||||
let parent_span = self.tcx.def_span(parent_did);
|
||||
let parent_force_inline_attr =
|
||||
self.tcx.get_attr(parent_did, sym::rustc_force_inline);
|
||||
if let Some(attr) = parent_force_inline_attr
|
||||
&& is_coro
|
||||
{
|
||||
self.dcx().emit_err(errors::RustcForceInlineCoro {
|
||||
attr_span: attr.span,
|
||||
span: parent_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
(Target::Fn, _) => (),
|
||||
(_, Some(attr)) => {
|
||||
self.dcx().emit_err(errors::RustcForceInline { attr_span: attr.span, span });
|
||||
}
|
||||
(_, None) => (),
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if `#[autodiff]` is applied to an item other than a function item.
|
||||
fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) {
|
||||
debug!("check_autodiff");
|
||||
|
|
|
@ -688,6 +688,24 @@ pub(crate) struct RustcPubTransparent {
|
|||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_rustc_force_inline)]
|
||||
pub(crate) struct RustcForceInline {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_rustc_force_inline_coro)]
|
||||
pub(crate) struct RustcForceInlineCoro {
|
||||
#[primary_span]
|
||||
pub attr_span: Span,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_link_ordinal)]
|
||||
pub(crate) struct LinkOrdinal {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue