Add inline attribute to generated delegation function if needed
This commit is contained in:
parent
1d6c526bb0
commit
8cf942d89f
4 changed files with 228 additions and 0 deletions
|
|
@ -44,6 +44,7 @@ use hir::{BodyId, HirId};
|
|||
use rustc_abi::ExternAbi;
|
||||
use rustc_ast::*;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::attrs::{AttributeKind, InlineAttr};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
|
||||
|
|
@ -87,6 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
|
||||
match sig_id {
|
||||
Ok(sig_id) => {
|
||||
self.add_inline_attribute_if_needed(span);
|
||||
|
||||
let is_method = self.is_method(sig_id, span);
|
||||
let (param_count, c_variadic) = self.param_count(sig_id);
|
||||
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
|
||||
|
|
@ -100,6 +103,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_inline_attribute_if_needed(&mut self, span: Span) {
|
||||
const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;
|
||||
let create_inline_attr_slice =
|
||||
|| [hir::Attribute::Parsed(AttributeKind::Inline(InlineAttr::Hint, span))];
|
||||
|
||||
let new_attributes = match self.attrs.get(&PARENT_ID) {
|
||||
Some(attrs) => {
|
||||
// Check if reuse already specifies any inline attribute, if so, do nothing
|
||||
if attrs
|
||||
.iter()
|
||||
.any(|a| matches!(a, hir::Attribute::Parsed(AttributeKind::Inline(..))))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
self.arena.alloc_from_iter(
|
||||
attrs.into_iter().map(|a| a.clone()).chain(create_inline_attr_slice()),
|
||||
)
|
||||
}
|
||||
None => self.arena.alloc_from_iter(create_inline_attr_slice()),
|
||||
};
|
||||
|
||||
self.attrs.insert(PARENT_ID, new_attributes);
|
||||
}
|
||||
|
||||
fn get_delegation_sig_id(
|
||||
&self,
|
||||
item_id: NodeId,
|
||||
|
|
|
|||
94
tests/pretty/delegation_inline_attribute.pp
Normal file
94
tests/pretty/delegation_inline_attribute.pp
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
//@ pretty-compare-only
|
||||
//@ pretty-mode:hir
|
||||
//@ pp-exact:delegation_inline_attribute.pp
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(fn_delegation)]
|
||||
#[attr = MacroUse {arguments: UseAll}]
|
||||
extern crate std;
|
||||
#[prelude_import]
|
||||
use ::std::prelude::rust_2015::*;
|
||||
|
||||
mod to_reuse {
|
||||
fn foo(x: usize) -> usize { x }
|
||||
}
|
||||
|
||||
// Check that #[inline(hint)] is added to foo reuse
|
||||
#[attr = Inline(Hint)]
|
||||
fn bar(arg0: _) -> _ { to_reuse::foo(self + 1) }
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) { }
|
||||
fn foo1(&self) { }
|
||||
fn foo2(&self) { }
|
||||
fn foo3(&self) { }
|
||||
fn foo4(&self) { }
|
||||
}
|
||||
|
||||
impl Trait for u8 { }
|
||||
|
||||
struct S(u8);
|
||||
|
||||
mod to_import {
|
||||
fn check(arg: &'_ u8) -> &'_ u8 { arg }
|
||||
}
|
||||
|
||||
impl Trait for S {
|
||||
// Check that #[inline(hint)] is added to foo reuse
|
||||
#[attr = Inline(Hint)]
|
||||
fn foo(self: _)
|
||||
->
|
||||
_ {
|
||||
{
|
||||
// Check that #[inline(hint)] is added to foo0 reuse inside another reuse
|
||||
#[attr = Inline(Hint)]
|
||||
fn foo0(arg0: _) -> _ { to_reuse::foo(self + 1) }
|
||||
|
||||
// Check that #[inline(hint)] is added when other attributes present in inner reuse
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
|
||||
#[attr = MustUse]
|
||||
#[attr = Cold]
|
||||
#[attr = Inline(Hint)]
|
||||
fn foo1(arg0: _) -> _ { to_reuse::foo(self / 2) }
|
||||
|
||||
// Check that #[inline(never)] is preserved in inner reuse
|
||||
#[attr = Inline(Never)]
|
||||
fn foo2(arg0: _) -> _ { to_reuse::foo(self / 2) }
|
||||
|
||||
// Check that #[inline(always)] is preserved in inner reuse
|
||||
#[attr = Inline(Always)]
|
||||
fn foo3(arg0: _) -> _ { to_reuse::foo(self / 2) }
|
||||
|
||||
// Check that #[inline(never)] is preserved when there are other attributes in inner reuse
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
|
||||
#[attr = Inline(Never)]
|
||||
#[attr = MustUse]
|
||||
#[attr = Cold]
|
||||
fn foo4(arg0: _) -> _ { to_reuse::foo(self / 2) }
|
||||
}.foo()
|
||||
}
|
||||
|
||||
// Check that #[inline(hint)] is added when there are other attributes present in trait reuse
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
|
||||
#[attr = MustUse]
|
||||
#[attr = Cold]
|
||||
#[attr = Inline(Hint)]
|
||||
fn foo1(self: _) -> _ { self.0.foo1() }
|
||||
|
||||
// Check that #[inline(never)] is preserved in trait reuse
|
||||
#[attr = Inline(Never)]
|
||||
fn foo2(self: _) -> _ { self.0.foo2() }
|
||||
|
||||
// Check that #[inline(always)] is preserved in trait reuse
|
||||
#[attr = Inline(Always)]
|
||||
fn foo3(self: _) -> _ { self.0.foo3() }
|
||||
|
||||
// Check that #[inline(never)] is preserved when there are other attributes in trait reuse
|
||||
#[attr = Deprecation {deprecation: Deprecation {since: Unspecified}}]
|
||||
#[attr = Inline(Never)]
|
||||
#[attr = MustUse]
|
||||
#[attr = Cold]
|
||||
fn foo4(self: _) -> _ { self.0.foo4() }
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
104
tests/pretty/delegation_inline_attribute.rs
Normal file
104
tests/pretty/delegation_inline_attribute.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
//@ pretty-compare-only
|
||||
//@ pretty-mode:hir
|
||||
//@ pp-exact:delegation_inline_attribute.pp
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(fn_delegation)]
|
||||
|
||||
mod to_reuse {
|
||||
pub fn foo(x: usize) -> usize {
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
// Check that #[inline(hint)] is added to foo reuse
|
||||
reuse to_reuse::foo as bar {
|
||||
self + 1
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn foo(&self) {}
|
||||
fn foo1(&self) {}
|
||||
fn foo2(&self) {}
|
||||
fn foo3(&self) {}
|
||||
fn foo4(&self) {}
|
||||
}
|
||||
|
||||
impl Trait for u8 {}
|
||||
|
||||
struct S(u8);
|
||||
|
||||
mod to_import {
|
||||
pub fn check(arg: &u8) -> &u8 { arg }
|
||||
}
|
||||
|
||||
impl Trait for S {
|
||||
// Check that #[inline(hint)] is added to foo reuse
|
||||
reuse Trait::foo {
|
||||
// Check that #[inline(hint)] is added to foo0 reuse inside another reuse
|
||||
reuse to_reuse::foo as foo0 {
|
||||
self + 1
|
||||
}
|
||||
|
||||
// Check that #[inline(hint)] is added when other attributes present in inner reuse
|
||||
#[cold]
|
||||
#[must_use]
|
||||
#[deprecated]
|
||||
reuse to_reuse::foo as foo1 {
|
||||
self / 2
|
||||
}
|
||||
|
||||
// Check that #[inline(never)] is preserved in inner reuse
|
||||
#[inline(never)]
|
||||
reuse to_reuse::foo as foo2 {
|
||||
self / 2
|
||||
}
|
||||
|
||||
// Check that #[inline(always)] is preserved in inner reuse
|
||||
#[inline(always)]
|
||||
reuse to_reuse::foo as foo3 {
|
||||
self / 2
|
||||
}
|
||||
|
||||
// Check that #[inline(never)] is preserved when there are other attributes in inner reuse
|
||||
#[cold]
|
||||
#[must_use]
|
||||
#[inline(never)]
|
||||
#[deprecated]
|
||||
reuse to_reuse::foo as foo4 {
|
||||
self / 2
|
||||
}
|
||||
}
|
||||
|
||||
// Check that #[inline(hint)] is added when there are other attributes present in trait reuse
|
||||
#[cold]
|
||||
#[must_use]
|
||||
#[deprecated]
|
||||
reuse Trait::foo1 {
|
||||
self.0
|
||||
}
|
||||
|
||||
// Check that #[inline(never)] is preserved in trait reuse
|
||||
#[inline(never)]
|
||||
reuse Trait::foo2 {
|
||||
self.0
|
||||
}
|
||||
|
||||
// Check that #[inline(always)] is preserved in trait reuse
|
||||
#[inline(always)]
|
||||
reuse Trait::foo3 {
|
||||
self.0
|
||||
}
|
||||
|
||||
// Check that #[inline(never)] is preserved when there are other attributes in trait reuse
|
||||
#[cold]
|
||||
#[must_use]
|
||||
#[inline(never)]
|
||||
#[deprecated]
|
||||
reuse Trait::foo4 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ use ::std::prelude::rust_2015::*;
|
|||
fn b<C>(e: C) { }
|
||||
|
||||
trait G {
|
||||
#[attr = Inline(Hint)]
|
||||
fn b(arg0: _) -> _ { b({ }) }
|
||||
}
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ mod m {
|
|||
fn add(a: u32, b: u32) -> u32 { a + b }
|
||||
}
|
||||
|
||||
#[attr = Inline(Hint)]
|
||||
fn add(arg0: _, arg1: _) -> _ { m::add(arg0, arg1) }
|
||||
|
||||
fn main() { { let _ = add(1, 2); }; }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue