Rust: Tracking issue for changing the global, default allocator (RFC 1974)

Created on 29 Jul 2015  Â·  74Comments  Â·  Source: rust-lang/rust

Tracking issue for https://github.com/rust-lang/rfcs/pull/1183~~ https://github.com/rust-lang/rfcs/pull/1974

Known bugs:

  • [ ] The #[global_allocator] attribute doesn't work in modules #44113

Current status:

A quick summary of the current state of this feature is that you can change the default global allocator via:

// Change this program's global allocator. At most one `#[global_allocator]` 
// allowed in any crate graph.
#[global_allocator]
static ALLOCATOR: MyAlloc = MyAlloc;


// When defining a global allocator, the `Alloc` trait must be defined
// for `&'a T` instead of `T`
use std::heap::Alloc;

struct MyAlloc;

impl<'a> Alloc for &'a MyAlloc {
    // ...
}
B-unstable C-tracking-issue T-libs

Most helpful comment

If I don't want to read a 100 page PhD thesis about the Haskell ecosystem, could you summarize what this would look like in Rust and how it would be implemented?

All 74 comments

Reopening as tracking issue for stabilization.

Man now I'm wishing github didn't have all those links to commits which referenced this, oh well! Some thoughts for stabilization:

  • The names alloc_system and alloc_jemalloc aren't stable, and we may not want to stabilize them. Can we get away providing no stable allocators by default?
  • The allocation symbols all have funky names (leading __rust prefixes). It'd be nice if you instead tagged a function as "this is the allocator malloc function" and then the compiler would automatically wire it to the right symbol name.
  • The allocation functions are not typechecked, and along the line of the previous bullet it would be nice if the functions were tagged to be typechecked.

I don't think these are necessarily blocks for stabilization, nothing will work unless the symbols are right and the signatures match, so I would consider it backwards compatible to add compiler verification at a later date. Otherwise this is such a low-level feature that expecting you to read some docs or look at some examples seems not totally unreasonable.

@ruud-v-a made a really good point about a problem with requiring an align parameter on deallocation (and presumably it also affects reallocate, at least in terms of how it is specified); see https://github.com/rust-lang/rfcs/pull/1398#issuecomment-198584430

It would be nice to push on this in order to punt jemalloc out of the tree. I don't know what all the blocking issues are but I gather we're not particularly happy with the current interface.

FWIW I've got a version of jemalloc out-of-tree on crates.io as well (nightly only)

Oh I don't actually see this linked but there is an RFC for what is hopefully the "final form" of this: https://github.com/rust-lang/rfcs/pull/1974

I'm not sure if this is the right thread or https://github.com/rust-lang/rfcs/pull/1974 is the right thread???

Wow this has been painful trying to understand where this is landing (Yay! Lets read like hundreds of github comments, a few PRs, and some out dated docs to try to understand how to do something a systems language should do in it sleep... allocate memory). From this thread it seems like its now been adopted as some sort of trait based allocator with #[global_allocator] ???

I'm trying and failing to implement a Darwin/MacOS KEXT with rust. Here's the lonely rust file and its sister c glue file I've been hacking around with (not a lot to show for a few days of work... at least I can stack allocate and print from the kernel in rust 🎊 )

My initial goal of plugging rust into the IOMalloc and IOFree methods provided by the Darwin kernel seemed like a straight forward task but oh how I've been wrong. I mean who doesn't want nice Box syntax and ergonomic allocation / free when writing in rust?!? (yes I realize the kernel has special constraints on lifetimes and timings of things, but in principle rust should be able to plug into its alloc / free mechanisms)

Pointing back to some stable docs from a few release ago https://doc.rust-lang.org/1.16.0/book/custom-allocators.html it seemed straight froward enough, of course including #![feature] gated things in the stable docs is asinine as "features" are inherently unstable (why were these docs even in a stable release??? Because you know #[feature] may not be used on the stable release channel).

Current nightly (nightly-x86_64-apple-darwin - rustc 1.21.0-nightly (52a330969 2017-07-27)) of course after this merge and this has removed the #![allocator] feature in favor of global_allocator and default_lib_allocator.

error[E0557]: feature has been removed
#![feature(allocator)]

Ok, so clearly there is some frustration here trying to understand the state of things.

Really all I'm seeking is what is the most stable way for a no_std, no libc rust program making use of a kernel provided alloc/fee to plug into the correct allocation handlers? The last comments on the previous PR leave me very confused.

From what I can gather I need to follow something like this https://github.com/rust-lang/rust/pull/42727/files#diff-e3210055d7c3792841be2a5c1ba9b5b0 except of course my target being a no_std environment seems to make this 100x more painful.

Any pointers are greatly appropriated. Mahalo

@wmealing Yes, unstable Rust is a moving target, and following it takes significant time investment. Yes, today’s stable Rust is basically insufficient for no_std environment. It’s a work in progress, many people are working on stabilizing these things. If you need stable non-default allocators, please check again in a few months. A new stable Rust version comes out every six weeks. A low-investment way to follow what’s in them is reading “Announcing Rust 1.x” posts on https://blog.rust-lang.org/

@wmealing You actually linked precisely the document that tells you exactly what you need to do. The only wrinkle is the fact that you don't have std, so you'd need to know (I found out by looking up the documentation and clicking the "src" link in the top right) that the relevant pieces the example code imports from std::heap can also be found in alloc::heap.

(why were these docs even in a stable release??? Because you know #[feature] may not be used on the stable release channel).

They were in a section of the book titled "Nightly Rust", that described explicitly unstable features. Historically, we never had a place to put them, so that's where they went. More recently, the "Unstable Book" was added, and so all that stuff was moved out, which is why you don't see them in today's book.

@SimonSapin @Ketsuban @steveklabnik Thanks for the quick responses.

I'll give the approach with alloc::heap a try. 🍰

Also my handle isn't @wmealing 🤣

(Ah sorry, auto-complete fail…)

No problem Simon, :) I have must an early rust contribution maybe thats why @wmealing is in your autocomplete. Its no bother at all.

I'm not sure if jemalloc as a crate makes sense. jemalloc offers a way to load with LD_PRELOAD, and it just works without recompilation.

@ishitatsuyuki, jemalloc has a sized deallocation function (sdalloc) as an optimization, which can only be used when specifically compiling for it.

When trying define a global allocator inside a module, you get a weird error message: {{[E0432]: unresolved import super}}. Example: alloc.rs.txt. The global_allocator attribute expands to code containing use super::<varname> but I don't know why rustc fails to resolve that in that case. Happens with both inline and file modules. Is it something that's not supported?

@rkapl I think that's definitely a bug! Want to file a dedicated issue for that?

@alexcrichton Done, #44113 .

Thanks!

@alexcrichton If I wanted to try out using the system allocator (rather than defining a custom allocator) for a binary compiled on the latest nightly on macOS, what would the best way to do this be?

@SimonSapin Thank you for the link to documentation.

I tried:

rustc +nightly --version
rustc 1.22.0-nightly (981ce7d8d 2017-09-03)
#![feature(alloc_system)]

extern crate alloc_system;

fn main() {
    let a = Box::new(4); // Allocates from the system allocator.
    println!("{}", a);
}

On build a warning is printed:

cargo +nightly run --release
   Compiling rust-test v0.1.0 (rust-test)
warning: unused extern crate
 --> src/main.rs:3:1
  |
3 | extern crate alloc_system;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(unused_extern_crates)] on by default

And if I run strings rust-test | grep jemalloc, I still see references to jemalloc.

I'm pretty sure that documentation is hopelessly out of date. What you have to do now is something like: https://github.com/rust-lang/rust/blob/1685c9298685f73db4fe890c1ed27b22408aaad7/src/test/run-pass/smallest-hello-world.rs#L20-L25

Thank you @lnicola! Confirmed jemalloc strings are no longer present and binary size dropped from ~400KB to ~200KB.

@SimonSapin unfortunately the docu for supplying such an allocator is not yet there:

https://doc.rust-lang.org/nightly/unstable-book/library-features/allocator-api.html

Sometimes you want the memory for one collection to use a different allocator than the memory for another collection. In this case, replacing the global allocator is not a workable option. Instead, you need to pass in an instance of an Alloc to each collection for which you want a custom allocator.
TBD

Is the api finished, i.e. could I use it right now if i have a look how the current allocators are implemented?

And a more grave question: if the Alloc trait resides in std::heap, can we use it in #![no_std] crates? If not (what i presume), how can we map the allocation in no_std crates to kalloc or ExAllocatePoolWithTag?

@Trolldemorted The std::heap Alloc trait is just a re-export of the trait defined in the alloc crate.

The #[global_allocator] attribute doesn't work in modules

Also, it doesn't work in functions. fn main() { #[global_allocator] static mut ALLOC: ... = ...; }

@rfcbot fcp merge

I think the #[global_allocator] has baked for long enough now at this point, and I've overall been quite happy with the current design and its possibility for future extensions. Overall I got the same feeling during the initial RFC process that the current design is overall well accepted.

Note that stabilization of this feature will require #32838 to be stable as well, and I'm going to shortly propose stabilization on that. I figured it's probably best to focus mostly on the #[global_allocator] attribute here rather than the Alloc trait itself.

Team member @alexcrichton has proposed to merge this. The next step is review by the rest of the tagged teams:

  • [x] @BurntSushi
  • [x] @Kimundi
  • [x] @alexcrichton
  • [x] @aturon
  • [x] @dtolnay
  • [x] @sfackler

No concerns currently listed.

Once these reviewers reach consensus, this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@SimonSapin We can stabilize #[global_allocator] and alloc_system to enable people to at the very least select the system allocator.

Looks like this can be stabilized?

Both Tor and Firefox need this (Firefox needs to be able to ensure the allocator is system, tor needs to be able to set it to tor_malloc and tor_free).

The docs are already written and need to be moved.

There is a small bug in https://github.com/rust-lang/rust/issues/44113 but we can ship with this bug. I can also try to fix that.

Anyone mind me making a stabilization PR?

@Manishearth ah that's what the ticky boxes are for (although help with the actual PR when that's ready would be greatly appreciated!)

uh lol I wrote that comment two days ago and then left it in a tab and submitted it today. Didn't notice we were in the ticky box phase. great! :D

The alloc_system crate should be added to the set of those documented together with std.

Should alloc_system::System be re-exported under std::heap? (Perhaps renamed SystemAlloc?)

(Edit: if so, the alloc_system crate should still be stabilized for no_std programs.)

@SimonSapin I think it's already reexported?

Oops, sorry :)

:bell: This is now entering its final comment period, as per the review above. :bell:

I'm not too happy with the need to implement a trait on a reference, it feels like an ugly hack. So I'm going to throw a few alternative proposals out there for discussion:

Using a function

struct MyAlloc {..}
impl Alloc for MyAlloc {..}

// Returns an instance of the global allocator. The returned type must implement the Alloc trait.
#[global_allocator]
fn get_global_allocator() -> MyAlloc {
    MyAlloc {..}
}

Each call to the global allocator gets a new instance of the allocator, thus making &mut a non-issue. The only downside is that it allocs and deallocs will technically use different allocator instances, which is not allowed.

Define a SharedAlloc trait

Since you already need to write two impls of the Alloc trait, one for MyAlloc and one for &'a MyAlloc, there is actually very little downside to simply defining a SharedAlloc trait (which takes &self instead of &mut self) instead of using a hack with lifetimes and references.

We can also add a blanket impl in liballoc which impls Alloc for all SharedAlloc types, which reduces the amount of boilerplate even further. This impl should allow user specialization though, so that features like Mutex::get_mut can be used in the Alloc implementation if the user wishes.

// Blanket implementation inside liballoc:
impl<T: SharedAlloc> Alloc for T {..}

// User implementation:
struct MyAlloc {..}
impl SharedAlloc for MyAlloc {..}

#[global_allocator]
static MY_ALLOC: MyAlloc = MyAlloc {..};

See the RFC for an extensive discussion of the options.
On Sat, Nov 4, 2017 at 8:18 AM Amanieu notifications@github.com wrote:

I'm not too happy with the need to implement a trait on a reference, it
feels like an ugly hack. So I'm going to throw a few alternative proposals
out there for discussion:
Using a function

struct MyAlloc {..}impl Alloc for MyAlloc {..}
// Returns an instance of the global allocator. The returned type must implement the Alloc trait.

[global_allocator]fn get_global_allocator() -> MyAlloc {

MyAlloc {..}

}

Each call to the global allocator gets a new instance of the allocator,
thus making &mut a non-issue. The only downside is that it allocs and
deallocs will technically use different allocator instances, which is not
allowed.
Define a SharedAlloc trait

Since you already need to write two impls of the Alloc trait, one for
MyAlloc and one for &'a MyAlloc, there is actually very little downside
to simply defining a SharedAlloc trait (which takes &self instead of &mut
self) instead of using a hack with lifetimes and references.

We can also add a blanket impl in liballoc which impls Alloc for all
SharedAlloc types, which reduces the amount of boilerplate even further.
This impl should allow user specialization though, so that features like
Mutex::get_mut can be used in the Alloc implementation if the user wishes.

// Blanket implementation inside liballoc:impl Alloc for T {..}
// User implementation:struct MyAlloc {..}impl SharedAlloc for MyAlloc {..}

[global_allocator]static MY_ALLOC: MyAlloc = MyAlloc {..};

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/rust-lang/rust/issues/27389#issuecomment-341904790,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABY2UfzO9TxA0pSlOd6v1fL3jz_S_h1Iks5szIBWgaJpZM4FiVNM
.

it feels like an ugly hack

Can you identify why it feels that way? It doesn't to me.

@SimonSapin (comming from https://github.com/rust-lang/rust/issues/32838#issuecomment-341877578)

What do you think would be a non-awful way to select the global allocator?

https://github.com/ezyang/thesis/releases/download/rev20170925/main.pdf That is an implemented PhD thesis retrofitting the needed functionality onto Haskell + Cabal. It is not be hard to tweak the design for Rust + Cabal. Indeed the end goal isn't even so new to that thesis, but is an old ML thing. The "retrofitting onto existing language" part is new however, and exactly what would have been the hard part, except the thesis + implementation war stories demolish it. There is no hard part left, our work is entirely cut out for us.

The list of things that would use this includes:

  • liblog logging implementation
  • panic printing implementation (as opposed to unwind vs abort, a codegen not library distinction)
  • "framework libraries" providing main shims (i.e. library has undef function and defines main, crate root defines the other function).
  • global allocator

(buried in other threads I think I might have longer lists.)

The underlying (anti-)pattern here is singletons / ambient authority---this things are iffy so it's great in general that the trait system pushes us away from them. But, for the use-cases above, there isn't a pure-trait solution that anyone has found.

Crucially, global allocation is an unremarkable example of this. It's 100% a library issue, not language issue. (We do have misc language support for allocation, but that boils down to use of the global allocator, not the definition of it.) There's no special case.

And yes, I shouldn't be saying this as I already have many other open source and even Rust obligations (foremost https://github.com/rust-lang/rfcs/pull/1133), but you all could successfully conscript me to distill that thesis into an RFC for Rust :).

CC @aturon

The current design was proposed in an RFC 7 months ago, accepted and implemented 5 months ago, and landed in Nightly 4 months ago. At this point I guess that fundamental changes to the design are unlikely without a concrete counter-proposal.

If I don't want to read a 100 page PhD thesis about the Haskell ecosystem, could you summarize what this would look like in Rust and how it would be implemented?

@Ericson2314

Are you proposing that there's no design work needed to incorporate the SML module system into Rust? And that the issues around Cabal in Backpack would be the same as for Cargo? Even if we wanted to bolt on SML modules (that's a big if), I am highly skeptical that it's "just a matter of engineering". And even if it were, I can't imagine implementing, let alone stabilizing such a thing for another 3 years...

As we talked about on IRC, what would be the most compelling way to change the course of things here would instead be to argue that:

  • There are important use-cases not adequately addressed by this feature.
  • The changes you have in mind can be done in a low-cost way (or at any rate, the cost is commensurate with the size/importance of the use case).
  • There's no forward-compatible way to address the missing use cases.

@sfackler

edit, I just remembered from reading my old comments that @ezyang wrote an illustrated Rust-style RFC for backpack: https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst .

Sure, though I first should credit that thesis, and @ezyang's writing in general, for being extremely readable. Very briefly:

  1. In Rust, can do things like

    abstract mod FooBarBaz {
       // Acts a lot like proposed `abstract type`
       // (https://github.com/rust-lang/rfcs/blob/master/text/2071-impl-trait-type-alias.md)
       type Foo;
    
       // Acts a lot like lang item / `extern { static FOO: Foo }`
       static FOO: Foo; 
    }
    
  2. In Cargo.toml for crate with abstract modules, declare abstract modules by path

  3. Dependencies can (but need not) have their abstract modules instantiated with something concrete. The design fundamentally allows for the same crate can be instantiated two different ways, too, though our use-cases may not benefit from this

    [dependencies]
    alloc_system = "*"
    alloc_jemalloc = "*"
    alloc_with_system = { name = "alloc", requires = { "x::y" = "alloc_system::global_allocator" } }
    alloc_with_jemalloc = { name = "alloc", requires = { "x::y" = "alloc_jemalloc::global_allocator" } }
    
  4. Cargo solver figures exact plan of instantiation (this mirrors the public/private dep rules in terms of ensuring unified dependencies must be instantiated the same way).

  5. rustc is given this exact plan, so it need do that sort of solving / global (multi-crate) coherence checking. Also this is a bone for non-Cargo Rust users not being completely stuck.

@aturon

Are you proposing that there's no design work needed to incorporate the SML module system into Rust?

Well, it's not all SML verbatim, but that's a good thing. Haskell and Rust and both languages with traits / type classes first and foremost, so the thesis is both answering what's feasible and what makes aesthetic sense. I'm still reading, but my prior knowledge of the work leads me to say "basically no".

The biggest difference I see so far is that in Haskell modules are not namespaced per library/package/crate. So unlike my sketch above, "abstract crates" as opposed to "abstract modules" might be the most natural translation.

And that the issues around Cabal in Backpack would be the same as for Cargo?

Again I need to finish reading, but I don't anticipate any. In fact, our private-public dependency division anticipates some of this work (Cabal only has public dependencies).

There are important use-cases not adequately addressed by this feature.

I worry that if we attack each bullet point I list separately, some will never get addressed---stuck in low priority limbo. I think this feature will also probably be necessary for breaking up std into smaller libraries, though that's a hard argument to demonstrate short of actually doing it.

The changes you have in mind can be done in a low-cost way (or at any rate, the cost is commensurate with the size/importance of the use case).

If there is design work, it's probably in finding even more minimal subsets of Backpack. I concede your point about stabilization; even if everything does port over flawlessly, it's still a big change so one we'd probably want to stabilize slowly and incremental.

There's no forward-compatible way to address the missing use cases.

Maybe an ad-hoc attribute is the right stop-gap (!), but I'd be more comfortable if we knew how it fit into the larger picture. Yes, we didn't block impl trait on abstract types, but at least we sketched something out.

Quite frankly, #[global_allocator] was not designed by the lang team, and I doubt anyone currently knows the full semantics of it. Abstraction sealing in the presence of dependency cycles as can occur today (e.g. your allocator depends on liballoco) is not trivial stuff.

Quite frankly, #[global_allocator] was not designed by the lang team, and I doubt anyone currently knows the full semantics of it.

Really? This is how you're going to pitch your idea?

Oh woah, sorry. I have this whole time been missing that there is no static HEAP, just the Copy Heap struct which acts as an always abstract handle. That avoids a lot of the complexity. I still don't like #[global_allocator], but at least the Heap interface I now expect to be fully compatible with anything I'm proposing.

The final comment period is now complete.

@sfackler looks like we can accept this?

@sfackler: Wondering about the status now, given @Manishearth’s comment?

I think we can now accept a PR that:

  • Stabilizes and documents the #[gloabal_allocator] attribute
  • Stabilizes and documents the std::heap module and the std::heap::System struct.
  • Double-check that everything else in std::heap has its own #[unstable] attribute and did not rely on the module’s

Who wants to work on this?

The rest of the module (in particular the Alloc trait) is tracked at https://github.com/rust-lang/rust/issues/32838.

This stabilization is not very useful on its own as it only enables selecting System, but it’s a step.

This issue should stay open because it also tracks changing the default to System. (Or a new tracking issue should be opened for that.)

My personal take on the status here is that we're ready to stabilize the #[global_allocator] feature when necessary, but I don't personally think this is too useful to do without the Alloc trait itself being stable. It'd allow switching to malloc/free on stable Rust which is important for tools like valgrind, but otherwise it wouldn't allow actual custom allocators or for the main distribution to jettison jemalloc-by-default.

I would, personally at least, wait to do much here until #32838 is ready to make progress.

https://github.com/rust-lang-nursery/portability-wg/issues/3 is talking about this more generally, FYI.

@rfcbot concern indirection overhead

(Does this still work after FCP has ended?)

The way this works at the moment is that Heap::alloc for example calls a function declaration extern "Rust" { fn __rust_alloc(…) -> …; }.

When #[global_allocator] is used, it expands to roughly (I’m glossing over handling of different defaults in cdylib/staticlib vs executables) code that defines this function extern fn __rust_alloc(…) -> … { … }. This indirection (or something like it) is necessary because the allocator may be defined in a crate downstream of liballoc.

Do we have a clear idea of what is the performance overhead of this indirection? It definitely prevents inlining. (I think.) Does it have a cost similar to a virtual call to a trait object’s method? How significant is this cost in practice? Are we ready to stabilize a design that make this cost unavoidable? (Or is it avoidable?)

Or is it avoidable?

It might be avoidable in the future. This RFC doesn't actually commit to anything with regards to how the alloc crate finds the system allocator. I jot down some notes of how I think dependency inversion can work in the general case here: https://github.com/rust-lang-nursery/portability-wg/issues/3#issuecomment-374029037

@SimonSapin the performance overhead is the overhead of a function call, which is the same as the overhead of calling functions (like malloc, for example).

Depending on how we handle its link visibility, the overhead may even be less than calling malloc, if __rust_alloc can avoid the PLT.

@SimonSapin note that the cost is also reduced to zero in cases of LTO.

Alright, if people are confident that this is not an issue please carry on :)

However, at least for non-LTO the missing inlining does incur some cost, e.g. the MIN_ALIGN optimization in https://github.com/rust-lang/rust/blob/master/src/liballoc_jemalloc/lib.rs would be more effective if the alignment would be known at compile-time, which it typically is if inlining happens.

Drive-by-comment: Currently, the Alloc trait docs say "Note that as of the time of this writing allocators not intending to be global allocators can still panic in their implementation without violating memory safety."

Should there be a separate GlobalAllocator trait not for the reasons discussed in the RFC, but just to let an allocator author indicate that their allocator meets this additional guarantee and therefore is safe to use as a global allocator?

https://github.com/rust-lang/rust/pull/49669 adds a new GlobalAlloc trait for use with this attribute instead of Alloc. Tracking issue: https://github.com/rust-lang/rust/issues/49668.

I am certainly not very happy that we're making performance worse in the normal case. LTO is nice, but it's very expensive, so most programs are not compiled with LTO--it's a huge hammer for attacking this problem, and isn't actually necessary today. Moreover, relying excessively on LTO for performance runs counter to the goal of improving Rust's compilation speed for optimized builds. Allocation is a huge hotspot for many programs, and I don't think we should reduce allocation performance in a way that can only be recovered with compiler magic that people rarely enable.

@pythonesque Worse than what? As far as I can tell this indirection has existed since at least https://github.com/rust-lang/rust/pull/27400 in Rust 1.4.0, released in 2015.

I don't think we should reduce allocation performance in a way that can only be recovered with compiler magic that people rarely enable

I think what would help is if cargo had another build flag other than just --debug and --release, something like that --publish that you do when you are actually going to publish and distribute a binary to a larger audience than simply your development machine. In those cases, the extra build time for the final set up optimizations that should be turned on for this case like LTO (and I think I read somewhere the number of code gen units that is default also hurts optimizations a little?). If a build server is what publishes the binary, the extra time waiting for these optimizations for a published release is even less of a problem.

The way it is now, if you want LTO you have to enable it for all release builds, included "development" release builds you are just building and running to test our some performance intensive piece of the software.

The way it is now, if you want LTO you have to enable it for all release builds, included "development" release builds you are just building and running to test our some performance intensive piece of the software.

No. You can add a [profile.release] in your cargo.toml. And it will apply to release builds only.

On topic, it would be nice if one could choose the system allocator the same way. Something simple for the end user. Like "allocator = system" in the [target].

@Mazwak Right now the incantation is:

#[global_allocator] static A: std::alloc::System = std::alloc::System;

But the plan is to eventually make System the default (and the only one provided in the standard library), so adding a Cargo.toml config doesn’t seem useful.

Stabilization PR: https://github.com/rust-lang/rust/pull/51241 (finally!)

Oh I forgot to mention my ~ month-old RFC https://github.com/rust-lang/rfcs/pull/2492 that would subsume #![global_allocator]. Thankfully, #![global_allocator] can be desguared into it, but at the same time if the RFC was accepted it would be a bit silly to stabilize #![global_allocator] only to deprecate it soon after.

@Ericson2314 The #[global_allocator] attribute has already gone through the RFC process with an FCP to merge the RFC, then implementation in Nightly, then FCP in this tracking issue to stablize the feature, then a stabilization PR landed. It is now stable in Rust 1.28 which is currently in Beta and reaches the Stable channel next week.

At this point the existence of an alternative design proposal is not enough to justify an emergency revert in my opinion.

That's fine. I just wanted to not this in the proper place.

Was this page helpful?
0 / 5 - 0 ratings