Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 694adee

Browse files
committedJun 21, 2017
Auto merge of #42682 - alexcrichton:jobserver, r=michaelwoerister
Integrate jobserver support to parallel codegen This commit integrates the `jobserver` crate into the compiler. The crate was previously integrated in to Cargo as part of rust-lang/cargo#4110. The purpose here is to two-fold: * Primarily the compiler can cooperate with Cargo on parallelism. When you run `cargo build -j4` then this'll make sure that the entire build process between Cargo/rustc won't use more than 4 cores, whereas today you'd get 4 rustc instances which may all try to spawn lots of threads. * Secondarily rustc/Cargo can now integrate with a foreign GNU `make` jobserver. This means that if you call cargo/rustc from `make` or another jobserver-compatible implementation it'll use foreign parallelism settings instead of creating new ones locally. As the number of parallel codegen instances in the compiler continues to grow over time with the advent of incremental compilation it's expected that this'll become more of a problem, so this is intended to nip concurrent concerns in the bud by having all the tools to cooperate! Note that while rustc has support for itself creating a jobserver it's far more likely that rustc will always use the jobserver configured by Cargo. Cargo today will now set a jobserver unconditionally for rustc to use.
2 parents 622e7e6 + 201f069 commit 694adee

File tree

19 files changed

+514
-311
lines changed

19 files changed

+514
-311
lines changed
 

‎src/Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src/libcore/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ path = "lib.rs"
99
test = false
1010
bench = false
1111

12+
[dev-dependencies]
13+
rand = { path = "../librand" }
14+
1215
[[test]]
1316
name = "coretests"
1417
path = "../libcore/tests/lib.rs"

‎src/librustc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ crate-type = ["dylib"]
1212
arena = { path = "../libarena" }
1313
fmt_macros = { path = "../libfmt_macros" }
1414
graphviz = { path = "../libgraphviz" }
15+
jobserver = "0.1"
1516
log = "0.3"
1617
owning_ref = "0.3.3"
1718
rustc_back = { path = "../librustc_back" }

‎src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ extern crate rustc_errors as errors;
6161
#[macro_use] extern crate syntax;
6262
extern crate syntax_pos;
6363
#[macro_use] #[no_link] extern crate rustc_bitflags;
64+
extern crate jobserver;
6465

6566
extern crate serialize as rustc_serialize; // used by deriving
6667

‎src/librustc/session/mod.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ use syntax_pos::{Span, MultiSpan};
3838
use rustc_back::{LinkerFlavor, PanicStrategy};
3939
use rustc_back::target::Target;
4040
use rustc_data_structures::flock;
41+
use jobserver::Client;
4142

42-
use std::path::{Path, PathBuf};
4343
use std::cell::{self, Cell, RefCell};
4444
use std::collections::HashMap;
4545
use std::env;
46+
use std::fmt;
4647
use std::io::Write;
48+
use std::path::{Path, PathBuf};
4749
use std::rc::Rc;
48-
use std::fmt;
50+
use std::sync::{Once, ONCE_INIT};
4951
use std::time::Duration;
5052

5153
mod code_stats;
@@ -134,6 +136,10 @@ pub struct Session {
134136
pub print_fuel_crate: Option<String>,
135137
/// Always set to zero and incremented so that we can print fuel expended by a crate.
136138
pub print_fuel: Cell<u64>,
139+
140+
/// Loaded up early on in the initialization of this `Session` to avoid
141+
/// false positives about a job server in our environment.
142+
pub jobserver_from_env: Option<Client>,
137143
}
138144

139145
pub struct PerfStats {
@@ -697,6 +703,24 @@ pub fn build_session_(sopts: config::Options,
697703
print_fuel_crate: print_fuel_crate,
698704
print_fuel: print_fuel,
699705
out_of_fuel: Cell::new(false),
706+
707+
// Note that this is unsafe because it may misinterpret file descriptors
708+
// on Unix as jobserver file descriptors. We hopefully execute this near
709+
// the beginning of the process though to ensure we don't get false
710+
// positives, or in other words we try to execute this before we open
711+
// any file descriptors ourselves.
712+
//
713+
// Also note that we stick this in a global because there could be
714+
// multiple `Session` instances in this process, and the jobserver is
715+
// per-process.
716+
jobserver_from_env: unsafe {
717+
static mut GLOBAL_JOBSERVER: *mut Option<Client> = 0 as *mut _;
718+
static INIT: Once = ONCE_INIT;
719+
INIT.call_once(|| {
720+
GLOBAL_JOBSERVER = Box::into_raw(Box::new(Client::from_env()));
721+
});
722+
(*GLOBAL_JOBSERVER).clone()
723+
},
700724
};
701725

702726
sess

‎src/librustc_trans/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ crate-type = ["dylib"]
1010
test = false
1111

1212
[dependencies]
13+
crossbeam = "0.2"
1314
flate2 = "0.2"
15+
jobserver = "0.1.5"
1416
log = "0.3"
1517
owning_ref = "0.3.3"
1618
rustc = { path = "../librustc" }

‎src/librustc_trans/back/link.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,34 +329,38 @@ pub fn filename_for_input(sess: &Session,
329329
}
330330

331331
pub fn each_linked_rlib(sess: &Session,
332-
f: &mut FnMut(CrateNum, &Path)) {
332+
f: &mut FnMut(CrateNum, &Path)) -> Result<(), String> {
333333
let crates = sess.cstore.used_crates(LinkagePreference::RequireStatic).into_iter();
334334
let fmts = sess.dependency_formats.borrow();
335335
let fmts = fmts.get(&config::CrateTypeExecutable)
336336
.or_else(|| fmts.get(&config::CrateTypeStaticlib))
337337
.or_else(|| fmts.get(&config::CrateTypeCdylib))
338338
.or_else(|| fmts.get(&config::CrateTypeProcMacro));
339-
let fmts = fmts.unwrap_or_else(|| {
340-
bug!("could not find formats for rlibs");
341-
});
339+
let fmts = match fmts {
340+
Some(f) => f,
341+
None => return Err(format!("could not find formats for rlibs"))
342+
};
342343
for (cnum, path) in crates {
343-
match fmts[cnum.as_usize() - 1] {
344-
Linkage::NotLinked | Linkage::IncludedFromDylib => continue,
345-
_ => {}
344+
match fmts.get(cnum.as_usize() - 1) {
345+
Some(&Linkage::NotLinked) |
346+
Some(&Linkage::IncludedFromDylib) => continue,
347+
Some(_) => {}
348+
None => return Err(format!("could not find formats for rlibs"))
346349
}
347350
let name = sess.cstore.crate_name(cnum).clone();
348351
let path = match path {
349352
LibSource::Some(p) => p,
350353
LibSource::MetadataOnly => {
351-
sess.fatal(&format!("could not find rlib for: `{}`, found rmeta (metadata) file",
352-
name));
354+
return Err(format!("could not find rlib for: `{}`, found rmeta (metadata) file",
355+
name))
353356
}
354357
LibSource::None => {
355-
sess.fatal(&format!("could not find rlib for: `{}`", name));
358+
return Err(format!("could not find rlib for: `{}`", name))
356359
}
357360
};
358361
f(cnum, &path);
359362
}
363+
Ok(())
360364
}
361365

362366
fn out_filename(sess: &Session,
@@ -669,7 +673,7 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
669673
let mut ab = link_rlib(sess, None, objects, out_filename, tempdir);
670674
let mut all_native_libs = vec![];
671675

672-
each_linked_rlib(sess, &mut |cnum, path| {
676+
let res = each_linked_rlib(sess, &mut |cnum, path| {
673677
let name = sess.cstore.crate_name(cnum);
674678
let native_libs = sess.cstore.native_libraries(cnum);
675679

@@ -694,6 +698,9 @@ fn link_staticlib(sess: &Session, objects: &[PathBuf], out_filename: &Path,
694698

695699
all_native_libs.extend(sess.cstore.native_libraries(cnum));
696700
});
701+
if let Err(e) = res {
702+
sess.fatal(&e);
703+
}
697704

698705
ab.update_symbols();
699706
ab.build();

‎src/librustc_trans/back/lto.rs

Lines changed: 50 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@
1010

1111
use back::link;
1212
use back::write;
13-
use back::symbol_export::{self, ExportedSymbols};
14-
use rustc::session::{self, config};
13+
use back::symbol_export;
14+
use rustc::session::config;
15+
use errors::FatalError;
1516
use llvm;
1617
use llvm::archive_ro::ArchiveRO;
1718
use llvm::{ModuleRef, TargetMachineRef, True, False};
1819
use rustc::util::common::time;
1920
use rustc::util::common::path2cstr;
2021
use rustc::hir::def_id::LOCAL_CRATE;
21-
use back::write::{ModuleConfig, with_llvm_pmb};
22+
use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
2223

2324
use libc;
2425
use flate2::read::ZlibDecoder;
@@ -39,30 +40,31 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
3940
}
4041
}
4142

42-
pub fn run(sess: &session::Session,
43+
pub fn run(cgcx: &CodegenContext,
4344
llmod: ModuleRef,
4445
tm: TargetMachineRef,
45-
exported_symbols: &ExportedSymbols,
4646
config: &ModuleConfig,
47-
temp_no_opt_bc_filename: &Path) {
48-
if sess.opts.cg.prefer_dynamic {
49-
sess.struct_err("cannot prefer dynamic linking when performing LTO")
47+
temp_no_opt_bc_filename: &Path) -> Result<(), FatalError> {
48+
let handler = cgcx.handler;
49+
if cgcx.opts.cg.prefer_dynamic {
50+
handler.struct_err("cannot prefer dynamic linking when performing LTO")
5051
.note("only 'staticlib', 'bin', and 'cdylib' outputs are \
5152
supported with LTO")
5253
.emit();
53-
sess.abort_if_errors();
54+
return Err(FatalError)
5455
}
5556

5657
// Make sure we actually can run LTO
57-
for crate_type in sess.crate_types.borrow().iter() {
58+
for crate_type in cgcx.crate_types.iter() {
5859
if !crate_type_allows_lto(*crate_type) {
59-
sess.fatal("lto can only be run for executables, cdylibs and \
60-
static library outputs");
60+
let e = handler.fatal("lto can only be run for executables, cdylibs and \
61+
static library outputs");
62+
return Err(e)
6163
}
6264
}
6365

6466
let export_threshold =
65-
symbol_export::crates_export_threshold(&sess.crate_types.borrow());
67+
symbol_export::crates_export_threshold(&cgcx.crate_types);
6668

6769
let symbol_filter = &|&(ref name, level): &(String, _)| {
6870
if symbol_export::is_below_threshold(level, export_threshold) {
@@ -74,7 +76,7 @@ pub fn run(sess: &session::Session,
7476
}
7577
};
7678

77-
let mut symbol_white_list: Vec<CString> = exported_symbols
79+
let mut symbol_white_list: Vec<CString> = cgcx.exported_symbols
7880
.exported_symbols(LOCAL_CRATE)
7981
.iter()
8082
.filter_map(symbol_filter)
@@ -83,16 +85,11 @@ pub fn run(sess: &session::Session,
8385
// For each of our upstream dependencies, find the corresponding rlib and
8486
// load the bitcode from the archive. Then merge it into the current LLVM
8587
// module that we've got.
86-
link::each_linked_rlib(sess, &mut |cnum, path| {
87-
// `#![no_builtins]` crates don't participate in LTO.
88-
if sess.cstore.is_no_builtins(cnum) {
89-
return;
90-
}
91-
88+
for &(cnum, ref path) in cgcx.each_linked_rlib_for_lto.iter() {
9289
symbol_white_list.extend(
93-
exported_symbols.exported_symbols(cnum)
94-
.iter()
95-
.filter_map(symbol_filter));
90+
cgcx.exported_symbols.exported_symbols(cnum)
91+
.iter()
92+
.filter_map(symbol_filter));
9693

9794
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
9895
let bytecodes = archive.iter().filter_map(|child| {
@@ -102,7 +99,7 @@ pub fn run(sess: &session::Session,
10299
let bc_encoded = data.data();
103100

104101
let bc_decoded = if is_versioned_bytecode_format(bc_encoded) {
105-
time(sess.time_passes(), &format!("decode {}", name), || {
102+
time(cgcx.time_passes, &format!("decode {}", name), || {
106103
// Read the version
107104
let version = extract_bytecode_format_version(bc_encoded);
108105

@@ -117,44 +114,49 @@ pub fn run(sess: &session::Session,
117114
let res = ZlibDecoder::new(compressed_data)
118115
.read_to_end(&mut inflated);
119116
if res.is_err() {
120-
sess.fatal(&format!("failed to decompress bc of `{}`",
121-
name))
117+
let msg = format!("failed to decompress bc of `{}`",
118+
name);
119+
Err(handler.fatal(&msg))
120+
} else {
121+
Ok(inflated)
122122
}
123-
inflated
124123
} else {
125-
sess.fatal(&format!("Unsupported bytecode format version {}",
126-
version))
124+
Err(handler.fatal(&format!("Unsupported bytecode format version {}",
125+
version)))
127126
}
128-
})
127+
})?
129128
} else {
130-
time(sess.time_passes(), &format!("decode {}", name), || {
129+
time(cgcx.time_passes, &format!("decode {}", name), || {
131130
// the object must be in the old, pre-versioning format, so
132131
// simply inflate everything and let LLVM decide if it can
133132
// make sense of it
134133
let mut inflated = Vec::new();
135134
let res = ZlibDecoder::new(bc_encoded)
136135
.read_to_end(&mut inflated);
137136
if res.is_err() {
138-
sess.fatal(&format!("failed to decompress bc of `{}`",
139-
name))
137+
let msg = format!("failed to decompress bc of `{}`",
138+
name);
139+
Err(handler.fatal(&msg))
140+
} else {
141+
Ok(inflated)
140142
}
141-
inflated
142-
})
143+
})?
143144
};
144145

145146
let ptr = bc_decoded.as_ptr();
146147
debug!("linking {}", name);
147-
time(sess.time_passes(), &format!("ll link {}", name), || unsafe {
148-
if !llvm::LLVMRustLinkInExternalBitcode(llmod,
149-
ptr as *const libc::c_char,
150-
bc_decoded.len() as libc::size_t) {
151-
write::llvm_err(sess.diagnostic(),
152-
format!("failed to load bc of `{}`",
153-
name));
148+
time(cgcx.time_passes, &format!("ll link {}", name), || unsafe {
149+
if llvm::LLVMRustLinkInExternalBitcode(llmod,
150+
ptr as *const libc::c_char,
151+
bc_decoded.len() as libc::size_t) {
152+
Ok(())
153+
} else {
154+
let msg = format!("failed to load bc of `{}`", name);
155+
Err(write::llvm_err(handler, msg))
154156
}
155-
});
157+
})?;
156158
}
157-
});
159+
}
158160

159161
// Internalize everything but the exported symbols of the current module
160162
let arr: Vec<*const libc::c_char> = symbol_white_list.iter()
@@ -167,13 +169,13 @@ pub fn run(sess: &session::Session,
167169
arr.len() as libc::size_t);
168170
}
169171

170-
if sess.no_landing_pads() {
172+
if cgcx.no_landing_pads {
171173
unsafe {
172174
llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
173175
}
174176
}
175177

176-
if sess.opts.cg.save_temps {
178+
if cgcx.opts.cg.save_temps {
177179
let cstr = path2cstr(temp_no_opt_bc_filename);
178180
unsafe {
179181
llvm::LLVMWriteBitcodeToFile(llmod, cstr.as_ptr());
@@ -203,12 +205,13 @@ pub fn run(sess: &session::Session,
203205
assert!(!pass.is_null());
204206
llvm::LLVMRustAddPass(pm, pass);
205207

206-
time(sess.time_passes(), "LTO passes", ||
208+
time(cgcx.time_passes, "LTO passes", ||
207209
llvm::LLVMRunPassManager(pm, llmod));
208210

209211
llvm::LLVMDisposePassManager(pm);
210212
}
211213
debug!("lto done");
214+
Ok(())
212215
}
213216

214217
fn is_versioned_bytecode_format(bc: &[u8]) -> bool {

‎src/librustc_trans/back/write.rs

Lines changed: 344 additions & 232 deletions
Large diffs are not rendered by default.

‎src/librustc_trans/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc::dep_graph::WorkProduct;
4040
use syntax_pos::symbol::Symbol;
4141

4242
extern crate flate2;
43+
extern crate crossbeam;
4344
extern crate libc;
4445
extern crate owning_ref;
4546
#[macro_use] extern crate rustc;
@@ -52,6 +53,7 @@ extern crate rustc_const_math;
5253
#[macro_use]
5354
#[no_link]
5455
extern crate rustc_bitflags;
56+
extern crate jobserver;
5557

5658
#[macro_use] extern crate log;
5759
#[macro_use] extern crate syntax;

‎src/test/compile-fail-fulldeps/derive-no-std-not-supported.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#![no_std]
1212

13-
extern crate rand;
1413
extern crate serialize as rustc_serialize;
1514

1615
#[derive(RustcEncodable)] //~ ERROR this trait cannot be derived

‎src/test/compile-fail/asm-src-loc-codegen-units.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10-
//
10+
1111
// WONTFIX(#20184) Needs landing pads (not present in stage1) or the compiler hangs.
1212
// ignore-stage1
1313
// compile-flags: -C codegen-units=2
14-
// error-pattern: build without -C codegen-units for more exact errors
1514
// ignore-emscripten
1615

1716
#![feature(asm)]
1817

1918
fn main() {
2019
unsafe {
21-
asm!("nowayisthisavalidinstruction");
20+
asm!("nowayisthisavalidinstruction"); //~ ERROR instruction
2221
}
2322
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub trait Foo {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn foo() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
pub fn foo() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.

‎src/test/compile-fail/issue-36881.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(rand)]
11+
// aux-build:issue-36881-aux.rs
1212

1313
fn main() {
14-
extern crate rand;
15-
use rand::Rng; //~ ERROR unresolved import
14+
extern crate issue_36881_aux;
15+
use issue_36881_aux::Foo; //~ ERROR unresolved import
1616
}

‎src/test/compile-fail/lint-unused-extern-crate.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,34 @@
99
// except according to those terms.
1010

1111
// aux-build:lint_unused_extern_crate.rs
12+
// aux-build:lint_unused_extern_crate2.rs
13+
// aux-build:lint_unused_extern_crate3.rs
14+
// aux-build:lint_unused_extern_crate4.rs
1215

1316
#![deny(unused_extern_crates)]
1417
#![allow(unused_variables)]
1518
#![allow(deprecated)]
16-
#![feature(alloc)]
17-
#![feature(libc)]
18-
#![feature(rand)]
1919

20-
extern crate libc; //~ ERROR: unused extern crate
20+
extern crate lint_unused_extern_crate4; //~ ERROR: unused extern crate
2121

22-
extern crate alloc as collecs; // no error, it is used
22+
extern crate lint_unused_extern_crate3; // no error, it is used
2323

24-
extern crate rand; // no error, the use marks it as used
25-
// even if imported objects aren't used
24+
extern crate lint_unused_extern_crate2; // no error, the use marks it as used
25+
// even if imported objects aren't used
2626

2727
extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
2828

2929
#[allow(unused_imports)]
30-
use rand::isaac::IsaacRng;
30+
use lint_unused_extern_crate2::foo as bar;
3131

3232
use other::*;
3333

3434
mod foo {
35-
// Test that this is unused even though an earler `extern crate rand` is used.
36-
extern crate rand; //~ ERROR unused extern crate
35+
// Test that this is unused even though an earler `extern crate` is used.
36+
extern crate lint_unused_extern_crate2; //~ ERROR unused extern crate
3737
}
3838

3939
fn main() {
40-
let x: collecs::vec::Vec<usize> = Vec::new();
40+
lint_unused_extern_crate3::foo();
4141
let y = foo();
4242
}

‎src/test/run-pass/auxiliary/allocator-dummy.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010

1111
// no-prefer-dynamic
1212

13-
#![feature(allocator, core_intrinsics)]
13+
#![feature(allocator, core_intrinsics, panic_unwind)]
1414
#![allocator]
1515
#![crate_type = "rlib"]
1616
#![no_std]
1717

18+
extern crate unwind;
19+
1820
pub static mut HITS: usize = 0;
1921

2022
type size_t = usize;

0 commit comments

Comments
 (0)
Please sign in to comment.