Auto merge of #134082 - davidtwco:forced-inlining, r= · rust-lang/rust@3487c46 (original) (raw)
`@@ -18,6 +18,7 @@ use rustc_session::{Session, lint};
`
18
18
`use rustc_span::symbol::Ident;
`
19
19
`use rustc_span::{Span, sym};
`
20
20
`use rustc_target::spec::{SanitizerSet, abi};
`
``
21
`+
use tracing::debug;
`
21
22
``
22
23
`use crate::errors;
`
23
24
`use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature_attr};
`
`@@ -522,31 +523,55 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
522
523
` mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
`
523
524
``
524
525
` codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
`
525
``
`-
if !attr.has_name(sym::inline) {
`
526
``
`-
return ia;
`
527
``
`-
}
`
528
``
`-
match attr.meta_kind() {
`
529
``
`-
Some(MetaItemKind::Word) => InlineAttr::Hint,
`
530
``
`-
Some(MetaItemKind::List(ref items)) => {
`
531
``
`-
inline_span = Some(attr.span);
`
532
``
`-
if items.len() != 1 {
`
533
``
`-
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
`
534
``
`-
.emit();
`
535
``
`-
InlineAttr::None
`
536
``
`-
} else if list_contains_name(items, sym::always) {
`
537
``
`-
InlineAttr::Always
`
538
``
`-
} else if list_contains_name(items, sym::never) {
`
539
``
`-
InlineAttr::Never
`
540
``
`-
} else {
`
541
``
`-
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
`
``
526
`+
if attr.has_name(sym::inline) {
`
``
527
`+
match attr.meta_kind() {
`
``
528
`+
Some(MetaItemKind::Word) => InlineAttr::Hint,
`
``
529
`+
Some(MetaItemKind::List(ref items)) => {
`
``
530
`+
inline_span = Some(attr.span);
`
``
531
`+
if items.len() != 1 {
`
``
532
`+
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
`
``
533
`+
.emit();
`
``
534
`+
InlineAttr::None
`
``
535
`+
} else if list_contains_name(items, sym::always) {
`
``
536
`+
InlineAttr::Always
`
``
537
`+
} else if list_contains_name(items, sym::never) {
`
``
538
`+
InlineAttr::Never
`
``
539
`+
} else {
`
``
540
`+
struct_span_code_err!(
`
``
541
`+
tcx.dcx(),
`
``
542
`+
items[0].span(),
`
``
543
`+
E0535,
`
``
544
`+
"invalid argument"
`
``
545
`+
)
`
542
546
`` .with_help("valid inline arguments are always
and never
")
``
543
547
`.emit();
`
544
548
``
545
``
`-
InlineAttr::None
`
``
549
`+
InlineAttr::None
`
``
550
`+
}
`
546
551
`}
`
``
552
`+
Some(MetaItemKind::NameValue(_)) => ia,
`
``
553
`+
None => ia,
`
547
554
`}
`
548
``
`-
Some(MetaItemKind::NameValue(_)) => ia,
`
549
``
`-
None => ia,
`
``
555
`+
} else {
`
``
556
`+
ia
`
``
557
`+
}
`
``
558
`+
});
`
``
559
`+
codegen_fn_attrs.inline = attrs.iter().fold(codegen_fn_attrs.inline, |ia, attr| {
`
``
560
`+
if attr.has_name(sym::rustc_force_inline) && tcx.features().rustc_attrs() {
`
``
561
`+
match attr.meta_kind() {
`
``
562
`+
Some(MetaItemKind::NameValue(lit)) => {
`
``
563
`+
InlineAttr::Force { attr_span: attr.span, reason: Some(lit.symbol) }
`
``
564
`+
}
`
``
565
`+
Some(MetaItemKind::Word) => {
`
``
566
`+
InlineAttr::Force { attr_span: attr.span, reason: None }
`
``
567
`+
}
`
``
568
`+
_ => {
`
``
569
`` +
debug!("rustc_force_inline
not checked by attribute validation");
``
``
570
`+
ia
`
``
571
`+
}
`
``
572
`+
}
`
``
573
`+
} else {
`
``
574
`+
ia
`
550
575
`}
`
551
576
`});
`
552
577
``
`@@ -601,7 +626,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
601
626
`` // is probably a poor usage of #[inline(always)]
and easily avoided by not using the attribute.
``
602
627
`if tcx.features().target_feature_11()
`
603
628
` && tcx.is_closure_like(did.to_def_id())
`
604
``
`-
&& codegen_fn_attrs.inline != InlineAttr::Always
`
``
629
`+
&& !codegen_fn_attrs.inline.always()
`
605
630
`{
`
606
631
`let owner_id = tcx.parent(did.to_def_id());
`
607
632
`if tcx.def_kind(owner_id).has_codegen_attrs() {
`
`@@ -611,11 +636,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
611
636
`}
`
612
637
`}
`
613
638
``
614
``
`-
// If a function uses #[target_feature] it can't be inlined into general
`
``
639
`` +
// If a function uses #[target_feature]
it can't be inlined into general
``
615
640
`// purpose functions as they wouldn't have the right target features
`
616
``
`-
// enabled. For that reason we also forbid #[inline(always)] as it can't be
`
``
641
`` +
// enabled. For that reason we also forbid #[inline(always)]
as it can't be
``
617
642
`// respected.
`
618
``
`-
if !codegen_fn_attrs.target_features.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always
`
``
643
`+
//
`
``
644
`` +
// #[rustc_force_inline]
doesn't need to be prohibited here, that
``
``
645
`+
// is implemented entirely in rustc can attempt to inline and error if it cannot.
`
``
646
`+
if !codegen_fn_attrs.target_features.is_empty()
`
``
647
`+
&& matches!(codegen_fn_attrs.inline, InlineAttr::Always)
`
619
648
`{
`
620
649
`if let Some(span) = inline_span {
`
621
650
` tcx.dcx().span_err(
`
`@@ -626,7 +655,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
626
655
`}
`
627
656
`}
`
628
657
``
629
``
`-
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
`
``
658
`+
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() {
`
630
659
`if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
`
631
660
`let hir_id = tcx.local_def_id_to_hir_id(did);
`
632
661
` tcx.node_span_lint(
`