Skip to content

global_allocator can not not be defined inside module #44113

Closed
@rkapl

Description

@rkapl

When trying define a global allocator inside a module, you get a weird error message: [E0432]: unresolved import super. The global_allocator is expanded to code containing use super::<varname> but I don't know why rustc fails to resolve that in this case. Happens with both inline and file modules.

Looks like the module that is created by expanding global_allocator thinks its parent is the root crate despite being in the breaks module.

Example:

#![feature(global_allocator, allocator_api)]                                                                                                                                                                       
                                                                                                                                                                                                                   
struct TAlloc;                                                                                                                                                                                                     
                                                                                                                                                                                                                   
unsafe impl<'a> std::heap::Alloc for &'a TAlloc{                                                                                                                                                                   
    unsafe fn alloc(&mut self, _layout: std::heap::Layout) -> std::result::Result<*mut u8, std::heap::AllocErr> {                                                                                                  
        return Err(std::heap::AllocErr::Unsupported{details: "Stub allocator"});                                                                                                                                   
    }                                                                                                                                                                                                              
    unsafe fn dealloc(&mut self, _ptr: *mut u8, _layout: std::heap::Layout) {                                                                                                                                      
    }                                                                                                                                                                                                              
}                                                                                                                                                                                                                  
                                                                                                                                                                                                                   
mod breaks{                                                                                                                                                                                                        
    #[global_allocator]                                                                                                                                                                                            
    static ALLOCATOR: ::TAlloc = ::TAlloc;                                                                                                                                                                         
}                                                                                                                                                                                                                  
                                                                                                                                                                                                                   
pub fn main() {                                                                                                                                                                                                    
}

causes:

error[E0432]: unresolved import `super`
  --> alloc.rs:15:5
   |
15 |     static ALLOCATOR: ::TAlloc = ::TAlloc;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ALLOCATOR` in the root

Activity

added
A-allocatorsArea: Custom and system allocators
C-bugCategory: This is a bug.
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
on Aug 28, 2017
mattico

mattico commented on Sep 27, 2017

@mattico
Contributor

I looked into this a bit, writing some notes here so I don't forget what I found.

The problem is here:

let super_path = f.cx.path(f.span, vec![
Ident::from_str("super"),
f.global,
]);

The Path for the allocator is hard-coded to be super::<allocator name>. We need to instead get a proper Path for f.global.

There may be a function hidden in the compiler somewhere that can help get a Path for an Item. If there isn't we could keep a Vec<Mod> as we traverse modules and convert that to a Path if we find an allocator definition.

mattico

mattico commented on Sep 27, 2017

@mattico
Contributor

Another option is to generate stub impls of the global alloc functions in the AST but then fill them out later when there's more information available.

whitequark

whitequark commented on Oct 19, 2017

@whitequark
Member

To add to this, this is also broken:

pub fn main() {
    #[global_allocator]
    static ALLOCATOR: ::TAlloc = ::TAlloc;
}
mark-i-m

mark-i-m commented on Mar 24, 2018

@mark-i-m
Member

Started working on this... It's very WIP at the moment, though. If anyone has feedback, let me know.

added a commit that references this issue on Jun 25, 2018

Auto merge of #51335 - mark-i-m:allocator, r=oli-obk

16 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-allocatorsArea: Custom and system allocatorsC-bugCategory: This is a bug.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @steveklabnik@whitequark@carols10cents@mattico@rkapl

      Issue actions

        global_allocator can not not be defined inside module · Issue #44113 · rust-lang/rust