mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
auto merge of #14955 : alexcrichton/rust/rollup, r=alexcrichton
This commit is contained in:
commit
09967665ea
@ -20,13 +20,13 @@ please do two things:
|
||||
|
||||
Pull requests will be treated as "review requests", and we will give
|
||||
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
|
||||
focus on a single issue at a time, like any other. We will not accept
|
||||
pull-requests that try to "sneak" unrelated changes in.
|
||||
|
||||
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
|
||||
to test for. In those cases, please include a note in your commit
|
||||
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
|
||||
[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).
|
||||
|
@ -98,8 +98,8 @@
|
||||
# This is hardly all there is to know of The Rust Build System's
|
||||
# mysteries. The tale continues on the wiki[1][2].
|
||||
#
|
||||
# [1]: https://github.com/mozilla/rust/wiki/Note-build-system
|
||||
# [2]: https://github.com/mozilla/rust/wiki/Note-testsuite
|
||||
# [1]: https://github.com/rust-lang/rust/wiki/Note-build-system
|
||||
# [2]: https://github.com/rust-lang/rust/wiki/Note-testsuite
|
||||
#
|
||||
# If you really feel like getting your hands dirty, then:
|
||||
#
|
||||
|
10
README.md
10
README.md
@ -14,8 +14,8 @@ documentation.
|
||||
|
||||
[installer]: http://www.rust-lang.org/install.html
|
||||
[tutorial]: http://doc.rust-lang.org/tutorial.html
|
||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||
[win-wiki]: https://github.com/mozilla/rust/wiki/Using-Rust-on-Windows
|
||||
[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust
|
||||
[win-wiki]: https://github.com/rust-lang/rust/wiki/Using-Rust-on-Windows
|
||||
|
||||
## Building from Source
|
||||
|
||||
@ -38,7 +38,7 @@ documentation.
|
||||
|
||||
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
|
||||
|
||||
Now that you have Rust's source code, you can configure and build it:
|
||||
@ -58,7 +58,7 @@ documentation.
|
||||
3. Read the [tutorial].
|
||||
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
|
||||
[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].
|
||||
|
||||
[wiki]: https://github.com/mozilla/rust/wiki
|
||||
[wiki]: https://github.com/rust-lang/rust/wiki
|
||||
|
||||
## License
|
||||
|
||||
|
2
configure
vendored
2
configure
vendored
@ -421,6 +421,7 @@ opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
|
||||
opt rpath 1 "build rpaths into rustc itself"
|
||||
opt nightly 0 "build nightly packages"
|
||||
opt verify-install 1 "verify installed binaries work"
|
||||
opt jemalloc 1 "build liballoc with jemalloc"
|
||||
valopt prefix "/usr/local" "set installation prefix"
|
||||
valopt local-rust-root "/usr/local" "set prefix for local rust binary"
|
||||
valopt llvm-root "" "set LLVM root"
|
||||
@ -1167,6 +1168,7 @@ putvar CFG_MANDIR
|
||||
putvar CFG_DISABLE_INJECT_STD_VERSION
|
||||
putvar CFG_JEMALLOC_ROOT
|
||||
putvar CFG_LIBUV_ROOT
|
||||
putvar CFG_DISABLE_JEMALLOC
|
||||
|
||||
# Avoid spurious warnings from clang by feeding it original source on
|
||||
# ccache-miss rather than preprocessed input.
|
||||
|
@ -184,7 +184,7 @@ To build an executable with debug info:
|
||||
rustdoc
|
||||
|
||||
.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"
|
||||
See \fBAUTHORS.txt\fR in the Rust source distribution.
|
||||
|
@ -87,7 +87,7 @@ The generated HTML can be viewed with any standard web browser.
|
||||
rustc
|
||||
|
||||
.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"
|
||||
See \fBAUTHORS.txt\fR in the Rust source distribution.
|
||||
|
@ -360,10 +360,10 @@ endef
|
||||
# contains spaces which confuse make.
|
||||
# * `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
|
||||
#
|
||||
#
|
||||
# Below that, HOST_RPATH_VAR and TARGET_RPATH_VAR are defined in terms of the
|
||||
# above settings.
|
||||
#
|
||||
#
|
||||
define SREQ_CMDS
|
||||
|
||||
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))
|
||||
|
||||
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) := \
|
||||
$$(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))
|
||||
|
||||
|
6
mk/rt.mk
6
mk/rt.mk
@ -306,6 +306,8 @@ $$(JEMALLOC_LOCAL_$(1)): $$(JEMALLOC_DEPS) $$(MKFILE_DEPS)
|
||||
EXTRA_CFLAGS="$$(CFG_CFLAGS_$(1)) $$(CFG_JEMALLOC_CFLAGS_$(1)) -g1"
|
||||
$$(Q)$$(MAKE) -C "$$(JEMALLOC_BUILD_DIR_$(1))" build_lib_static
|
||||
|
||||
ifeq ($$(CFG_DISABLE_JEMALLOC),)
|
||||
RUSTFLAGS_alloc := --cfg jemalloc
|
||||
ifeq ($(1),$$(CFG_BUILD))
|
||||
ifneq ($$(CFG_JEMALLOC_ROOT),)
|
||||
$$(JEMALLOC_LIB_$(1)): $$(CFG_JEMALLOC_ROOT)/libjemalloc_pic.a
|
||||
@ -319,6 +321,10 @@ else
|
||||
$$(JEMALLOC_LIB_$(1)): $$(JEMALLOC_LOCAL_$(1))
|
||||
$$(Q)cp $$< $$@
|
||||
endif
|
||||
else
|
||||
$$(JEMALLOC_LIB_$(1)): $$(MKFILE_DEPS)
|
||||
$$(Q)touch $$@
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# compiler-rt
|
||||
|
@ -84,6 +84,7 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/stamp.$(4): \
|
||||
-L "$$(RT_OUTPUT_DIR_$(2))" \
|
||||
-L "$$(LLVM_LIBDIR_$(2))" \
|
||||
-L "$$(dir $$(LLVM_STDCPP_LOCATION_$(2)))" \
|
||||
$$(RUSTFLAGS_$(4)) \
|
||||
--out-dir $$(@D) $$<
|
||||
@touch $$@
|
||||
$$(call LIST_ALL_OLD_GLOB_MATCHES,\
|
||||
|
12
mk/tests.mk
12
mk/tests.mk
@ -91,7 +91,8 @@ endif
|
||||
define DEF_TARGET_COMMANDS
|
||||
|
||||
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
|
||||
|
||||
ifdef CFG_WINDOWSY_$(1)
|
||||
@ -105,13 +106,13 @@ ifdef CFG_WINDOWSY_$(1)
|
||||
$$(if $$(findstring stage3,$$(1)), \
|
||||
stage3/$$(CFG_LIBDIR_RELATIVE), \
|
||||
)))))/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
|
||||
|
||||
# Run the compiletest runner itself under valgrind
|
||||
ifdef CTEST_VALGRIND
|
||||
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
|
||||
CFG_RUN_CTEST_$(1)=$$(RPATH_VAR$$(1)_T_$$(3)_H_$$(3)) \
|
||||
$$(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: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test \
|
||||
-L "$$(RT_OUTPUT_DIR_$(2))" \
|
||||
-L "$$(LLVM_LIBDIR_$(2))"
|
||||
-L "$$(LLVM_LIBDIR_$(2))" \
|
||||
$$(RUSTFLAGS_$(4))
|
||||
|
||||
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)): \
|
||||
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
|
||||
@$$(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)) \
|
||||
$$(call CRATE_TEST_EXTRA_ARGS,$(1),$(2),$(3),$(4)) \
|
||||
&& touch $$@
|
||||
|
@ -13,21 +13,19 @@ use std::str;
|
||||
use std::io::process::{ProcessExit, Command, Process, ProcessOutput};
|
||||
use std::dynamic_lib::DynamicLibrary;
|
||||
|
||||
fn target_env(lib_path: &str, prog: &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");
|
||||
|
||||
fn target_env(lib_path: &str, aux_path: Option<&str>) -> Vec<(String, String)> {
|
||||
// Need to be sure to put both the lib_path and the aux path in the dylib
|
||||
// search path for the child.
|
||||
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));
|
||||
|
||||
// Remove the previous dylib search path var
|
||||
let var = DynamicLibrary::envvar();
|
||||
let mut env: Vec<(String,String)> =
|
||||
os::env().move_iter().map(|(a,b)|(a.to_string(), b.to_string())).collect();
|
||||
let mut env: Vec<(String,String)> = os::env();
|
||||
match env.iter().position(|&(ref k, _)| k.as_slice() == var) {
|
||||
Some(i) => { env.remove(i); }
|
||||
None => {}
|
||||
@ -35,8 +33,8 @@ fn target_env(lib_path: &str, prog: &str) -> Vec<(String, String)> {
|
||||
|
||||
// Add the new dylib search path var
|
||||
let newpath = DynamicLibrary::create_path(path.as_slice());
|
||||
env.push((var.to_string(),
|
||||
str::from_utf8(newpath.as_slice()).unwrap().to_string()));
|
||||
let newpath = str::from_utf8(newpath.as_slice()).unwrap().to_string();
|
||||
env.push((var.to_string(), newpath));
|
||||
return env;
|
||||
}
|
||||
|
||||
@ -44,11 +42,12 @@ pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
|
||||
|
||||
pub fn run(lib_path: &str,
|
||||
prog: &str,
|
||||
aux_path: Option<&str>,
|
||||
args: &[String],
|
||||
env: Vec<(String, String)> ,
|
||||
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() {
|
||||
Ok(mut process) => {
|
||||
for input in input.iter() {
|
||||
@ -69,11 +68,12 @@ pub fn run(lib_path: &str,
|
||||
|
||||
pub fn run_background(lib_path: &str,
|
||||
prog: &str,
|
||||
aux_path: Option<&str>,
|
||||
args: &[String],
|
||||
env: Vec<(String, String)> ,
|
||||
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() {
|
||||
Ok(mut process) => {
|
||||
for input in input.iter() {
|
||||
|
@ -230,6 +230,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
testfile: &Path,
|
||||
src: String,
|
||||
pretty_type: &str) -> ProcRes {
|
||||
let aux_dir = aux_output_dir_name(config, testfile);
|
||||
compose_and_run(config,
|
||||
testfile,
|
||||
make_pp_args(config,
|
||||
@ -238,6 +239,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
pretty_type.to_string()),
|
||||
props.exec_env.clone(),
|
||||
config.compile_lib_path.as_slice(),
|
||||
Some(aux_dir.as_str().unwrap()),
|
||||
Some(src))
|
||||
}
|
||||
|
||||
@ -354,6 +356,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
|
||||
procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
[
|
||||
"push".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("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
[
|
||||
"forward".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("",
|
||||
config.adb_path
|
||||
.as_slice(),
|
||||
None,
|
||||
[
|
||||
"shell".to_string(),
|
||||
adb_arg.clone()
|
||||
@ -425,6 +430,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
status
|
||||
} = procsrv::run("",
|
||||
gdb_path.as_slice(),
|
||||
None,
|
||||
debugger_opts.as_slice(),
|
||||
vec!(("".to_string(), "".to_string())),
|
||||
None)
|
||||
@ -486,7 +492,8 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
|
||||
testfile,
|
||||
proc_args,
|
||||
Vec::new(),
|
||||
"",
|
||||
config.run_lib_path.as_slice(),
|
||||
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,
|
||||
testfile,
|
||||
make_run_args(config, props, testfile),
|
||||
env,
|
||||
config.run_lib_path.as_slice(),
|
||||
Some(aux_dir.as_str().unwrap()),
|
||||
None)
|
||||
}
|
||||
}
|
||||
@ -1045,6 +1054,7 @@ fn compose_and_run_compiler(
|
||||
aux_args,
|
||||
Vec::new(),
|
||||
config.compile_lib_path.as_slice(),
|
||||
Some(aux_dir.as_str().unwrap()),
|
||||
None);
|
||||
if !auxres.status.success() {
|
||||
fatal_proc_rec(
|
||||
@ -1066,6 +1076,7 @@ fn compose_and_run_compiler(
|
||||
args,
|
||||
Vec::new(),
|
||||
config.compile_lib_path.as_slice(),
|
||||
Some(aux_dir.as_str().unwrap()),
|
||||
input)
|
||||
}
|
||||
|
||||
@ -1078,9 +1089,10 @@ fn compose_and_run(config: &Config, testfile: &Path,
|
||||
ProcArgs{ args, prog }: ProcArgs,
|
||||
procenv: Vec<(String, String)> ,
|
||||
lib_path: &str,
|
||||
aux_path: Option<&str>,
|
||||
input: Option<String>) -> ProcRes {
|
||||
return program_output(config, testfile, lib_path,
|
||||
prog, args, procenv, input);
|
||||
prog, aux_path, args, procenv, input);
|
||||
}
|
||||
|
||||
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,
|
||||
args: Vec<String> , env: Vec<(String, String)> ,
|
||||
aux_path: Option<&str>, args: Vec<String>,
|
||||
env: Vec<(String, String)>,
|
||||
input: Option<String>) -> ProcRes {
|
||||
let cmdline =
|
||||
{
|
||||
@ -1205,6 +1218,7 @@ fn program_output(config: &Config, testfile: &Path, lib_path: &str, prog: String
|
||||
status
|
||||
} = procsrv::run(lib_path,
|
||||
prog.as_slice(),
|
||||
aux_path,
|
||||
args.as_slice(),
|
||||
env,
|
||||
input).expect(format!("failed to exec `{}`", prog).as_slice());
|
||||
@ -1326,6 +1340,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
// copy to target
|
||||
let copy_result = procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
[
|
||||
"push".to_string(),
|
||||
args.prog.clone(),
|
||||
@ -1361,6 +1376,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
}
|
||||
procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
runargs.as_slice(),
|
||||
vec!(("".to_string(), "".to_string())), Some("".to_string()))
|
||||
.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: _ } =
|
||||
procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
runargs.as_slice(),
|
||||
vec!(("".to_string(), "".to_string())),
|
||||
Some("".to_string()))
|
||||
@ -1397,6 +1414,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
let procsrv::Result{ out: stdout_out, err: _, status: _ } =
|
||||
procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
runargs.as_slice(),
|
||||
vec!(("".to_string(), "".to_string())),
|
||||
Some("".to_string()))
|
||||
@ -1411,6 +1429,7 @@ fn _arm_exec_compiled_test(config: &Config,
|
||||
let procsrv::Result{ out: stderr_out, err: _, status: _ } =
|
||||
procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
runargs.as_slice(),
|
||||
vec!(("".to_string(), "".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
|
||||
let copy_result = procsrv::run("",
|
||||
config.adb_path.as_slice(),
|
||||
None,
|
||||
[
|
||||
"push".to_string(),
|
||||
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(),
|
||||
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,
|
||||
@ -1522,7 +1542,7 @@ fn extract_function_from_bitcode(config: &Config, _props: &TestProps,
|
||||
format!("-o={}", extracted_bc.as_str().unwrap()),
|
||||
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,
|
||||
@ -1538,7 +1558,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
|
||||
args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
|
||||
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,
|
||||
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
|
||||
|
@ -111,14 +111,14 @@ match val.do_something() {
|
||||
[#3101][iss] is the issue that proposed making this the only behavior, with
|
||||
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
|
||||
|
||||
In general, tail-call optimization is not guaranteed: see for a detailed
|
||||
explanation with references. There is a [proposed extension][tce] that would
|
||||
allow tail-call elimination in certain contexts. The compiler is still free to
|
||||
optimize tail-calls [when it pleases][sco], however.
|
||||
In general, tail-call optimization is not guaranteed: see [here][tml] for a
|
||||
detailed explanation with references. There is a [proposed extension][tce] that
|
||||
would allow tail-call elimination in certain contexts. The compiler is still
|
||||
free to optimize tail-calls [when it pleases][sco], however.
|
||||
|
||||
[tml]: https://mail.mozilla.org/pipermail/rust-dev/2013-April/003557.html
|
||||
[sco]: http://llvm.org/docs/CodeGenerator.html#sibling-call-optimization
|
||||
|
@ -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.
|
||||
|
||||
[rustc]: https://github.com/mozilla/rust/tree/master/src/librustc
|
||||
[resolve]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/resolve.rs
|
||||
[borrowck]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/borrowck/
|
||||
[rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc
|
||||
[resolve]: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/resolve.rs
|
||||
[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.
|
||||
|
||||
@ -21,9 +21,9 @@ Some examples that demonstrate different aspects of the language:
|
||||
* The extra library's [json] module. Enums and pattern matching
|
||||
|
||||
[sprocketnes]: https://github.com/pcwalton/sprocketnes
|
||||
[hash]: https://github.com/mozilla/rust/blob/master/src/libstd/hash/mod.rs
|
||||
[HashMap]: https://github.com/mozilla/rust/blob/master/src/libcollections/hashmap.rs
|
||||
[json]: https://github.com/mozilla/rust/blob/master/src/libserialize/json.rs
|
||||
[hash]: https://github.com/rust-lang/rust/blob/master/src/libstd/hash/mod.rs
|
||||
[HashMap]: https://github.com/rust-lang/rust/blob/master/src/libcollections/hashmap.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.
|
||||
|
||||
@ -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].
|
||||
|
||||
[win64]: https://github.com/mozilla/rust/issues/1237
|
||||
[libgcc]: https://github.com/mozilla/rust/issues/11782
|
||||
[win64]: https://github.com/rust-lang/rust/issues/1237
|
||||
[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?
|
||||
|
||||
|
@ -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-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 [wiki](http://github.com/mozilla/rust/wiki)
|
||||
* The Rust [wiki](http://github.com/rust-lang/rust/wiki)
|
||||
|
@ -361,7 +361,7 @@ fn main() {
|
||||
|
||||
// This is ugly for now, but will be replaced by
|
||||
// `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;
|
||||
|
||||
println!("{}", *numbers.get(num as uint));
|
||||
|
@ -34,46 +34,46 @@ msgstr "## 構造体"
|
||||
#: src/doc/complement-lang-faq.md:83
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
|
||||
#| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
|
||||
msgid ""
|
||||
"[rustc]: https://github.com/mozilla/rust/tree/master/src/librustc [resolve]: "
|
||||
"https://github.com/mozilla/rust/blob/master/src/librustc/middle/resolve.rs "
|
||||
"[borrowck]: https://github.com/mozilla/rust/blob/master/src/librustc/middle/"
|
||||
"[rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc [resolve]: "
|
||||
"https://github.com/rust-lang/rust/blob/master/src/librustc/middle/resolve.rs "
|
||||
"[borrowck]: https://github.com/rust-lang/rust/blob/master/src/librustc/middle/"
|
||||
"borrowck/"
|
||||
msgstr ""
|
||||
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
|
||||
"[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
|
||||
"developing-Rust"
|
||||
|
||||
#. type: Plain text
|
||||
#: src/doc/complement-lang-faq.md:99
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
|
||||
#| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
|
||||
msgid ""
|
||||
"[sprocketnes]: https://github.com/pcwalton/sprocketnes [hash]: https://"
|
||||
"github.com/mozilla/rust/blob/master/src/libstd/hash.rs [HashMap]: https://"
|
||||
"github.com/mozilla/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/libstd/hash.rs [HashMap]: https://"
|
||||
"github.com/rust-lang/rust/blob/master/src/libstd/hashmap.rs [json]: https://"
|
||||
"github.com/rust-lang/rust/blob/master/src/libextra/json.rs"
|
||||
msgstr ""
|
||||
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
|
||||
"[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
|
||||
"developing-Rust"
|
||||
|
||||
#. type: Plain text
|
||||
#: src/doc/complement-lang-faq.md:110
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
|
||||
#| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
|
||||
msgid ""
|
||||
"[unwind]: https://github.com/mozilla/rust/issues/908 [libgcc]: https://"
|
||||
"github.com/mozilla/rust/issues/1603"
|
||||
"[unwind]: https://github.com/rust-lang/rust/issues/908 [libgcc]: https://"
|
||||
"github.com/rust-lang/rust/issues/1603"
|
||||
msgstr ""
|
||||
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
|
||||
"[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
|
||||
"developing-Rust"
|
||||
|
||||
#. type: Plain text
|
||||
|
@ -303,15 +303,15 @@ msgstr ""
|
||||
#: src/doc/tutorial.md:92
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust"
|
||||
#| "[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
|
||||
#| "https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust"
|
||||
msgid ""
|
||||
"[bug-3319]: https://github.com/mozilla/rust/issues/3319 [wiki-start]: "
|
||||
"https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust "
|
||||
"[git]: https://github.com/mozilla/rust.git"
|
||||
"[bug-3319]: https://github.com/rust-lang/rust/issues/3319 [wiki-start]: "
|
||||
"https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust "
|
||||
"[git]: https://github.com/rust-lang/rust.git"
|
||||
msgstr ""
|
||||
"[bug-3319]: https://github.com/mozilla/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-"
|
||||
"[bug-3319]: https://github.com/rust-lang/rust/issues/3319\n"
|
||||
"[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-"
|
||||
"developing-Rust"
|
||||
|
||||
#. type: Plain text
|
||||
|
@ -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"
|
||||
supported build environments that are most likely to work.
|
||||
|
||||
[wiki-start]: https://github.com/mozilla/rust/wiki/Note-getting-started-developing-Rust
|
||||
[git]: https://github.com/mozilla/rust.git
|
||||
[wiki-start]: https://github.com/rust-lang/rust/wiki/Note-getting-started-developing-Rust
|
||||
[git]: https://github.com/rust-lang/rust.git
|
||||
[rust-install]: http://www.rust-lang.org/install.html
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
# Syntax basics
|
||||
@ -3345,6 +3345,6 @@ There is further documentation on the [wiki], however those tend to be even more
|
||||
[testing]: guide-testing.html
|
||||
[runtime]: guide-runtime.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
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div id="versioninfo">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
;; Version: 0.2.0
|
||||
;; Author: Mozilla
|
||||
;; Url: https://github.com/mozilla/rust
|
||||
;; Url: https://github.com/rust-lang/rust
|
||||
;; Keywords: languages
|
||||
|
||||
;;; Commentary:
|
||||
|
@ -13,7 +13,7 @@
|
||||
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
|
||||
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
|
||||
"""
|
||||
|
22
src/etc/vim/plugin/rust.vim
Normal file
22
src/etc/vim/plugin/rust.vim
Normal 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
|
35
src/etc/vim/syntax_checkers/rust/rustc.vim
Normal file
35
src/etc/vim/syntax_checkers/rust/rustc.vim
Normal 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
|
@ -9,111 +9,83 @@
|
||||
// except according to those terms.
|
||||
|
||||
// FIXME: #13994: port to the sized deallocation API when available
|
||||
// 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};
|
||||
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
|
||||
// and `nonnull`
|
||||
|
||||
#[cfg(not(test))] use core::raw;
|
||||
#[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.
|
||||
///
|
||||
/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The
|
||||
/// alignment must be no larger than the largest supported page size on the platform.
|
||||
/// Behavior is undefined if the requested size is 0 or the alignment is not a
|
||||
/// power of 2. The alignment must be no larger than the largest supported page
|
||||
/// size on the platform.
|
||||
#[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() {
|
||||
abort()
|
||||
}
|
||||
ptr
|
||||
imp::allocate(size, align)
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// alignment must be no larger than the largest supported page size on the platform.
|
||||
/// Behavior is undefined if the requested size is 0 or the alignment is not a
|
||||
/// 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
|
||||
/// allocation referenced by `ptr`. The `old_size` parameter may also be the value returned by
|
||||
/// `usable_size` for the requested size.
|
||||
/// The `old_size` and `align` parameters are the parameters that were used to
|
||||
/// create the allocation referenced by `ptr`. The `old_size` parameter may also
|
||||
/// be the value returned by `usable_size` for the requested size.
|
||||
#[inline]
|
||||
#[allow(unused_variable)] // for the parameter names in the documentation
|
||||
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() {
|
||||
abort()
|
||||
}
|
||||
ptr
|
||||
pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint,
|
||||
old_size: uint) -> *mut u8 {
|
||||
imp::reallocate(ptr, size, align, old_size)
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// alignment must be no larger than the largest supported page size on the platform.
|
||||
/// Behavior is undefined if the requested size is 0 or the alignment is not a
|
||||
/// 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 allocation referenced by `ptr`. The `old_size` parameter may be
|
||||
/// any value in range_inclusive(requested_size, usable_size).
|
||||
#[inline]
|
||||
#[allow(unused_variable)] // for the parameter names in the documentation
|
||||
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
|
||||
pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint,
|
||||
old_size: uint) -> bool {
|
||||
imp::reallocate_inplace(ptr, size, align, old_size)
|
||||
}
|
||||
|
||||
/// Deallocate the memory referenced by `ptr`.
|
||||
///
|
||||
/// The `ptr` parameter must not be null.
|
||||
///
|
||||
/// The `size` and `align` parameters are the parameters that were used to create the
|
||||
/// allocation referenced by `ptr`. The `size` parameter may also be the value returned by
|
||||
/// `usable_size` for the requested size.
|
||||
/// The `size` and `align` parameters are the parameters that were used to
|
||||
/// create the allocation referenced by `ptr`. The `size` parameter may also be
|
||||
/// the value returned by `usable_size` for the requested size.
|
||||
#[inline]
|
||||
#[allow(unused_variable)] // for the parameter names in the documentation
|
||||
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]
|
||||
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.
|
||||
///
|
||||
/// 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]
|
||||
pub fn stats_print() {
|
||||
unsafe {
|
||||
je_malloc_stats_print(None, mut_null(), null())
|
||||
}
|
||||
imp::stats_print();
|
||||
}
|
||||
|
||||
// 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"]
|
||||
#[inline]
|
||||
#[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 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
|
||||
}
|
||||
|
||||
#[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)]
|
||||
mod bench {
|
||||
extern crate test;
|
||||
|
@ -94,6 +94,14 @@ pub mod owned;
|
||||
pub mod arc;
|
||||
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
|
||||
// as an rlib (it only exists as an rlib). It turns out that an
|
||||
// optimized standard library doesn't actually use *any* symbols
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
use libc::{c_void, size_t, free, malloc, realloc};
|
||||
use core::ptr::{RawPtr, mut_null};
|
||||
use core::intrinsics::abort;
|
||||
|
||||
/// A wrapper around libc::malloc, aborting on out-of-memory
|
||||
#[inline]
|
||||
@ -25,8 +24,7 @@ pub unsafe fn malloc_raw(size: uint) -> *mut u8 {
|
||||
} else {
|
||||
let p = malloc(size as size_t);
|
||||
if p.is_null() {
|
||||
// we need a non-allocating way to print an error here
|
||||
abort();
|
||||
::oom();
|
||||
}
|
||||
p as *mut u8
|
||||
}
|
||||
@ -43,8 +41,7 @@ pub unsafe fn realloc_raw(ptr: *mut u8, size: uint) -> *mut u8 {
|
||||
} else {
|
||||
let p = realloc(ptr as *mut c_void, size as size_t);
|
||||
if p.is_null() {
|
||||
// we need a non-allocating way to print an error here
|
||||
abort();
|
||||
::oom();
|
||||
}
|
||||
p as *mut u8
|
||||
}
|
||||
|
@ -2592,7 +2592,7 @@ pub mod consts {
|
||||
pub static PROT_GROWSUP : c_int = 0x020000000;
|
||||
|
||||
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_GROWSDOWN : c_int = 0x0100;
|
||||
pub static MAP_DENYWRITE : c_int = 0x0800;
|
||||
@ -2615,7 +2615,7 @@ pub mod consts {
|
||||
pub static PROT_GROWSUP : c_int = 0x02000000;
|
||||
|
||||
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_DENYWRITE : c_int = 0x02000;
|
||||
pub static MAP_EXECUTABLE : c_int = 0x04000;
|
||||
|
@ -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
|
||||
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)
|
||||
|
||||
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.
|
||||
|
||||
|
@ -44,7 +44,7 @@
|
||||
//!
|
||||
//! # 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::hash::Hash;
|
||||
@ -270,7 +270,7 @@ mod svh_visitor {
|
||||
ExprBlock(..) => SawExprBlock,
|
||||
ExprAssign(..) => SawExprAssign,
|
||||
ExprAssignOp(op, _, _) => SawExprAssignOp(op),
|
||||
ExprField(_, id, _) => SawExprField(content(id)),
|
||||
ExprField(_, id, _) => SawExprField(content(id.node)),
|
||||
ExprIndex(..) => SawExprIndex,
|
||||
ExprPath(..) => SawExprPath,
|
||||
ExprAddrOf(m, _) => SawExprAddrOf(m),
|
||||
|
@ -235,7 +235,7 @@ impl<'a> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a> {
|
||||
self.lookup_and_handle_method(expr.id, expr.span);
|
||||
}
|
||||
ast::ExprField(ref lhs, ref ident, _) => {
|
||||
self.handle_field_access(&**lhs, ident);
|
||||
self.handle_field_access(&**lhs, &ident.node);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
|
||||
|
||||
ast::ExprField(ref base, f_name, _) => {
|
||||
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, _) => {
|
||||
|
@ -303,7 +303,7 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
||||
match ty.node {
|
||||
ast::TyPath(_, _, id) => {
|
||||
match self.tcx.def_map.borrow().get_copy(&id) {
|
||||
def::DefPrimTy(..) => {},
|
||||
def::DefPrimTy(..) | def::DefTyParam(..) => {},
|
||||
def => {
|
||||
let did = def.def_id();
|
||||
if is_local(did) {
|
||||
@ -801,7 +801,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
ast::ExprField(ref base, ident, _) => {
|
||||
match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
|
||||
ty::ty_struct(id, _) => {
|
||||
self.check_field(expr.span, id, NamedField(ident));
|
||||
self.check_field(expr.span, id, NamedField(ident.node));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -5241,7 +5241,7 @@ impl<'a> Resolver<'a> {
|
||||
// field, we need to add any trait methods we find that match
|
||||
// the field name so that we can do some nice error reporting
|
||||
// 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);
|
||||
}
|
||||
ExprMethodCall(ident, _, _) => {
|
||||
|
@ -1210,7 +1210,7 @@ impl<'l> Visitor<DxrVisitorEnv> for DxrVisitor<'l> {
|
||||
ty::ty_struct(def_id, _) => {
|
||||
let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
|
||||
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);
|
||||
self.fmt.ref_str(recorder::VarRef,
|
||||
ex.span,
|
||||
|
@ -419,7 +419,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr,
|
||||
let brepr = adt::represent_type(cx, bt);
|
||||
let (bv, inlineable) = const_expr(cx, &**base, is_local);
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ impl TypeMap {
|
||||
metadata: DIType) {
|
||||
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!",
|
||||
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:)*}
|
||||
// function -> {<unsafe_> <abi_> fn( (:param-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_)) {
|
||||
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));
|
||||
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 {
|
||||
// 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.
|
||||
fn finalize(&self, cx: &CrateContext) -> DICompositeType {
|
||||
fn finalize(&self, cx: &CrateContext) -> MetadataCreationResult {
|
||||
match *self {
|
||||
FinalMetadata(metadata) => metadata,
|
||||
FinalMetadata(metadata) => MetadataCreationResult::new(metadata, false),
|
||||
UnfinishedMetadata {
|
||||
unfinished_type,
|
||||
unique_type_id,
|
||||
@ -1713,7 +1739,7 @@ impl RecursiveTypeDescription {
|
||||
member_descriptions.as_slice(),
|
||||
file_metadata,
|
||||
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,
|
||||
at_pointer_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 = content_type_name.as_slice();
|
||||
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 member_llvm_types = box_llvm_type.field_types();
|
||||
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 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,
|
||||
box_llvm_type,
|
||||
box_type_name.as_slice(),
|
||||
unique_type_id,
|
||||
gc_box_unique_id,
|
||||
member_descriptions,
|
||||
file_metadata,
|
||||
file_metadata,
|
||||
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
|
||||
// 'next' and 'prev' pointers are in the correct order.
|
||||
fn box_layout_is_correct(cx: &CrateContext,
|
||||
@ -2540,11 +2582,18 @@ fn at_box_metadata(cx: &CrateContext,
|
||||
|
||||
|
||||
fn fixed_vec_metadata(cx: &CrateContext,
|
||||
unique_type_id: UniqueTypeId,
|
||||
element_type: ty::t,
|
||||
len: uint,
|
||||
span: Span)
|
||||
-> DIType {
|
||||
-> MetadataCreationResult {
|
||||
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_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]);
|
||||
return unsafe {
|
||||
let metadata = unsafe {
|
||||
llvm::LLVMDIBuilderCreateArrayType(
|
||||
DIB(cx),
|
||||
bytes_to_bits(element_type_size * (len as u64)),
|
||||
@ -2564,24 +2613,30 @@ fn fixed_vec_metadata(cx: &CrateContext,
|
||||
element_type_metadata,
|
||||
subscripts)
|
||||
};
|
||||
|
||||
return MetadataCreationResult::new(metadata, false);
|
||||
}
|
||||
|
||||
fn heap_vec_metadata(cx: &CrateContext,
|
||||
vec_type: ty::t,
|
||||
vec_pointer_type: ty::t,
|
||||
element_type: ty::t,
|
||||
unique_type_id: UniqueTypeId,
|
||||
span: Span)
|
||||
-> DICompositeType {
|
||||
|
||||
-> MetadataCreationResult {
|
||||
let element_type_metadata = type_metadata(cx, element_type, span);
|
||||
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 vec_llvm_type = Type::vec(cx, &element_llvm_type);
|
||||
let vec_type_name = ppaux::ty_to_str(cx.tcx(), vec_type);
|
||||
let vec_type_name = vec_type_name.as_slice();
|
||||
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 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 array_type_metadata = unsafe {
|
||||
@ -2619,15 +2674,20 @@ fn heap_vec_metadata(cx: &CrateContext,
|
||||
let loc = span_start(cx, span);
|
||||
let file_metadata = file_metadata(cx, loc.file.name.as_slice());
|
||||
|
||||
composite_type_metadata(
|
||||
cx,
|
||||
vec_llvm_type,
|
||||
vec_type_name,
|
||||
unique_type_id,
|
||||
member_descriptions,
|
||||
file_metadata,
|
||||
file_metadata,
|
||||
span)
|
||||
let vec_box_unique_id = debug_context(cx).type_map
|
||||
.borrow_mut()
|
||||
.get_unique_type_id_of_heap_vec_box(cx, element_type);
|
||||
|
||||
let vecbox_metadata = composite_type_metadata(cx,
|
||||
vecbox_llvm_type,
|
||||
vec_pointer_type_name,
|
||||
vec_box_unique_id,
|
||||
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,
|
||||
@ -2635,9 +2695,18 @@ fn vec_slice_metadata(cx: &CrateContext,
|
||||
element_type: ty::t,
|
||||
unique_type_id: UniqueTypeId,
|
||||
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_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,
|
||||
member_llvm_types.as_slice(),
|
||||
element_type));
|
||||
|
||||
let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
|
||||
ty: element_type,
|
||||
mutbl: ast::MutImmutable
|
||||
});
|
||||
|
||||
let member_descriptions = [
|
||||
MemberDescription {
|
||||
name: "data_ptr".to_string(),
|
||||
llvm_type: *member_llvm_types.get(0),
|
||||
type_metadata: type_metadata(cx, data_ptr_type, span),
|
||||
type_metadata: element_type_metadata,
|
||||
offset: ComputedMemberOffset,
|
||||
},
|
||||
MemberDescription {
|
||||
@ -2672,15 +2735,15 @@ fn vec_slice_metadata(cx: &CrateContext,
|
||||
let loc = span_start(cx, span);
|
||||
let file_metadata = file_metadata(cx, loc.file.name.as_slice());
|
||||
|
||||
return composite_type_metadata(
|
||||
cx,
|
||||
slice_llvm_type,
|
||||
slice_type_name.as_slice(),
|
||||
unique_type_id,
|
||||
member_descriptions,
|
||||
file_metadata,
|
||||
file_metadata,
|
||||
span);
|
||||
let metadata = composite_type_metadata(cx,
|
||||
slice_llvm_type,
|
||||
slice_type_name.as_slice(),
|
||||
unique_type_id,
|
||||
member_descriptions,
|
||||
file_metadata,
|
||||
file_metadata,
|
||||
span);
|
||||
return MetadataCreationResult::new(metadata, false);
|
||||
|
||||
fn slice_layout_is_correct(cx: &CrateContext,
|
||||
member_llvm_types: &[Type],
|
||||
@ -2693,12 +2756,12 @@ fn vec_slice_metadata(cx: &CrateContext,
|
||||
}
|
||||
|
||||
fn subroutine_type_metadata(cx: &CrateContext,
|
||||
unique_type_id: UniqueTypeId,
|
||||
signature: &ty::FnSig,
|
||||
span: Span)
|
||||
-> DICompositeType {
|
||||
-> MetadataCreationResult {
|
||||
let loc = span_start(cx, span);
|
||||
let file_metadata = file_metadata(cx, loc.file.name.as_slice());
|
||||
|
||||
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
|
||||
|
||||
// return type
|
||||
@ -2712,12 +2775,19 @@ fn subroutine_type_metadata(cx: &CrateContext,
|
||||
signature_metadata.push(type_metadata(cx, argument_type, span));
|
||||
}
|
||||
|
||||
return unsafe {
|
||||
llvm::LLVMDIBuilderCreateSubroutineType(
|
||||
DIB(cx),
|
||||
file_metadata,
|
||||
create_DIArray(DIB(cx), signature_metadata.as_slice()))
|
||||
match debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id) {
|
||||
Some(metadata) => return MetadataCreationResult::new(metadata, true),
|
||||
None => { /* proceed */ }
|
||||
};
|
||||
|
||||
return MetadataCreationResult::new(
|
||||
unsafe {
|
||||
llvm::LLVMDIBuilderCreateSubroutineType(
|
||||
DIB(cx),
|
||||
file_metadata,
|
||||
create_DIArray(DIB(cx), signature_metadata.as_slice()))
|
||||
},
|
||||
false);
|
||||
}
|
||||
|
||||
fn trait_metadata(cx: &CrateContext,
|
||||
@ -2758,7 +2828,6 @@ fn trait_metadata(cx: &CrateContext,
|
||||
definition_span)
|
||||
}
|
||||
|
||||
|
||||
fn type_metadata(cx: &CrateContext,
|
||||
t: ty::t,
|
||||
usage_site_span: Span)
|
||||
@ -2766,20 +2835,25 @@ fn type_metadata(cx: &CrateContext,
|
||||
// Get the unique type id of this type.
|
||||
let unique_type_id = {
|
||||
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) {
|
||||
Some(metadata) => {
|
||||
return metadata;
|
||||
},
|
||||
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);
|
||||
match type_map.find_metadata_for_unique_id(unique_type_id) {
|
||||
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);
|
||||
return metadata;
|
||||
},
|
||||
None => {
|
||||
// There really is no type metadata for this type, so proceed by creating
|
||||
// it
|
||||
// There really is no type metadata for this type, so proceed by creating it
|
||||
unique_type_id
|
||||
}
|
||||
}
|
||||
@ -2799,7 +2873,7 @@ fn type_metadata(cx: &CrateContext,
|
||||
)
|
||||
|
||||
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_bot |
|
||||
ty::ty_bool |
|
||||
@ -2807,73 +2881,54 @@ fn type_metadata(cx: &CrateContext,
|
||||
ty::ty_int(_) |
|
||||
ty::ty_uint(_) |
|
||||
ty::ty_float(_) => {
|
||||
(basic_type_metadata(cx, t), false)
|
||||
MetadataCreationResult::new(basic_type_metadata(cx, t), false)
|
||||
}
|
||||
ty::ty_enum(def_id, _) => {
|
||||
let is_c_style_enum = match *adt::represent_type(cx, t) {
|
||||
adt::CEnum(..) => true,
|
||||
_ => false
|
||||
};
|
||||
|
||||
(prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx),
|
||||
!is_c_style_enum)
|
||||
prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span).finalize(cx)
|
||||
}
|
||||
ty::ty_box(pointee_type) => {
|
||||
let box_content_metadata = at_box_metadata(cx, pointee_type, unique_type_id);
|
||||
return_if_created_in_meantime!();
|
||||
(pointer_type_metadata(cx, t, box_content_metadata), false)
|
||||
at_box_metadata(cx, t, pointee_type, unique_type_id)
|
||||
}
|
||||
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) => {
|
||||
(match ty::get(pointee_type).sty {
|
||||
match ty::get(pointee_type).sty {
|
||||
ty::ty_vec(ref mt, None) => {
|
||||
let vec_metadata = heap_vec_metadata(cx,
|
||||
pointee_type,
|
||||
mt.ty,
|
||||
unique_type_id,
|
||||
usage_site_span);
|
||||
return_if_created_in_meantime!();
|
||||
pointer_type_metadata(cx, t, vec_metadata)
|
||||
heap_vec_metadata(cx, pointee_type, mt.ty, unique_type_id, usage_site_span)
|
||||
}
|
||||
ty::ty_str => {
|
||||
let i8_t = ty::mk_i8();
|
||||
let vec_metadata = heap_vec_metadata(cx,
|
||||
pointee_type,
|
||||
i8_t,
|
||||
unique_type_id,
|
||||
usage_site_span);
|
||||
pointer_type_metadata(cx, t, vec_metadata)
|
||||
heap_vec_metadata(cx, pointee_type, i8_t, unique_type_id, usage_site_span)
|
||||
}
|
||||
_ => {
|
||||
let pointee_metadata = type_metadata(cx, pointee_type, usage_site_span);
|
||||
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) => {
|
||||
(match ty::get(mt.ty).sty {
|
||||
match ty::get(mt.ty).sty {
|
||||
ty::ty_vec(ref mt, None) => {
|
||||
vec_slice_metadata(cx, t, mt.ty, unique_type_id, usage_site_span)
|
||||
}
|
||||
ty::ty_str => {
|
||||
let i8_t = ty::mk_i8();
|
||||
vec_slice_metadata(cx, t, i8_t, unique_type_id, usage_site_span)
|
||||
vec_slice_metadata(cx, t, ty::mk_i8(), unique_type_id, usage_site_span)
|
||||
}
|
||||
_ => {
|
||||
let pointee = type_metadata(cx, mt.ty, usage_site_span);
|
||||
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) => {
|
||||
(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) => {
|
||||
(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 {
|
||||
def_id,
|
||||
@ -2881,24 +2936,24 @@ fn type_metadata(cx: &CrateContext,
|
||||
store,
|
||||
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) => {
|
||||
let struct_metadata = prepare_struct_metadata(cx,
|
||||
t,
|
||||
def_id,
|
||||
substs,
|
||||
unique_type_id,
|
||||
usage_site_span).finalize(cx);
|
||||
(struct_metadata, true)
|
||||
prepare_struct_metadata(cx,
|
||||
t,
|
||||
def_id,
|
||||
substs,
|
||||
unique_type_id,
|
||||
usage_site_span).finalize(cx)
|
||||
}
|
||||
ty::ty_tup(ref elements) => {
|
||||
let tuple_metadata = prepare_tuple_metadata(cx,
|
||||
t,
|
||||
elements.as_slice(),
|
||||
unique_type_id,
|
||||
usage_site_span).finalize(cx);
|
||||
(tuple_metadata, true)
|
||||
prepare_tuple_metadata(cx,
|
||||
t,
|
||||
elements.as_slice(),
|
||||
unique_type_id,
|
||||
usage_site_span).finalize(cx)
|
||||
}
|
||||
_ => {
|
||||
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();
|
||||
|
||||
if should_already_be_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());
|
||||
}
|
||||
|
||||
if already_stored_in_typemap {
|
||||
// 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 unique_type_id_str = type_map.get_unique_type_id_as_string(unique_type_id);
|
||||
let error_message = format!("Expected type metadata for unique type id '{}' to
|
||||
already be in the TypeMap but it was not. (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());
|
||||
let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
|
||||
Some(metadata) => metadata,
|
||||
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 unique type id '{}' to \
|
||||
already be in the debuginfo::TypeMap but it was not. (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());
|
||||
}
|
||||
};
|
||||
|
||||
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 {
|
||||
type_map.register_type_with_metadata(cx, t, type_metadata);
|
||||
type_map.register_unique_id_with_metadata(cx, unique_type_id, type_metadata);
|
||||
type_map.register_type_with_metadata(cx, t, 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)]
|
||||
|
@ -389,7 +389,7 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
trans_def(bcx, expr, bcx.def(expr.id))
|
||||
}
|
||||
ast::ExprField(ref base, ident, _) => {
|
||||
trans_rec_field(bcx, &**base, ident)
|
||||
trans_rec_field(bcx, &**base, ident.node)
|
||||
}
|
||||
ast::ExprIndex(ref base, ref idx) => {
|
||||
trans_index(bcx, expr, &**base, &**idx)
|
||||
|
@ -2352,7 +2352,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
expr: &ast::Expr,
|
||||
lvalue_pref: LvaluePreference,
|
||||
base: &ast::Expr,
|
||||
field: ast::Name,
|
||||
field: &ast::SpannedIdent,
|
||||
tys: &[ast::P<ast::Ty>]) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
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) => {
|
||||
debug!("struct named {}", ppaux::ty_to_str(tcx, base_t));
|
||||
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
|
||||
}
|
||||
@ -2383,7 +2384,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
match method::lookup(fcx,
|
||||
expr,
|
||||
base,
|
||||
field,
|
||||
field.node.name,
|
||||
expr_t,
|
||||
tps.as_slice(),
|
||||
DontDerefArgs,
|
||||
@ -2392,14 +2393,14 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
IgnoreStaticMethods) {
|
||||
Some(_) => {
|
||||
fcx.type_error_message(
|
||||
expr.span,
|
||||
field.span,
|
||||
|actual| {
|
||||
format!("attempted to take value of method `{}` on type \
|
||||
`{}`", token::get_name(field), actual)
|
||||
`{}`", token::get_ident(field.node), actual)
|
||||
},
|
||||
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.");
|
||||
}
|
||||
|
||||
@ -2410,7 +2411,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
format!("attempted access of field `{}` on \
|
||||
type `{}`, but no field with that \
|
||||
name was found",
|
||||
token::get_name(field),
|
||||
token::get_ident(field.node),
|
||||
actual)
|
||||
},
|
||||
expr_t, None);
|
||||
@ -3214,7 +3215,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
|
||||
}
|
||||
}
|
||||
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) => {
|
||||
check_expr_with_lvalue_pref(fcx, &**base, lvalue_pref);
|
||||
|
@ -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,
|
||||
ast_util::AutoSuffix).to_string(),
|
||||
ty_float(t) => ast_util::float_ty_to_str(t).to_string(),
|
||||
ty_box(typ) => format!("@{}", ty_to_str(cx, typ)),
|
||||
ty_uniq(typ) => format!("~{}", ty_to_str(cx, typ)),
|
||||
ty_box(typ) => format!("Gc<{}>", 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_rptr(r, ref tm) => {
|
||||
let mut buf = region_ptr_to_str(cx, r);
|
||||
|
@ -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
|
||||
// to ensure that the stack bounds are what they truly are for this
|
||||
// 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)
|
||||
asm!("mov $0, %gs:0x08" :: "r"(stack_hi) :: "volatile");
|
||||
|
@ -183,7 +183,7 @@ fn main() {
|
||||
|
||||
## 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.
|
||||
|
||||
```rust
|
||||
|
@ -57,6 +57,16 @@ use libc::c_char;
|
||||
#[cfg(windows)]
|
||||
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;
|
||||
static BUF_BYTES : uint = 2048u;
|
||||
@ -1762,6 +1772,11 @@ mod tests {
|
||||
n
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_num_cpus() {
|
||||
assert!(os::num_cpus() > 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_setenv() {
|
||||
let n = make_rand_name();
|
||||
|
@ -11,23 +11,11 @@
|
||||
use from_str::FromStr;
|
||||
use from_str::from_str;
|
||||
use libc::uintptr_t;
|
||||
use libc;
|
||||
use option::{Some, None, Option};
|
||||
use os;
|
||||
use str::Str;
|
||||
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.
|
||||
/// You should usually not use this unless your test definitely
|
||||
/// 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() {
|
||||
1
|
||||
} else {
|
||||
num_cpus()
|
||||
os::num_cpus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +132,8 @@ impl<A:Send> Future<A> {
|
||||
let (tx, rx) = channel();
|
||||
|
||||
spawn(proc() {
|
||||
tx.send(blk());
|
||||
// Don't fail if the other end has hung up
|
||||
let _ = tx.send_opt(blk());
|
||||
});
|
||||
|
||||
Future::from_receiver(rx)
|
||||
@ -144,6 +145,7 @@ mod test {
|
||||
use prelude::*;
|
||||
use sync::Future;
|
||||
use task;
|
||||
use comm::{channel, Sender};
|
||||
|
||||
#[test]
|
||||
fn test_from_value() {
|
||||
@ -206,4 +208,28 @@ mod test {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -464,7 +464,7 @@ pub enum Expr_ {
|
||||
|
||||
ExprAssign(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>),
|
||||
|
||||
/// 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
|
||||
// optional (InternedString,StrStyle): if present, this is a location
|
||||
// (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),
|
||||
ViewItemUse(Gc<ViewPath>),
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ use std::fmt;
|
||||
|
||||
/// CrateIds identify crates and include the crate name and optionally a path
|
||||
/// 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/mozilla/rust` and a crate name of `std` with a version of
|
||||
/// `github.com/rust-lang/rust#std:1.0` would be a package ID with a path 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
|
||||
/// be the last component of the path. If no version is given, it is inferred
|
||||
/// to be `0.0`.
|
||||
|
@ -13,7 +13,7 @@ use ast::{P, Ident, Generics, NodeId, Expr};
|
||||
use ast;
|
||||
use ast_util;
|
||||
use attr;
|
||||
use codemap::{Span, respan, Spanned, DUMMY_SP};
|
||||
use codemap::{Span, respan, Spanned, DUMMY_SP, Pos};
|
||||
use ext::base::ExtCtxt;
|
||||
use fold::Folder;
|
||||
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> {
|
||||
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> {
|
||||
self.expr(sp, ast::ExprAddrOf(ast::MutImmutable, e))
|
||||
|
@ -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(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())
|
||||
}
|
||||
ExprIndex(el, er) => {
|
||||
|
@ -1796,7 +1796,7 @@ impl<'a> Parser<'a> {
|
||||
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_ {
|
||||
ExprField(expr, ident, tys)
|
||||
}
|
||||
@ -2090,7 +2090,8 @@ impl<'a> Parser<'a> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -1487,7 +1487,7 @@ impl<'a> State<'a> {
|
||||
ast::ExprField(ref expr, id, ref tys) => {
|
||||
try!(self.print_expr(&**expr));
|
||||
try!(word(&mut self.s, "."));
|
||||
try!(self.print_ident(id));
|
||||
try!(self.print_ident(id.node));
|
||||
if tys.len() > 0u {
|
||||
try!(word(&mut self.s, "::<"));
|
||||
try!(self.commasep(
|
||||
|
@ -26,13 +26,13 @@ struct fish {
|
||||
fn main() {
|
||||
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 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);
|
||||
assert_eq!(z, 21);
|
||||
let forty: fish = fish{a: box(GC) 40};
|
||||
let two: fish = fish{a: box(GC) 2};
|
||||
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);
|
||||
assert_eq!(answer, 42);
|
||||
}
|
||||
|
21
src/test/compile-fail/issue-14915.rs
Normal file
21
src/test/compile-fail/issue-14915.rs
Normal 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>`
|
||||
}
|
@ -32,7 +32,7 @@ struct A {
|
||||
|
||||
fn main() {
|
||||
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 w = v.clone();
|
||||
let b = &*v;
|
||||
|
@ -16,7 +16,7 @@ struct BarStruct;
|
||||
|
||||
impl<'a> BarStruct {
|
||||
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() {}
|
||||
|
@ -28,7 +28,16 @@ impl Point {
|
||||
|
||||
fn main() {
|
||||
let point: Point = Point::new();
|
||||
let px: int = point.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 function.
|
||||
let px: int = point
|
||||
.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.
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl<'a> set_f<'a> for c<'a> {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@
|
||||
ifndef IS_WINDOWS
|
||||
|
||||
all:
|
||||
$(RUSTDOC) --test foo.rs
|
||||
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) --test foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
cp verify.sh $(TMPDIR)
|
||||
$(call RUN,verify.sh) $(TMPDIR)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
-include ../tools.mk
|
||||
all:
|
||||
$(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
|
||||
$(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json
|
||||
|
@ -1,5 +1,5 @@
|
||||
-include ../tools.mk
|
||||
all:
|
||||
$(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
$(HOST_RPATH_ENV) $(RUSTDOC) -w html -o $(TMPDIR)/doc foo.rs
|
||||
cp verify.sh $(TMPDIR)
|
||||
$(call RUN,verify.sh) $(TMPDIR)
|
||||
|
@ -1,15 +1,15 @@
|
||||
export LD_LIBRARY_PATH:=$(TMPDIR):$(LD_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
|
||||
# augment HOST_RPATH_DIR / TARGET_RPATH_DIR.
|
||||
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 = \
|
||||
$(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
|
||||
# e.g. for `$(CC) -o $(RUN_BINFILE)`.
|
||||
|
15
src/test/run-pass/issue-14933.rs
Normal file
15
src/test/run-pass/issue-14933.rs
Normal 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() {}
|
@ -10,6 +10,7 @@
|
||||
|
||||
// ignore-android
|
||||
// ignore-win32
|
||||
// exec-env:RUST_LOG=debug
|
||||
|
||||
#![feature(phase)]
|
||||
|
||||
@ -29,9 +30,8 @@ fn main() {
|
||||
return
|
||||
}
|
||||
|
||||
let env = [("RUST_LOG".to_string(), "debug".to_string())];
|
||||
let p = Command::new(args[0].as_slice())
|
||||
.arg("child").env(env.as_slice())
|
||||
.arg("child")
|
||||
.spawn().unwrap().wait_with_output().unwrap();
|
||||
assert!(p.status.success());
|
||||
let mut lines = str::from_utf8(p.error.as_slice()).unwrap().lines();
|
||||
|
Loading…
Reference in New Issue
Block a user