Extends rustc_force_inline to inherent methods
- Changes parser to allow application to inherent methods. - Adds tests to confirm extended functionality works just as the existing.
This commit is contained in:
parent
caccb4d036
commit
5bf5e71160
20 changed files with 346 additions and 25 deletions
|
|
@ -72,7 +72,11 @@ impl<S: Stage> SingleAttributeParser<S> for RustcForceInlineParser {
|
|||
const PATH: &'static [Symbol] = &[sym::rustc_force_inline];
|
||||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
|
||||
Allow(Target::Fn),
|
||||
Allow(Target::Method(MethodKind::Inherent)),
|
||||
]);
|
||||
|
||||
const TEMPLATE: AttributeTemplate = template!(Word, List: &["reason"], NameValueStr: "reason");
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller::{closure#0}` before ForceInline
|
||||
+ // MIR for `caller::{closure#0}` after ForceInline
|
||||
|
||||
fn caller::{closure#0}(_1: &{closure@$DIR/forced_closure_inherent.rs:14:6: 14:8}) -> () {
|
||||
let mut _0: ();
|
||||
let _2: ();
|
||||
+ scope 1 (inlined Foo::callee_forced) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
- _2 = Foo::callee_forced() -> [return: bb1, unwind unreachable];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_2);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller::{closure#0}` before ForceInline
|
||||
+ // MIR for `caller::{closure#0}` after ForceInline
|
||||
|
||||
fn caller::{closure#0}(_1: &{closure@$DIR/forced_closure_inherent.rs:14:6: 14:8}) -> () {
|
||||
let mut _0: ();
|
||||
let _2: ();
|
||||
+ scope 1 (inlined Foo::callee_forced) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
- _2 = Foo::callee_forced() -> [return: bb1, unwind continue];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_2);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
19
tests/mir-opt/inline/forced_closure_inherent.rs
Normal file
19
tests/mir-opt/inline/forced_closure_inherent.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -Copt-level=0 --crate-type=lib
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo {}
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
pub fn callee_forced() {}
|
||||
}
|
||||
|
||||
// EMIT_MIR forced_closure_inherent.caller-{closure#0}.ForceInline.diff
|
||||
pub fn caller() {
|
||||
(|| {
|
||||
Foo::callee_forced();
|
||||
// CHECK-LABEL: fn caller::{closure#0}(
|
||||
// CHECK: (inlined Foo::callee_forced)
|
||||
})();
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::bar) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::bar() -> [return: bb1, unwind unreachable];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::bar) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::bar() -> [return: bb1, unwind continue];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
17
tests/mir-opt/inline/forced_inherent.rs
Normal file
17
tests/mir-opt/inline/forced_inherent.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -Copt-level=0 --crate-type=lib
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
// EMIT_MIR forced_inherent.caller.ForceInline.diff
|
||||
fn caller() {
|
||||
Foo::bar();
|
||||
// CHECK-LABEL: fn caller(
|
||||
// CHECK: (inlined Foo::bar)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::bar) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::bar() -> [return: bb1, unwind unreachable];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::bar) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::bar() -> [return: bb1, unwind continue];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
25
tests/mir-opt/inline/forced_inherent_ambiguous.rs
Normal file
25
tests/mir-opt/inline/forced_inherent_ambiguous.rs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -Copt-level=0 --crate-type=lib
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
trait Tr {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
impl Tr for Foo {
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
// EMIT_MIR forced_inherent_ambiguous.caller.ForceInline.diff
|
||||
fn caller() {
|
||||
Foo::bar();
|
||||
// CHECK-LABEL: fn caller(
|
||||
// CHECK: (inlined Foo::bar)
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> {async fn body of caller()} {
|
||||
let mut _0: {async fn body of caller()};
|
||||
|
||||
bb0: {
|
||||
_0 = {coroutine@$DIR/forced_inherent_async.rs:14:19: 18:2 (#0)};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> {async fn body of caller()} {
|
||||
let mut _0: {async fn body of caller()};
|
||||
|
||||
bb0: {
|
||||
_0 = {coroutine@$DIR/forced_inherent_async.rs:14:19: 18:2 (#0)};
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
18
tests/mir-opt/inline/forced_inherent_async.rs
Normal file
18
tests/mir-opt/inline/forced_inherent_async.rs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -Copt-level=0 --crate-type=lib
|
||||
//@ edition: 2021
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo {}
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
pub fn callee_forced() {}
|
||||
}
|
||||
|
||||
// EMIT_MIR forced_inherent_async.caller.ForceInline.diff
|
||||
async fn caller() {
|
||||
Foo::callee_forced();
|
||||
// CHECK-LABEL: fn caller(
|
||||
// CHECK: (inlined Foo::callee_forced)
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::callee_forced) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::callee_forced() -> [return: bb1, unwind unreachable];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
- // MIR for `caller` before ForceInline
|
||||
+ // MIR for `caller` after ForceInline
|
||||
|
||||
fn caller() -> () {
|
||||
let mut _0: ();
|
||||
let _1: ();
|
||||
+ scope 1 (inlined Foo::callee_forced) {
|
||||
+ }
|
||||
|
||||
bb0: {
|
||||
StorageLive(_1);
|
||||
- _1 = Foo::callee_forced() -> [return: bb1, unwind continue];
|
||||
- }
|
||||
-
|
||||
- bb1: {
|
||||
StorageDead(_1);
|
||||
_0 = const ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
21
tests/mir-opt/inline/forced_inherent_dead_code.rs
Normal file
21
tests/mir-opt/inline/forced_inherent_dead_code.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
|
||||
//@ compile-flags: -Copt-level=0 -Clink-dead-code
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo {}
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
pub fn callee_forced() {}
|
||||
}
|
||||
|
||||
// EMIT_MIR forced_inherent_dead_code.caller.ForceInline.diff
|
||||
pub fn caller() {
|
||||
Foo::callee_forced();
|
||||
// CHECK-LABEL: fn caller(
|
||||
// CHECK: (inlined Foo::callee_forced)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
caller();
|
||||
}
|
||||
21
tests/ui/force-inlining/inherent.rs
Normal file
21
tests/ui/force-inlining/inherent.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//@ check-fail
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
#[rustc_force_inline]
|
||||
//~^ ERROR: `Foo::bar` is incompatible with `#[rustc_force_inline]`
|
||||
#[rustc_no_mir_inline]
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
fn bar_caller() {
|
||||
unsafe {
|
||||
Foo::bar();
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
bar_caller();
|
||||
}
|
||||
13
tests/ui/force-inlining/inherent.stderr
Normal file
13
tests/ui/force-inlining/inherent.stderr
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
error: `Foo::bar` is incompatible with `#[rustc_force_inline]`
|
||||
--> $DIR/inherent.rs:7:5
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
LL | fn bar() {}
|
||||
| -------- `Foo::bar` defined here
|
||||
|
|
||||
= note: incompatible due to: #[rustc_no_mir_inline]
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
@ -114,7 +114,6 @@ trait FooQux = FooBaz;
|
|||
//~^ ERROR attribute cannot be used on
|
||||
impl<T> Bar<T> {
|
||||
#[rustc_force_inline]
|
||||
//~^ ERROR attribute cannot be used on
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
|
||||
--> $DIR/invalid.rs:132:11
|
||||
--> $DIR/invalid.rs:131:11
|
||||
|
|
||||
LL | fn barqux(#[rustc_force_inline] _x: u32) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -134,7 +134,7 @@ error: `#[rustc_force_inline]` attribute cannot be used on foreign functions
|
|||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
= help: `#[rustc_force_inline]` can be applied to functions and inherent methods
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on type aliases
|
||||
--> $DIR/invalid.rs:66:1
|
||||
|
|
@ -222,7 +222,7 @@ error: `#[rustc_force_inline]` attribute cannot be used on provided trait method
|
|||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
= help: `#[rustc_force_inline]` can be applied to functions and inherent methods
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on trait aliases
|
||||
--> $DIR/invalid.rs:109:1
|
||||
|
|
@ -240,16 +240,8 @@ LL | #[rustc_force_inline]
|
|||
|
|
||||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on inherent methods
|
||||
--> $DIR/invalid.rs:116:5
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on trait impl blocks
|
||||
--> $DIR/invalid.rs:121:1
|
||||
--> $DIR/invalid.rs:120:1
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -257,7 +249,7 @@ LL | #[rustc_force_inline]
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on macro defs
|
||||
--> $DIR/invalid.rs:128:1
|
||||
--> $DIR/invalid.rs:127:1
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -265,7 +257,7 @@ LL | #[rustc_force_inline]
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on function params
|
||||
--> $DIR/invalid.rs:132:11
|
||||
--> $DIR/invalid.rs:131:11
|
||||
|
|
||||
LL | fn barqux(#[rustc_force_inline] _x: u32) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -273,15 +265,15 @@ LL | fn barqux(#[rustc_force_inline] _x: u32) {}
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on closures
|
||||
--> $DIR/invalid.rs:149:14
|
||||
--> $DIR/invalid.rs:148:14
|
||||
|
|
||||
LL | let _x = #[rustc_force_inline] || { };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
= help: `#[rustc_force_inline]` can be applied to functions and inherent methods
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on expressions
|
||||
--> $DIR/invalid.rs:151:14
|
||||
--> $DIR/invalid.rs:150:14
|
||||
|
|
||||
LL | let _y = #[rustc_force_inline] 3 + 4;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -289,7 +281,7 @@ LL | let _y = #[rustc_force_inline] 3 + 4;
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on statements
|
||||
--> $DIR/invalid.rs:153:5
|
||||
--> $DIR/invalid.rs:152:5
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -297,7 +289,7 @@ LL | #[rustc_force_inline]
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: `#[rustc_force_inline]` attribute cannot be used on match arms
|
||||
--> $DIR/invalid.rs:158:9
|
||||
--> $DIR/invalid.rs:157:9
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -305,7 +297,7 @@ LL | #[rustc_force_inline]
|
|||
= help: `#[rustc_force_inline]` can only be applied to functions
|
||||
|
||||
error: attribute cannot be applied to a `async`, `gen` or `async gen` function
|
||||
--> $DIR/invalid.rs:136:1
|
||||
--> $DIR/invalid.rs:135:1
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -314,7 +306,7 @@ LL | async fn async_foo() {}
|
|||
| -------------------- `async`, `gen` or `async gen` function
|
||||
|
||||
error: attribute cannot be applied to a `async`, `gen` or `async gen` function
|
||||
--> $DIR/invalid.rs:140:1
|
||||
--> $DIR/invalid.rs:139:1
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -323,7 +315,7 @@ LL | gen fn gen_foo() {}
|
|||
| ---------------- `async`, `gen` or `async gen` function
|
||||
|
||||
error: attribute cannot be applied to a `async`, `gen` or `async gen` function
|
||||
--> $DIR/invalid.rs:144:1
|
||||
--> $DIR/invalid.rs:143:1
|
||||
|
|
||||
LL | #[rustc_force_inline]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -331,7 +323,7 @@ LL |
|
|||
LL | async gen fn async_gen_foo() {}
|
||||
| ---------------------------- `async`, `gen` or `async gen` function
|
||||
|
||||
error: aborting due to 37 previous errors
|
||||
error: aborting due to 36 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0539, E0805.
|
||||
For more information about an error, try `rustc --explain E0539`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue