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(

`