Repository navigation
global_allocator can not not be defined inside module #44113
Copy link
Copy link
Closed
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsC-bugCategory: This is a bug.Category: This is a bug.T-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
Description
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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-allocatorsArea: Custom and system allocatorsArea: Custom and system allocatorsC-bugCategory: This is a bug.Category: This is a bug.T-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
Activity
mattico commentedon Sep 27, 2017
I looked into this a bit, writing some notes here so I don't forget what I found.
The problem is here:
rust/src/librustc_allocator/expand.rs
Lines 94 to 97 in 0e6f4cf
The
Pathfor the allocator is hard-coded to besuper::<allocator name>. We need to instead get a properPathforf.global.There may be a function hidden in the compiler somewhere that can help get a
Pathfor anItem. If there isn't we could keep aVec<Mod>as we traverse modules and convert that to aPathif we find an allocator definition.mattico commentedon Sep 27, 2017
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 commentedon Oct 19, 2017
To add to this, this is also broken:
mark-i-m commentedon Mar 22, 2018
playground example: https://play.rust-lang.org/?gist=db5d76e6c9da2e3e08de7592862e7ff3&version=nightly
mark-i-m commentedon Mar 24, 2018
Started working on this... It's very WIP at the moment, though. If anyone has feedback, let me know.
Auto merge of #51335 - mark-i-m:allocator, r=oli-obk
Global allocators have to be defined in the root of the crate
steveklabnik commentedon Apr 3, 2019
We now have a good error for this:
So the real question is, is this something we want to enable in the future? If so, then this shouldn't be closed, and the bug would be tracking that. If we do not, then this should be closed.
mark-i-m commentedon Apr 3, 2019
Personally, i would like for that to be possible. For example, when building an OS, it would be nice to be able to everything in a memory management module. Currently, you have to break that abstraction to put the allocator in thr crate root, which then requires exposing the implementation outside the memory management module.
mark-i-m commentedon Apr 3, 2019
So I realized that I never gave an update here. The current status is as follows:
About a year ago, I attempted to implement a fix, but we ran into a lot of weird hygiene issues (that even alexcrichton wasn't able to help with). Then, I changed course and implemented the error that Steve posted above. That's about all I know how to do, and that was the end of my endeavors in this space.
Somebody with expertise in macro/hygiene wizardry and compiler internals is needed to fix the problems we ran into in #49320.
rkapl commentedon Apr 3, 2019
For me, the error message is more important than solving the problem perfectly. In my use case, i have just moved the allocator to the root -- but the real problem was finding this solution.
jq-rs commentedon Apr 25, 2019
Adding submodule support may be useful when combining several crates with custom global allocator with c libraries. With several crates the ´´´__rg_alloc´´´ symbol is overlapping in the linking phase and linking is failing. Or is there a workaround already for this (besides allowing multidefs)?
mark-i-m commentedon Apr 25, 2019
I think it is intentionally disallowed to have multiple global allocators. After all, they would no longer be global...
jq-rs commentedon Apr 25, 2019
In this case they are the same allocator as they are using the same global alloc crate. Still, as they are from different internal crates, they are seen as different allocators during linking. Multidefs is the workaround, but it of course may cause other issues elsewhere. But yes, I agree that maybe submodules is not the way to properly solve this problem.
petrochenkov commentedon Jul 16, 2019
Fixed in #62735.
Rollup merge of rust-lang#62735 - petrochenkov:galloc, r=alexcrichton
Rollup merge of rust-lang#62735 - petrochenkov:galloc, r=alexcrichton
Rollup merge of rust-lang#62735 - petrochenkov:galloc, r=alexcrichton
Rollup merge of rust-lang#62735 - petrochenkov:galloc, r=alexcrichton