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

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

View File

@ -20,13 +20,13 @@ please do two things:
Pull requests will be treated as "review requests", and we will give
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).

View File

@ -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:
#

View File

@ -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
View File

@ -421,6 +421,7 @@ opt llvm-static-stdcpp 0 "statically link to libstdc++ for LLVM"
opt rpath 1 "build rpaths into rustc itself"
opt 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.

View File

@ -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.

View File

@ -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.

View File

@ -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))

View File

@ -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

View File

@ -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,\

View File

@ -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 $$@

View File

@ -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() {

View File

@ -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)
}

View File

@ -22,7 +22,7 @@ If you don't have enough time for a search, then don't worry about that. Just su
the bug. If it's a duplicate, somebody will notice that and close it during triage.
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

View File

@ -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

View File

@ -5,9 +5,9 @@
There aren't many large programs yet. The Rust [compiler][rustc], 60,000+ lines at the time of writing, is written in Rust. As the oldest body of Rust code it has gone through many iterations of the language, and some parts are nicer to look at than others. It may not be the best code to learn from, but [borrowck] and [resolve] were written recently.
[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?

View File

@ -75,4 +75,4 @@ li {list-style-type: none; }
* [`#rust-internals`](http://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust-internals) - compiler and libraries
* [`#rust-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)

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -90,8 +90,8 @@ Snapshot binaries are currently built and tested on several platforms:
You may find that other platforms work, but these are our "tier 1"
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

View File

@ -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>

View File

@ -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:

View File

@ -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
"""

View File

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

View File

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

View File

@ -9,111 +9,83 @@
// except according to those terms.
// 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;

View File

@ -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

View File

@ -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
}

View File

@ -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;

View File

@ -4,12 +4,12 @@ An informal guide to reading and working on the rustc compiler.
If you wish to expand on this document, or have a more experienced
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.

View File

@ -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),

View File

@ -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);
}
_ => ()
}

View File

@ -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, _) => {

View File

@ -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));
}
_ => {}
}

View File

@ -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, _, _) => {

View File

@ -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,

View File

@ -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)
})
}

View File

@ -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)]

View File

@ -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)

View File

@ -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);

View File

@ -351,8 +351,8 @@ pub fn ty_to_str(cx: &ctxt, typ: t) -> String {
ty_uint(t) => ast_util::uint_ty_to_str(t, None,
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);

View File

@ -146,7 +146,7 @@ pub unsafe fn record_stack_bounds(stack_lo: uint, stack_hi: uint) {
// means that if we want to perform valid FFI on windows, then we need
// 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");

View File

@ -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

View File

@ -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();

View File

@ -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()
}
}
}

View File

@ -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());
}
}

View File

@ -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>),
}

View File

@ -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`.

View File

@ -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))

View File

@ -876,7 +876,7 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
}
ExprField(el, id, ref tys) => {
ExprField(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) => {

View File

@ -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)
}
}

View File

@ -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(

View File

@ -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);
}

View File

@ -0,0 +1,21 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::gc::{GC,Gc};
fn main() {
let x: Box<int> = box 0;
let y: Gc<int> = box (GC) 0;
println!("{}", x + 1); //~ ERROR binary operation `+` cannot be applied to type `Box<int>`
//~^ ERROR cannot determine a type for this bounded type parameter: unconstrained type
println!("{}", y + 1);
//~^ ERROR binary operation `+` cannot be applied to type `Gc<int>`
}

View File

@ -32,7 +32,7 @@ struct A {
fn main() {
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;

View File

@ -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() {}

View File

@ -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.
}

View File

@ -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
}
}

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)`.

View File

@ -0,0 +1,15 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(default_type_params)]
pub type BigRat<T = int> = T;
fn main() {}

View File

@ -10,6 +10,7 @@
// ignore-android
// ignore-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();