Remove libnative
With runtime removal complete, there's nothing left of libnative. This commit removes it. Fixes #18687 [breaking-change]
This commit is contained in:
parent
ad022b1a1b
commit
3ee916e50b
@ -49,7 +49,7 @@
|
||||
# automatically generated for all stage/host/target combinations.
|
||||
################################################################################
|
||||
|
||||
TARGET_CRATES := libc std green native flate arena term \
|
||||
TARGET_CRATES := libc std green flate arena term \
|
||||
serialize sync getopts collections test time rand \
|
||||
log regex graphviz core rbml alloc rustrt \
|
||||
unicode
|
||||
@ -67,7 +67,6 @@ DEPS_std := core libc rand alloc collections rustrt sync unicode \
|
||||
native:rust_builtin native:backtrace
|
||||
DEPS_graphviz := std
|
||||
DEPS_green := std native:context_switch
|
||||
DEPS_native := std
|
||||
DEPS_syntax := std term serialize log fmt_macros arena libc
|
||||
DEPS_rustc_trans := rustc rustc_back rustc_llvm libc
|
||||
DEPS_rustc := syntax flate arena serialize getopts rbml \
|
||||
@ -95,9 +94,9 @@ DEPS_regex := std
|
||||
DEPS_regex_macros = rustc syntax std regex
|
||||
DEPS_fmt_macros = std
|
||||
|
||||
TOOL_DEPS_compiletest := test getopts native
|
||||
TOOL_DEPS_rustdoc := rustdoc native
|
||||
TOOL_DEPS_rustc := rustc_trans native
|
||||
TOOL_DEPS_compiletest := test getopts
|
||||
TOOL_DEPS_rustdoc := rustdoc
|
||||
TOOL_DEPS_rustc := rustc_trans
|
||||
TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
|
||||
TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
|
||||
TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
|
||||
|
@ -8,6 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![no_start]
|
||||
|
||||
#[cfg(rustdoc)]
|
||||
extern crate "rustdoc" as this;
|
||||
|
||||
|
@ -1,116 +0,0 @@
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc::{c_char, c_int};
|
||||
use libc;
|
||||
use std::mem;
|
||||
use std::ptr::{null, null_mut};
|
||||
use std::rt::rtio;
|
||||
use std::rt::rtio::IoError;
|
||||
|
||||
use super::net;
|
||||
|
||||
pub struct GetAddrInfoRequest;
|
||||
|
||||
impl GetAddrInfoRequest {
|
||||
pub fn run(host: Option<&str>, servname: Option<&str>,
|
||||
hint: Option<rtio::AddrinfoHint>)
|
||||
-> Result<Vec<rtio::AddrinfoInfo>, IoError>
|
||||
{
|
||||
assert!(host.is_some() || servname.is_some());
|
||||
|
||||
let c_host = host.map(|x| x.to_c_str());
|
||||
let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
|
||||
let c_serv = servname.map(|x| x.to_c_str());
|
||||
let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
|
||||
|
||||
let hint = hint.map(|hint| {
|
||||
libc::addrinfo {
|
||||
ai_flags: hint.flags as c_int,
|
||||
ai_family: hint.family as c_int,
|
||||
ai_socktype: 0,
|
||||
ai_protocol: 0,
|
||||
ai_addrlen: 0,
|
||||
ai_canonname: null_mut(),
|
||||
ai_addr: null_mut(),
|
||||
ai_next: null_mut()
|
||||
}
|
||||
});
|
||||
|
||||
let hint_ptr = hint.as_ref().map_or(null(), |x| {
|
||||
x as *const libc::addrinfo
|
||||
});
|
||||
let mut res = null_mut();
|
||||
|
||||
// Make the call
|
||||
let s = unsafe {
|
||||
getaddrinfo(c_host, c_serv, hint_ptr, &mut res)
|
||||
};
|
||||
|
||||
// Error?
|
||||
if s != 0 {
|
||||
return Err(get_error(s));
|
||||
}
|
||||
|
||||
// Collect all the results we found
|
||||
let mut addrs = Vec::new();
|
||||
let mut rp = res;
|
||||
while rp.is_not_null() {
|
||||
unsafe {
|
||||
let addr = match net::sockaddr_to_addr(mem::transmute((*rp).ai_addr),
|
||||
(*rp).ai_addrlen as uint) {
|
||||
Ok(a) => a,
|
||||
Err(e) => return Err(e)
|
||||
};
|
||||
addrs.push(rtio::AddrinfoInfo {
|
||||
address: addr,
|
||||
family: (*rp).ai_family as uint,
|
||||
socktype: 0,
|
||||
protocol: 0,
|
||||
flags: (*rp).ai_flags as uint
|
||||
});
|
||||
|
||||
rp = (*rp).ai_next as *mut libc::addrinfo;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe { freeaddrinfo(res); }
|
||||
|
||||
Ok(addrs)
|
||||
}
|
||||
}
|
||||
|
||||
extern "system" {
|
||||
fn getaddrinfo(node: *const c_char, service: *const c_char,
|
||||
hints: *const libc::addrinfo,
|
||||
res: *mut *mut libc::addrinfo) -> c_int;
|
||||
fn freeaddrinfo(res: *mut libc::addrinfo);
|
||||
#[cfg(not(windows))]
|
||||
fn gai_strerror(errcode: c_int) -> *const c_char;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_error(_: c_int) -> IoError {
|
||||
net::last_error()
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn get_error(s: c_int) -> IoError {
|
||||
use std::c_str::CString;
|
||||
|
||||
let err_str = unsafe {
|
||||
CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
|
||||
};
|
||||
IoError {
|
||||
code: s as uint,
|
||||
extra: 0,
|
||||
detail: Some(err_str),
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,155 +0,0 @@
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! The native I/O and threading crate
|
||||
//!
|
||||
//! This crate contains an implementation of 1:1 scheduling for a "native"
|
||||
//! runtime. In addition, all I/O provided by this crate is the thread blocking
|
||||
//! version of I/O.
|
||||
//!
|
||||
//! # Starting with libnative
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate native;
|
||||
//!
|
||||
//! #[start]
|
||||
//! fn start(argc: int, argv: *const *const u8) -> int {
|
||||
//! native::start(argc, argv, main)
|
||||
//! }
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // this code is running on the main OS thread
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! # Force spawning a native task
|
||||
//!
|
||||
//! ```rust
|
||||
//! extern crate native;
|
||||
//!
|
||||
//! use std::task::TaskBuilder;
|
||||
//! use native::NativeTaskBuilder;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! // We're not sure whether this main function is run in 1:1 or M:N mode.
|
||||
//!
|
||||
//! TaskBuilder::new().native().spawn(proc() {
|
||||
//! // this code is guaranteed to be run on a native thread
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
#![crate_name = "native"]
|
||||
#![experimental]
|
||||
#![license = "MIT/ASL2"]
|
||||
#![crate_type = "rlib"]
|
||||
#![crate_type = "dylib"]
|
||||
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://doc.rust-lang.org/nightly/")]
|
||||
|
||||
#![deny(unused_results, unused_must_use)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(unknown_features)]
|
||||
#![feature(default_type_params, lang_items, slicing_syntax, globs)]
|
||||
|
||||
// NB this crate explicitly does *not* allow glob imports, please seriously
|
||||
// consider whether they're needed before adding that feature here (the
|
||||
// answer is that you don't need them)
|
||||
#![feature(macro_rules, unsafe_destructor, default_type_params)]
|
||||
|
||||
extern crate alloc;
|
||||
extern crate libc;
|
||||
|
||||
use std::os;
|
||||
use std::rt;
|
||||
use std::str;
|
||||
|
||||
pub use task::NativeTaskBuilder;
|
||||
|
||||
pub mod task;
|
||||
|
||||
#[cfg(any(windows, android))]
|
||||
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
|
||||
#[cfg(all(unix, not(android)))]
|
||||
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
||||
|
||||
#[lang = "start"]
|
||||
#[cfg(not(test))]
|
||||
pub fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
|
||||
use std::mem;
|
||||
start(argc, argv, proc() {
|
||||
let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
|
||||
main();
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes the given procedure after initializing the runtime with the given
|
||||
/// argc/argv.
|
||||
///
|
||||
/// This procedure is guaranteed to run on the thread calling this function, but
|
||||
/// the stack bounds for this rust task will *not* be set. Care must be taken
|
||||
/// for this function to not overflow its stack.
|
||||
///
|
||||
/// This function will only return once *all* native threads in the system have
|
||||
/// exited.
|
||||
pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
|
||||
let something_around_the_top_of_the_stack = 1;
|
||||
let addr = &something_around_the_top_of_the_stack as *const int;
|
||||
let my_stack_top = addr as uint;
|
||||
|
||||
// FIXME #11359 we just assume that this thread has a stack of a
|
||||
// certain size, and estimate that there's at most 20KB of stack
|
||||
// frames above our current position.
|
||||
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
|
||||
|
||||
// When using libgreen, one of the first things that we do is to turn off
|
||||
// the SIGPIPE signal (set it to ignore). By default, some platforms will
|
||||
// send a *signal* when a EPIPE error would otherwise be delivered. This
|
||||
// runtime doesn't install a SIGPIPE handler, causing it to kill the
|
||||
// program, which isn't exactly what we want!
|
||||
//
|
||||
// Hence, we set SIGPIPE to ignore when the program starts up in order to
|
||||
// prevent this problem.
|
||||
#[cfg(windows)] fn ignore_sigpipe() {}
|
||||
#[cfg(unix)] fn ignore_sigpipe() {
|
||||
use libc;
|
||||
use libc::funcs::posix01::signal::signal;
|
||||
unsafe {
|
||||
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
|
||||
}
|
||||
}
|
||||
ignore_sigpipe();
|
||||
|
||||
rt::init(argc, argv);
|
||||
let mut exit_code = None;
|
||||
let mut main = Some(main);
|
||||
let mut task = task::new((my_stack_bottom, my_stack_top),
|
||||
rt::thread::main_guard_page());
|
||||
task.name = Some(str::Slice("<main>"));
|
||||
drop(task.run(|| {
|
||||
unsafe {
|
||||
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
|
||||
}
|
||||
exit_code = Some(run(main.take().unwrap()));
|
||||
}).destroy());
|
||||
unsafe { rt::cleanup(); }
|
||||
// If the exit code wasn't set, then the task block must have panicked.
|
||||
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
|
||||
}
|
||||
|
||||
/// Executes a procedure on the current thread in a Rust task context.
|
||||
///
|
||||
/// This function has all of the same details as `start` except for a different
|
||||
/// number of arguments.
|
||||
pub fn run(main: proc()) -> int {
|
||||
main();
|
||||
os::get_exit_status()
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Tasks implemented on top of OS threads
|
||||
//!
|
||||
//! This module contains the implementation of the 1:1 threading module required
|
||||
//! by rust tasks. This implements the necessary API traits laid out by std::rt
|
||||
//! in order to spawn new tasks and deschedule the current task.
|
||||
|
||||
use std::any::Any;
|
||||
use std::mem;
|
||||
use std::rt::bookkeeping;
|
||||
use std::rt::local::Local;
|
||||
use std::rt::mutex::NativeMutex;
|
||||
use std::rt::stack;
|
||||
use std::rt::task::{Task, BlockedTask, TaskOpts};
|
||||
use std::rt::thread::Thread;
|
||||
use std::rt;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::rt::local::Local;
|
||||
use std::rt::task::{Task, TaskOpts};
|
||||
use std::task;
|
||||
use std::task::{TaskBuilder, Spawner};
|
||||
|
||||
use super::{Ops, NativeTaskBuilder, NativeSpawner};
|
||||
|
||||
#[test]
|
||||
fn smoke() {
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
tx.send(());
|
||||
});
|
||||
rx.recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_panic() {
|
||||
let (tx, rx) = channel::<()>();
|
||||
spawn(proc() {
|
||||
let _tx = tx;
|
||||
panic!()
|
||||
});
|
||||
assert_eq!(rx.recv_opt(), Err(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_opts() {
|
||||
let mut opts = TaskOpts::new();
|
||||
opts.name = Some("test".into_maybe_owned());
|
||||
opts.stack_size = Some(20 * 4096);
|
||||
let (tx, rx) = channel();
|
||||
opts.on_exit = Some(proc(r) tx.send(r));
|
||||
NativeSpawner.spawn(opts, proc() {});
|
||||
assert!(rx.recv().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn smoke_opts_panic() {
|
||||
let mut opts = TaskOpts::new();
|
||||
let (tx, rx) = channel();
|
||||
opts.on_exit = Some(proc(r) tx.send(r));
|
||||
NativeSpawner.spawn(opts, proc() { panic!() });
|
||||
assert!(rx.recv().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn yield_test() {
|
||||
let (tx, rx) = channel();
|
||||
spawn(proc() {
|
||||
for _ in range(0u, 10) { task::deschedule(); }
|
||||
tx.send(());
|
||||
});
|
||||
rx.recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_children() {
|
||||
let (tx1, rx) = channel();
|
||||
spawn(proc() {
|
||||
let (tx2, rx) = channel();
|
||||
spawn(proc() {
|
||||
let (tx3, rx) = channel();
|
||||
spawn(proc() {
|
||||
tx3.send(());
|
||||
});
|
||||
rx.recv();
|
||||
tx2.send(());
|
||||
});
|
||||
rx.recv();
|
||||
tx1.send(());
|
||||
});
|
||||
rx.recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_inherits() {
|
||||
let (tx, rx) = channel();
|
||||
TaskBuilder::new().spawner(NativeSpawner).spawn(proc() {
|
||||
spawn(proc() {
|
||||
let mut task: Box<Task> = Local::take();
|
||||
match task.maybe_take_runtime::<Ops>() {
|
||||
Some(ops) => {
|
||||
task.put_runtime(ops);
|
||||
}
|
||||
None => panic!(),
|
||||
}
|
||||
Local::put(task);
|
||||
tx.send(());
|
||||
});
|
||||
});
|
||||
rx.recv();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_native_builder() {
|
||||
let res = TaskBuilder::new().native().try(proc() {
|
||||
"Success!".to_string()
|
||||
});
|
||||
assert_eq!(res.ok().unwrap(), "Success!".to_string());
|
||||
}
|
||||
}
|
@ -198,10 +198,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
*sess.features.borrow_mut() = features;
|
||||
});
|
||||
|
||||
let any_exe = sess.crate_types.borrow().iter().any(|ty| {
|
||||
*ty == config::CrateTypeExecutable
|
||||
});
|
||||
|
||||
// strip before expansion to allow macros to depend on
|
||||
// configuration variables e.g/ in
|
||||
//
|
||||
@ -215,8 +211,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
|
||||
|
||||
krate = time(time_passes, "crate injection", krate, |krate|
|
||||
syntax::std_inject::maybe_inject_crates_ref(krate,
|
||||
sess.opts.alt_std_name.clone(),
|
||||
any_exe));
|
||||
sess.opts.alt_std_name.clone()));
|
||||
|
||||
let mut addl_plugins = Some(addl_plugins);
|
||||
let Plugins { macros, registrars }
|
||||
|
@ -248,9 +248,7 @@
|
||||
|
||||
#[path = "sys/common/mod.rs"] mod sys_common;
|
||||
|
||||
// FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
|
||||
// but name resolution doesn't work without it being pub.
|
||||
pub mod rt;
|
||||
mod rt;
|
||||
mod failure;
|
||||
|
||||
// A curious inner-module that's not exported that contains the binding
|
||||
|
@ -58,6 +58,7 @@
|
||||
|
||||
use failure;
|
||||
use rustrt;
|
||||
use startup;
|
||||
|
||||
// Reexport some of our utilities which are expected by other crates.
|
||||
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
|
||||
@ -86,6 +87,81 @@ pub fn init(argc: int, argv: *const *const u8) {
|
||||
unsafe { unwind::register(failure::on_fail); }
|
||||
}
|
||||
|
||||
#[cfg(any(windows, android))]
|
||||
static OS_DEFAULT_STACK_ESTIMATE: uint = 1 << 20;
|
||||
#[cfg(all(unix, not(android)))]
|
||||
static OS_DEFAULT_STACK_ESTIMATE: uint = 2 * (1 << 20);
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "start"]
|
||||
fn lang_start(main: *const u8, argc: int, argv: *const *const u8) -> int {
|
||||
use std::mem;
|
||||
start(argc, argv, proc() {
|
||||
let main: extern "Rust" fn() = unsafe { mem::transmute(main) };
|
||||
main();
|
||||
})
|
||||
}
|
||||
|
||||
/// Executes the given procedure after initializing the runtime with the given
|
||||
/// argc/argv.
|
||||
///
|
||||
/// This procedure is guaranteed to run on the thread calling this function, but
|
||||
/// the stack bounds for this rust task will *not* be set. Care must be taken
|
||||
/// for this function to not overflow its stack.
|
||||
///
|
||||
/// This function will only return once *all* native threads in the system have
|
||||
/// exited.
|
||||
pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int {
|
||||
use prelude::*;
|
||||
use rt;
|
||||
use rustrt::task::Task;
|
||||
use str;
|
||||
|
||||
let something_around_the_top_of_the_stack = 1;
|
||||
let addr = &something_around_the_top_of_the_stack as *const int;
|
||||
let my_stack_top = addr as uint;
|
||||
|
||||
// FIXME #11359 we just assume that this thread has a stack of a
|
||||
// certain size, and estimate that there's at most 20KB of stack
|
||||
// frames above our current position.
|
||||
let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
|
||||
|
||||
// When using libgreen, one of the first things that we do is to turn off
|
||||
// the SIGPIPE signal (set it to ignore). By default, some platforms will
|
||||
// send a *signal* when a EPIPE error would otherwise be delivered. This
|
||||
// runtime doesn't install a SIGPIPE handler, causing it to kill the
|
||||
// program, which isn't exactly what we want!
|
||||
//
|
||||
// Hence, we set SIGPIPE to ignore when the program starts up in order to
|
||||
// prevent this problem.
|
||||
#[cfg(windows)] fn ignore_sigpipe() {}
|
||||
#[cfg(unix)] fn ignore_sigpipe() {
|
||||
use libc;
|
||||
use libc::funcs::posix01::signal::signal;
|
||||
unsafe {
|
||||
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != -1);
|
||||
}
|
||||
}
|
||||
ignore_sigpipe();
|
||||
|
||||
init(argc, argv);
|
||||
let mut exit_code = None;
|
||||
let mut main = Some(main);
|
||||
let mut task = task::new((my_stack_bottom, my_stack_top),
|
||||
rt::thread::main_guard_page());
|
||||
task.name = Some(str::Slice("<main>"));
|
||||
drop(task.run(|| {
|
||||
unsafe {
|
||||
rt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top);
|
||||
}
|
||||
(main.take().unwrap())();
|
||||
exit_code = Some(os::get_exit_status());
|
||||
}).destroy());
|
||||
unsafe { rt::cleanup(); }
|
||||
// If the exit code wasn't set, then the task block must have panicked.
|
||||
return exit_code.unwrap_or(rt::DEFAULT_ERROR_CODE);
|
||||
}
|
||||
|
||||
/// One-time runtime cleanup.
|
||||
///
|
||||
/// This function is unsafe because it performs no checks to ensure that the
|
||||
|
@ -22,10 +22,10 @@
|
||||
|
||||
use std::mem;
|
||||
|
||||
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>, any_exe: bool)
|
||||
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
|
||||
-> ast::Crate {
|
||||
if use_std(&krate) {
|
||||
inject_crates_ref(krate, alt_std_name, any_exe)
|
||||
inject_crates_ref(krate, alt_std_name)
|
||||
} else {
|
||||
krate
|
||||
}
|
||||
@ -43,17 +43,12 @@ fn use_std(krate: &ast::Crate) -> bool {
|
||||
!attr::contains_name(krate.attrs.as_slice(), "no_std")
|
||||
}
|
||||
|
||||
fn use_start(krate: &ast::Crate) -> bool {
|
||||
!attr::contains_name(krate.attrs.as_slice(), "no_start")
|
||||
}
|
||||
|
||||
fn no_prelude(attrs: &[ast::Attribute]) -> bool {
|
||||
attr::contains_name(attrs, "no_implicit_prelude")
|
||||
}
|
||||
|
||||
struct StandardLibraryInjector<'a> {
|
||||
alt_std_name: Option<String>,
|
||||
any_exe: bool,
|
||||
}
|
||||
|
||||
impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||
@ -80,23 +75,6 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
span: DUMMY_SP
|
||||
});
|
||||
|
||||
if use_start(&krate) && self.any_exe {
|
||||
let visible_rt_name = "rt";
|
||||
let actual_rt_name = "native";
|
||||
// Gensym the ident so it can't be named
|
||||
let visible_rt_name = token::gensym_ident(visible_rt_name);
|
||||
let actual_rt_name = token::intern_and_get_ident(actual_rt_name);
|
||||
|
||||
vis.push(ast::ViewItem {
|
||||
node: ast::ViewItemExternCrate(visible_rt_name,
|
||||
Some((actual_rt_name, ast::CookedStr)),
|
||||
ast::DUMMY_NODE_ID),
|
||||
attrs: Vec::new(),
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP
|
||||
});
|
||||
}
|
||||
|
||||
// `extern crate` must be precede `use` items
|
||||
mem::swap(&mut vis, &mut krate.module.view_items);
|
||||
krate.module.view_items.extend(vis.into_iter());
|
||||
@ -118,12 +96,9 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_crates_ref(krate: ast::Crate,
|
||||
alt_std_name: Option<String>,
|
||||
any_exe: bool) -> ast::Crate {
|
||||
fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
|
||||
let mut fold = StandardLibraryInjector {
|
||||
alt_std_name: alt_std_name,
|
||||
any_exe: any_exe,
|
||||
};
|
||||
fold.fold_crate(krate)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user