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(

`