Change:
I have a project that overrides the global allocator in , and recently noticed that I can no longer link the test binary for my project with recent beta/nightly compilers. points to which certainly looks relevant. I reproduced the error using a slightly modified example from the global allocator documentation: If I move the allocator definition from to , I no longer have a problem. Is that the right thing to do? If so, do I need to do anything else to make sure my tests use the desired allocator? I tried this code: I expected to see this happen: Instead, this happened: searched nightlies: from nightly-2023-05-25 to nightly-2023-06-16 regressed nightly: nightly-2023-05-26 searched commit range: regressed commit: <details<summarybisected with <a href=''cargo-bisect-rustc</av0.6.6</summaryHost triple: x86_64-unknown-linux-gnu Reproduce with: </details modify labels: +regression-from-stable-to-beta -regression-untriaged
Adding the full linker error output here in case it's of interest.
I tried adding based on a brief look at the change that pointed to. It doesn't seem to make any difference, but that's why it's in my repro above.
I can reproduce this. and such are properly defined in the library rlib. It seems to be caused by the library order. Traditional linkers require symbols to have their uses in object files before their definition. So for circular dependencies and has to be used or libraries have to be mentioned multiple times. And indeed which doesn't have this restriction is entirely fine with this. I think registering a circular dependency between the defining crate of and liballoc (and every crate that depends on it) at would work. Edit: Reading the code it references closer, I think adding to would be enough to fix this. I can't work on this tomorrow, but unless someone else picks it up, I will work on this.
Finished some work early. fixes the issue.
thank you for the quick fix!
WG-prioritization assigning priority (). label -I-prioritize +P-high

Discussion:
use crate::traits::*; use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCodegen, ModuleKind}; <del> use rustc_ast::expand::allocator::AllocatorKind; </del> <ins> use rustc_ast::expand::allocator::{global_fn_name, AllocatorKind, ALLOCATOR_METHODS}; </ins> use rustc_attr as attr; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};

missing_weak_lang_items .iter() .map(|item| (format!("{prefix}{item}"), SymbolExportKind::Text)), <del> ) </del> <ins> ); if tcx.allocator_kind(()).is_some() { // At least one crate needs a global allocator. This crate may be placed // after the crate that defines it in the linker order, in which case some // linkers return an error. By adding the global allocator shim methods to // the linked_symbols list, linking the generated symbols.o will ensure that // circular dependencies involving the global allocator don't lead to linker // errors. linked_symbols.extend(ALLOCATOR_METHODS.iter().map(|method| { ( format!("{prefix}{}", global_fn_name(method.name).as_str()), SymbolExportKind::Text, ) })); } </ins> }); }

<ins> # ignore-cross-compile include ../tools.mk all: rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) my_lib.rs $(RUSTC) main.rs --test --extern my_lib=$(TMPDIR)/libmy_lib.rlib </ins>

<ins> #![crate_type = "bin"] fn main() { my_lib::do_something(); } </ins>

<ins> #![crate_type = "lib"] use std::alloc::System; #[global_allocator] static ALLOCATOR: System = System; pub fn do_something() { format!("allocating a string!"); } </ins>