Rollup merge of #114550 - dtolnay:globalalloc, r=compiler-errors

Generate better function argument names in global_allocator expansion

Generated code for `#[global_allocator] static ALLOCATOR: Allocator = Allocator;`—

**Before:**

```rust
const _: () = {
    #[rustc_std_internal_symbol]
    unsafe fn __rust_alloc(arg0: usize, arg1: usize) -> *mut u8 {
        ::core::alloc::GlobalAlloc::alloc(
            &ALLOCATOR,
            ::core::alloc::Layout::from_size_align_unchecked(arg0, arg1),
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_dealloc(arg0: *mut u8, arg1: usize, arg2: usize) -> () {
        ::core::alloc::GlobalAlloc::dealloc(
            &ALLOCATOR,
            arg0,
            ::core::alloc::Layout::from_size_align_unchecked(arg1, arg2),
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_realloc(
        arg0: *mut u8,
        arg1: usize,
        arg2: usize,
        arg3: usize,
    ) -> *mut u8 {
        ::core::alloc::GlobalAlloc::realloc(
            &ALLOCATOR,
            arg0,
            ::core::alloc::Layout::from_size_align_unchecked(arg1, arg2),
            arg3,
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_alloc_zeroed(arg0: usize, arg1: usize) -> *mut u8 {
        ::core::alloc::GlobalAlloc::alloc_zeroed(
            &ALLOCATOR,
            ::core::alloc::Layout::from_size_align_unchecked(arg0, arg1),
        )
    }
};
```

**After:**

```rust
const _: () = {
    #[rustc_std_internal_symbol]
    unsafe fn __rust_alloc(size: usize, align: usize) -> *mut u8 {
        ::core::alloc::GlobalAlloc::alloc(
            &ALLOCATOR,
            ::core::alloc::Layout::from_size_align_unchecked(size, align),
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize) -> () {
        ::core::alloc::GlobalAlloc::dealloc(
            &ALLOCATOR,
            ptr,
            ::core::alloc::Layout::from_size_align_unchecked(size, align),
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_realloc(
        ptr: *mut u8,
        size: usize,
        align: usize,
        new_size: usize,
    ) -> *mut u8 {
        ::core::alloc::GlobalAlloc::realloc(
            &ALLOCATOR,
            ptr,
            ::core::alloc::Layout::from_size_align_unchecked(size, align),
            new_size,
        )
    }
    #[rustc_std_internal_symbol]
    unsafe fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
        ::core::alloc::GlobalAlloc::alloc_zeroed(
            &ALLOCATOR,
            ::core::alloc::Layout::from_size_align_unchecked(size, align),
        )
    }
};
```
This commit is contained in:
Matthias Krüger 2023-08-07 00:06:07 +02:00 committed by GitHub
commit 1ea9951b43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 30 deletions

View File

@ -33,29 +33,41 @@ pub enum AllocatorTy {
pub struct AllocatorMethod {
pub name: Symbol,
pub inputs: &'static [AllocatorTy],
pub inputs: &'static [AllocatorMethodInput],
pub output: AllocatorTy,
}
pub struct AllocatorMethodInput {
pub name: &'static str,
pub ty: AllocatorTy,
}
pub static ALLOCATOR_METHODS: &[AllocatorMethod] = &[
AllocatorMethod {
name: sym::alloc,
inputs: &[AllocatorTy::Layout],
inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }],
output: AllocatorTy::ResultPtr,
},
AllocatorMethod {
name: sym::dealloc,
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout],
inputs: &[
AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr },
AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout },
],
output: AllocatorTy::Unit,
},
AllocatorMethod {
name: sym::realloc,
inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize],
inputs: &[
AllocatorMethodInput { name: "ptr", ty: AllocatorTy::Ptr },
AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout },
AllocatorMethodInput { name: "new_size", ty: AllocatorTy::Usize },
],
output: AllocatorTy::ResultPtr,
},
AllocatorMethod {
name: sym::alloc_zeroed,
inputs: &[AllocatorTy::Layout],
inputs: &[AllocatorMethodInput { name: "layout", ty: AllocatorTy::Layout }],
output: AllocatorTy::ResultPtr,
},
];

View File

@ -2,7 +2,7 @@ use crate::util::check_builtin_macro_attribute;
use crate::errors;
use rustc_ast::expand::allocator::{
global_fn_name, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS,
global_fn_name, AllocatorMethod, AllocatorMethodInput, AllocatorTy, ALLOCATOR_METHODS,
};
use rustc_ast::ptr::P;
use rustc_ast::{self as ast, AttrVec, Expr, FnHeader, FnSig, Generics, Param, StmtKind};
@ -70,13 +70,7 @@ struct AllocFnFactory<'a, 'b> {
impl AllocFnFactory<'_, '_> {
fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
let mut abi_args = ThinVec::new();
let mut i = 0;
let mut mk = || {
let name = Ident::from_str_and_span(&format!("arg{i}"), self.span);
i += 1;
name
};
let args = method.inputs.iter().map(|ty| self.arg_ty(ty, &mut abi_args, &mut mk)).collect();
let args = method.inputs.iter().map(|input| self.arg_ty(input, &mut abi_args)).collect();
let result = self.call_allocator(method.name, args);
let output_ty = self.ret_ty(&method.output);
let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
@ -113,18 +107,19 @@ impl AllocFnFactory<'_, '_> {
thin_vec![self.cx.attr_word(sym::rustc_std_internal_symbol, self.span)]
}
fn arg_ty(
&self,
ty: &AllocatorTy,
args: &mut ThinVec<Param>,
ident: &mut dyn FnMut() -> Ident,
) -> P<Expr> {
match *ty {
fn arg_ty(&self, input: &AllocatorMethodInput, args: &mut ThinVec<Param>) -> P<Expr> {
match input.ty {
AllocatorTy::Layout => {
// If an allocator method is ever introduced having multiple
// Layout arguments, these argument names need to be
// disambiguated somehow. Currently the generated code would
// fail to compile with "identifier is bound more than once in
// this parameter list".
let size = Ident::from_str_and_span("size", self.span);
let align = Ident::from_str_and_span("align", self.span);
let usize = self.cx.path_ident(self.span, Ident::new(sym::usize, self.span));
let ty_usize = self.cx.ty_path(usize);
let size = ident();
let align = ident();
args.push(self.cx.param(self.span, size, ty_usize.clone()));
args.push(self.cx.param(self.span, align, ty_usize));
@ -138,13 +133,13 @@ impl AllocFnFactory<'_, '_> {
}
AllocatorTy::Ptr => {
let ident = ident();
let ident = Ident::from_str_and_span(input.name, self.span);
args.push(self.cx.param(self.span, ident, self.ptr_u8()));
self.cx.expr_ident(self.span, ident)
}
AllocatorTy::Usize => {
let ident = ident();
let ident = Ident::from_str_and_span(input.name, self.span);
args.push(self.cx.param(self.span, ident, self.usize()));
self.cx.expr_ident(self.span, ident)
}

View File

@ -39,8 +39,8 @@ fn codegen_inner(
if kind == AllocatorKind::Default {
for method in ALLOCATOR_METHODS {
let mut arg_tys = Vec::with_capacity(method.inputs.len());
for ty in method.inputs.iter() {
match *ty {
for input in method.inputs.iter() {
match input.ty {
AllocatorTy::Layout => {
arg_tys.push(usize_ty); // size
arg_tys.push(usize_ty); // align

View File

@ -27,8 +27,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
if kind == AllocatorKind::Default {
for method in ALLOCATOR_METHODS {
let mut types = Vec::with_capacity(method.inputs.len());
for ty in method.inputs.iter() {
match *ty {
for input in method.inputs.iter() {
match input.ty {
AllocatorTy::Layout => {
types.push(usize);
types.push(usize);

View File

@ -34,8 +34,8 @@ pub(crate) unsafe fn codegen(
if kind == AllocatorKind::Default {
for method in ALLOCATOR_METHODS {
let mut args = Vec::with_capacity(method.inputs.len());
for ty in method.inputs.iter() {
match *ty {
for input in method.inputs.iter() {
match input.ty {
AllocatorTy::Layout => {
args.push(usize); // size
args.push(usize); // align