1
Fork 0

auto merge of #14955 : alexcrichton/rust/rollup, r=alexcrichton

This commit is contained in:
bors 2014-06-17 02:51:53 +00:00
commit 09967665ea
64 changed files with 777 additions and 356 deletions

View file

@ -20,13 +20,13 @@ please do two things:
Pull requests will be treated as "review requests", and we will give Pull requests will be treated as "review requests", and we will give
feedback we expect to see corrected on feedback we expect to see corrected on
[style](https://github.com/mozilla/rust/wiki/Note-style-guide) and [style](https://github.com/rust-lang/rust/wiki/Note-style-guide) and
substance before pulling. Changes contributed via pull request should substance before pulling. Changes contributed via pull request should
focus on a single issue at a time, like any other. We will not accept focus on a single issue at a time, like any other. We will not accept
pull-requests that try to "sneak" unrelated changes in. pull-requests that try to "sneak" unrelated changes in.
Normally, all pull requests must include regression tests (see Normally, all pull requests must include regression tests (see
[Note-testsuite](https://github.com/mozilla/rust/wiki/Note-testsuite)) [Note-testsuite](https://github.com/rust-lang/rust/wiki/Note-testsuite))
that test your change. Occasionally, a change will be very difficult that test your change. Occasionally, a change will be very difficult
to test for. In those cases, please include a note in your commit to test for. In those cases, please include a note in your commit
message explaining why. message explaining why.
@ -41,4 +41,4 @@ example, if it's 2014, and you change a Rust file that was created in
``` ```
For more details, please refer to For more details, please refer to
[Note-development-policy](https://github.com/mozilla/rust/wiki/Note-development-policy). [Note-development-policy](https://github.com/rust-lang/rust/wiki/Note-development-policy).

View file

@ -98,8 +98,8 @@
# This is hardly all there is to know of The Rust Build System's # This is hardly all there is to know of The Rust Build System's
# mysteries. The tale continues on the wiki[1][2]. # mysteries. The tale continues on the wiki[1][2].
# #
# [1]: https://github.com/mozilla/rust/wiki/Note-build-system # [1]: https://github.com/rust-lang/rust/wiki/Note-build-system
# [2]: https://github.com/mozilla/rust/wiki/Note-testsuite # [2]: https://github.com/rust-lang/rust/wiki/Note-testsuite
# #
# If you really feel like getting your hands dirty, then: # If you really feel like getting your hands dirty, then:
# #

View file

@ -14,8 +14,8 @@ documentation.
[installer]: http://www.rust-lang.org/install.html [installer]: http://www.rust-lang.org/install.html
[tutorial]: http://doc.rust-lang.org/tutorial.html [tutorial]: http://doc.rust-lang.org/tutorial.html
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust [wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust
[win-wiki]: https://github.com/mozilla/rust/wiki/Using-Rust-on-Windows [win-wiki]: https://github.com/rust-lang/rust/wiki/Using-Rust-on-Windows
## Building from Source ## Building from Source
@ -38,7 +38,7 @@ documentation.
Or to build from the [repo] do: Or to build from the [repo] do:
$ git clone https://github.com/mozilla/rust.git $ git clone https://github.com/rust-lang/rust.git
$ cd rust $ cd rust
Now that you have Rust's source code, you can configure and build it: Now that you have Rust's source code, you can configure and build it:
@ -58,7 +58,7 @@ documentation.
3. Read the [tutorial]. 3. Read the [tutorial].
4. Enjoy! 4. Enjoy!
[repo]: https://github.com/mozilla/rust [repo]: https://github.com/rust-lang/rust
[tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz [tarball]: http://static.rust-lang.org/dist/rust-nightly.tar.gz
[tutorial]: http://doc.rust-lang.org/tutorial.html [tutorial]: http://doc.rust-lang.org/tutorial.html
@ -83,7 +83,7 @@ swap, it will take a very long time to build.
There is a lot more documentation in the [wiki]. There is a lot more documentation in the [wiki].
[wiki]: https://github.com/mozilla/rust/wiki [wiki]: https://github.com/rust-lang/rust/wiki
## License ## License

2
configure vendored
View file

@ -421,6 +421,7 @@ opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
opt rpath 1 "build rpaths into rustc itself" opt rpath 1 "build rpaths into rustc itself"
opt nightly 0 "build nightly packages" opt nightly 0 "build nightly packages"
opt verify-install 1 "verify installed binaries work" opt verify-install 1 "verify installed binaries work"
opt jemalloc 1 "build liballoc with jemalloc"
valopt prefix "/usr/local" "set installation prefix" valopt prefix "/usr/local" "set installation prefix"
valopt local-rust-root "/usr/local" "set prefix for local rust binary" valopt local-rust-root "/usr/local" "set prefix for local rust binary"
valopt llvm-root "" "set LLVM root" valopt llvm-root "" "set LLVM root"
@ -1167,6 +1168,7 @@ putvar CFG_MANDIR
putvar CFG_DISABLE_INJECT_STD_VERSION putvar CFG_DISABLE_INJECT_STD_VERSION
putvar CFG_JEMALLOC_ROOT putvar CFG_JEMALLOC_ROOT
putvar CFG_LIBUV_ROOT putvar CFG_LIBUV_ROOT
putvar CFG_DISABLE_JEMALLOC
# Avoid spurious warnings from clang by feeding it original source on # Avoid spurious warnings from clang by feeding it original source on
# ccache-miss rather than preprocessed input. # ccache-miss rather than preprocessed input.

View file

@ -184,7 +184,7 @@ To build an executable with debug info:
rustdoc rustdoc
.SH "BUGS" .SH "BUGS"
See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
.SH "AUTHOR" .SH "AUTHOR"
See \fBAUTHORS.txt\fR in the Rust source distribution. See \fBAUTHORS.txt\fR in the Rust source distribution.

View file

@ -87,7 +87,7 @@ The generated HTML can be viewed with any standard web browser.
rustc rustc
.SH "BUGS" .SH "BUGS"
See <\fBhttps://github.com/mozilla/rust/issues\fR> for issues. See <\fBhttps://github.com/rust-lang/rust/issues\fR> for issues.
.SH "AUTHOR" .SH "AUTHOR"
See \fBAUTHORS.txt\fR in the Rust source distribution. See \fBAUTHORS.txt\fR in the Rust source distribution.

View file

@ -360,10 +360,10 @@ endef
# contains spaces which confuse make. # contains spaces which confuse make.
# * `LD_LIBRARY_PATH_ENV_HOSTDIR`: the entry to add to lookup path for the host # * `LD_LIBRARY_PATH_ENV_HOSTDIR`: the entry to add to lookup path for the host
# * `LD_LIBRARY_PATH_ENV_TARGETDIR`: the entry to add to lookup path for target # * `LD_LIBRARY_PATH_ENV_TARGETDIR`: the entry to add to lookup path for target
# #
# Below that, HOST_RPATH_VAR and TARGET_RPATH_VAR are defined in terms of the # Below that, HOST_RPATH_VAR and TARGET_RPATH_VAR are defined in terms of the
# above settings. # above settings.
# #
define SREQ_CMDS define SREQ_CMDS
ifeq ($$(OSTYPE_$(3)),apple-darwin) ifeq ($$(OSTYPE_$(3)),apple-darwin)
@ -382,9 +382,9 @@ LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3) := \
$$(CURDIR)/$$(TLIB1_T_$(2)_H_$(CFG_BUILD)) $$(CURDIR)/$$(TLIB1_T_$(2)_H_$(CFG_BUILD))
HOST_RPATH_VAR$(1)_T_$(2)_H_$(3) := \ HOST_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)):$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3)) $$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_HOSTDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
TARGET_RPATH_VAR$(1)_T_$(2)_H_$(3) := \ TARGET_RPATH_VAR$(1)_T_$(2)_H_$(3) := \
$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3)):$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3)) $$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))=$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3)):$$$$$$(LD_LIBRARY_PATH_ENV_NAME$(1)_T_$(2)_H_$(3))
RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(HOST_RPATH_VAR$(1)_T_$(2)_H_$(3)) RPATH_VAR$(1)_T_$(2)_H_$(3) := $$(HOST_RPATH_VAR$(1)_T_$(2)_H_$(3))

View file

@ -306,6 +306,8 @@ $$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1)) -g1" EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1)) -g1"
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static $$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
ifeq ($$(CFG_DISABLE_JEMALLOC),)
RUSTFLAGS_alloc := --cfg jemalloc
ifeq ($(1),$$(CFG_BUILD)) ifeq ($(1),$$(CFG_BUILD))
ifneq ($$(CFG_JEMALLOC_ROOT),) ifneq ($$(CFG_JEMALLOC_ROOT),)
$$(JEMALLOC_LIB_$(1)): $$(CFG_JEMALLOC_ROOT)/libjemalloc_pic.a $$(JEMALLOC_LIB_$(1)): $$(CFG_JEMALLOC_ROOT)/libjemalloc_pic.a
@ -319,6 +321,10 @@ else
$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_LOCAL_$(1)) $$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_LOCAL_$(1))
$$(Q)cp $$< $$@ $$(Q)cp $$< $$@
endif endif
else
$$(JEMALLOC_LIB_$(1)): $$(MKFILE_DEPS)
$$(Q)touch $$@
endif
################################################################################ ################################################################################
# compiler-rt # compiler-rt

View file

@ -84,6 +84,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
-L "$$(RT_OUTPUT_DIR_$(2))" \ -L "$$(RT_OUTPUT_DIR_$(2))" \
-L "$$(LLVM_LIBDIR_$(2))" \ -L "$$(LLVM_LIBDIR_$(2))" \
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \ -L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
$$(RUSTFLAGS_$(4)) \
--out-dir $$(@D) $$< --out-dir $$(@D) $$<
@touch $$@ @touch $$@
$$(call LIST_ALL_OLD_GLOB_MATCHES,\ $$(call LIST_ALL_OLD_GLOB_MATCHES,\

View file

@ -91,7 +91,8 @@ endif
define DEF_TARGET_COMMANDS define DEF_TARGET_COMMANDS
ifdef CFG_UNIXY_$(1) ifdef CFG_UNIXY_$(1)
CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),,$$(CFG_VALGRIND) $$(1)) CFG_RUN_TEST_$(1)=$$(TARGET_RPATH_VAR$$(2)_T_$$(3)_H_$$(4)) \
$$(call CFG_RUN_$(1),,$$(CFG_VALGRIND) $$(1))
endif endif
ifdef CFG_WINDOWSY_$(1) ifdef CFG_WINDOWSY_$(1)
@ -105,13 +106,13 @@ ifdef CFG_WINDOWSY_$(1)
$$(if $$(findstring stage3,$$(1)), \ $$(if $$(findstring stage3,$$(1)), \
stage3/$$(CFG_LIBDIR_RELATIVE), \ stage3/$$(CFG_LIBDIR_RELATIVE), \
)))))/rustlib/$$(CFG_BUILD)/lib )))))/rustlib/$$(CFG_BUILD)/lib
CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),$$(call CFG_TESTLIB_$(1),$$(1),$$(3)),$$(1)) CFG_RUN_TEST_$(1)=$$(call CFG_RUN_$(1),$$(call CFG_TESTLIB_$(1),$$(1),$$(4)),$$(1))
endif endif
# Run the compiletest runner itself under valgrind # Run the compiletest runner itself under valgrind
ifdef CTEST_VALGRIND ifdef CTEST_VALGRIND
CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \ CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \
$$(call CFG_RUN_TEST_$$(CFG_BUILD),$$(2),$$(3)) $$(call CFG_RUN_TEST_$$(CFG_BUILD),$$(3),$$(4))
else else
CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \ CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \
$$(call CFG_RUN_$$(CFG_BUILD),$$(TLIB$$(1)_T_$$(3)_H_$$(3)),$$(2)) $$(call CFG_RUN_$$(CFG_BUILD),$$(TLIB$$(1)_T_$$(3)_H_$$(3)),$$(2))
@ -375,7 +376,8 @@ $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)): \
@$$(call E, rustc: $$@) @$$(call E, rustc: $$@)
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \ $$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
-L "$$(RT_OUTPUT_DIR_$(2))" \ -L "$$(RT_OUTPUT_DIR_$(2))" \
-L "$$(LLVM_LIBDIR_$(2))" -L "$$(LLVM_LIBDIR_$(2))" \
$$(RUSTFLAGS_$(4))
endef endef
@ -391,7 +393,7 @@ check-stage$(1)-T-$(2)-H-$(3)-$(4)-exec: $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \ $$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2)) $(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$<) @$$(call E, run: $$<)
$$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(2),$(3)) $$(TESTARGS) \ $$(Q)$$(call CFG_RUN_TEST_$(2),$$<,$(1),$(2),$(3)) $$(TESTARGS) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \ --logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \ $$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
&& touch $$@ && touch $$@

View file

@ -13,21 +13,19 @@ use std::str;
use std::io::process::{ProcessExit, Command, Process, ProcessOutput}; use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
use std::dynamic_lib::DynamicLibrary; use std::dynamic_lib::DynamicLibrary;
fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> { fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
let prog = if cfg!(windows) {prog.slice_to(prog.len() - 4)} else {prog};
let mut aux_path = prog.to_string();
aux_path.push_str(".libaux");
// Need to be sure to put both the lib_path and the aux path in the dylib // Need to be sure to put both the lib_path and the aux path in the dylib
// search path for the child. // search path for the child.
let mut path = DynamicLibrary::search_path(); let mut path = DynamicLibrary::search_path();
path.insert(0, Path::new(aux_path)); match aux_path {
Some(p) => path.insert(0, Path::new(p)),
None => {}
}
path.insert(0, Path::new(lib_path)); path.insert(0, Path::new(lib_path));
// Remove the previous dylib search path var // Remove the previous dylib search path var
let var = DynamicLibrary::envvar(); let var = DynamicLibrary::envvar();
let mut env: Vec<(String,String)> = let mut env: Vec<(String,String)> = os::env();
os::env().move_iter().map(|(a,b)|(a.to_string(), b.to_string())).collect();
match env.iter().position(|&(ref k, _)| k.as_slice() == var) { match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
Some(i) => { env.remove(i); } Some(i) => { env.remove(i); }
None => {} None => {}
@ -35,8 +33,8 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
// Add the new dylib search path var // Add the new dylib search path var
let newpath = DynamicLibrary::create_path(path.as_slice()); let newpath = DynamicLibrary::create_path(path.as_slice());
env.push((var.to_string(), let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
str::from_utf8(newpath.as_slice()).unwrap().to_string())); env.push((var.to_string(), newpath));
return env; return env;
} }
@ -44,11 +42,12 @@ pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
pub fn run(lib_path: &str, pub fn run(lib_path: &str,
prog: &str, prog: &str,
aux_path: Option<&str>,
args: &[String], args: &[String],
env: Vec<(String, String)> , env: Vec<(String, String)> ,
input: Option<String>) -> Option<Result> { input: Option<String>) -> Option<Result> {
let env = env.clone().append(target_env(lib_path, prog).as_slice()); let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() { match Command::new(prog).args(args).env(env.as_slice()).spawn() {
Ok(mut process) => { Ok(mut process) => {
for input in input.iter() { for input in input.iter() {
@ -69,11 +68,12 @@ pub fn run(lib_path: &str,
pub fn run_background(lib_path: &str, pub fn run_background(lib_path: &str,
prog: &str, prog: &str,
aux_path: Option<&str>,
args: &[String], args: &[String],
env: Vec<(String, String)> , env: Vec<(String, String)> ,
input: Option<String>) -> Option<Process> { input: Option<String>) -> Option<Process> {
let env = env.clone().append(target_env(lib_path, prog).as_slice()); let env = env.clone().append(target_env(lib_path, aux_path).as_slice());
match Command::new(prog).args(args).env(env.as_slice()).spawn() { match Command::new(prog).args(args).env(env.as_slice()).spawn() {
Ok(mut process) => { Ok(mut process) => {
for input in input.iter() { for input in input.iter() {

View file

@ -230,6 +230,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
testfile: &Path, testfile: &Path,
src: String, src: String,
pretty_type: &str) -> ProcRes { pretty_type: &str) -> ProcRes {
let aux_dir = aux_output_dir_name(config, testfile);
compose_and_run(config, compose_and_run(config,
testfile, testfile,
make_pp_args(config, make_pp_args(config,
@ -238,6 +239,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
pretty_type.to_string()), pretty_type.to_string()),
props.exec_env.clone(), props.exec_env.clone(),
config.compile_lib_path.as_slice(), config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
Some(src)) Some(src))
} }
@ -354,6 +356,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
[ [
"push".to_string(), "push".to_string(),
exe_file.as_str().unwrap().to_string(), exe_file.as_str().unwrap().to_string(),
@ -365,6 +368,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
[ [
"forward".to_string(), "forward".to_string(),
"tcp:5039".to_string(), "tcp:5039".to_string(),
@ -385,6 +389,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
let mut process = procsrv::run_background("", let mut process = procsrv::run_background("",
config.adb_path config.adb_path
.as_slice(), .as_slice(),
None,
[ [
"shell".to_string(), "shell".to_string(),
adb_arg.clone() adb_arg.clone()
@ -425,6 +430,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
status status
} = procsrv::run("", } = procsrv::run("",
gdb_path.as_slice(), gdb_path.as_slice(),
None,
debugger_opts.as_slice(), debugger_opts.as_slice(),
vec!(("".to_string(), "".to_string())), vec!(("".to_string(), "".to_string())),
None) None)
@ -486,7 +492,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
testfile, testfile,
proc_args, proc_args,
Vec::new(), Vec::new(),
"", config.run_lib_path.as_slice(),
None,
None); None);
} }
} }
@ -994,11 +1001,13 @@ fn exec_compiled_test(config: &Config, props: &TestProps,
} }
_=> { _=> {
let aux_dir = aux_output_dir_name(config, testfile);
compose_and_run(config, compose_and_run(config,
testfile, testfile,
make_run_args(config, props, testfile), make_run_args(config, props, testfile),
env, env,
config.run_lib_path.as_slice(), config.run_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
None) None)
} }
} }
@ -1045,6 +1054,7 @@ fn compose_and_run_compiler(
aux_args, aux_args,
Vec::new(), Vec::new(),
config.compile_lib_path.as_slice(), config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
None); None);
if !auxres.status.success() { if !auxres.status.success() {
fatal_proc_rec( fatal_proc_rec(
@ -1066,6 +1076,7 @@ fn compose_and_run_compiler(
args, args,
Vec::new(), Vec::new(),
config.compile_lib_path.as_slice(), config.compile_lib_path.as_slice(),
Some(aux_dir.as_str().unwrap()),
input) input)
} }
@ -1078,9 +1089,10 @@ fn compose_and_run(config: &Config, testfile: &Path,
ProcArgs{ args, prog }: ProcArgs, ProcArgs{ args, prog }: ProcArgs,
procenv: Vec<(String, String)> , procenv: Vec<(String, String)> ,
lib_path: &str, lib_path: &str,
aux_path: Option<&str>,
input: Option<String>) -> ProcRes { input: Option<String>) -> ProcRes {
return program_output(config, testfile, lib_path, return program_output(config, testfile, lib_path,
prog, args, procenv, input); prog, aux_path, args, procenv, input);
} }
enum TargetLocation { enum TargetLocation {
@ -1189,7 +1201,8 @@ fn split_maybe_args(argstr: &Option<String>) -> Vec<String> {
} }
fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String, fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String,
args: Vec<String> , env: Vec<(String, String)> , aux_path: Option<&str>, args: Vec<String>,
env: Vec<(String, String)>,
input: Option<String>) -> ProcRes { input: Option<String>) -> ProcRes {
let cmdline = let cmdline =
{ {
@ -1205,6 +1218,7 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
status status
} = procsrv::run(lib_path, } = procsrv::run(lib_path,
prog.as_slice(), prog.as_slice(),
aux_path,
args.as_slice(), args.as_slice(),
env, env,
input).expect(format!("failed to exec `{}`", prog).as_slice()); input).expect(format!("failed to exec `{}`", prog).as_slice());
@ -1326,6 +1340,7 @@ fn _arm_exec_compiled_test(config: &Config,
// copy to target // copy to target
let copy_result = procsrv::run("", let copy_result = procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
[ [
"push".to_string(), "push".to_string(),
args.prog.clone(), args.prog.clone(),
@ -1361,6 +1376,7 @@ fn _arm_exec_compiled_test(config: &Config,
} }
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
runargs.as_slice(), runargs.as_slice(),
vec!(("".to_string(), "".to_string())), Some("".to_string())) vec!(("".to_string(), "".to_string())), Some("".to_string()))
.expect(format!("failed to exec `{}`", config.adb_path).as_slice()); .expect(format!("failed to exec `{}`", config.adb_path).as_slice());
@ -1374,6 +1390,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: exitcode_out, err: _, status: _ } = let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
runargs.as_slice(), runargs.as_slice(),
vec!(("".to_string(), "".to_string())), vec!(("".to_string(), "".to_string())),
Some("".to_string())) Some("".to_string()))
@ -1397,6 +1414,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: stdout_out, err: _, status: _ } = let procsrv::Result{ out: stdout_out, err: _, status: _ } =
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
runargs.as_slice(), runargs.as_slice(),
vec!(("".to_string(), "".to_string())), vec!(("".to_string(), "".to_string())),
Some("".to_string())) Some("".to_string()))
@ -1411,6 +1429,7 @@ fn _arm_exec_compiled_test(config: &Config,
let procsrv::Result{ out: stderr_out, err: _, status: _ } = let procsrv::Result{ out: stderr_out, err: _, status: _ } =
procsrv::run("", procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
runargs.as_slice(), runargs.as_slice(),
vec!(("".to_string(), "".to_string())), vec!(("".to_string(), "".to_string())),
Some("".to_string())) Some("".to_string()))
@ -1438,6 +1457,7 @@ fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
// FIXME (#9639): This needs to handle non-utf8 paths // FIXME (#9639): This needs to handle non-utf8 paths
let copy_result = procsrv::run("", let copy_result = procsrv::run("",
config.adb_path.as_slice(), config.adb_path.as_slice(),
None,
[ [
"push".to_string(), "push".to_string(),
file.as_str() file.as_str()
@ -1505,7 +1525,7 @@ fn compile_cc_with_clang_and_save_bitcode(config: &Config, _props: &TestProps,
bitcodefile.as_str().unwrap().to_string(), bitcodefile.as_str().unwrap().to_string(),
testcc.as_str().unwrap().to_string()) testcc.as_str().unwrap().to_string())
}; };
compose_and_run(config, testfile, proc_args, Vec::new(), "", None) compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
} }
fn extract_function_from_bitcode(config: &Config, _props: &TestProps, fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
@ -1522,7 +1542,7 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
format!("-o={}", extracted_bc.as_str().unwrap()), format!("-o={}", extracted_bc.as_str().unwrap()),
bitcodefile.as_str().unwrap().to_string()) bitcodefile.as_str().unwrap().to_string())
}; };
compose_and_run(config, testfile, proc_args, Vec::new(), "", None) compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
} }
fn disassemble_extract(config: &Config, _props: &TestProps, fn disassemble_extract(config: &Config, _props: &TestProps,
@ -1538,7 +1558,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()), args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
extracted_bc.as_str().unwrap().to_string()) extracted_bc.as_str().unwrap().to_string())
}; };
compose_and_run(config, testfile, proc_args, Vec::new(), "", None) compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
} }

View file

@ -22,7 +22,7 @@ If you don't have enough time for a search, then don't worry about that. Just su
the bug. If it's a duplicate, somebody will notice that and close it during triage. the bug. If it's a duplicate, somebody will notice that and close it during triage.
If you have the time for it, it would be useful to type the text of the error If you have the time for it, it would be useful to type the text of the error
message you got [into the issue tracker search box](https://github.com/mozilla/rust/issues) message you got [into the issue tracker search box](https://github.com/rust-lang/rust/issues)
to see if there's an existing bug that resembles your problem. If there is, to see if there's an existing bug that resembles your problem. If there is,
and it's an open bug, you can comment on that issue and say you are also affected. and it's an open bug, you can comment on that issue and say you are also affected.
This will encourage the devs to fix it. But again, don't let this stop you from This will encourage the devs to fix it. But again, don't let this stop you from

View file

@ -111,14 +111,14 @@ match val.do_something() {
[#3101][iss] is the issue that proposed making this the only behavior, with [#3101][iss] is the issue that proposed making this the only behavior, with
rationale and discussion. rationale and discussion.
[iss]: https://github.com/mozilla/rust/issues/3101 [iss]: https://github.com/rust-lang/rust/issues/3101
## No guaranteed tail-call optimization ## No guaranteed tail-call optimization
In general, tail-call optimization is not guaranteed: see for a detailed In general, tail-call optimization is not guaranteed: see [here][tml] for a
explanation with references. There is a [proposed extension][tce] that would detailed explanation with references. There is a [proposed extension][tce] that
allow tail-call elimination in certain contexts. The compiler is still free to would allow tail-call elimination in certain contexts. The compiler is still
optimize tail-calls [when it pleases][sco], however. free to optimize tail-calls [when it pleases][sco], however.
[tml]: https://mail.mozilla.org/pipermail/rust-dev/2013-April/003557.html [tml]: https://mail.mozilla.org/pipermail/rust-dev/2013-April/003557.html
[sco]: http://llvm.org/docs/CodeGenerator.html#sibling-call-optimization [sco]: http://llvm.org/docs/CodeGenerator.html#sibling-call-optimization

View file

@ -5,9 +5,9 @@
There aren't many large programs yet. The Rust [compiler][rustc], 60,000+ lines at the time of writing, is written in Rust. As the oldest body of Rust code it has gone through many iterations of the language, and some parts are nicer to look at than others. It may not be the best code to learn from, but [borrowck] and [resolve] were written recently. There aren't many large programs yet. The Rust [compiler][rustc], 60,000+ lines at the time of writing, is written in Rust. As the oldest body of Rust code it has gone through many iterations of the language, and some parts are nicer to look at than others. It may not be the best code to learn from, but [borrowck] and [resolve] were written recently.
[rustc]: https://github.com/mozilla/rust/tree/master/src/librustc [rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc
[resolve]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/resolve.rs [resolve]: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/resolve.rs
[borrowck]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/borrowck/ [borrowck]: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/borrowck/
A research browser engine called [Servo][servo], currently 30,000+ lines across more than a dozen crates, will be exercising a lot of Rust's distinctive type-system and concurrency features, and integrating many native libraries. A research browser engine called [Servo][servo], currently 30,000+ lines across more than a dozen crates, will be exercising a lot of Rust's distinctive type-system and concurrency features, and integrating many native libraries.
@ -21,9 +21,9 @@ Some examples that demonstrate different aspects of the language:
* The extra library's [json] module. Enums and pattern matching * The extra library's [json] module. Enums and pattern matching
[sprocketnes]: https://github.com/pcwalton/sprocketnes [sprocketnes]: https://github.com/pcwalton/sprocketnes
[hash]: https://github.com/mozilla/rust/blob/master/src/libstd/hash/mod.rs [hash]: https://github.com/rust-lang/rust/blob/master/src/libstd/hash/mod.rs
[HashMap]: https://github.com/mozilla/rust/blob/master/src/libcollections/hashmap.rs [HashMap]: https://github.com/rust-lang/rust/blob/master/src/libcollections/hashmap.rs
[json]: https://github.com/mozilla/rust/blob/master/src/libserialize/json.rs [json]: https://github.com/rust-lang/rust/blob/master/src/libserialize/json.rs
You may also be interested in browsing [GitHub's Rust][github-rust] page. You may also be interested in browsing [GitHub's Rust][github-rust] page.
@ -33,8 +33,8 @@ You may also be interested in browsing [GitHub's Rust][github-rust] page.
Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depends on libgcc DLL at runtime][libgcc]. Yes. All development happens in lock-step on all 3 target platforms. Using MinGW, not Cygwin. Note that the windows implementation currently has some limitations: in particular 64-bit build is [not fully supported yet][win64], and all executables created by rustc [depends on libgcc DLL at runtime][libgcc].
[win64]: https://github.com/mozilla/rust/issues/1237 [win64]: https://github.com/rust-lang/rust/issues/1237
[libgcc]: https://github.com/mozilla/rust/issues/11782 [libgcc]: https://github.com/rust-lang/rust/issues/11782
## Is it OO? How do I do this thing I normally do in an OO language? ## Is it OO? How do I do this thing I normally do in an OO language?

View file

@ -75,4 +75,4 @@ li {list-style-type: none; }
* [`#rust-internals`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals) - compiler and libraries * [`#rust-internals`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals) - compiler and libraries
* [`#rust-osdev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-osdev) - operating system development * [`#rust-osdev`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-osdev) - operating system development
* The Rust community on [Reddit](http://reddit.com/r/rust) * The Rust community on [Reddit](http://reddit.com/r/rust)
* The Rust [wiki](http://github.com/mozilla/rust/wiki) * The Rust [wiki](http://github.com/rust-lang/rust/wiki)

View file

@ -361,7 +361,7 @@ fn main() {
// This is ugly for now, but will be replaced by // This is ugly for now, but will be replaced by
// `numbers[num as uint] += 1` in the near future. // `numbers[num as uint] += 1` in the near future.
// See: https://github.com/mozilla/rust/issues/6515 // See: https://github.com/rust-lang/rust/issues/6515
*numbers.get_mut(num as uint) = *numbers.get_mut(num as uint) + 1; *numbers.get_mut(num as uint) = *numbers.get_mut(num as uint) + 1;
println!("{}", *numbers.get(num as uint)); println!("{}", *numbers.get(num as uint));

View file

@ -34,46 +34,46 @@ msgstr "## 構造体"
#: src/doc/complement-lang-faq.md:83 #: src/doc/complement-lang-faq.md:83
#, fuzzy #, fuzzy
#| msgid "" #| msgid ""
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: " #| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust" #| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
msgid "" msgid ""
"[rustc]: https://github.com/mozilla/rust/tree/master/src/librustc [resolve]: " "[rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc [resolve]: "
"https://github.com/mozilla/rust/blob/master/src/librustc/middle/resolve.rs " "https://github.com/rust-lang/rust/blob/master/src/librustc/middle/resolve.rs "
"[borrowck]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/" "[borrowck]: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/"
"borrowck/" "borrowck/"
msgstr "" msgstr ""
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n" "[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-" "[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
"developing-Rust" "developing-Rust"
#. type: Plain text #. type: Plain text
#: src/doc/complement-lang-faq.md:99 #: src/doc/complement-lang-faq.md:99
#, fuzzy #, fuzzy
#| msgid "" #| msgid ""
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: " #| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust" #| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
msgid "" msgid ""
"[sprocketnes]: https://github.com/pcwalton/sprocketnes [hash]: https://" "[sprocketnes]: https://github.com/pcwalton/sprocketnes [hash]: https://"
"github.com/mozilla/rust/blob/master/src/libstd/hash.rs [HashMap]: https://" "github.com/rust-lang/rust/blob/master/src/libstd/hash.rs [HashMap]: https://"
"github.com/mozilla/rust/blob/master/src/libstd/hashmap.rs [json]: https://" "github.com/rust-lang/rust/blob/master/src/libstd/hashmap.rs [json]: https://"
"github.com/mozilla/rust/blob/master/src/libextra/json.rs" "github.com/rust-lang/rust/blob/master/src/libextra/json.rs"
msgstr "" msgstr ""
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n" "[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-" "[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
"developing-Rust" "developing-Rust"
#. type: Plain text #. type: Plain text
#: src/doc/complement-lang-faq.md:110 #: src/doc/complement-lang-faq.md:110
#, fuzzy #, fuzzy
#| msgid "" #| msgid ""
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: " #| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust" #| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
msgid "" msgid ""
"[unwind]: https://github.com/mozilla/rust/issues/908 [libgcc]: https://" "[unwind]: https://github.com/rust-lang/rust/issues/908 [libgcc]: https://"
"github.com/mozilla/rust/issues/1603" "github.com/rust-lang/rust/issues/1603"
msgstr "" msgstr ""
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n" "[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-" "[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
"developing-Rust" "developing-Rust"
#. type: Plain text #. type: Plain text

View file

@ -303,15 +303,15 @@ msgstr ""
#: src/doc/tutorial.md:92 #: src/doc/tutorial.md:92
#, fuzzy #, fuzzy
#| msgid "" #| msgid ""
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: " #| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust" #| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
msgid "" msgid ""
"[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: " "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
"https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust " "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust "
"[git]: https://github.com/mozilla/rust.git" "[git]: https://github.com/rust-lang/rust.git"
msgstr "" msgstr ""
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n" "[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-" "[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
"developing-Rust" "developing-Rust"
#. type: Plain text #. type: Plain text

View file

@ -90,8 +90,8 @@ Snapshot binaries are currently built and tested on several platforms:
You may find that other platforms work, but these are our "tier 1" You may find that other platforms work, but these are our "tier 1"
supported build environments that are most likely to work. supported build environments that are most likely to work.
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust [wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust
[git]: https://github.com/mozilla/rust.git [git]: https://github.com/rust-lang/rust.git
[rust-install]: http://www.rust-lang.org/install.html [rust-install]: http://www.rust-lang.org/install.html
To build from source you will also need the following prerequisite To build from source you will also need the following prerequisite
@ -183,7 +183,7 @@ There is ctags support via `src/etc/ctags.rust`, but many other
tools and editors are not yet supported. If you end up writing a Rust tools and editors are not yet supported. If you end up writing a Rust
mode for your favorite editor, let us know so that we can link to it. mode for your favorite editor, let us know so that we can link to it.
[sublime]: http://github.com/dbp/sublime-rust [sublime]: http://github.com/jhasse/sublime-rust
[sublime-pkg]: http://wbond.net/sublime_packages/package_control [sublime-pkg]: http://wbond.net/sublime_packages/package_control
# Syntax basics # Syntax basics
@ -3345,6 +3345,6 @@ There is further documentation on the [wiki], however those tend to be even more
[testing]: guide-testing.html [testing]: guide-testing.html
[runtime]: guide-runtime.html [runtime]: guide-runtime.html
[rustdoc]: rustdoc.html [rustdoc]: rustdoc.html
[wiki]: https://github.com/mozilla/rust/wiki/Docs [wiki]: https://github.com/rust-lang/rust/wiki/Docs
[wiki-packages]: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools [wiki-packages]: https://github.com/rust-lang/rust/wiki/Doc-packages,-editors,-and-other-tools

View file

@ -1,6 +1,6 @@
<div id="versioninfo"> <div id="versioninfo">
<img src="http://www.rust-lang.org/logos/rust-logo-32x32-blk.png" width="32" height="32" alt><br> <img src="http://www.rust-lang.org/logos/rust-logo-32x32-blk.png" width="32" height="32" alt><br>
<span class="white-sticker"><a href="http://rust-lang.org">Rust</a> VERSION</span><br> <span class="white-sticker"><a href="http://rust-lang.org">Rust</a> VERSION</span><br>
<a href="http://github.com/mozilla/rust/commit/STAMP" <a href="http://github.com/rust-lang/rust/commit/STAMP"
class="hash white-sticker">SHORT_HASH</a> class="hash white-sticker">SHORT_HASH</a>
</div> </div>

View file

@ -2,7 +2,7 @@
;; Version: 0.2.0 ;; Version: 0.2.0
;; Author: Mozilla ;; Author: Mozilla
;; Url: https://github.com/mozilla/rust ;; Url: https://github.com/rust-lang/rust
;; Keywords: languages ;; Keywords: languages
;;; Commentary: ;;; Commentary:

View file

@ -13,7 +13,7 @@
This script takes a list of keywords and generates a testcase, that checks This script takes a list of keywords and generates a testcase, that checks
if using the keyword as identifier fails, for every keyword. The generate if using the keyword as identifier fails, for every keyword. The generate
test files are set read-only. test files are set read-only.
Test for https://github.com/mozilla/rust/issues/2275 Test for https://github.com/rust-lang/rust/issues/2275
sample usage: src/etc/generate-keyword-tests.py as break sample usage: src/etc/generate-keyword-tests.py as break
""" """

View file

@ -0,0 +1,22 @@
" Vim syntastic plugin helper
" Language: Rust
" Maintainer: Andrew Gallant <jamslam@gmail.com>
if exists("g:loaded_syntastic_rust_filetype")
finish
endif
let g:loaded_syntastic_rust_filetype = 1
let s:save_cpo = &cpo
set cpo&vim
" This is to let Syntastic know about the Rust filetype.
" It enables tab completion for the 'SyntasticInfo' command.
" (This does not actually register the syntax checker.)
if exists('g:syntastic_extra_filetypes')
call add(g:syntastic_extra_filetypes, 'rust')
else
let g:syntastic_extra_filetypes = ['rust']
endif
let &cpo = s:save_cpo
unlet s:save_cpo

View file

@ -0,0 +1,35 @@
" Vim syntastic plugin
" Language: Rust
" Maintainer: Andrew Gallant <jamslam@gmail.com>
"
" See for details on how to add an external Syntastic checker:
" https://github.com/scrooloose/syntastic/wiki/Syntax-Checker-Guide#external
if exists("g:loaded_syntastic_rust_rustc_checker")
finish
endif
let g:loaded_syntastic_rust_rustc_checker = 1
let s:save_cpo = &cpo
set cpo&vim
function! SyntaxCheckers_rust_rustc_GetLocList() dict
let makeprg = self.makeprgBuild({ 'args': '--parse-only' })
let errorformat =
\ '%E%f:%l:%c: %\d%#:%\d%# %.%\{-}error:%.%\{-} %m,' .
\ '%W%f:%l:%c: %\d%#:%\d%# %.%\{-}warning:%.%\{-} %m,' .
\ '%C%f:%l %m,' .
\ '%-Z%.%#'
return SyntasticMake({
\ 'makeprg': makeprg,
\ 'errorformat': errorformat })
endfunction
call g:SyntasticRegistry.CreateAndRegisterChecker({
\ 'filetype': 'rust',
\ 'name': 'rustc'})
let &cpo = s:save_cpo
unlet s:save_cpo

View file

@ -9,111 +9,83 @@
// except according to those terms. // except according to those terms.
// FIXME: #13994: port to the sized deallocation API when available // FIXME: #13994: port to the sized deallocation API when available
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias` and `nonnull` // FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
// and `nonnull`
use core::intrinsics::{abort, cttz32};
use core::option::{None, Option};
use core::ptr::{RawPtr, mut_null, null};
use libc::{c_char, c_int, c_void, size_t};
#[cfg(not(test))] use core::raw; #[cfg(not(test))] use core::raw;
#[cfg(not(test))] use util; #[cfg(not(test))] use util;
#[link(name = "jemalloc", kind = "static")]
extern {
fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
fn je_dallocx(ptr: *mut c_void, flags: c_int);
fn je_nallocx(size: size_t, flags: c_int) -> size_t;
fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void, *c_char)>,
cbopaque: *mut c_void,
opts: *c_char);
}
// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
#[cfg(not(windows), not(target_os = "android"))]
#[link(name = "pthread")]
extern {}
// MALLOCX_ALIGN(a) macro
#[inline(always)]
fn mallocx_align(a: uint) -> c_int { unsafe { cttz32(a as u32) as c_int } }
/// Return a pointer to `size` bytes of memory. /// Return a pointer to `size` bytes of memory.
/// ///
/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The /// Behavior is undefined if the requested size is 0 or the alignment is not a
/// alignment must be no larger than the largest supported page size on the platform. /// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.
#[inline] #[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8; imp::allocate(size, align)
if ptr.is_null() {
abort()
}
ptr
} }
/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory. /// Extend or shrink the allocation referenced by `ptr` to `size` bytes of
/// memory.
/// ///
/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The /// Behavior is undefined if the requested size is 0 or the alignment is not a
/// alignment must be no larger than the largest supported page size on the platform. /// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.
/// ///
/// The `old_size` and `align` parameters are the parameters that were used to create the /// The `old_size` and `align` parameters are the parameters that were used to
/// allocation referenced by `ptr`. The `old_size` parameter may also be the value returned by /// create the allocation referenced by `ptr`. The `old_size` parameter may also
/// `usable_size` for the requested size. /// be the value returned by `usable_size` for the requested size.
#[inline] #[inline]
#[allow(unused_variable)] // for the parameter names in the documentation pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> *mut u8 { old_size: uint) -> *mut u8 {
let ptr = je_rallocx(ptr as *mut c_void, size as size_t, mallocx_align(align)) as *mut u8; imp::reallocate(ptr, size, align, old_size)
if ptr.is_null() {
abort()
}
ptr
} }
/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory in-place. /// Extend or shrink the allocation referenced by `ptr` to `size` bytes of
/// memory in-place.
/// ///
/// Return true if successful, otherwise false if the allocation was not altered. /// Return true if successful, otherwise false if the allocation was not
/// altered.
/// ///
/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The /// Behavior is undefined if the requested size is 0 or the alignment is not a
/// alignment must be no larger than the largest supported page size on the platform. /// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.
/// ///
/// The `old_size` and `align` parameters are the parameters that were used to /// The `old_size` and `align` parameters are the parameters that were used to
/// create the allocation referenced by `ptr`. The `old_size` parameter may be /// create the allocation referenced by `ptr`. The `old_size` parameter may be
/// any value in range_inclusive(requested_size, usable_size). /// any value in range_inclusive(requested_size, usable_size).
#[inline] #[inline]
#[allow(unused_variable)] // for the parameter names in the documentation pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> bool { old_size: uint) -> bool {
je_xallocx(ptr as *mut c_void, size as size_t, 0, mallocx_align(align)) == size as size_t imp::reallocate_inplace(ptr, size, align, old_size)
} }
/// Deallocate the memory referenced by `ptr`. /// Deallocate the memory referenced by `ptr`.
/// ///
/// The `ptr` parameter must not be null. /// The `ptr` parameter must not be null.
/// ///
/// The `size` and `align` parameters are the parameters that were used to create the /// The `size` and `align` parameters are the parameters that were used to
/// allocation referenced by `ptr`. The `size` parameter may also be the value returned by /// create the allocation referenced by `ptr`. The `size` parameter may also be
/// `usable_size` for the requested size. /// the value returned by `usable_size` for the requested size.
#[inline] #[inline]
#[allow(unused_variable)] // for the parameter names in the documentation
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) { pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
je_dallocx(ptr as *mut c_void, mallocx_align(align)) imp::deallocate(ptr, size, align)
} }
/// Return the usable size of an allocation created with the specified the `size` and `align`. /// Return the usable size of an allocation created with the specified the
/// `size` and `align`.
#[inline] #[inline]
pub fn usable_size(size: uint, align: uint) -> uint { pub fn usable_size(size: uint, align: uint) -> uint {
unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint } imp::usable_size(size, align)
} }
/// Print implementation-defined allocator statistics. /// Print implementation-defined allocator statistics.
/// ///
/// These statistics may be inconsistent if other threads use the allocator during the call. /// These statistics may be inconsistent if other threads use the allocator
/// during the call.
#[unstable] #[unstable]
pub fn stats_print() { pub fn stats_print() {
unsafe { imp::stats_print();
je_malloc_stats_print(None, mut_null(), null())
}
} }
// The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size // The compiler never calls `exchange_free` on ~ZeroSizeType, so zero-size
@ -145,7 +117,8 @@ unsafe fn exchange_free(ptr: *mut u8, size: uint, align: uint) {
#[lang="closure_exchange_malloc"] #[lang="closure_exchange_malloc"]
#[inline] #[inline]
#[allow(deprecated)] #[allow(deprecated)]
unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uint) -> *mut u8 { unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
align: uint) -> *mut u8 {
let total_size = util::get_box_size(size, align); let total_size = util::get_box_size(size, align);
let p = allocate(total_size, 8); let p = allocate(total_size, 8);
@ -155,6 +128,198 @@ unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint, align: uin
alloc as *mut u8 alloc as *mut u8
} }
#[cfg(jemalloc)]
mod imp {
use core::option::{None, Option};
use core::ptr::{RawPtr, mut_null, null};
use core::num::Bitwise;
use libc::{c_char, c_int, c_void, size_t};
#[link(name = "jemalloc", kind = "static")]
extern {
fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void;
fn je_rallocx(ptr: *mut c_void, size: size_t,
flags: c_int) -> *mut c_void;
fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t,
flags: c_int) -> size_t;
fn je_dallocx(ptr: *mut c_void, flags: c_int);
fn je_nallocx(size: size_t, flags: c_int) -> size_t;
fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void, *c_char)>,
cbopaque: *mut c_void,
opts: *c_char);
}
// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough
#[cfg(not(windows), not(target_os = "android"))]
#[link(name = "pthread")]
extern {}
// MALLOCX_ALIGN(a) macro
#[inline(always)]
fn mallocx_align(a: uint) -> c_int { a.trailing_zeros() as c_int }
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8;
if ptr.is_null() {
::oom()
}
ptr
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
_old_size: uint) -> *mut u8 {
let ptr = je_rallocx(ptr as *mut c_void, size as size_t,
mallocx_align(align)) as *mut u8;
if ptr.is_null() {
::oom()
}
ptr
}
#[inline]
pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
_old_size: uint) -> bool {
je_xallocx(ptr as *mut c_void, size as size_t, 0,
mallocx_align(align)) == size as size_t
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, align: uint) {
je_dallocx(ptr as *mut c_void, mallocx_align(align))
}
#[inline]
pub fn usable_size(size: uint, align: uint) -> uint {
unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint }
}
pub fn stats_print() {
unsafe {
je_malloc_stats_print(None, mut_null(), null())
}
}
}
#[cfg(not(jemalloc), unix)]
mod imp {
use core::mem;
use core::ptr;
use libc;
use libc_heap;
extern {
fn posix_memalign(memptr: *mut *mut libc::c_void,
align: libc::size_t,
size: libc::size_t) -> libc::c_int;
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
// The posix_memalign manpage states
//
// alignment [...] must be a power of and a multiple of
// sizeof(void *)
//
// The `align` parameter to this function is the *minimum* alignment for
// a block of memory, so we special case everything under `*uint` to
// just pass it to malloc, which is guaranteed to align to at least the
// size of `*uint`.
if align < mem::size_of::<*uint>() {
libc_heap::malloc_raw(size)
} else {
let mut out = 0 as *mut libc::c_void;
let ret = posix_memalign(&mut out,
align as libc::size_t,
size as libc::size_t);
if ret != 0 {
::oom();
}
out as *mut u8
}
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
old_size: uint) -> *mut u8 {
let new_ptr = allocate(size, align);
ptr::copy_memory(new_ptr, ptr as *u8, old_size);
deallocate(ptr, old_size, align);
return new_ptr;
}
#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, _size: uint, _align: uint,
_old_size: uint) -> bool {
false
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
libc::free(ptr as *mut libc::c_void)
}
#[inline]
pub fn usable_size(size: uint, _align: uint) -> uint {
size
}
pub fn stats_print() {
}
}
#[cfg(not(jemalloc), windows)]
mod imp {
use libc::{c_void, size_t};
use core::ptr::RawPtr;
extern {
fn _aligned_malloc(size: size_t, align: size_t) -> *mut c_void;
fn _aligned_realloc(block: *mut c_void, size: size_t,
align: size_t) -> *mut c_void;
fn _aligned_free(ptr: *mut c_void);
}
#[inline]
pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 {
let ptr = _aligned_malloc(size as size_t, align as size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
}
#[inline]
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
_old_size: uint) -> *mut u8 {
let ptr = _aligned_realloc(ptr as *mut c_void, size as size_t,
align as size_t);
if ptr.is_null() {
::oom();
}
ptr as *mut u8
}
#[inline]
pub unsafe fn reallocate_inplace(_ptr: *mut u8, _size: uint, _align: uint,
_old_size: uint) -> bool {
false
}
#[inline]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, _align: uint) {
_aligned_free(ptr as *mut c_void)
}
#[inline]
pub fn usable_size(size: uint, _align: uint) -> uint {
size
}
pub fn stats_print() {}
}
#[cfg(test)] #[cfg(test)]
mod bench { mod bench {
extern crate test; extern crate test;

View file

@ -94,6 +94,14 @@ pub mod owned;
pub mod arc; pub mod arc;
pub mod rc; pub mod rc;
/// Common OOM routine used by liballoc
fn oom() -> ! {
// FIXME(#14674): This really needs to do something other than just abort
// here, but any printing done must be *guaranteed* to not
// allocate.
unsafe { core::intrinsics::abort() }
}
// FIXME(#14344): When linking liballoc with libstd, this library will be linked // FIXME(#14344): When linking liballoc with libstd, this library will be linked
// as an rlib (it only exists as an rlib). It turns out that an // as an rlib (it only exists as an rlib). It turns out that an
// optimized standard library doesn't actually use *any* symbols // optimized standard library doesn't actually use *any* symbols

View file

@ -13,7 +13,6 @@
use libc::{c_void, size_t, free, malloc, realloc}; use libc::{c_void, size_t, free, malloc, realloc};
use core::ptr::{RawPtr, mut_null}; use core::ptr::{RawPtr, mut_null};
use core::intrinsics::abort;
/// A wrapper around libc::malloc, aborting on out-of-memory /// A wrapper around libc::malloc, aborting on out-of-memory
#[inline] #[inline]
@ -25,8 +24,7 @@ pub unsafe fn malloc_raw(size: uint) -> *mut u8 {
} else { } else {
let p = malloc(size as size_t); let p = malloc(size as size_t);
if p.is_null() { if p.is_null() {
// we need a non-allocating way to print an error here ::oom();
abort();
} }
p as *mut u8 p as *mut u8
} }
@ -43,8 +41,7 @@ pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
} else { } else {
let p = realloc(ptr as *mut c_void, size as size_t); let p = realloc(ptr as *mut c_void, size as size_t);
if p.is_null() { if p.is_null() {
// we need a non-allocating way to print an error here ::oom();
abort();
} }
p as *mut u8 p as *mut u8
} }

View file

@ -2592,7 +2592,7 @@ pub mod consts {
pub static PROT_GROWSUP : c_int = 0x020000000; pub static PROT_GROWSUP : c_int = 0x020000000;
pub static MAP_TYPE : c_int = 0x000f; pub static MAP_TYPE : c_int = 0x000f;
pub static MAP_ANONONYMOUS : c_int = 0x0020; pub static MAP_ANONYMOUS : c_int = 0x0020;
pub static MAP_32BIT : c_int = 0x0040; pub static MAP_32BIT : c_int = 0x0040;
pub static MAP_GROWSDOWN : c_int = 0x0100; pub static MAP_GROWSDOWN : c_int = 0x0100;
pub static MAP_DENYWRITE : c_int = 0x0800; pub static MAP_DENYWRITE : c_int = 0x0800;
@ -2615,7 +2615,7 @@ pub mod consts {
pub static PROT_GROWSUP : c_int = 0x02000000; pub static PROT_GROWSUP : c_int = 0x02000000;
pub static MAP_TYPE : c_int = 0x000f; pub static MAP_TYPE : c_int = 0x000f;
pub static MAP_ANONONYMOUS : c_int = 0x0800; pub static MAP_ANONYMOUS : c_int = 0x0800;
pub static MAP_GROWSDOWN : c_int = 0x01000; pub static MAP_GROWSDOWN : c_int = 0x01000;
pub static MAP_DENYWRITE : c_int = 0x02000; pub static MAP_DENYWRITE : c_int = 0x02000;
pub static MAP_EXECUTABLE : c_int = 0x04000; pub static MAP_EXECUTABLE : c_int = 0x04000;

View file

@ -4,12 +4,12 @@ An informal guide to reading and working on the rustc compiler.
If you wish to expand on this document, or have a more experienced If you wish to expand on this document, or have a more experienced
Rust contributor add anything else to it, please get in touch: Rust contributor add anything else to it, please get in touch:
https://github.com/mozilla/rust/wiki/Note-development-policy https://github.com/rust-lang/rust/wiki/Note-development-policy
("Communication" subheading) ("Communication" subheading)
or file a bug: or file a bug:
https://github.com/mozilla/rust/issues https://github.com/rust-lang/rust/issues
Your concerns are probably the same as someone else's. Your concerns are probably the same as someone else's.

View file

@ -44,7 +44,7 @@
//! //!
//! # Relevant links //! # Relevant links
//! //!
//! Original issue: https://github.com/mozilla/rust/issues/10207 //! Original issue: https://github.com/rust-lang/rust/issues/10207
use std::fmt; use std::fmt;
use std::hash::Hash; use std::hash::Hash;
@ -270,7 +270,7 @@ mod svh_visitor {
ExprBlock(..) => SawExprBlock, ExprBlock(..) => SawExprBlock,
ExprAssign(..) => SawExprAssign, ExprAssign(..) => SawExprAssign,
ExprAssignOp(op, _, _) => SawExprAssignOp(op), ExprAssignOp(op, _, _) => SawExprAssignOp(op),
ExprField(_, id, _) => SawExprField(content(id)), ExprField(_, id, _) => SawExprField(content(id.node)),
ExprIndex(..) => SawExprIndex, ExprIndex(..) => SawExprIndex,
ExprPath(..) => SawExprPath, ExprPath(..) => SawExprPath,
ExprAddrOf(m, _) => SawExprAddrOf(m), ExprAddrOf(m, _) => SawExprAddrOf(m),

View file

@ -235,7 +235,7 @@ impl<'a> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a> {
self.lookup_and_handle_method(expr.id, expr.span); self.lookup_and_handle_method(expr.id, expr.span);
} }
ast::ExprField(ref lhs, ref ident, _) => { ast::ExprField(ref lhs, ref ident, _) => {
self.handle_field_access(&**lhs, ident); self.handle_field_access(&**lhs, &ident.node);
} }
_ => () _ => ()
} }

View file

@ -447,7 +447,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
ast::ExprField(ref base, f_name, _) => { ast::ExprField(ref base, f_name, _) => {
let base_cmt = if_ok!(self.cat_expr(&**base)); let base_cmt = if_ok!(self.cat_expr(&**base));
Ok(self.cat_field(expr, base_cmt, f_name, expr_ty)) Ok(self.cat_field(expr, base_cmt, f_name.node, expr_ty))
} }
ast::ExprIndex(ref base, _) => { ast::ExprIndex(ref base, _) => {

View file

@ -303,7 +303,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
match ty.node { match ty.node {
ast::TyPath(_, _, id) => { ast::TyPath(_, _, id) => {
match self.tcx.def_map.borrow().get_copy(&id) { match self.tcx.def_map.borrow().get_copy(&id) {
def::DefPrimTy(..) => {}, def::DefPrimTy(..) | def::DefTyParam(..) => {},
def => { def => {
let did = def.def_id(); let did = def.def_id();
if is_local(did) { if is_local(did) {
@ -801,7 +801,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
ast::ExprField(ref base, ident, _) => { ast::ExprField(ref base, ident, _) => {
match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty { match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
ty::ty_struct(id, _) => { ty::ty_struct(id, _) => {
self.check_field(expr.span, id, NamedField(ident)); self.check_field(expr.span, id, NamedField(ident.node));
} }
_ => {} _ => {}
} }

View file

@ -5241,7 +5241,7 @@ impl<'a> Resolver<'a> {
// field, we need to add any trait methods we find that match // field, we need to add any trait methods we find that match
// the field name so that we can do some nice error reporting // the field name so that we can do some nice error reporting
// later on in typeck. // later on in typeck.
let traits = self.search_for_traits_containing_method(ident.name); let traits = self.search_for_traits_containing_method(ident.node.name);
self.trait_map.insert(expr.id, traits); self.trait_map.insert(expr.id, traits);
} }
ExprMethodCall(ident, _, _) => { ExprMethodCall(ident, _, _) => {

View file

@ -1210,7 +1210,7 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
ty::ty_struct(def_id, _) => { ty::ty_struct(def_id, _) => {
let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id); let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
for f in fields.iter() { for f in fields.iter() {
if f.name == ident.name { if f.name == ident.node.name {
let sub_span = self.span.span_for_last_ident(ex.span); let sub_span = self.span.span_for_last_ident(ex.span);
self.fmt.ref_str(recorder::VarRef, self.fmt.ref_str(recorder::VarRef,
ex.span, ex.span,

View file

@ -419,7 +419,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
let brepr = adt::represent_type(cx, bt); let brepr = adt::represent_type(cx, bt);
let (bv, inlineable) = const_expr(cx, &**base, is_local); let (bv, inlineable) = const_expr(cx, &**base, is_local);
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| { expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
let ix = ty::field_idx_strict(cx.tcx(), field.name, field_tys); let ix = ty::field_idx_strict(cx.tcx(), field.node.name, field_tys);
(adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable) (adt::const_get_field(cx, &*brepr, bv, discr, ix), inlineable)
}) })
} }

View file

@ -237,7 +237,7 @@ impl TypeMap {
metadata: DIType) { metadata: DIType) {
if !self.type_to_metadata.insert(ty::type_id(type_), metadata) { if !self.type_to_metadata.insert(ty::type_id(type_), metadata) {
cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!", cx.sess().bug(format!("Type metadata for ty::t '{}' is already in the TypeMap!",
ppaux::ty_to_str(cx.tcx(), type_)).as_slice()); ppaux::ty_to_str(cx.tcx(), type_)).as_slice());
} }
} }
@ -291,6 +291,8 @@ impl TypeMap {
// :return-type-uid: : (:bounds:)*} // :return-type-uid: : (:bounds:)*}
// function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \ // function -> {<unsafe_> <abi_> fn( (:param-uid:)* <,_...> ) -> \
// :return-type-uid:} // :return-type-uid:}
// unique vec box (~[]) -> {HEAP_VEC_BOX<:pointee-uid:>}
// gc box -> {GC_BOX<:pointee-uid:>}
match self.type_to_unique_id.find_copy(&ty::type_id(type_)) { match self.type_to_unique_id.find_copy(&ty::type_id(type_)) {
Some(unique_type_id) => return unique_type_id, Some(unique_type_id) => return unique_type_id,
@ -552,6 +554,30 @@ impl TypeMap {
let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id)); let interner_key = self.unique_id_interner.intern(Rc::new(enum_variant_type_id));
UniqueTypeId(interner_key) UniqueTypeId(interner_key)
} }
fn get_unique_type_id_of_heap_vec_box(&mut self,
cx: &CrateContext,
element_type: ty::t)
-> UniqueTypeId {
let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
let heap_vec_box_type_id = format!("$$HEAP_VEC_BOX<{}>$$",
self.get_unique_type_id_as_string(element_type_id)
.as_slice());
let interner_key = self.unique_id_interner.intern(Rc::new(heap_vec_box_type_id));
UniqueTypeId(interner_key)
}
fn get_unique_type_id_of_gc_box(&mut self,
cx: &CrateContext,
element_type: ty::t)
-> UniqueTypeId {
let element_type_id = self.get_unique_type_id_of_type(cx, element_type);
let gc_box_type_id = format!("$$GC_BOX<{}>$$",
self.get_unique_type_id_as_string(element_type_id)
.as_slice());
let interner_key = self.unique_id_interner.intern(Rc::new(gc_box_type_id));
UniqueTypeId(interner_key)
}
} }
@ -1677,9 +1703,9 @@ fn create_and_register_recursive_type_forward_declaration(
impl RecursiveTypeDescription { impl RecursiveTypeDescription {
// Finishes up the description of the type in question (mostly by providing descriptions of the // Finishes up the description of the type in question (mostly by providing descriptions of the
// fields of the given type) and returns the final type metadata. // fields of the given type) and returns the final type metadata.
fn finalize(&self, cx: &CrateContext) -> DICompositeType { fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
match *self { match *self {
FinalMetadata(metadata) => metadata, FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
UnfinishedMetadata { UnfinishedMetadata {
unfinished_type, unfinished_type,
unique_type_id, unique_type_id,
@ -1713,7 +1739,7 @@ impl RecursiveTypeDescription {
member_descriptions.as_slice(), member_descriptions.as_slice(),
file_metadata, file_metadata,
codemap::DUMMY_SP); codemap::DUMMY_SP);
return metadata_stub; return MetadataCreationResult::new(metadata_stub, true);
} }
} }
} }
@ -2459,14 +2485,22 @@ fn create_struct_stub(cx: &CrateContext,
} }
fn at_box_metadata(cx: &CrateContext, fn at_box_metadata(cx: &CrateContext,
at_pointer_type: ty::t,
content_type: ty::t, content_type: ty::t,
unique_type_id: UniqueTypeId) -> DIType { unique_type_id: UniqueTypeId)
-> MetadataCreationResult {
let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => return MetadataCreationResult::new(metadata, true),
None => { /* proceed */ }
};
let content_type_name = ppaux::ty_to_str(cx.tcx(), content_type); let content_type_name = ppaux::ty_to_str(cx.tcx(), content_type);
let content_type_name = content_type_name.as_slice(); let content_type_name = content_type_name.as_slice();
let content_llvm_type = type_of::type_of(cx, content_type); let content_llvm_type = type_of::type_of(cx, content_type);
let content_type_metadata = type_metadata(cx, content_type, codemap::DUMMY_SP);
let box_type_name = format!("Boxed<{}>", content_type_name); let box_type_name = format!("GcBox<{}>", content_type_name);
let box_llvm_type = Type::at_box(cx, content_llvm_type); let box_llvm_type = Type::at_box(cx, content_llvm_type);
let member_llvm_types = box_llvm_type.field_types(); let member_llvm_types = box_llvm_type.field_types();
assert!(box_layout_is_correct(cx, assert!(box_layout_is_correct(cx,
@ -2513,16 +2547,24 @@ fn at_box_metadata(cx: &CrateContext,
let loc = span_start(cx, codemap::DUMMY_SP); let loc = span_start(cx, codemap::DUMMY_SP);
let file_metadata = file_metadata(cx, loc.file.name.as_slice()); let file_metadata = file_metadata(cx, loc.file.name.as_slice());
return composite_type_metadata( let gc_box_unique_id = debug_context(cx).type_map
.borrow_mut()
.get_unique_type_id_of_gc_box(cx, content_type);
let gc_box_metadata = composite_type_metadata(
cx, cx,
box_llvm_type, box_llvm_type,
box_type_name.as_slice(), box_type_name.as_slice(),
unique_type_id, gc_box_unique_id,
member_descriptions, member_descriptions,
file_metadata, file_metadata,
file_metadata, file_metadata,
codemap::DUMMY_SP); codemap::DUMMY_SP);
let gc_pointer_metadata = pointer_type_metadata(cx, at_pointer_type, gc_box_metadata);
return MetadataCreationResult::new(gc_pointer_metadata, false);
// Unfortunately, we cannot assert anything but the correct types here---and not whether the // Unfortunately, we cannot assert anything but the correct types here---and not whether the
// 'next' and 'prev' pointers are in the correct order. // 'next' and 'prev' pointers are in the correct order.
fn box_layout_is_correct(cx: &CrateContext, fn box_layout_is_correct(cx: &CrateContext,
@ -2540,11 +2582,18 @@ fn at_box_metadata(cx: &CrateContext,
fn fixed_vec_metadata(cx: &CrateContext, fn fixed_vec_metadata(cx: &CrateContext,
unique_type_id: UniqueTypeId,
element_type: ty::t, element_type: ty::t,
len: uint, len: uint,
span: Span) span: Span)
-> DIType { -> MetadataCreationResult {
let element_type_metadata = type_metadata(cx, element_type, span); let element_type_metadata = type_metadata(cx, element_type, span);
match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => return MetadataCreationResult::new(metadata, true),
None => { /* proceed */ }
};
let element_llvm_type = type_of::type_of(cx, element_type); let element_llvm_type = type_of::type_of(cx, element_type);
let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type); let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
@ -2556,7 +2605,7 @@ fn fixed_vec_metadata(cx: &CrateContext,
}; };
let subscripts = create_DIArray(DIB(cx), [subrange]); let subscripts = create_DIArray(DIB(cx), [subrange]);
return unsafe { let metadata = unsafe {
llvm::LLVMDIBuilderCreateArrayType( llvm::LLVMDIBuilderCreateArrayType(
DIB(cx), DIB(cx),
bytes_to_bits(element_type_size * (len as u64)), bytes_to_bits(element_type_size * (len as u64)),
@ -2564,24 +2613,30 @@ fn fixed_vec_metadata(cx: &CrateContext,
element_type_metadata, element_type_metadata,
subscripts) subscripts)
}; };
return MetadataCreationResult::new(metadata, false);
} }
fn heap_vec_metadata(cx: &CrateContext, fn heap_vec_metadata(cx: &CrateContext,
vec_type: ty::t, vec_pointer_type: ty::t,
element_type: ty::t, element_type: ty::t,
unique_type_id: UniqueTypeId, unique_type_id: UniqueTypeId,
span: Span) span: Span)
-> DICompositeType { -> MetadataCreationResult {
let element_type_metadata = type_metadata(cx, element_type, span); let element_type_metadata = type_metadata(cx, element_type, span);
let element_llvm_type = type_of::type_of(cx, element_type); let element_llvm_type = type_of::type_of(cx, element_type);
let (element_size, element_align) = size_and_align_of(cx, element_llvm_type); let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
let vec_llvm_type = Type::vec(cx, &element_llvm_type); match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
let vec_type_name = ppaux::ty_to_str(cx.tcx(), vec_type); Some(metadata) => return MetadataCreationResult::new(metadata, true),
let vec_type_name = vec_type_name.as_slice(); None => { /* proceed */ }
};
let member_llvm_types = vec_llvm_type.field_types(); let vecbox_llvm_type = Type::vec(cx, &element_llvm_type);
let vec_pointer_type_name = ppaux::ty_to_str(cx.tcx(), vec_pointer_type);
let vec_pointer_type_name = vec_pointer_type_name.as_slice();
let member_llvm_types = vecbox_llvm_type.field_types();
let int_type_metadata = type_metadata(cx, ty::mk_int(), span); let int_type_metadata = type_metadata(cx, ty::mk_int(), span);
let array_type_metadata = unsafe { let array_type_metadata = unsafe {
@ -2619,15 +2674,20 @@ fn heap_vec_metadata(cx: &CrateContext,
let loc = span_start(cx, span); let loc = span_start(cx, span);
let file_metadata = file_metadata(cx, loc.file.name.as_slice()); let file_metadata = file_metadata(cx, loc.file.name.as_slice());
composite_type_metadata( let vec_box_unique_id = debug_context(cx).type_map
cx, .borrow_mut()
vec_llvm_type, .get_unique_type_id_of_heap_vec_box(cx, element_type);
vec_type_name,
unique_type_id, let vecbox_metadata = composite_type_metadata(cx,
member_descriptions, vecbox_llvm_type,
file_metadata, vec_pointer_type_name,
file_metadata, vec_box_unique_id,
span) member_descriptions,
file_metadata,
file_metadata,
span);
MetadataCreationResult::new(pointer_type_metadata(cx, vec_pointer_type, vecbox_metadata), false)
} }
fn vec_slice_metadata(cx: &CrateContext, fn vec_slice_metadata(cx: &CrateContext,
@ -2635,9 +2695,18 @@ fn vec_slice_metadata(cx: &CrateContext,
element_type: ty::t, element_type: ty::t,
unique_type_id: UniqueTypeId, unique_type_id: UniqueTypeId,
span: Span) span: Span)
-> DICompositeType { -> MetadataCreationResult {
let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
ty: element_type,
mutbl: ast::MutImmutable
});
debug!("vec_slice_metadata: {:?}", ty::get(vec_type)); let element_type_metadata = type_metadata(cx, data_ptr_type, span);
match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => return MetadataCreationResult::new(metadata, true),
None => { /* proceed */ }
};
let slice_llvm_type = type_of::type_of(cx, vec_type); let slice_llvm_type = type_of::type_of(cx, vec_type);
let slice_type_name = ppaux::ty_to_str(cx.tcx(), vec_type); let slice_type_name = ppaux::ty_to_str(cx.tcx(), vec_type);
@ -2646,17 +2715,11 @@ fn vec_slice_metadata(cx: &CrateContext,
assert!(slice_layout_is_correct(cx, assert!(slice_layout_is_correct(cx,
member_llvm_types.as_slice(), member_llvm_types.as_slice(),
element_type)); element_type));
let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
ty: element_type,
mutbl: ast::MutImmutable
});
let member_descriptions = [ let member_descriptions = [
MemberDescription { MemberDescription {
name: "data_ptr".to_string(), name: "data_ptr".to_string(),
llvm_type: *member_llvm_types.get(0), llvm_type: *member_llvm_types.get(0),
type_metadata: type_metadata(cx, data_ptr_type, span), type_metadata: element_type_metadata,
offset: ComputedMemberOffset, offset: ComputedMemberOffset,
}, },
MemberDescription { MemberDescription {
@ -2672,15 +2735,15 @@ fn vec_slice_metadata(cx: &CrateContext,
let loc = span_start(cx, span); let loc = span_start(cx, span);
let file_metadata = file_metadata(cx, loc.file.name.as_slice()); let file_metadata = file_metadata(cx, loc.file.name.as_slice());
return composite_type_metadata( let metadata = composite_type_metadata(cx,
cx, slice_llvm_type,
slice_llvm_type, slice_type_name.as_slice(),
slice_type_name.as_slice(), unique_type_id,
unique_type_id, member_descriptions,
member_descriptions, file_metadata,
file_metadata, file_metadata,
file_metadata, span);
span); return MetadataCreationResult::new(metadata, false);
fn slice_layout_is_correct(cx: &CrateContext, fn slice_layout_is_correct(cx: &CrateContext,
member_llvm_types: &[Type], member_llvm_types: &[Type],
@ -2693,12 +2756,12 @@ fn vec_slice_metadata(cx: &CrateContext,
} }
fn subroutine_type_metadata(cx: &CrateContext, fn subroutine_type_metadata(cx: &CrateContext,
unique_type_id: UniqueTypeId,
signature: &ty::FnSig, signature: &ty::FnSig,
span: Span) span: Span)
-> DICompositeType { -> MetadataCreationResult {
let loc = span_start(cx, span); let loc = span_start(cx, span);
let file_metadata = file_metadata(cx, loc.file.name.as_slice()); let file_metadata = file_metadata(cx, loc.file.name.as_slice());
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1); let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
// return type // return type
@ -2712,12 +2775,19 @@ fn subroutine_type_metadata(cx: &CrateContext,
signature_metadata.push(type_metadata(cx, argument_type, span)); signature_metadata.push(type_metadata(cx, argument_type, span));
} }
return unsafe { match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
llvm::LLVMDIBuilderCreateSubroutineType( Some(metadata) => return MetadataCreationResult::new(metadata, true),
DIB(cx), None => { /* proceed */ }
file_metadata,
create_DIArray(DIB(cx), signature_metadata.as_slice()))
}; };
return MetadataCreationResult::new(
unsafe {
llvm::LLVMDIBuilderCreateSubroutineType(
DIB(cx),
file_metadata,
create_DIArray(DIB(cx), signature_metadata.as_slice()))
},
false);
} }
fn trait_metadata(cx: &CrateContext, fn trait_metadata(cx: &CrateContext,
@ -2758,7 +2828,6 @@ fn trait_metadata(cx: &CrateContext,
definition_span) definition_span)
} }
fn type_metadata(cx: &CrateContext, fn type_metadata(cx: &CrateContext,
t: ty::t, t: ty::t,
usage_site_span: Span) usage_site_span: Span)
@ -2766,20 +2835,25 @@ fn type_metadata(cx: &CrateContext,
// Get the unique type id of this type. // Get the unique type id of this type.
let unique_type_id = { let unique_type_id = {
let mut type_map = debug_context(cx).type_map.borrow_mut(); let mut type_map = debug_context(cx).type_map.borrow_mut();
// First, try to find the type in TypeMap. If we have seen it before, we can exit early here
match type_map.find_metadata_for_type(t) { match type_map.find_metadata_for_type(t) {
Some(metadata) => { Some(metadata) => {
return metadata; return metadata;
}, },
None => { None => {
// The ty::t is not in the TypeMap but maybe we have already seen an equivalent type
// (e.g. only differing in region arguments). In order to find out, generate the
// unique type id and look that up.
let unique_type_id = type_map.get_unique_type_id_of_type(cx, t); let unique_type_id = type_map.get_unique_type_id_of_type(cx, t);
match type_map.find_metadata_for_unique_id(unique_type_id) { match type_map.find_metadata_for_unique_id(unique_type_id) {
Some(metadata) => { Some(metadata) => {
// There is already an equivalent type in the TypeMap. Register this ty::t
// as an alias in the cache and return the cached metadata
type_map.register_type_with_metadata(cx, t, metadata); type_map.register_type_with_metadata(cx, t, metadata);
return metadata; return metadata;
}, },
None => { None => {
// There really is no type metadata for this type, so proceed by creating // There really is no type metadata for this type, so proceed by creating it
// it
unique_type_id unique_type_id
} }
} }
@ -2799,7 +2873,7 @@ fn type_metadata(cx: &CrateContext,
) )
let sty = &ty::get(t).sty; let sty = &ty::get(t).sty;
let (type_metadata, should_already_be_stored_in_typemap) = match *sty { let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
ty::ty_nil | ty::ty_nil |
ty::ty_bot | ty::ty_bot |
ty::ty_bool | ty::ty_bool |
@ -2807,73 +2881,54 @@ fn type_metadata(cx: &CrateContext,
ty::ty_int(_) | ty::ty_int(_) |
ty::ty_uint(_) | ty::ty_uint(_) |
ty::ty_float(_) => { ty::ty_float(_) => {
(basic_type_metadata(cx, t), false) MetadataCreationResult::new(basic_type_metadata(cx, t), false)
} }
ty::ty_enum(def_id, _) => { ty::ty_enum(def_id, _) => {
let is_c_style_enum = match *adt::represent_type(cx, t) { prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
adt::CEnum(..) => true,
_ => false
};
(prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx),
!is_c_style_enum)
} }
ty::ty_box(pointee_type) => { ty::ty_box(pointee_type) => {
let box_content_metadata = at_box_metadata(cx, pointee_type, unique_type_id); at_box_metadata(cx, t, pointee_type, unique_type_id)
return_if_created_in_meantime!();
(pointer_type_metadata(cx, t, box_content_metadata), false)
} }
ty::ty_vec(ref mt, Some(len)) => { ty::ty_vec(ref mt, Some(len)) => {
(fixed_vec_metadata(cx, mt.ty, len, usage_site_span), false) fixed_vec_metadata(cx, unique_type_id, mt.ty, len, usage_site_span)
} }
ty::ty_uniq(pointee_type) => { ty::ty_uniq(pointee_type) => {
(match ty::get(pointee_type).sty { match ty::get(pointee_type).sty {
ty::ty_vec(ref mt, None) => { ty::ty_vec(ref mt, None) => {
let vec_metadata = heap_vec_metadata(cx, heap_vec_metadata(cx, pointee_type, mt.ty, unique_type_id, usage_site_span)
pointee_type,
mt.ty,
unique_type_id,
usage_site_span);
return_if_created_in_meantime!();
pointer_type_metadata(cx, t, vec_metadata)
} }
ty::ty_str => { ty::ty_str => {
let i8_t = ty::mk_i8(); let i8_t = ty::mk_i8();
let vec_metadata = heap_vec_metadata(cx, heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
pointee_type,
i8_t,
unique_type_id,
usage_site_span);
pointer_type_metadata(cx, t, vec_metadata)
} }
_ => { _ => {
let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span); let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
return_if_created_in_meantime!(); return_if_created_in_meantime!();
pointer_type_metadata(cx, t, pointee_metadata) MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee_metadata),
false)
} }
}, false) }
} }
ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => { ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
(match ty::get(mt.ty).sty { match ty::get(mt.ty).sty {
ty::ty_vec(ref mt, None) => { ty::ty_vec(ref mt, None) => {
vec_slice_metadata(cx, t, mt.ty, unique_type_id, usage_site_span) vec_slice_metadata(cx, t, mt.ty, unique_type_id, usage_site_span)
} }
ty::ty_str => { ty::ty_str => {
let i8_t = ty::mk_i8(); vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
vec_slice_metadata(cx, t, i8_t, unique_type_id, usage_site_span)
} }
_ => { _ => {
let pointee = type_metadata(cx, mt.ty, usage_site_span); let pointee = type_metadata(cx, mt.ty, usage_site_span);
return_if_created_in_meantime!(); return_if_created_in_meantime!();
pointer_type_metadata(cx, t, pointee) MetadataCreationResult::new(pointer_type_metadata(cx, t, pointee), false)
} }
}, false) }
} }
ty::ty_bare_fn(ref barefnty) => { ty::ty_bare_fn(ref barefnty) => {
(subroutine_type_metadata(cx, &barefnty.sig, usage_site_span), false) subroutine_type_metadata(cx, unique_type_id, &barefnty.sig, usage_site_span)
} }
ty::ty_closure(ref closurety) => { ty::ty_closure(ref closurety) => {
(subroutine_type_metadata(cx, &closurety.sig, usage_site_span), false) subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
} }
ty::ty_trait(box ty::TyTrait { ty::ty_trait(box ty::TyTrait {
def_id, def_id,
@ -2881,24 +2936,24 @@ fn type_metadata(cx: &CrateContext,
store, store,
ref bounds ref bounds
}) => { }) => {
(trait_metadata(cx, def_id, t, substs, store, bounds, unique_type_id), false) MetadataCreationResult::new(
trait_metadata(cx, def_id, t, substs, store, bounds, unique_type_id),
false)
} }
ty::ty_struct(def_id, ref substs) => { ty::ty_struct(def_id, ref substs) => {
let struct_metadata = prepare_struct_metadata(cx, prepare_struct_metadata(cx,
t, t,
def_id, def_id,
substs, substs,
unique_type_id, unique_type_id,
usage_site_span).finalize(cx); usage_site_span).finalize(cx)
(struct_metadata, true)
} }
ty::ty_tup(ref elements) => { ty::ty_tup(ref elements) => {
let tuple_metadata = prepare_tuple_metadata(cx, prepare_tuple_metadata(cx,
t, t,
elements.as_slice(), elements.as_slice(),
unique_type_id, unique_type_id,
usage_site_span).finalize(cx); usage_site_span).finalize(cx)
(tuple_metadata, true)
} }
_ => { _ => {
cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}", cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}",
@ -2909,33 +2964,57 @@ fn type_metadata(cx: &CrateContext,
{ {
let mut type_map = debug_context(cx).type_map.borrow_mut(); let mut type_map = debug_context(cx).type_map.borrow_mut();
if should_already_be_stored_in_typemap { if already_stored_in_typemap {
// Make sure that we already have a TypeMap entry entry for the ty::t.
if type_map.find_metadata_for_type(t).is_none() {
let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
let error_message = format!("Expected type metadata for ty::t '{}' to already be in
the TypeMap but it was not (unique type id = {})",
ppaux::ty_to_str(cx.tcx(), t),
unique_type_id_str.as_slice());
cx.sess().span_bug(usage_site_span, error_message.as_slice());
}
// Also make sure that we already have a TypeMap entry entry for the unique type id. // Also make sure that we already have a TypeMap entry entry for the unique type id.
if type_map.find_metadata_for_unique_id(unique_type_id).is_none() { let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id); Some(metadata) => metadata,
let error_message = format!("Expected type metadata for unique type id '{}' to None => {
already be in the TypeMap but it was not. (ty::t = {})", let unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
unique_type_id_str.as_slice(), let error_message = format!("Expected type metadata for unique type id '{}' to \
ppaux::ty_to_str(cx.tcx(), t)); already be in the debuginfo::TypeMap but it was not. (ty::t = {})",
cx.sess().span_bug(usage_site_span, error_message.as_slice()); unique_type_id_str.as_slice(),
ppaux::ty_to_str(cx.tcx(), t));
cx.sess().span_bug(usage_site_span, error_message.as_slice());
}
};
match type_map.find_metadata_for_type(t) {
Some(metadata) => {
if metadata != metadata_for_uid {
let unique_type_id_str =
type_map.get_unique_type_id_as_string(unique_type_id);
let error_message = format!("Mismatch between ty::t and UniqueTypeId maps \
in debuginfo::TypeMap. UniqueTypeId={}, ty::t={}",
unique_type_id_str.as_slice(),
ppaux::ty_to_str(cx.tcx(), t));
cx.sess().span_bug(usage_site_span, error_message.as_slice());
}
}
None => {
type_map.register_type_with_metadata(cx, t, metadata);
}
} }
} else { } else {
type_map.register_type_with_metadata(cx, t, type_metadata); type_map.register_type_with_metadata(cx, t, metadata);
type_map.register_unique_id_with_metadata(cx, unique_type_id, type_metadata); type_map.register_unique_id_with_metadata(cx, unique_type_id, metadata);
} }
} }
type_metadata metadata
}
struct MetadataCreationResult {
metadata: DIType,
already_stored_in_typemap: bool
}
impl MetadataCreationResult {
fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationResult {
MetadataCreationResult {
metadata: metadata,
already_stored_in_typemap: already_stored_in_typemap
}
}
} }
#[deriving(PartialEq)] #[deriving(PartialEq)]

View file

@ -389,7 +389,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
trans_def(bcx, expr, bcx.def(expr.id)) trans_def(bcx, expr, bcx.def(expr.id))
} }
ast::ExprField(ref base, ident, _) => { ast::ExprField(ref base, ident, _) => {
trans_rec_field(bcx, &**base, ident) trans_rec_field(bcx, &**base, ident.node)
} }
ast::ExprIndex(ref base, ref idx) => { ast::ExprIndex(ref base, ref idx) => {
trans_index(bcx, expr, &**base, &**idx) trans_index(bcx, expr, &**base, &**idx)

View file

@ -2352,7 +2352,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
expr: &ast::Expr, expr: &ast::Expr,
lvalue_pref: LvaluePreference, lvalue_pref: LvaluePreference,
base: &ast::Expr, base: &ast::Expr,
field: ast::Name, field: &ast::SpannedIdent,
tys: &[ast::P<ast::Ty>]) { tys: &[ast::P<ast::Ty>]) {
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
check_expr_with_lvalue_pref(fcx, base, lvalue_pref); check_expr_with_lvalue_pref(fcx, base, lvalue_pref);
@ -2365,7 +2365,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
ty::ty_struct(base_id, ref substs) => { ty::ty_struct(base_id, ref substs) => {
debug!("struct named {}", ppaux::ty_to_str(tcx, base_t)); debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
let fields = ty::lookup_struct_fields(tcx, base_id); let fields = ty::lookup_struct_fields(tcx, base_id);
lookup_field_ty(tcx, base_id, fields.as_slice(), field, &(*substs)) lookup_field_ty(tcx, base_id, fields.as_slice(),
field.node.name, &(*substs))
} }
_ => None _ => None
} }
@ -2383,7 +2384,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
match method::lookup(fcx, match method::lookup(fcx,
expr, expr,
base, base,
field, field.node.name,
expr_t, expr_t,
tps.as_slice(), tps.as_slice(),
DontDerefArgs, DontDerefArgs,
@ -2392,14 +2393,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
IgnoreStaticMethods) { IgnoreStaticMethods) {
Some(_) => { Some(_) => {
fcx.type_error_message( fcx.type_error_message(
expr.span, field.span,
|actual| { |actual| {
format!("attempted to take value of method `{}` on type \ format!("attempted to take value of method `{}` on type \
`{}`", token::get_name(field), actual) `{}`", token::get_ident(field.node), actual)
}, },
expr_t, None); expr_t, None);
tcx.sess.span_note(expr.span, tcx.sess.span_note(field.span,
"maybe a missing `()` to call it? If not, try an anonymous function."); "maybe a missing `()` to call it? If not, try an anonymous function.");
} }
@ -2410,7 +2411,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
format!("attempted access of field `{}` on \ format!("attempted access of field `{}` on \
type `{}`, but no field with that \ type `{}`, but no field with that \
name was found", name was found",
token::get_name(field), token::get_ident(field.node),
actual) actual)
}, },
expr_t, None); expr_t, None);
@ -3214,7 +3215,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
} }
} }
ast::ExprField(ref base, ref field, ref tys) => { ast::ExprField(ref base, ref field, ref tys) => {
check_field(fcx, expr, lvalue_pref, &**base, field.name, tys.as_slice()); check_field(fcx, expr, lvalue_pref, &**base, field, tys.as_slice());
} }
ast::ExprIndex(ref base, ref idx) => { ast::ExprIndex(ref base, ref idx) => {
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref); check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);

View file

@ -351,8 +351,8 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
ty_uint(t) => ast_util::uint_ty_to_str(t, None, ty_uint(t) => ast_util::uint_ty_to_str(t, None,
ast_util::AutoSuffix).to_string(), ast_util::AutoSuffix).to_string(),
ty_float(t) => ast_util::float_ty_to_str(t).to_string(), ty_float(t) => ast_util::float_ty_to_str(t).to_string(),
ty_box(typ) => format!("@{}", ty_to_str(cx, typ)), ty_box(typ) => format!("Gc<{}>", ty_to_str(cx, typ)),
ty_uniq(typ) => format!("~{}", ty_to_str(cx, typ)), ty_uniq(typ) => format!("Box<{}>", ty_to_str(cx, typ)),
ty_ptr(ref tm) => format!("*{}", mt_to_str(cx, tm)), ty_ptr(ref tm) => format!("*{}", mt_to_str(cx, tm)),
ty_rptr(r, ref tm) => { ty_rptr(r, ref tm) => {
let mut buf = region_ptr_to_str(cx, r); let mut buf = region_ptr_to_str(cx, r);

View file

@ -146,7 +146,7 @@ pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
// means that if we want to perform valid FFI on windows, then we need // means that if we want to perform valid FFI on windows, then we need
// to ensure that the stack bounds are what they truly are for this // to ensure that the stack bounds are what they truly are for this
// task. More info can be found at: // task. More info can be found at:
// https://github.com/mozilla/rust/issues/3445#issuecomment-26114839 // https://github.com/rust-lang/rust/issues/3445#issuecomment-26114839
// //
// stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom) // stack range is at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile"); asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");

View file

@ -183,7 +183,7 @@ fn main() {
## Using `ToJson` ## Using `ToJson`
This example use the ToJson impl to deserialize the JSON string. This example uses the ToJson impl to deserialize the JSON string.
Example of `ToJson` trait implementation for TestStruct1. Example of `ToJson` trait implementation for TestStruct1.
```rust ```rust

View file

@ -57,6 +57,16 @@ use libc::c_char;
#[cfg(windows)] #[cfg(windows)]
use str::OwnedStr; use str::OwnedStr;
/// Get the number of cores available
pub fn num_cpus() -> uint {
unsafe {
return rust_get_num_cpus();
}
extern {
fn rust_get_num_cpus() -> libc::uintptr_t;
}
}
pub static TMPBUF_SZ : uint = 1000u; pub static TMPBUF_SZ : uint = 1000u;
static BUF_BYTES : uint = 2048u; static BUF_BYTES : uint = 2048u;
@ -1762,6 +1772,11 @@ mod tests {
n n
} }
#[test]
fn test_num_cpus() {
assert!(os::num_cpus() > 0);
}
#[test] #[test]
fn test_setenv() { fn test_setenv() {
let n = make_rand_name(); let n = make_rand_name();

View file

@ -11,23 +11,11 @@
use from_str::FromStr; use from_str::FromStr;
use from_str::from_str; use from_str::from_str;
use libc::uintptr_t; use libc::uintptr_t;
use libc;
use option::{Some, None, Option}; use option::{Some, None, Option};
use os; use os;
use str::Str; use str::Str;
use sync::atomics; use sync::atomics;
/// Get the number of cores available
pub fn num_cpus() -> uint {
unsafe {
return rust_get_num_cpus();
}
extern {
fn rust_get_num_cpus() -> libc::uintptr_t;
}
}
/// Dynamically inquire about whether we're running under V. /// Dynamically inquire about whether we're running under V.
/// You should usually not use this unless your test definitely /// You should usually not use this unless your test definitely
/// can't run correctly un-altered. Valgrind is there to help /// can't run correctly un-altered. Valgrind is there to help
@ -81,7 +69,7 @@ pub fn default_sched_threads() -> uint {
if limit_thread_creation_due_to_osx_and_valgrind() { if limit_thread_creation_due_to_osx_and_valgrind() {
1 1
} else { } else {
num_cpus() os::num_cpus()
} }
} }
} }

View file

@ -132,7 +132,8 @@ impl<A:Send> Future<A> {
let (tx, rx) = channel(); let (tx, rx) = channel();
spawn(proc() { spawn(proc() {
tx.send(blk()); // Don't fail if the other end has hung up
let _ = tx.send_opt(blk());
}); });
Future::from_receiver(rx) Future::from_receiver(rx)
@ -144,6 +145,7 @@ mod test {
use prelude::*; use prelude::*;
use sync::Future; use sync::Future;
use task; use task;
use comm::{channel, Sender};
#[test] #[test]
fn test_from_value() { fn test_from_value() {
@ -206,4 +208,28 @@ mod test {
assert_eq!(actual, expected); assert_eq!(actual, expected);
}); });
} }
#[test]
fn test_dropped_future_doesnt_fail() {
struct Bomb(Sender<bool>);
local_data_key!(LOCAL: Bomb)
impl Drop for Bomb {
fn drop(&mut self) {
let Bomb(ref tx) = *self;
tx.send(task::failing());
}
}
// Spawn a future, but drop it immediately. When we receive the result
// later on, we should never view the task as having failed.
let (tx, rx) = channel();
drop(Future::spawn(proc() {
LOCAL.replace(Some(Bomb(tx)));
}));
// Make sure the future didn't fail the task.
assert!(!rx.recv());
}
} }

View file

@ -464,7 +464,7 @@ pub enum Expr_ {
ExprAssign(Gc<Expr>, Gc<Expr>), ExprAssign(Gc<Expr>, Gc<Expr>),
ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>), ExprAssignOp(BinOp, Gc<Expr>, Gc<Expr>),
ExprField(Gc<Expr>, Ident, Vec<P<Ty>>), ExprField(Gc<Expr>, SpannedIdent, Vec<P<Ty>>),
ExprIndex(Gc<Expr>, Gc<Expr>), ExprIndex(Gc<Expr>, Gc<Expr>),
/// Expression that looks like a "name". For example, /// Expression that looks like a "name". For example,
@ -977,7 +977,7 @@ pub enum ViewItem_ {
// ident: name used to refer to this crate in the code // ident: name used to refer to this crate in the code
// optional (InternedString,StrStyle): if present, this is a location // optional (InternedString,StrStyle): if present, this is a location
// (containing arbitrary characters) from which to fetch the crate sources // (containing arbitrary characters) from which to fetch the crate sources
// For example, extern crate whatever = "github.com/mozilla/rust" // For example, extern crate whatever = "github.com/rust-lang/rust"
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId), ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
ViewItemUse(Gc<ViewPath>), ViewItemUse(Gc<ViewPath>),
} }

View file

@ -12,8 +12,8 @@ use std::fmt;
/// CrateIds identify crates and include the crate name and optionally a path /// CrateIds identify crates and include the crate name and optionally a path
/// and version. In the full form, they look like relative URLs. Example: /// and version. In the full form, they look like relative URLs. Example:
/// `github.com/mozilla/rust#std:1.0` would be a package ID with a path of /// `github.com/rust-lang/rust#std:1.0` would be a package ID with a path of
/// `github.com/mozilla/rust` and a crate name of `std` with a version of /// `github.com/rust-lang/rust` and a crate name of `std` with a version of
/// `1.0`. If no crate name is given after the hash, the name is inferred to /// `1.0`. If no crate name is given after the hash, the name is inferred to
/// be the last component of the path. If no version is given, it is inferred /// be the last component of the path. If no version is given, it is inferred
/// to be `0.0`. /// to be `0.0`.

View file

@ -13,7 +13,7 @@ use ast::{P, Ident, Generics, NodeId, Expr};
use ast; use ast;
use ast_util; use ast_util;
use attr; use attr;
use codemap::{Span, respan, Spanned, DUMMY_SP}; use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
use ext::base::ExtCtxt; use ext::base::ExtCtxt;
use fold::Folder; use fold::Folder;
use owned_slice::OwnedSlice; use owned_slice::OwnedSlice;
@ -560,7 +560,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
} }
fn expr_field_access(&self, sp: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> { fn expr_field_access(&self, sp: Span, expr: Gc<ast::Expr>, ident: ast::Ident) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprField(expr, ident, Vec::new())) let field_name = token::get_ident(ident);
let field_span = Span {
lo: sp.lo - Pos::from_uint(field_name.get().len()),
hi: sp.hi,
expn_info: sp.expn_info,
};
let id = Spanned { node: ident, span: field_span };
self.expr(sp, ast::ExprField(expr, id, Vec::new()))
} }
fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> { fn expr_addr_of(&self, sp: Span, e: Gc<ast::Expr>) -> Gc<ast::Expr> {
self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e)) self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))

View file

@ -876,7 +876,7 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
} }
ExprField(el, id, ref tys) => { ExprField(el, id, ref tys) => {
ExprField(folder.fold_expr(el), ExprField(folder.fold_expr(el),
folder.fold_ident(id), respan(id.span, folder.fold_ident(id.node)),
tys.iter().map(|&x| folder.fold_ty(x)).collect()) tys.iter().map(|&x| folder.fold_ty(x)).collect())
} }
ExprIndex(el, er) => { ExprIndex(el, er) => {

View file

@ -1796,7 +1796,7 @@ impl<'a> Parser<'a> {
ExprIndex(expr, idx) ExprIndex(expr, idx)
} }
pub fn mk_field(&mut self, expr: Gc<Expr>, ident: Ident, pub fn mk_field(&mut self, expr: Gc<Expr>, ident: ast::SpannedIdent,
tys: Vec<P<Ty>>) -> ast::Expr_ { tys: Vec<P<Ty>>) -> ast::Expr_ {
ExprField(expr, ident, tys) ExprField(expr, ident, tys)
} }
@ -2090,7 +2090,8 @@ impl<'a> Parser<'a> {
e = self.mk_expr(lo, hi, nd); e = self.mk_expr(lo, hi, nd);
} }
_ => { _ => {
let field = self.mk_field(e, i, tys); let id = spanned(dot, hi, i);
let field = self.mk_field(e, id, tys);
e = self.mk_expr(lo, hi, field) e = self.mk_expr(lo, hi, field)
} }
} }

View file

@ -1487,7 +1487,7 @@ impl<'a> State<'a> {
ast::ExprField(ref expr, id, ref tys) => { ast::ExprField(ref expr, id, ref tys) => {
try!(self.print_expr(&**expr)); try!(self.print_expr(&**expr));
try!(word(&mut self.s, ".")); try!(word(&mut self.s, "."));
try!(self.print_ident(id)); try!(self.print_ident(id.node));
if tys.len() > 0u { if tys.len() > 0u {
try!(word(&mut self.s, "::<")); try!(word(&mut self.s, "::<"));
try!(self.commasep( try!(self.commasep(

View file

@ -26,13 +26,13 @@ struct fish {
fn main() { fn main() {
let a: clam = clam{x: box(GC) 1, y: box(GC) 2}; let a: clam = clam{x: box(GC) 1, y: box(GC) 2};
let b: clam = clam{x: box(GC) 10, y: box(GC) 20}; let b: clam = clam{x: box(GC) 10, y: box(GC) 20};
let z: int = a.x + b.y; //~ ERROR binary operation `+` cannot be applied to type `@int` let z: int = a.x + b.y; //~ ERROR binary operation `+` cannot be applied to type `Gc<int>`
println!("{:?}", z); println!("{:?}", z);
assert_eq!(z, 21); assert_eq!(z, 21);
let forty: fish = fish{a: box(GC) 40}; let forty: fish = fish{a: box(GC) 40};
let two: fish = fish{a: box(GC) 2}; let two: fish = fish{a: box(GC) 2};
let answer: int = forty.a + two.a; let answer: int = forty.a + two.a;
//~^ ERROR binary operation `+` cannot be applied to type `@int` //~^ ERROR binary operation `+` cannot be applied to type `Gc<int>`
println!("{:?}", answer); println!("{:?}", answer);
assert_eq!(answer, 42); assert_eq!(answer, 42);
} }

View file

@ -0,0 +1,21 @@
// 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 std::gc::{GC,Gc};
fn main() {
let x: Box<int> = box 0;
let y: Gc<int> = box (GC) 0;
println!("{}", x + 1); //~ ERROR binary operation `+` cannot be applied to type `Box<int>`
//~^ ERROR cannot determine a type for this bounded type parameter: unconstrained type
println!("{}", y + 1);
//~^ ERROR binary operation `+` cannot be applied to type `Gc<int>`
}

View file

@ -32,7 +32,7 @@ struct A {
fn main() { fn main() {
let a = A {v: box B{v: None} as Box<Foo+Send>}; let a = A {v: box B{v: None} as Box<Foo+Send>};
//~^ ERROR cannot pack type `~B`, which does not fulfill `Send` //~^ ERROR cannot pack type `Box<B>`, which does not fulfill `Send`
let v = Rc::new(RefCell::new(a)); let v = Rc::new(RefCell::new(a));
let w = v.clone(); let w = v.clone();
let b = &*v; let b = &*v;

View file

@ -16,7 +16,7 @@ struct BarStruct;
impl<'a> BarStruct { impl<'a> BarStruct {
fn foo(&'a mut self) -> Gc<BarStruct> { self } fn foo(&'a mut self) -> Gc<BarStruct> { self }
//~^ ERROR: error: mismatched types: expected `@BarStruct` but found `&'a mut BarStruct //~^ ERROR: error: mismatched types: expected `Gc<BarStruct>` but found `&'a mut BarStruct
} }
fn main() {} fn main() {}

View file

@ -28,7 +28,16 @@ impl Point {
fn main() { fn main() {
let point: Point = Point::new(); let point: Point = Point::new();
let px: int = point.get_x;//~ ERROR attempted to take value of method `get_x` on type `Point` let px: int = point
//~^ NOTE maybe a missing `()` to call it? If not, try an anonymous function. .get_x;//~ ERROR attempted to take value of method `get_x` on type `Point`
//~^ NOTE maybe a missing `()` to call it? If not, try an anonymous
// Ensure the span is useful
let ys = &[1,2,3,4,5,6,7];
let a = ys.iter()
.map(|x| x)
.filter(|&&x| x == 1)
.filter_map; //~ ERROR attempted to take value of method `filter_map` on type
//~^ NOTE maybe a missing `()` to call it? If not, try an anonymous function.
} }

View file

@ -33,7 +33,7 @@ impl<'a> set_f<'a> for c<'a> {
} }
fn set_f_bad(&self, b: Gc<b>) { fn set_f_bad(&self, b: Gc<b>) {
self.f = b; //~ ERROR mismatched types: expected `@@&'a int` but found `@@&int` self.f = b; //~ ERROR mismatched types: expected `Gc<Gc<&'a int>>` but found `Gc<Gc<&int>>`
//~^ ERROR cannot infer //~^ ERROR cannot infer
} }
} }

View file

@ -4,8 +4,8 @@
ifndef IS_WINDOWS ifndef IS_WINDOWS
all: all:
$(RUSTDOC) --test foo.rs $(HOST_RPATH_ENV) $(RUSTDOC) --test foo.rs
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
cp verify.sh $(TMPDIR) cp verify.sh $(TMPDIR)
$(call RUN,verify.sh) $(TMPDIR) $(call RUN,verify.sh) $(TMPDIR)

View file

@ -1,4 +1,4 @@
-include ../tools.mk -include ../tools.mk
all: all:
$(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs $(HOST_RPATH_ENV) $(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
$(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json $(HOST_RPATH_ENV) $(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json

View file

@ -1,5 +1,5 @@
-include ../tools.mk -include ../tools.mk
all: all:
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs $(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
cp verify.sh $(TMPDIR) cp verify.sh $(TMPDIR)
$(call RUN,verify.sh) $(TMPDIR) $(call RUN,verify.sh) $(TMPDIR)

View file

@ -1,15 +1,15 @@
export LD_LIBRARY_PATH:=$(TMPDIR):$(LD_LIBRARY_PATH) export LD_LIBRARY_PATH:=$(TMPDIR):$(LD_LIBRARY_PATH)
export DYLD_LIBRARY_PATH:=$(TMPDIR):$(DYLD_LIBRARY_PATH) export DYLD_LIBRARY_PATH:=$(TMPDIR):$(DYLD_LIBRARY_PATH)
RUSTC := $(RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
CC := $(CC) -L $(TMPDIR)
# These deliberately use `=` and not `:=` so that client makefiles can # These deliberately use `=` and not `:=` so that client makefiles can
# augment HOST_RPATH_DIR / TARGET_RPATH_DIR. # augment HOST_RPATH_DIR / TARGET_RPATH_DIR.
HOST_RPATH_ENV = \ HOST_RPATH_ENV = \
$(LD_LIB_PATH_ENVVAR)=$$$(LD_LIB_PATH_ENVVAR):$(HOST_RPATH_DIR) $(LD_LIB_PATH_ENVVAR)=$(HOST_RPATH_DIR):$$$(LD_LIB_PATH_ENVVAR)
TARGET_RPATH_ENV = \ TARGET_RPATH_ENV = \
$(LD_LIB_PATH_ENVVAR)=$$$(LD_LIB_PATH_ENVVAR):$(TARGET_RPATH_DIR) $(LD_LIB_PATH_ENVVAR)=$(TARGET_RPATH_DIR):$$$(LD_LIB_PATH_ENVVAR)
RUSTC := $(HOST_RPATH_ENV) $(RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR)
CC := $(CC) -L $(TMPDIR)
# This is the name of the binary we will generate and run; use this # This is the name of the binary we will generate and run; use this
# e.g. for `$(CC) -o $(RUN_BINFILE)`. # e.g. for `$(CC) -o $(RUN_BINFILE)`.

View file

@ -0,0 +1,15 @@
// 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.
#![feature(default_type_params)]
pub type BigRat<T = int> = T;
fn main() {}

View file

@ -10,6 +10,7 @@
// ignore-android // ignore-android
// ignore-win32 // ignore-win32
// exec-env:RUST_LOG=debug
#![feature(phase)] #![feature(phase)]
@ -29,9 +30,8 @@ fn main() {
return return
} }
let env = [("RUST_LOG".to_string(), "debug".to_string())];
let p = Command::new(args[0].as_slice()) let p = Command::new(args[0].as_slice())
.arg("child").env(env.as_slice()) .arg("child")
.spawn().unwrap().wait_with_output().unwrap(); .spawn().unwrap().wait_with_output().unwrap();
assert!(p.status.success()); assert!(p.status.success());
let mut lines = str::from_utf8(p.error.as_slice()).unwrap().lines(); let mut lines = str::from_utf8(p.error.as_slice()).unwrap().lines();