Auto merge of #134082 - davidtwco:forced-inlining, r= · rust-lang/rust@4ce6fc9 (original) (raw)
`@@ -19,6 +19,7 @@ use rustc_session::{Session, lint};
`
19
19
`use rustc_span::symbol::Ident;
`
20
20
`use rustc_span::{Span, sym};
`
21
21
`use rustc_target::spec::{SanitizerSet, abi};
`
``
22
`+
use tracing::debug;
`
22
23
``
23
24
`use crate::errors;
`
24
25
`use crate::target_features::{check_target_feature_trait_unsafe, from_target_feature_attr};
`
`@@ -514,31 +515,50 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
514
515
`}
`
515
516
``
516
517
` codegen_fn_attrs.inline = attrs.iter().fold(InlineAttr::None, |ia, attr| {
`
517
``
`-
if !attr.has_name(sym::inline) {
`
518
``
`-
return ia;
`
519
``
`-
}
`
520
``
`-
match attr.meta_kind() {
`
521
``
`-
Some(MetaItemKind::Word) => InlineAttr::Hint,
`
522
``
`-
Some(MetaItemKind::List(ref items)) => {
`
523
``
`-
inline_span = Some(attr.span);
`
524
``
`-
if items.len() != 1 {
`
525
``
`-
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
`
526
``
`-
.emit();
`
527
``
`-
InlineAttr::None
`
528
``
`-
} else if list_contains_name(items, sym::always) {
`
529
``
`-
InlineAttr::Always
`
530
``
`-
} else if list_contains_name(items, sym::never) {
`
531
``
`-
InlineAttr::Never
`
532
``
`-
} else {
`
533
``
`-
struct_span_code_err!(tcx.dcx(), items[0].span(), E0535, "invalid argument")
`
``
518
`+
if attr.has_name(sym::inline) {
`
``
519
`+
match attr.meta_kind() {
`
``
520
`+
Some(MetaItemKind::Word) => InlineAttr::Hint,
`
``
521
`+
Some(MetaItemKind::List(ref items)) => {
`
``
522
`+
inline_span = Some(attr.span);
`
``
523
`+
if items.len() != 1 {
`
``
524
`+
struct_span_code_err!(tcx.dcx(), attr.span, E0534, "expected one argument")
`
``
525
`+
.emit();
`
``
526
`+
InlineAttr::None
`
``
527
`+
} else if list_contains_name(items, sym::always) {
`
``
528
`+
InlineAttr::Always
`
``
529
`+
} else if list_contains_name(items, sym::never) {
`
``
530
`+
InlineAttr::Never
`
``
531
`+
} else {
`
``
532
`+
struct_span_code_err!(
`
``
533
`+
tcx.dcx(),
`
``
534
`+
items[0].span(),
`
``
535
`+
E0535,
`
``
536
`+
"invalid argument"
`
``
537
`+
)
`
534
538
`` .with_help("valid inline arguments are always
and never
")
``
535
539
`.emit();
`
536
540
``
537
``
`-
InlineAttr::None
`
``
541
`+
InlineAttr::None
`
``
542
`+
}
`
538
543
`}
`
``
544
`+
Some(MetaItemKind::NameValue(_)) => ia,
`
``
545
`+
None => ia,
`
539
546
`}
`
540
``
`-
Some(MetaItemKind::NameValue(_)) => ia,
`
541
``
`-
None => ia,
`
``
547
`+
} else if attr.has_name(sym::rustc_force_inline) && tcx.features().rustc_attrs() {
`
``
548
`+
match attr.meta_kind() {
`
``
549
`+
Some(MetaItemKind::NameValue(lit)) => {
`
``
550
`+
InlineAttr::Force { attr_span: attr.span, reason: Some(lit.symbol) }
`
``
551
`+
}
`
``
552
`+
Some(MetaItemKind::Word) => {
`
``
553
`+
InlineAttr::Force { attr_span: attr.span, reason: None }
`
``
554
`+
}
`
``
555
`+
_ => {
`
``
556
`` +
debug!("rustc_force_inline
not checked by attribute validation");
``
``
557
`+
ia
`
``
558
`+
}
`
``
559
`+
}
`
``
560
`+
} else {
`
``
561
`+
ia
`
542
562
`}
`
543
563
`});
`
544
564
``
`@@ -586,7 +606,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
586
606
`` // is probably a poor usage of #[inline(always)]
and easily avoided by not using the attribute.
``
587
607
`if tcx.features().target_feature_11()
`
588
608
` && tcx.is_closure_like(did.to_def_id())
`
589
``
`-
&& codegen_fn_attrs.inline != InlineAttr::Always
`
``
609
`+
&& !codegen_fn_attrs.inline.always()
`
590
610
`{
`
591
611
`let owner_id = tcx.parent(did.to_def_id());
`
592
612
`if tcx.def_kind(owner_id).has_codegen_attrs() {
`
`@@ -596,11 +616,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
596
616
`}
`
597
617
`}
`
598
618
``
599
``
`-
// If a function uses #[target_feature] it can't be inlined into general
`
``
619
`` +
// If a function uses #[target_feature]
it can't be inlined into general
``
600
620
`// purpose functions as they wouldn't have the right target features
`
601
``
`-
// enabled. For that reason we also forbid #[inline(always)] as it can't be
`
``
621
`` +
// enabled. For that reason we also forbid #[inline(always)]
as it can't be
``
602
622
`// respected.
`
603
``
`-
if !codegen_fn_attrs.target_features.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always
`
``
623
`+
//
`
``
624
`` +
// #[rustc_force_inline]
doesn't need to be prohibited here, that
``
``
625
`+
// is implemented entirely in rustc can attempt to inline and error if it cannot.
`
``
626
`+
if !codegen_fn_attrs.target_features.is_empty()
`
``
627
`+
&& matches!(codegen_fn_attrs.inline, InlineAttr::Always)
`
604
628
`{
`
605
629
`if let Some(span) = inline_span {
`
606
630
` tcx.dcx().span_err(
`
`@@ -611,7 +635,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
`
611
635
`}
`
612
636
`}
`
613
637
``
614
``
`-
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
`
``
638
`+
if !codegen_fn_attrs.no_sanitize.is_empty() && codegen_fn_attrs.inline.always() {
`
615
639
`if let (Some(no_sanitize_span), Some(inline_span)) = (no_sanitize_span, inline_span) {
`
616
640
`let hir_id = tcx.local_def_id_to_hir_id(did);
`
617
641
` tcx.node_span_lint(
`