tmp/install-debugger-scripts$(1)_H_$(2)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(HBIN$(1)_H_$(2))
$(Q)mkdir -p $$(HLIB$(1)_H_$(2))/rustlib/etc
$(Q)install $$(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(HBIN$(1)_H_$(2))
$(Q)install $$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(HLIB$(1)_H_$(2))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_H_$(2)-none.done:
$(Q)touch $$@
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-gdb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_GDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_GDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_GDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-lldb.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_LLDB_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_LLDB_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_LLDB_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-all.done: \
$$(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) \
$$(DEBUGGER_BIN_SCRIPTS_ALL_ABS)
+ $(Q)touch $$@.start_time
$(Q)mkdir -p $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)mkdir -p $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
$(Q)install $(DEBUGGER_BIN_SCRIPTS_ALL_ABS) $$(TBIN$(1)_T_$(2)_H_$(3))
$(Q)install $(DEBUGGER_RUSTLIB_ETC_SCRIPTS_ALL_ABS) $$(TLIB$(1)_T_$(2)_H_$(3))/rustlib/etc
- $(Q)touch $$@
+ $(Q)touch -r $$@.start_time $$@ && rm $$@.start_time
tmp/install-debugger-scripts$(1)_T_$(2)_H_$(3)-none.done:
$(Q)touch $$@
trpl: doc/book/index.html
doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md) | doc/
+ @$(call E, rustbook: $@)
$(Q)rm -rf doc/book
$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
style: doc/style/index.html
doc/style/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/style/*.md) | doc/
+ @$(call E, rustbook: $@)
$(Q)rm -rf doc/style
$(Q)$(RUSTBOOK) build $(S)src/doc/style doc/style
# the stamp in the source dir.
$$(LLVM_STAMP_$(1)): $(S)src/rustllvm/llvm-auto-clean-trigger
@$$(call E, make: cleaning llvm)
+ $(Q)touch $$@.start_time
$(Q)$(MAKE) clean-llvm$(1)
@$$(call E, make: done cleaning llvm)
- touch $$@
+ touch -r $$@.start_time $$@ && rm $$@.start_time
ifeq ($$(CFG_ENABLE_LLVM_STATIC_STDCPP),1)
LLVM_STDCPP_LOCATION_$(1) = $$(shell $$(CC_$(1)) $$(CFG_GCCISH_CFLAGS_$(1)) \
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
| $$(TLIB$(1)_T_$(2)_H_$(3))/
@$$(call E, rustc: $$(@D)/lib$(4))
+ @touch $$@.start_time
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call REMOVE_ALL_OLD_GLOB_MATCHES, \
--out-dir $$(@D) \
-C extra-filename=-$$(CFG_FILENAME_EXTRA) \
$$<
- @touch $$@
+ @touch -r $$@.start_time $$@ && rm $$@.start_time
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(dir $$@)$$(call CFG_LIB_GLOB_$(2),$(4)))
$$(call LIST_ALL_OLD_GLOB_MATCHES, \
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$<)
+ $$(Q)touch $$@.start_time
$$(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 $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
endef
define DEF_TEST_CRATE_RULES_android
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$(3)/stage$(1)/test/$(4)test-$(2)$$(X_$(2))
@$$(call E, run: $$< via adb)
+ $$(Q)touch $$@.start_time
$$(Q)$(CFG_ADB) push $$< $(CFG_ADB_TEST_DIR)
$$(Q)$(CFG_ADB) shell '(cd $(CFG_ADB_TEST_DIR); LD_LIBRARY_PATH=./$(2) \
./$$(notdir $$<) \
@if grep -q "result: ok" tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
then \
rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
- touch $$@; \
+ touch -r $$@.start_time $$@ && rm $$@.start_time; \
else \
rm tmp/check-stage$(1)-T-$(2)-H-$(3)-$(4).tmp; \
exit 101; \
# The tests select when to use debug configuration on their own;
# remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
-CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS))
+CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS))
# The tests cannot be optimized while the rest of the compiler is optimized, so
# filter out the optimization (if any) from rustc and then figure out if we need
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(CTEST_DEPS_$(4)_$(1)-T-$(2)-H-$(3))
@$$(call E, run $(4) [$(2)]: $$<)
+ $$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
$$(CTEST_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
- && touch $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(PRETTY_DEPS_$(4)) \
$$(PRETTY_DEPS$(1)_H_$(3)_$(4))
@$$(call E, run pretty-rpass [$(2)]: $$<)
+ $$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
$$(PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4)) \
--logfile $$(call TEST_LOG_FILE,$(1),$(2),$(3),$(4)) \
- && touch $$@
+ && touch -r $$@.start_time $$@ && rm $$@.start_time
endef
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)): $$(DOCTESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, run doc-$(4) [$(2)])
+ $$(Q)touch $$@.start_time
$$(Q)$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --cfg dox --test $$< \
- --test-args "$$(TESTARGS)" && touch $$@
+ --test-args "$$(TESTARGS)" && \
+ touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-$(4)):
touch $$@
ifeq ($(2),$$(CFG_BUILD))
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)): $$(CRATEDOCTESTDEP_$(1)_$(2)_$(3)_$(4))
@$$(call E, run doc-crate-$(4) [$(2)])
+ $$(Q)touch $$@.start_time
$$(Q)CFG_LLVM_LINKAGE_FILE=$$(LLVM_LINKAGE_PATH_$(3)) \
$$(RUSTDOC_$(1)_T_$(2)_H_$(3)) --test --cfg dox \
- $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && touch $$@
+ $$(CRATEFILE_$(4)) --test-args "$$(TESTARGS)" && \
+ touch -r $$@.start_time $$@ && rm $$@.start_time
else
$$(call TEST_OK_FILE,$(1),$(2),$(3),doc-crate-$(4)):
touch $$@
$$(CSREQ$(1)_T_$(2)_H_$(3))
@rm -rf $(3)/test/run-make/$$*
@mkdir -p $(3)/test/run-make/$$*
+ $$(Q)touch $$@.start_time
$$(Q)$$(CFG_PYTHON) $(S)src/etc/maketest.py $$(dir $$<) \
$$(MAKE) \
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
"$$(LD_LIBRARY_PATH_ENV_TARGETDIR$(1)_T_$(2)_H_$(3))" \
$(1) \
$$(S)
- @touch $$@
+ @touch -r $$@.start_time $$@ && rm $$@.start_time
else
# FIXME #11094 - The above rule doesn't work right for multiple targets
check-stage$(1)-T-$(2)-H-$(3)-rmake-exec:
use std::fmt;
use std::str::FromStr;
+use std::path::PathBuf;
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum Mode {
pub run_lib_path: String,
// The rustc executable
- pub rustc_path: Path,
+ pub rustc_path: PathBuf,
// The clang executable
- pub clang_path: Option<Path>,
+ pub clang_path: Option<PathBuf>,
// The llvm binaries path
- pub llvm_bin_path: Option<Path>,
+ pub llvm_bin_path: Option<PathBuf>,
// The valgrind path
pub valgrind_path: Option<String>,
pub force_valgrind: bool,
// The directory containing the tests to run
- pub src_base: Path,
+ pub src_base: PathBuf,
// The directory where programs should be built
- pub build_base: Path,
+ pub build_base: PathBuf,
// Directory for auxiliary libraries
- pub aux_base: Path,
+ pub aux_base: PathBuf,
// The name of the stage being built (stage1, etc)
pub stage_id: String,
pub filter: Option<String>,
// Write out a parseable log of tests that were run
- pub logfile: Option<Path>,
+ pub logfile: Option<PathBuf>,
// A command line to prefix program execution with,
// for running under valgrind
pub lldb_version: Option<String>,
// Path to the android tools
- pub android_cross_path: Path,
+ pub android_cross_path: PathBuf,
// Extra parameter to run adb on arm-linux-androideabi
pub adb_path: String,
#![feature(test)]
#![feature(unicode)]
#![feature(core)]
+#![feature(path)]
+#![feature(os)]
+#![feature(io)]
+#![feature(net)]
+#![feature(path_ext)]
#![deny(warnings)]
extern crate log;
use std::env;
+use std::fs;
use std::old_io;
-use std::old_io::fs;
+use std::path::{Path, PathBuf};
use std::thunk::Thunk;
use getopts::{optopt, optflag, reqopt};
use common::Config;
panic!()
}
- fn opt_path(m: &getopts::Matches, nm: &str) -> Path {
+ fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf {
match m.opt_str(nm) {
- Some(s) => Path::new(s),
+ Some(s) => PathBuf::new(&s),
None => panic!("no option (=path) found for {}", nm),
}
}
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
rustc_path: opt_path(matches, "rustc-path"),
- clang_path: matches.opt_str("clang-path").map(|s| Path::new(s)),
+ clang_path: matches.opt_str("clang-path").map(|s| PathBuf::new(&s)),
valgrind_path: matches.opt_str("valgrind-path"),
force_valgrind: matches.opt_present("force-valgrind"),
- llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| Path::new(s)),
+ llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::new(&s)),
src_base: opt_path(matches, "src-base"),
build_base: opt_path(matches, "build-base"),
aux_base: opt_path(matches, "aux-base"),
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
run_ignored: matches.opt_present("ignored"),
filter: filter,
- logfile: matches.opt_str("logfile").map(|s| Path::new(s)),
+ logfile: matches.opt_str("logfile").map(|s| PathBuf::new(&s)),
runtool: matches.opt_str("runtool"),
host_rustcflags: matches.opt_str("host-rustcflags"),
target_rustcflags: matches.opt_str("target-rustcflags"),
debug!("making tests from {:?}",
config.src_base.display());
let mut tests = Vec::new();
- let dirs = fs::readdir(&config.src_base).unwrap();
- for file in &dirs {
- let file = file.clone();
+ let dirs = fs::read_dir(&config.src_base).unwrap();
+ for file in dirs {
+ let file = file.unwrap().path();
debug!("inspecting file {:?}", file.display());
if is_test(config, &file) {
let t = make_test(config, &file, || {
_ => vec!(".rc".to_string(), ".rs".to_string())
};
let invalid_prefixes = vec!(".".to_string(), "#".to_string(), "~".to_string());
- let name = testfile.filename_str().unwrap();
+ let name = testfile.file_name().unwrap().to_str().unwrap();
let mut valid = false;
// Try to elide redundant long paths
fn shorten(path: &Path) -> String {
- let filename = path.filename_str();
- let p = path.dir_path();
- let dir = p.filename_str();
+ let filename = path.file_name().unwrap().to_str();
+ let p = path.parent().unwrap();
+ let dir = p.file_name().unwrap().to_str();
format!("{}/{}", dir.unwrap_or(""), filename.unwrap_or(""))
}
pub fn make_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
let config = (*config).clone();
- // FIXME (#9639): This needs to handle non-utf8 paths
- let testfile = testfile.as_str().unwrap().to_string();
+ let testfile = testfile.to_path_buf();
test::DynTestFn(Thunk::new(move || {
- runtest::run(config, testfile)
+ runtest::run(config, &testfile)
}))
}
pub fn make_metrics_test_closure(config: &Config, testfile: &Path) -> test::TestFn {
let config = (*config).clone();
- // FIXME (#9639): This needs to handle non-utf8 paths
- let testfile = testfile.as_str().unwrap().to_string();
+ let testfile = testfile.to_path_buf();
test::DynMetricFn(box move |mm: &mut test::MetricMap| {
- runtest::run_metrics(config, testfile, mm)
+ runtest::run_metrics(config, &testfile, mm)
})
}
// except according to those terms.
use self::WhichLine::*;
-use std::old_io::{BufferedReader, File};
+use std::fs::File;
+use std::io::BufReader;
+use std::io::prelude::*;
+use std::path::Path;
pub struct ExpectedError {
pub line: uint,
/// //~| ERROR message two for that same line.
// Load any test directives embedded in the file
pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
- let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
+ let rdr = BufReader::new(File::open(testfile).unwrap());
// `last_nonfollow_error` tracks the most recently seen
// line with an error template that did not use the
// except according to those terms.
use std::env;
+use std::fs::File;
+use std::io::BufReader;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
use common::Config;
use common;
pub run_flags: Option<String>,
// If present, the name of a file that this test should match when
// pretty-printed
- pub pp_exact: Option<Path>,
+ pub pp_exact: Option<PathBuf>,
// Modules from aux directory that should be compiled
pub aux_builds: Vec<String> ,
// Environment settings to use during execution
let mut pretty_mode = None;
let mut pretty_compare_only = false;
let mut forbid_output = Vec::new();
- iter_header(testfile, |ln| {
+ iter_header(testfile, &mut |ln| {
match parse_error_pattern(ln) {
Some(ep) => error_patterns.push(ep),
None => ()
}
}
- let val = iter_header(testfile, |ln| {
+ let val = iter_header(testfile, &mut |ln| {
!parse_name_directive(ln, "ignore-test") &&
!parse_name_directive(ln, &ignore_target(config)) &&
!parse_name_directive(ln, &ignore_stage(config)) &&
!val
}
-fn iter_header<F>(testfile: &Path, mut it: F) -> bool where
- F: FnMut(&str) -> bool,
-{
- use std::old_io::{BufferedReader, File};
-
- let mut rdr = BufferedReader::new(File::open(testfile).unwrap());
+fn iter_header(testfile: &Path, it: &mut FnMut(&str) -> bool) -> bool {
+ let rdr = BufReader::new(File::open(testfile).unwrap());
for ln in rdr.lines() {
// Assume that any directives will be found before the first
// module or function. This doesn't seem to be an optimization
})
}
-fn parse_pp_exact(line: &str, testfile: &Path) -> Option<Path> {
+fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> {
match parse_name_value_directive(line, "pp-exact") {
- Some(s) => Some(Path::new(s)),
+ Some(s) => Some(PathBuf::new(&s)),
None => {
if parse_name_directive(line, "pp-exact") {
- testfile.filename().map(|s| Path::new(s))
+ testfile.file_name().map(|s| PathBuf::new(s))
} else {
None
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::old_io::process::{ProcessExit, Command, Process, ProcessOutput};
+use std::process::{ExitStatus, Command, Child, Output, Stdio};
+use std::io::prelude::*;
use std::dynamic_lib::DynamicLibrary;
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
let var = DynamicLibrary::envvar();
let newpath = DynamicLibrary::create_path(&path);
let newpath = String::from_utf8(newpath).unwrap();
- cmd.env(var.to_string(), newpath);
+ cmd.env(var, &newpath);
}
-pub struct Result {pub status: ProcessExit, pub out: String, pub err: String}
+pub struct Result {pub status: ExitStatus, pub out: String, pub err: String}
pub fn run(lib_path: &str,
prog: &str,
input: Option<String>) -> Option<Result> {
let mut cmd = Command::new(prog);
- cmd.args(args);
+ cmd.args(args)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped());
add_target_env(&mut cmd, lib_path, aux_path);
for (key, val) in env {
- cmd.env(key, val);
+ cmd.env(&key, &val);
}
match cmd.spawn() {
if let Some(input) = input {
process.stdin.as_mut().unwrap().write_all(input.as_bytes()).unwrap();
}
- let ProcessOutput { status, output, error } =
+ let Output { status, stdout, stderr } =
process.wait_with_output().unwrap();
Some(Result {
status: status,
- out: String::from_utf8(output).unwrap(),
- err: String::from_utf8(error).unwrap()
+ out: String::from_utf8(stdout).unwrap(),
+ err: String::from_utf8(stderr).unwrap()
})
},
Err(..) => None
aux_path: Option<&str>,
args: &[String],
env: Vec<(String, String)> ,
- input: Option<String>) -> Option<Process> {
+ input: Option<String>) -> Option<Child> {
let mut cmd = Command::new(prog);
- cmd.args(args);
+ cmd.args(args)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::piped());
add_target_env(&mut cmd, lib_path, aux_path);
for (key, val) in env {
- cmd.env(key, val);
+ cmd.env(&key, &val);
}
match cmd.spawn() {
use self::TargetLocation::*;
use common::Config;
-use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind, DebugInfoGdb};
-use common::{Codegen, DebugInfoLldb};
+use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
+use common::{Codegen, DebugInfoLldb, DebugInfoGdb};
use errors;
use header::TestProps;
use header;
use procsrv;
use util::logv;
-#[cfg(target_os = "windows")]
-use util;
-
-#[cfg(target_os = "windows")]
-use std::ascii::AsciiExt;
-use std::old_io::File;
-use std::old_io::fs::PathExtensions;
-use std::old_io::fs;
-use std::old_io::net::tcp;
-use std::old_io::process::ProcessExit;
-use std::old_io::process;
-use std::old_io::timer;
-use std::old_io;
+
use std::env;
+use std::ffi::OsStr;
+use std::fmt;
+use std::fs::{self, File};
+use std::io::BufReader;
+use std::io::prelude::*;
use std::iter::repeat;
+use std::net::TcpStream;
+use std::old_io::timer;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output, ExitStatus};
use std::str;
-use std::string::String;
-use std::thread;
use std::time::Duration;
use test::MetricMap;
-pub fn run(config: Config, testfile: String) {
+pub fn run(config: Config, testfile: &Path) {
match &*config.target {
"arm-linux-androideabi" | "aarch64-linux-android" => {
run_metrics(config, testfile, &mut _mm);
}
-pub fn run_metrics(config: Config, testfile: String, mm: &mut MetricMap) {
+pub fn run_metrics(config: Config, testfile: &Path, mm: &mut MetricMap) {
if config.verbose {
// We're going to be dumping a lot of info. Start on a new line.
print!("\n\n");
}
- let testfile = Path::new(testfile);
debug!("running {:?}", testfile.display());
let props = header::load_props(&testfile);
debug!("loaded props");
};
// The value our Makefile configures valgrind to return on failure
- static VALGRIND_ERR: int = 100;
- if proc_res.status.matches_exit_status(VALGRIND_ERR) {
+ const VALGRIND_ERR: i32 = 100;
+ if proc_res.status.code() == Some(VALGRIND_ERR) {
fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
}
fn check_correct_failure_status(proc_res: &ProcRes) {
// The value the rust runtime returns on failure
- static RUST_ERR: int = 101;
- if !proc_res.status.matches_exit_status(RUST_ERR) {
+ const RUST_ERR: i32 = 101;
+ if proc_res.status.code() != Some(RUST_ERR) {
fatal_proc_rec(
- &format!("failure produced the wrong error: {:?}",
+ &format!("failure produced the wrong error: {}",
proc_res.status),
proc_res);
}
let rounds =
match props.pp_exact { Some(_) => 1, None => 2 };
- let src = File::open(testfile).read_to_end().unwrap();
- let src = String::from_utf8(src.clone()).unwrap();
+ let mut src = String::new();
+ File::open(testfile).unwrap().read_to_string(&mut src).unwrap();
let mut srcs = vec!(src);
let mut round = 0;
let mut expected = match props.pp_exact {
Some(ref file) => {
- let filepath = testfile.dir_path().join(file);
- let s = File::open(&filepath).read_to_end().unwrap();
- String::from_utf8(s).unwrap()
+ let filepath = testfile.parent().unwrap().join(file);
+ let mut s = String::new();
+ File::open(&filepath).unwrap().read_to_string(&mut s).unwrap();
+ s
}
None => { srcs[srcs.len() - 2].clone() }
};
pretty_type.to_string()),
props.exec_env.clone(),
&config.compile_lib_path,
- Some(aux_dir.as_str().unwrap()),
+ Some(aux_dir.to_str().unwrap()),
Some(src))
}
pretty_type,
format!("--target={}", config.target),
"-L".to_string(),
- aux_dir.as_str().unwrap().to_string());
+ aux_dir.to_str().unwrap().to_string());
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
args.extend(split_maybe_args(&props.compile_flags).into_iter());
return ProcArgs {
- prog: config.rustc_path.as_str().unwrap().to_string(),
+ prog: config.rustc_path.to_str().unwrap().to_string(),
args: args,
};
}
"--crate-type=lib".to_string(),
format!("--target={}", target),
"-L".to_string(),
- config.build_base.as_str().unwrap().to_string(),
+ config.build_base.to_str().unwrap().to_string(),
"-L".to_string(),
- aux_dir.as_str().unwrap().to_string());
+ aux_dir.to_str().unwrap().to_string());
args.extend(split_maybe_args(&config.target_rustcflags).into_iter());
args.extend(split_maybe_args(&props.compile_flags).into_iter());
// FIXME (#9639): This needs to handle non-utf8 paths
return ProcArgs {
- prog: config.rustc_path.as_str().unwrap().to_string(),
+ prog: config.rustc_path.to_str().unwrap().to_string(),
args: args,
};
}
// write debugger script
let mut script_str = String::with_capacity(2048);
script_str.push_str("set charset UTF-8\n");
- script_str.push_str(&format!("file {}\n", exe_file.as_str().unwrap()));
+ script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
script_str.push_str("target remote :5039\n");
script_str.push_str(&format!("set solib-search-path \
./{}/stage2/lib/rustlib/{}/lib/\n",
config.host, config.target));
for line in breakpoint_lines.iter() {
script_str.push_str(&format!("break {:?}:{}\n",
- testfile.filename_display(),
+ testfile.file_name().unwrap()
+ .to_string_lossy(),
*line)[..]);
}
script_str.push_str(&cmds);
- script_str.push_str("quit\n");
+ script_str.push_str("\nquit\n");
debug!("script_str = {}", script_str);
dump_output_file(config,
None,
&[
"push".to_string(),
- exe_file.as_str().unwrap().to_string(),
+ exe_file.to_str().unwrap().to_string(),
config.adb_test_dir.clone()
],
vec!(("".to_string(), "".to_string())),
if config.target.contains("aarch64")
{"64"} else {""},
config.adb_test_dir.clone(),
- str::from_utf8(
- exe_file.filename()
- .unwrap()).unwrap());
+ exe_file.file_name().unwrap().to_str()
+ .unwrap());
let mut process = procsrv::run_background("",
&config.adb_path
loop {
//waiting 1 second for gdbserver start
timer::sleep(Duration::milliseconds(1000));
- let result = thread::spawn(move || {
- tcp::TcpStream::connect("127.0.0.1:5039").unwrap();
- }).join();
- if result.is_err() {
- continue;
+ if TcpStream::connect("127.0.0.1:5039").is_ok() {
+ break
}
- break;
}
- let tool_path = match config.android_cross_path.as_str() {
+ let tool_path = match config.android_cross_path.to_str() {
Some(x) => x.to_string(),
None => fatal("cannot find android cross path")
};
vec!("-quiet".to_string(),
"-batch".to_string(),
"-nx".to_string(),
- format!("-command={}", debugger_script.as_str().unwrap()));
+ format!("-command={}", debugger_script.to_str().unwrap()));
let mut gdb_path = tool_path;
gdb_path.push_str(&format!("/bin/{}-gdb", config.target));
};
debugger_run_result = ProcRes {
- status: status,
+ status: Status::Normal(status),
stdout: out,
stderr: err,
cmdline: cmdline
};
- if process.signal_kill().is_err() {
+ if process.kill().is_err() {
println!("Adb process is already finished.");
}
}
.expect("Could not find Rust source root");
let rust_pp_module_rel_path = Path::new("./src/etc");
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
- .as_str()
+ .to_str()
.unwrap()
.to_string();
// write debugger script
// GDB's script auto loading safe path
script_str.push_str(
&format!("add-auto-load-safe-path {}\n",
- rust_pp_module_abs_path.replace("\\", "\\\\"))
+ rust_pp_module_abs_path.replace(r"\", r"\\"))
);
}
}
script_str.push_str("set print pretty off\n");
// Add the pretty printer directory to GDB's source-file search path
- script_str.push_str(&format!("directory {}\n", rust_pp_module_abs_path)[..]);
+ script_str.push_str(&format!("directory {}\n",
+ rust_pp_module_abs_path));
// Load the target executable
script_str.push_str(&format!("file {}\n",
- exe_file.as_str().unwrap().replace("\\", "\\\\"))[..]);
+ exe_file.to_str().unwrap()
+ .replace(r"\", r"\\")));
// Add line breakpoints
for line in &breakpoint_lines {
script_str.push_str(&format!("break '{}':{}\n",
- testfile.filename_display(),
- *line)[..]);
+ testfile.file_name().unwrap()
+ .to_string_lossy(),
+ *line));
}
script_str.push_str(&cmds);
- script_str.push_str("quit\n");
+ script_str.push_str("\nquit\n");
debug!("script_str = {}", script_str);
dump_output_file(config,
"debugger.script");
// run debugger script with gdb
- #[cfg(windows)]
- fn debugger() -> String {
- "gdb.exe".to_string()
- }
- #[cfg(unix)]
- fn debugger() -> String {
- "gdb".to_string()
+ fn debugger() -> &'static str {
+ if cfg!(windows) {"gdb.exe"} else {"gdb"}
}
let debugger_script = make_out_name(config, testfile, "debugger.script");
vec!("-quiet".to_string(),
"-batch".to_string(),
"-nx".to_string(),
- format!("-command={}", debugger_script.as_str().unwrap()));
+ format!("-command={}", debugger_script.to_str().unwrap()));
let proc_args = ProcArgs {
- prog: debugger(),
+ prog: debugger().to_string(),
args: debugger_opts,
};
check_debugger_output(&debugger_run_result, &check_lines);
}
-fn find_rust_src_root(config: &Config) -> Option<Path> {
+fn find_rust_src_root(config: &Config) -> Option<PathBuf> {
let mut path = config.src_base.clone();
let path_postfix = Path::new("src/etc/lldb_batchmode.py");
}
fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path) {
- use std::old_io::process::{Command, ProcessOutput};
-
if config.lldb_python_dir.is_none() {
fatal("Can't run LLDB test because LLDB's python path is not set.");
}
.expect("Could not find Rust source root");
let rust_pp_module_rel_path = Path::new("./src/etc/lldb_rust_formatters.py");
let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path)
- .as_str()
+ .to_str()
.unwrap()
.to_string();
- script_str.push_str(&format!("command script import {}\n", &rust_pp_module_abs_path[..])[..]);
+ script_str.push_str(&format!("command script import {}\n",
+ &rust_pp_module_abs_path[..])[..]);
script_str.push_str("type summary add --no-value ");
script_str.push_str("--python-function lldb_rust_formatters.print_val ");
script_str.push_str("-x \".*\" --category Rust\n");
}
// Finally, quit the debugger
- script_str.push_str("quit\n");
+ script_str.push_str("\nquit\n");
// Write the script into a file
debug!("script_str = {}", script_str);
rust_src_root: &Path)
-> ProcRes {
// Prepare the lldb_batchmode which executes the debugger script
- let lldb_script_path = rust_src_root.join(Path::new("./src/etc/lldb_batchmode.py"));
+ let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
let mut cmd = Command::new("python");
- cmd.arg(lldb_script_path)
+ cmd.arg(&lldb_script_path)
.arg(test_executable)
.arg(debugger_script)
- .env_set_all(&[("PYTHONPATH", config.lldb_python_dir.clone().unwrap())]);
-
- let (status, out, err) = match cmd.spawn() {
- Ok(process) => {
- let ProcessOutput { status, output, error } =
- process.wait_with_output().unwrap();
+ .env("PYTHONPATH", config.lldb_python_dir.as_ref().unwrap());
+ let (status, out, err) = match cmd.output() {
+ Ok(Output { status, stdout, stderr }) => {
(status,
- String::from_utf8(output).unwrap(),
- String::from_utf8(error).unwrap())
+ String::from_utf8(stdout).unwrap(),
+ String::from_utf8(stderr).unwrap())
},
Err(e) => {
fatal(&format!("Failed to setup Python process for \
dump_output(config, test_executable, &out, &err);
return ProcRes {
- status: status,
+ status: Status::Normal(status),
stdout: out,
stderr: err,
cmdline: format!("{:?}", cmd)
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
-> DebuggerCommands {
- use std::old_io::{BufferedReader, File};
-
let command_directive = format!("{}-command", debugger_prefix);
let check_directive = format!("{}-check", debugger_prefix);
let mut commands = vec!();
let mut check_lines = vec!();
let mut counter = 1;
- let mut reader = BufferedReader::new(File::open(file_path).unwrap());
+ let reader = BufReader::new(File::open(file_path).unwrap());
for line in reader.lines() {
match line {
Ok(line) => {
let prefixes = expected_errors.iter().map(|ee| {
format!("{}:{}:", testfile.display(), ee.line)
- }).collect::<Vec<String> >();
-
- #[cfg(windows)]
- fn prefix_matches( line : &str, prefix : &str ) -> bool {
- line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
- }
-
- #[cfg(unix)]
- fn prefix_matches( line : &str, prefix : &str ) -> bool {
- line.starts_with( prefix )
+ }).collect::<Vec<String>>();
+
+ fn prefix_matches(line: &str, prefix: &str) -> bool {
+ use std::ascii::AsciiExt;
+ // On windows just translate all '\' path separators to '/'
+ let line = line.replace(r"\", "/");
+ if cfg!(windows) {
+ line.to_ascii_lowercase().starts_with(&prefix.to_ascii_lowercase())
+ } else {
+ line.starts_with(prefix)
+ }
}
// A multi-line error will have followup lines which will always
}
struct ProcRes {
- status: ProcessExit,
+ status: Status,
stdout: String,
stderr: String,
cmdline: String,
}
+enum Status {
+ Parsed(i32),
+ Normal(ExitStatus),
+}
+
+impl Status {
+ fn code(&self) -> Option<i32> {
+ match *self {
+ Status::Parsed(i) => Some(i),
+ Status::Normal(ref e) => e.code(),
+ }
+ }
+
+ fn success(&self) -> bool {
+ match *self {
+ Status::Parsed(i) => i == 0,
+ Status::Normal(ref e) => e.success(),
+ }
+ }
+}
+
+impl fmt::Display for Status {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Status::Parsed(i) => write!(f, "exit code: {}", i),
+ Status::Normal(ref e) => e.fmt(f),
+ }
+ }
+}
+
fn compile_test(config: &Config, props: &TestProps,
testfile: &Path) -> ProcRes {
compile_test_(config, props, testfile, &[])
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
let mut link_args = vec!("-L".to_string(),
- aux_dir.as_str().unwrap().to_string());
+ aux_dir.to_str().unwrap().to_string());
link_args.extend(extra_args.iter().cloned());
let args = make_compile_args(config,
props,
make_run_args(config, props, testfile),
env,
&config.run_lib_path,
- Some(aux_dir.as_str().unwrap()),
+ Some(aux_dir.to_str().unwrap()),
None)
}
}
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
- let extra_link_args = vec!("-L".to_string(), aux_dir.as_str().unwrap().to_string());
+ let extra_link_args = vec!("-L".to_string(), aux_dir.to_str().unwrap().to_string());
for rel_ab in &props.aux_builds {
let abs_ab = config.aux_base.join(rel_ab);
crate_type,
|a,b| {
let f = make_lib_name(a, b, testfile);
- TargetLocation::ThisDirectory(f.dir_path())
+ let parent = f.parent().unwrap();
+ TargetLocation::ThisDirectory(parent.to_path_buf())
},
&abs_ab);
let auxres = compose_and_run(config,
aux_args,
Vec::new(),
&config.compile_lib_path,
- Some(aux_dir.as_str().unwrap()),
+ Some(aux_dir.to_str().unwrap()),
None);
if !auxres.status.success() {
fatal_proc_rec(
args,
Vec::new(),
&config.compile_lib_path,
- Some(aux_dir.as_str().unwrap()),
+ Some(aux_dir.to_str().unwrap()),
input)
}
fn ensure_dir(path: &Path) {
if path.is_dir() { return; }
- fs::mkdir(path, old_io::USER_RWX).unwrap();
+ fs::create_dir(path).unwrap();
}
fn compose_and_run(config: &Config, testfile: &Path,
}
enum TargetLocation {
- ThisFile(Path),
- ThisDirectory(Path),
+ ThisFile(PathBuf),
+ ThisDirectory(PathBuf),
}
fn make_compile_args<F>(config: &Config,
&*config.target
};
// FIXME (#9639): This needs to handle non-utf8 paths
- let mut args = vec!(testfile.as_str().unwrap().to_string(),
+ let mut args = vec!(testfile.to_str().unwrap().to_string(),
"-L".to_string(),
- config.build_base.as_str().unwrap().to_string(),
+ config.build_base.to_str().unwrap().to_string(),
format!("--target={}", target));
args.push_all(&extras);
if !props.no_prefer_dynamic {
path
}
};
- args.push(path.as_str().unwrap().to_string());
+ args.push(path.to_str().unwrap().to_string());
if props.force_host {
args.extend(split_maybe_args(&config.host_rustcflags).into_iter());
} else {
}
args.extend(split_maybe_args(&props.compile_flags).into_iter());
return ProcArgs {
- prog: config.rustc_path.as_str().unwrap().to_string(),
+ prog: config.rustc_path.to_str().unwrap().to_string(),
args: args,
};
}
-fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> Path {
+fn make_lib_name(config: &Config, auxfile: &Path, testfile: &Path) -> PathBuf {
// what we return here is not particularly important, as it
// happens; rustc ignores everything except for the directory.
let auxname = output_testname(auxfile);
aux_output_dir_name(config, testfile).join(&auxname)
}
-fn make_exe_name(config: &Config, testfile: &Path) -> Path {
+fn make_exe_name(config: &Config, testfile: &Path) -> PathBuf {
let mut f = output_base_name(config, testfile);
if !env::consts::EXE_SUFFIX.is_empty() {
- let mut fname = f.filename().unwrap().to_vec();
- fname.extend(env::consts::EXE_SUFFIX.bytes());
- f.set_filename(fname);
+ let mut fname = f.file_name().unwrap().to_os_string();
+ fname.push_os_str(OsStr::from_str(env::consts::EXE_SUFFIX));
+ f.set_file_name(&fname);
}
f
}
let exe_file = make_exe_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
- args.push(exe_file.as_str().unwrap().to_string());
+ args.push(exe_file.to_str().unwrap().to_string());
// Add the arguments in the run_flags directive
args.extend(split_maybe_args(&props.run_flags).into_iter());
input).expect(&format!("failed to exec `{}`", prog));
dump_output(config, testfile, &out, &err);
return ProcRes {
- status: status,
+ status: Status::Normal(status),
stdout: out,
stderr: err,
cmdline: cmdline,
};
}
-// Linux and mac don't require adjusting the library search path
-#[cfg(unix)]
-fn make_cmdline(_libpath: &str, prog: &str, args: &[String]) -> String {
- format!("{} {}", prog, args.connect(" "))
-}
-
-#[cfg(windows)]
fn make_cmdline(libpath: &str, prog: &str, args: &[String]) -> String {
+ use util;
- // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
- // for diagnostic purposes
- fn lib_path_cmd_prefix(path: &str) -> String {
- format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
- }
+ // Linux and mac don't require adjusting the library search path
+ if cfg!(unix) {
+ format!("{} {}", prog, args.connect(" "))
+ } else {
+ // Build the LD_LIBRARY_PATH variable as it would be seen on the command line
+ // for diagnostic purposes
+ fn lib_path_cmd_prefix(path: &str) -> String {
+ format!("{}=\"{}\"", util::lib_path_env_var(), util::make_new_path(path))
+ }
- format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
+ format!("{} {} {}", lib_path_cmd_prefix(libpath), prog, args.connect(" "))
+ }
}
fn dump_output(config: &Config, testfile: &Path, out: &str, err: &str) {
fn dump_output_file(config: &Config, testfile: &Path,
out: &str, extension: &str) {
let outfile = make_out_name(config, testfile, extension);
- File::create(&outfile).write_all(out.as_bytes()).unwrap();
+ File::create(&outfile).unwrap().write_all(out.as_bytes()).unwrap();
}
-fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> Path {
+fn make_out_name(config: &Config, testfile: &Path, extension: &str) -> PathBuf {
output_base_name(config, testfile).with_extension(extension)
}
-fn aux_output_dir_name(config: &Config, testfile: &Path) -> Path {
+fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
let f = output_base_name(config, testfile);
- let mut fname = f.filename().unwrap().to_vec();
- fname.extend("libaux".bytes());
- f.with_filename(fname)
+ let mut fname = f.file_name().unwrap().to_os_string();
+ fname.push_os_str(OsStr::from_str("libaux"));
+ f.with_file_name(&fname)
}
-fn output_testname(testfile: &Path) -> Path {
- Path::new(testfile.filestem().unwrap())
+fn output_testname(testfile: &Path) -> PathBuf {
+ PathBuf::new(testfile.file_stem().unwrap())
}
-fn output_base_name(config: &Config, testfile: &Path) -> Path {
+fn output_base_name(config: &Config, testfile: &Path) -> PathBuf {
config.build_base
.join(&output_testname(testfile))
.with_extension(&config.stage_id)
Some("".to_string()))
.expect(&format!("failed to exec `{}`", config.adb_path));
- let mut exitcode: int = 0;
+ let mut exitcode: i32 = 0;
for c in exitcode_out.chars() {
if !c.is_numeric() { break; }
exitcode = exitcode * 10 + match c {
- '0' ... '9' => c as int - ('0' as int),
+ '0' ... '9' => c as i32 - ('0' as i32),
_ => 101,
}
}
&stderr_out);
ProcRes {
- status: process::ProcessExit::ExitStatus(exitcode),
+ status: Status::Parsed(exitcode),
stdout: stdout_out,
stderr: stderr_out,
cmdline: cmdline
fn _arm_push_aux_shared_library(config: &Config, testfile: &Path) {
let tdir = aux_output_dir_name(config, testfile);
- let dirs = fs::readdir(&tdir).unwrap();
- for file in &dirs {
- if file.extension_str() == Some("so") {
+ let dirs = fs::read_dir(&tdir).unwrap();
+ for file in dirs {
+ let file = file.unwrap().path();
+ if file.extension().and_then(|s| s.to_str()) == Some("so") {
// FIXME (#9639): This needs to handle non-utf8 paths
let copy_result = procsrv::run("",
&config.adb_path,
None,
&[
"push".to_string(),
- file.as_str()
+ file.to_str()
.unwrap()
.to_string(),
config.adb_test_dir.to_string(),
// codegen tests (vs. clang)
-fn append_suffix_to_stem(p: &Path, suffix: &str) -> Path {
+fn append_suffix_to_stem(p: &Path, suffix: &str) -> PathBuf {
if suffix.len() == 0 {
- (*p).clone()
+ p.to_path_buf()
} else {
- let mut stem = p.filestem().unwrap().to_vec();
- stem.extend("-".bytes());
- stem.extend(suffix.bytes());
- p.with_filename(stem)
+ let mut stem = p.file_stem().unwrap().to_os_string();
+ stem.push_os_str(OsStr::from_str("-"));
+ stem.push_os_str(OsStr::from_str(suffix));
+ p.with_file_name(&stem)
}
}
let aux_dir = aux_output_dir_name(config, testfile);
// FIXME (#9639): This needs to handle non-utf8 paths
let mut link_args = vec!("-L".to_string(),
- aux_dir.as_str().unwrap().to_string());
+ aux_dir.to_str().unwrap().to_string());
let llvm_args = vec!("--emit=llvm-bc,obj".to_string(),
"--crate-type=lib".to_string());
link_args.extend(llvm_args.into_iter());
props,
link_args,
|a, b| TargetLocation::ThisDirectory(
- output_base_name(a, b).dir_path()),
+ output_base_name(a, b).parent()
+ .unwrap().to_path_buf()),
testfile);
compose_and_run_compiler(config, props, testfile, args, None)
}
let testcc = testfile.with_extension("cc");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
- prog: config.clang_path.as_ref().unwrap().as_str().unwrap().to_string(),
+ prog: config.clang_path.as_ref().unwrap().to_str().unwrap().to_string(),
args: vec!("-c".to_string(),
"-emit-llvm".to_string(),
"-o".to_string(),
- bitcodefile.as_str().unwrap().to_string(),
- testcc.as_str().unwrap().to_string())
+ bitcodefile.to_str().unwrap().to_string(),
+ testcc.to_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-extract");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
- prog: prog.as_str().unwrap().to_string(),
+ prog: prog.to_str().unwrap().to_string(),
args: vec!(format!("-func={}", fname),
- format!("-o={}", extracted_bc.as_str().unwrap()),
- bitcodefile.as_str().unwrap().to_string())
+ format!("-o={}", extracted_bc.to_str().unwrap()),
+ bitcodefile.to_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}
let prog = config.llvm_bin_path.as_ref().unwrap().join("llvm-dis");
let proc_args = ProcArgs {
// FIXME (#9639): This needs to handle non-utf8 paths
- prog: prog.as_str().unwrap().to_string(),
- args: vec!(format!("-o={}", extracted_ll.as_str().unwrap()),
- extracted_bc.as_str().unwrap().to_string())
+ prog: prog.to_str().unwrap().to_string(),
+ args: vec!(format!("-o={}", extracted_ll.to_str().unwrap()),
+ extracted_bc.to_str().unwrap().to_string())
};
compose_and_run(config, testfile, proc_args, Vec::new(), "", None, None)
}
fn count_extracted_lines(p: &Path) -> uint {
- let x = File::open(&p.with_extension("ll")).read_to_end().unwrap();
+ let mut x = Vec::new();
+ File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap();
let x = str::from_utf8(&x).unwrap();
x.lines().count()
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use common::Config;
-
-#[cfg(target_os = "windows")]
use std::env;
+use common::Config;
/// Conversion table from triple OS name to Rust SYSNAME
-static OS_TABLE: &'static [(&'static str, &'static str)] = &[
+const OS_TABLE: &'static [(&'static str, &'static str)] = &[
("mingw32", "windows"),
("win32", "windows"),
("windows", "windows"),
panic!("Cannot determine OS from triple");
}
-#[cfg(target_os = "windows")]
pub fn make_new_path(path: &str) -> String {
-
+ assert!(cfg!(windows));
// Windows just uses PATH as the library search path, so we have to
// maintain the current value while adding our own
match env::var(lib_path_env_var()) {
- Ok(curr) => {
- format!("{}{}{}", path, path_div(), curr)
- }
- Err(..) => path.to_string()
+ Ok(curr) => {
+ format!("{}{}{}", path, path_div(), curr)
+ }
+ Err(..) => path.to_string()
}
}
-#[cfg(target_os = "windows")]
pub fn lib_path_env_var() -> &'static str { "PATH" }
-
-#[cfg(target_os = "windows")]
-pub fn path_div() -> &'static str { ";" }
+fn path_div() -> &'static str { ";" }
pub fn logv(config: &Config, s: String) {
debug!("{}", s);
% The (old) Rust Threads and Communication Guide
This content has moved into
-[the Rust Programming Language book](book/tasks.html).
+[the Rust Programming Language book](book/concurrency.html).
let guards: Vec<_> = (0..3).map(|i| {
Thread::scoped(move || {
- for j in 0..3 { numbers[j] += 1 }
+ numbers[i] += 1;
+ println!("numbers[{}] is {}", i, numbers[i]);
});
}).collect();
}
It gives us this error:
```text
-7:29: 9:10 error: cannot move out of captured outer variable in an `FnMut` closure
-7 Thread::scoped(move || {
-8 for j in 0..3 { numbers[j] += 1 }
-9 });
+7:25: 10:6 error: cannot move out of captured outer variable in an `FnMut` closure
+7 Thread::scoped(move || {
+8 numbers[i] += 1;
+9 println!("numbers[{}] is {}", i, numbers[i]);
+10 });
+error: aborting due to previous error
```
It mentions that "captured outer variable in an `FnMut` closure".
* `quote_pat!`
* `quote_stmt!`
* `quote_tokens!`
+* `quote_matcher!`
* `quote_ty!`
+* `quote_attr!`
+
+Keep in mind that when `$name : ident` appears in the input to
+`quote_tokens!`, the result contains unquoted `name` followed by two tokens.
+However, input of the same form passed to `quote_matcher!` becomes a
+quasiquoted MBE-matcher of a nonterminal. No unquotation happens. Otherwise
+the result of `quote_matcher!` is identical to that of `quote_tokens!`.
Documentation is very limited at the moment.
* `staged_api` - Allows usage of stability markers and `#![staged_api]` in a crate
+* `static_assert` - The `#[static_assert]` functionality is experimental and
+ unstable. The attribute can be attached to a `static` of
+ type `bool` and the compiler will error if the `bool` is
+ `false` at compile time. This version of this functionality
+ is unintuitive and suboptimal.
+
* `start` - Allows use of the `#[start]` attribute, which changes the entry point
into a Rust program. This capabiilty, especially the signature for the
annotated function, is subject to change.
types, e.g. as the return type of a public function.
This capability may be removed in the future.
+* `allow_internal_unstable` - Allows `macro_rules!` macros to be tagged with the
+ `#[allow_internal_unstable]` attribute, designed
+ to allow `std` macros to call
+ `#[unstable]`/feature-gated functionality
+ internally without imposing on callers
+ (i.e. making them behave like function calls in
+ terms of encapsulation).
+
If a feature is promoted to a language feature, then all existing programs will
start to receive compilation warnings about #[feature] directives which enabled
the new feature (because the directive is no longer necessary). However, if a
brackets `[]` with `vec!`. Rust allows you to use either in either situation,
this is just convention.)
+There's an alternate form of `vec!` for repeating an initial value:
+
+```
+let v = vec![0; 10]; // ten zeroes
+```
+
You can get the length of, iterate over, and subscript vectors just like
arrays. In addition, (mutable) vectors can grow automatically:
## Tuples
-The first compound data type we're going to talk about are called *tuples*.
-Tuples are an ordered list of a fixed size. Like this:
+The first compound data type we're going to talk about is called the *tuple*.
+A tuple is an ordered list of fixed size. Like this:
```rust
let x = (1, "hello");
```
An `enum` variant can be defined as most normal types. Below are some example
-types have been listed which also would be allowed in an `enum`.
+types which also would be allowed in an `enum`.
```rust
struct Empty;
one_hundred: 100,
});
- let y = box foo(x);
+ let y: Box<BigStruct> = box foo(x);
}
```
import subprocess
import re
import os
-from licenseck import *
+from licenseck import check_license
import snapshot
err = 0
tab_flag = "ignore-tidy-tab"
linelength_flag = "ignore-tidy-linelength"
-# Be careful to support Python 2.4, 2.6, and 3.x here!
-config_proc = subprocess.Popen(["git", "config", "core.autocrlf"],
- stdout=subprocess.PIPE)
-result = config_proc.communicate()[0]
-
-true = "true".encode('utf8')
-autocrlf = result.strip() == true if result is not None else False
+interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h']
+uninteresting_files = ['miniz.c', 'jquery', 'rust_android_dummy']
def report_error_name_no(name, no, s):
if not check_license(name, contents):
report_error_name_no(name, 1, "incorrect license")
+
+def update_counts(current_name):
+ global file_counts
+ global count_other_linted_files
+
+ _, ext = os.path.splitext(current_name)
+
+ if ext in interesting_files:
+ file_counts[ext] += 1
+ else:
+ count_other_linted_files += 1
+
+
+def interesting_file(f):
+ if any(x in f for x in uninteresting_files):
+ return False
+
+ return any(os.path.splitext(f)[1] == ext for ext in interesting_files)
+
+
+# Be careful to support Python 2.4, 2.6, and 3.x here!
+config_proc = subprocess.Popen(["git", "config", "core.autocrlf"],
+ stdout=subprocess.PIPE)
+result = config_proc.communicate()[0]
+
+true = "true".encode('utf8')
+autocrlf = result.strip() == true if result is not None else False
+
current_name = ""
current_contents = ""
check_tab = True
src_dir = sys.argv[1]
-try:
- count_lines = 0
- count_non_blank_lines = 0
+count_lines = 0
+count_non_blank_lines = 0
+count_other_linted_files = 0
- interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h']
+file_counts = {ext: 0 for ext in interesting_files}
- file_counts = {ext: 0 for ext in interesting_files}
- file_counts['other'] = 0
-
- def update_counts(current_name):
- global file_counts
- _, ext = os.path.splitext(current_name)
-
- if ext in file_counts:
- file_counts[ext] += 1
- else:
- file_counts['other'] += 1
-
- all_paths = set()
+all_paths = set()
+try:
for (dirpath, dirnames, filenames) in os.walk(src_dir):
-
# Skip some third-party directories
skippable_dirs = {
'src/jemalloc',
if any(d in dirpath for d in skippable_dirs):
continue
- def interesting_file(f):
- if "miniz.c" in f \
- or "jquery" in f \
- or "rust_android_dummy" in f:
- return False
-
- return any(os.path.splitext(f)[1] == ext for ext in interesting_files)
-
file_names = [os.path.join(dirpath, f) for f in filenames
if interesting_file(f)
and not f.endswith("_gen.rs")
report_err("UTF-8 decoding error " + str(e))
print
-for ext in file_counts:
- print "* linted " + str(file_counts[ext]) + " " + ext + " files"
-print "* total lines of code: " + str(count_lines)
-print "* total non-blank lines of code: " + str(count_non_blank_lines)
+for ext in sorted(file_counts, key=file_counts.get, reverse=True):
+ print "* linted {} {} files".format(file_counts[ext], ext)
+print "* linted {} other files".format(count_other_linted_files)
+print "* total lines of code: {}".format(count_lines)
+print "* total non-blank lines of code: {}".format(count_non_blank_lines)
print
sys.exit(err)
sys.stderr.write("cannot load %s" % f)
exit(1)
-def is_valid_unicode(n):
- return 0 <= n <= 0xD7FF or 0xE000 <= n <= 0x10FFFF
+def is_surrogate(n):
+ return 0xD800 <= n <= 0xDFFF
def load_unicode_data(f):
fetch(f)
canon_decomp = {}
compat_decomp = {}
+ udict = {};
+ range_start = -1;
for line in fileinput.input(f):
- fields = line.split(";")
- if len(fields) != 15:
+ data = line.split(';');
+ if len(data) != 15:
continue
- [code, name, gencat, combine, bidi,
- decomp, deci, digit, num, mirror,
- old, iso, upcase, lowcase, titlecase ] = fields
-
- code_org = code
- code = int(code, 16)
-
- if not is_valid_unicode(code):
+ cp = int(data[0], 16);
+ if is_surrogate(cp):
continue
+ if range_start >= 0:
+ for i in xrange(range_start, cp):
+ udict[i] = data;
+ range_start = -1;
+ if data[1].endswith(", First>"):
+ range_start = cp;
+ continue;
+ udict[cp] = data;
+
+ for code in udict:
+ [code_org, name, gencat, combine, bidi,
+ decomp, deci, digit, num, mirror,
+ old, iso, upcase, lowcase, titlecase ] = udict[code];
# generate char to char direct common and simple conversions
# uppercase to lowercase
fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool {
use core::cmp::Ordering::{Equal, Less, Greater};
use core::slice::SliceExt;
- r.binary_search(|&(lo,hi)| {
+ r.binary_search_by(|&(lo,hi)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
- }).found().is_some()
+ }).is_ok()
}\n
""")
pub_string = ""
if is_pub:
pub_string = "pub "
- f.write(" %sstatic %s: %s = &[\n" % (pub_string, name, t_type))
+ f.write(" %sconst %s: %s = &[\n" % (pub_string, name, t_type))
data = ""
first = True
for dat in t_data:
def emit_regex_module(f, cats, w_data):
f.write("pub mod regex {\n")
regex_class = "&'static [(char, char)]"
- class_table = "&'static [(&'static str, &'static %s)]" % regex_class
+ class_table = "&'static [(&'static str, %s)]" % regex_class
emit_table(f, "UNICODE_CLASSES", cats, class_table,
- pfun=lambda x: "(\"%s\",&super::%s::%s_table)" % (x[0], x[1], x[0]))
+ pfun=lambda x: "(\"%s\",super::%s::%s_table)" % (x[0], x[1], x[0]))
- f.write(" pub static PERLD: &'static %s = &super::general_category::Nd_table;\n\n"
+ f.write(" pub const PERLD: %s = super::general_category::Nd_table;\n\n"
% regex_class)
- f.write(" pub static PERLS: &'static %s = &super::property::White_Space_table;\n\n"
+ f.write(" pub const PERLS: %s = super::property::White_Space_table;\n\n"
% regex_class)
emit_table(f, "PERLW", w_data, regex_class)
use core::slice::SliceExt;
use core::option::Option;
use core::option::Option::{Some, None};
- use core::slice;
+ use core::result::Result::{Ok, Err};
pub fn to_lower(c: char) -> char {
match bsearch_case_table(c, LuLl_table) {
}
fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option<usize> {
- match table.binary_search(|&(key, _)| {
+ match table.binary_search_by(|&(key, _)| {
if c == key { Equal }
else if key < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(i) => Some(i),
- slice::BinarySearchResult::NotFound(_) => None,
+ Ok(i) => Some(i),
+ Err(_) => None,
}
}
def emit_grapheme_module(f, grapheme_table, grapheme_cats):
f.write("""pub mod grapheme {
- use core::kinds::Copy;
use core::slice::SliceExt;
pub use self::GraphemeCat::*;
- use core::slice;
+ use core::result::Result::{Ok, Err};
#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
use core::cmp::Ordering::{Equal, Less, Greater};
- match r.binary_search(|&(lo, hi, _)| {
+ match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, cat) = r[idx];
cat
}
- slice::BinarySearchResult::NotFound(_) => GC_Any
+ Err(_) => GC_Any
}
}
f.write(" use core::option::Option;\n")
f.write(" use core::option::Option::{Some, None};\n")
f.write(" use core::slice::SliceExt;\n")
- f.write(" use core::slice;\n")
+ f.write(" use core::result::Result::{Ok, Err};\n")
f.write("""
fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 {
use core::cmp::Ordering::{Equal, Less, Greater};
- match r.binary_search(|&(lo, hi, _, _)| {
+ match r.binary_search_by(|&(lo, hi, _, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, r_ncjk, r_cjk) = r[idx];
if is_cjk { r_cjk } else { r_ncjk }
}
- slice::BinarySearchResult::NotFound(_) => 1
+ Err(_) => 1
}
}
""")
fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
use core::cmp::Ordering::{Equal, Less, Greater};
use core::slice::SliceExt;
- use core::slice;
- match r.binary_search(|&(lo, hi, _)| {
+ use core::result::Result::{Ok, Err};
+ match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
- slice::BinarySearchResult::Found(idx) => {
+ Ok(idx) => {
let (_, _, result) = r[idx];
result
}
- slice::BinarySearchResult::NotFound(_) => 0
+ Err(_) => 0
}
}\n
""")
unicode_version = re.search(pattern, readme.read()).groups()
rf.write("""
/// The version of [Unicode](http://www.unicode.org/)
-/// that the `UnicodeChar` and `UnicodeStrPrelude` traits are based on.
+/// that the unicode parts of `CharExt` and `UnicodeStrPrelude` traits are based on.
pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
""" % unicode_version)
(canon_decomp, compat_decomp, gencats, combines,
%precedence MOD_SEP
%precedence RARROW ':'
+// In where clauses, "for" should have greater precedence when used as
+// a higher ranked constraint than when used as the beginning of a
+// for_in_type (which is a ty)
+%precedence FORTYPE
+%precedence FOR
+
// Binops & unops, and their precedences
%precedence BOX
%precedence BOXPLACE
{
$$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
}
+| maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
+{
+ $$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
+}
+| maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
+{
+ $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
+}
;
maybe_impl_items
;
where_predicate
-: lifetime ':' bounds { $$ = mk_node("WherePredicate", 2, $1, $3); }
-| ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 2, $1, $3); }
+: maybe_for_lifetimes lifetime ':' bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
+| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
;
+maybe_for_lifetimes
+: FOR '<' lifetimes '>' { $$ = mk_none(); }
+| %prec FORTYPE %empty { $$ = mk_none(); }
+
ty_params
: ty_param { $$ = mk_node("TyParams", 1, $1); }
| ty_params ',' ty_param { $$ = ext_node($1, 1, $3); }
}
| ty_qualified_path ',' ty_sums maybe_bindings
{
- $$ = mk_node("GenericValues", 3, mk_none(), ext_node(mk_node("TySums", 1, $1), 1, $3), $4); }
+ $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4);
+}
;
ty_qualified_path
;
expr_qualified_path
-: '<' ty_sum AS trait_ref '>' MOD_SEP ident
+: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident
{
- $$ = mk_node("ExprQualifiedPath", 3, $2, $4, $7);
+ $$ = mk_node("ExprQualifiedPath", 3, $2, $3, $6);
}
-| '<' ty_sum AS trait_ref '>' MOD_SEP ident generic_args
+| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args
{
- $$ = mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8);
+ $$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7);
}
-| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
{
- $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12);
+ $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10);
}
-| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident
{
- $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13);
+ $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11);
}
-| SHL ty_sum AS trait_ref '>' MOD_SEP ident AS trait_ref '>' MOD_SEP ident generic_args
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args
{
- $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $4, $7), $9, $12, $13);
+ $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11);
}
-| SHL ty_sum AS trait_ref '>' MOD_SEP ident generic_args AS trait_ref '>' MOD_SEP ident generic_args
+| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args
{
- $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $4, $7, $8), $10, $13, $14);
+ $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12);
}
+maybe_as_trait_ref
+: AS trait_ref { $$ = $2; }
+| %empty { $$ = mk_none(); }
+;
lambda_expr
: %prec LAMBDA
-Subproject commit b001609960ca33047e5cbc5a231c1e24b6041d4b
+Subproject commit e24a1a025a1f214e40eedafe3b9c7b1d69937922
//! }
//! ```
+use boxed::Box;
+
use core::prelude::*;
use core::atomic;
pub fn new(data: T) -> Arc<T> {
// Start the weak pointer count as 1 which is the weak pointer that's
// held by all the strong pointers (kinda), see std/rc.rs for more info
- let x = box ArcInner {
+ let x: Box<_> = box ArcInner {
strong: atomic::AtomicUsize::new(1),
weak: atomic::AtomicUsize::new(1),
data: data,
//! }
//! ```
//!
-//! This will print `Cons(1i32, Box(Cons(2i32, Box(Nil))))`.
+//! This will print `Cons(1, Box(Cons(2, Box(Nil))))`.
#![stable(feature = "rust1", since = "1.0.0")]
/// let x = Box::new(5);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[inline(always)]
pub fn new(x: T) -> Box<T> {
box x
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Default for Box<[T]> {
#[stable(feature = "rust1", since = "1.0.0")]
- fn default() -> Box<[T]> { box [] }
+ fn default() -> Box<[T]> { Box::<[T; 0]>::new([]) }
}
#[stable(feature = "rust1", since = "1.0.0")]
#[test]
fn deref() {
fn homura<T: Deref<Target=i32>>(_: T) { }
- homura(Box::new(765i32));
+ homura(Box::new(765));
}
#[test]
fn raw_sized() {
unsafe {
- let x = Box::new(17i32);
+ let x = Box::new(17);
let p = boxed::into_raw(x);
assert_eq!(17, *p);
*p = 19;
extern crate test;
use self::test::Bencher;
use core::ptr::PtrExt;
+ use boxed::Box;
use heap;
#[test]
#[bench]
fn alloc_owned_small(b: &mut Bencher) {
b.iter(|| {
- box 10
+ let _: Box<_> = box 10;
})
}
}
// Primitive types using the heaps above
+// Need to conditionally define the mod from `boxed.rs` to avoid
+// duplicating the lang-items when building in test cfg; but also need
+// to allow code to have `use boxed::HEAP;`
+// and `use boxed::Box;` declarations.
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
+mod boxed { pub use std::boxed::{Box, HEAP}; }
+#[cfg(test)]
mod boxed_test;
pub mod arc;
pub mod rc;
#[cfg(test)]
mod tests {
use super::{Rc, Weak, weak_count, strong_count};
+ use std::boxed::Box;
use std::cell::RefCell;
use std::option::Option;
use std::option::Option::{Some, None};
#[test]
fn test_destructor() {
- let x = Rc::new(box 5);
+ let x: Rc<Box<_>> = Rc::new(box 5);
assert_eq!(**x, 5);
}
#[bench]
pub fn bench_copy_nonarena(b: &mut Bencher) {
b.iter(|| {
- box Point {
+ let _: Box<_> = box Point {
x: 1,
y: 2,
z: 3,
- }
+ };
})
}
#[bench]
pub fn bench_noncopy_nonarena(b: &mut Bencher) {
b.iter(|| {
- box Noncopy {
+ let _: Box<_> = box Noncopy {
string: "hello world".to_string(),
array: vec!( 1, 2, 3, 4, 5 ),
- }
+ };
})
}
#[test]
fn test_push_unique() {
- let mut heap = BinaryHeap::from_vec(vec![box 2, box 4, box 9]);
+ let mut heap = BinaryHeap::<Box<_>>::from_vec(vec![box 2, box 4, box 9]);
assert_eq!(heap.len(), 3);
assert!(*heap.peek().unwrap() == box 9);
heap.push(box 11);
// have to uselessly pretend to pad the longer one for type matching
if a_len < b_len {
- (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(b_len).skip(a_len)),
- b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0)))
+ (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(b_len).skip(a_len)),
+ b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0)))
} else {
- (a.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(0).skip(0)),
- b.blocks().enumerate().chain(iter::repeat(0u32).enumerate().take(a_len).skip(b_len)))
+ (a.blocks().enumerate().chain(iter::repeat(0).enumerate().take(0).skip(0)),
+ b.blocks().enumerate().chain(iter::repeat(0).enumerate().take(a_len).skip(b_len)))
}
}
//
// Note that we can technically avoid this branch with the expression
// `(nbits + u32::BITS - 1) / 32::BITS`, but if nbits is almost usize::MAX this will overflow.
- if bits % u32::BITS == 0 {
- bits / u32::BITS
+ if bits % u32::BITS as usize == 0 {
+ bits / u32::BITS as usize
} else {
- bits / u32::BITS + 1
+ bits / u32::BITS as usize + 1
}
}
/// Computes the bitmask for the final word of the vector
fn mask_for_bits(bits: usize) -> u32 {
// Note especially that a perfect multiple of u32::BITS should mask all 1s.
- !0u32 >> (u32::BITS - bits % u32::BITS) % u32::BITS
+ !0 >> (u32::BITS as usize - bits % u32::BITS as usize) % u32::BITS as usize
}
impl BitVec {
/// An operation might screw up the unused bits in the last block of the
/// `BitVec`. As per (3), it's assumed to be all 0s. This method fixes it up.
fn fix_last_block(&mut self) {
- let extra_bits = self.len() % u32::BITS;
+ let extra_bits = self.len() % u32::BITS as usize;
if extra_bits > 0 {
let mask = (1 << extra_bits) - 1;
let storage_len = self.storage.len();
pub fn from_elem(nbits: usize, bit: bool) -> BitVec {
let nblocks = blocks_for_bits(nbits);
let mut bit_vec = BitVec {
- storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(),
+ storage: repeat(if bit { !0 } else { 0 }).take(nblocks).collect(),
nbits: nbits
};
bit_vec.fix_last_block();
/// false, false, true, false]));
/// ```
pub fn from_bytes(bytes: &[u8]) -> BitVec {
- let len = bytes.len().checked_mul(u8::BITS).expect("capacity overflow");
+ let len = bytes.len().checked_mul(u8::BITS as usize).expect("capacity overflow");
let mut bit_vec = BitVec::with_capacity(len);
let complete_words = bytes.len() / 4;
let extra_bytes = bytes.len() % 4;
}
if extra_bytes > 0 {
- let mut last_word = 0u32;
+ let mut last_word = 0;
for (i, &byte) in bytes[complete_words*4..].iter().enumerate() {
last_word |= (reverse_bits(byte) as u32) << (i * 8);
}
if i >= self.nbits {
return None;
}
- let w = i / u32::BITS;
- let b = i % u32::BITS;
+ let w = i / u32::BITS as usize;
+ let b = i % u32::BITS as usize;
self.storage.get(w).map(|&block|
(block & (1 << b)) != 0
)
reason = "panic semantics are likely to change in the future")]
pub fn set(&mut self, i: usize, x: bool) {
assert!(i < self.nbits);
- let w = i / u32::BITS;
- let b = i % u32::BITS;
+ let w = i / u32::BITS as usize;
+ let b = i % u32::BITS as usize;
let flag = 1 << b;
let val = if x { self.storage[w] | flag }
else { self.storage[w] & !flag };
/// ```
#[inline]
pub fn set_all(&mut self) {
- for w in &mut self.storage { *w = !0u32; }
+ for w in &mut self.storage { *w = !0; }
self.fix_last_block();
}
/// assert_eq!(bv.all(), false);
/// ```
pub fn all(&self) -> bool {
- let mut last_word = !0u32;
+ let mut last_word = !0;
// Check that every block but the last is all-ones...
self.blocks().all(|elem| {
let tmp = last_word;
last_word = elem;
- tmp == !0u32
+ tmp == !0
// and then check the last one has enough ones
}) && (last_word == mask_for_bits(self.nbits))
}
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn capacity(&self) -> usize {
- self.storage.capacity().checked_mul(u32::BITS).unwrap_or(usize::MAX)
+ self.storage.capacity().checked_mul(u32::BITS as usize).unwrap_or(usize::MAX)
}
/// Grows the `BitVec` in-place, adding `n` copies of `value` to the `BitVec`.
let full_value = if value { !0 } else { 0 };
// Correct the old tail word, setting or clearing formerly unused bits
- let old_last_word = blocks_for_bits(self.nbits) - 1;
- if self.nbits % u32::BITS > 0 {
+ let num_cur_blocks = blocks_for_bits(self.nbits);
+ if self.nbits % u32::BITS as usize > 0 {
let mask = mask_for_bits(self.nbits);
if value {
- self.storage[old_last_word] |= !mask;
+ self.storage[num_cur_blocks - 1] |= !mask;
} else {
// Extra bits are already zero by invariant.
}
// Fill in words after the old tail word
let stop_idx = cmp::min(self.storage.len(), new_nblocks);
- for idx in old_last_word + 1..stop_idx {
+ for idx in num_cur_blocks..stop_idx {
self.storage[idx] = full_value;
}
// (3)
self.set(i, false);
self.nbits = i;
- if self.nbits % u32::BITS == 0 {
+ if self.nbits % u32::BITS as usize == 0 {
// (2)
self.storage.pop();
}
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn push(&mut self, elem: bool) {
- if self.nbits % u32::BITS == 0 {
+ if self.nbits % u32::BITS as usize == 0 {
self.storage.push(0);
}
let insert_pos = self.nbits;
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn clear(&mut self) {
- for w in &mut self.storage { *w = 0u32; }
+ for w in &mut self.storage { *w = 0; }
}
}
// Truncate
let trunc_len = cmp::max(old_len - n, 1);
bit_vec.storage.truncate(trunc_len);
- bit_vec.nbits = trunc_len * u32::BITS;
+ bit_vec.nbits = trunc_len * u32::BITS as usize;
}
/// Iterator over each u32 stored in the `BitSet`.
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize {
- self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones())
+ self.bit_vec.blocks().fold(0, |acc, n| acc + n.count_ones() as usize)
}
/// Returns whether there are no bits set in this set
fn next(&mut self) -> Option<usize> {
while self.next_idx < self.set.bit_vec.len() ||
self.next_idx < self.other.bit_vec.len() {
- let bit_idx = self.next_idx % u32::BITS;
+ let bit_idx = self.next_idx % u32::BITS as usize;
if bit_idx == 0 {
let s_bit_vec = &self.set.bit_vec;
let o_bit_vec = &self.other.bit_vec;
// Merging the two words is a bit of an awkward dance since
// one BitVec might be longer than the other
- let word_idx = self.next_idx / u32::BITS;
+ let word_idx = self.next_idx / u32::BITS as usize;
let w1 = if word_idx < s_bit_vec.storage.len() {
s_bit_vec.storage[word_idx]
} else { 0 };
assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), bools);
- let long: Vec<_> = (0i32..10000).map(|i| i % 2 == 0).collect();
+ let long: Vec<_> = (0..10000).map(|i| i % 2 == 0).collect();
let bit_vec: BitVec = long.iter().map(|n| *n).collect();
assert_eq!(bit_vec.iter().collect::<Vec<bool>>(), long)
}
#[test]
fn test_bit_vec_push_pop() {
- let mut s = BitVec::from_elem(5 * u32::BITS - 2, false);
- assert_eq!(s.len(), 5 * u32::BITS - 2);
- assert_eq!(s[5 * u32::BITS - 3], false);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize - 2, false);
+ assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
+ assert_eq!(s[5 * u32::BITS as usize - 3], false);
s.push(true);
s.push(true);
- assert_eq!(s[5 * u32::BITS - 2], true);
- assert_eq!(s[5 * u32::BITS - 1], true);
+ assert_eq!(s[5 * u32::BITS as usize - 2], true);
+ assert_eq!(s[5 * u32::BITS as usize - 1], true);
// Here the internal vector will need to be extended
s.push(false);
- assert_eq!(s[5 * u32::BITS], false);
+ assert_eq!(s[5 * u32::BITS as usize], false);
s.push(false);
- assert_eq!(s[5 * u32::BITS + 1], false);
- assert_eq!(s.len(), 5 * u32::BITS + 2);
+ assert_eq!(s[5 * u32::BITS as usize + 1], false);
+ assert_eq!(s.len(), 5 * u32::BITS as usize + 2);
// Pop it all off
assert_eq!(s.pop(), Some(false));
assert_eq!(s.pop(), Some(false));
assert_eq!(s.pop(), Some(true));
assert_eq!(s.pop(), Some(true));
- assert_eq!(s.len(), 5 * u32::BITS - 2);
+ assert_eq!(s.len(), 5 * u32::BITS as usize - 2);
}
#[test]
fn test_bit_vec_truncate() {
- let mut s = BitVec::from_elem(5 * u32::BITS, true);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
- assert_eq!(s, BitVec::from_elem(5 * u32::BITS, true));
- assert_eq!(s.len(), 5 * u32::BITS);
- s.truncate(4 * u32::BITS);
- assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
+ assert_eq!(s, BitVec::from_elem(5 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 5 * u32::BITS as usize);
+ s.truncate(4 * u32::BITS as usize);
+ assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 4 * u32::BITS as usize);
// Truncating to a size > s.len() should be a noop
- s.truncate(5 * u32::BITS);
- assert_eq!(s, BitVec::from_elem(4 * u32::BITS, true));
- assert_eq!(s.len(), 4 * u32::BITS);
- s.truncate(3 * u32::BITS - 10);
- assert_eq!(s, BitVec::from_elem(3 * u32::BITS - 10, true));
- assert_eq!(s.len(), 3 * u32::BITS - 10);
+ s.truncate(5 * u32::BITS as usize);
+ assert_eq!(s, BitVec::from_elem(4 * u32::BITS as usize, true));
+ assert_eq!(s.len(), 4 * u32::BITS as usize);
+ s.truncate(3 * u32::BITS as usize - 10);
+ assert_eq!(s, BitVec::from_elem(3 * u32::BITS as usize - 10, true));
+ assert_eq!(s.len(), 3 * u32::BITS as usize - 10);
s.truncate(0);
assert_eq!(s, BitVec::from_elem(0, true));
assert_eq!(s.len(), 0);
#[test]
fn test_bit_vec_reserve() {
- let mut s = BitVec::from_elem(5 * u32::BITS, true);
+ let mut s = BitVec::from_elem(5 * u32::BITS as usize, true);
// Check capacity
- assert!(s.capacity() >= 5 * u32::BITS);
- s.reserve(2 * u32::BITS);
- assert!(s.capacity() >= 7 * u32::BITS);
- s.reserve(7 * u32::BITS);
- assert!(s.capacity() >= 12 * u32::BITS);
- s.reserve_exact(7 * u32::BITS);
- assert!(s.capacity() >= 12 * u32::BITS);
- s.reserve(7 * u32::BITS + 1);
- assert!(s.capacity() >= 12 * u32::BITS + 1);
+ assert!(s.capacity() >= 5 * u32::BITS as usize);
+ s.reserve(2 * u32::BITS as usize);
+ assert!(s.capacity() >= 7 * u32::BITS as usize);
+ s.reserve(7 * u32::BITS as usize);
+ assert!(s.capacity() >= 12 * u32::BITS as usize);
+ s.reserve_exact(7 * u32::BITS as usize);
+ assert!(s.capacity() >= 12 * u32::BITS as usize);
+ s.reserve(7 * u32::BITS as usize + 1);
+ assert!(s.capacity() >= 12 * u32::BITS as usize + 1);
// Check that length hasn't changed
- assert_eq!(s.len(), 5 * u32::BITS);
+ assert_eq!(s.len(), 5 * u32::BITS as usize);
s.push(true);
s.push(false);
s.push(true);
- assert_eq!(s[5 * u32::BITS - 1], true);
- assert_eq!(s[5 * u32::BITS - 0], true);
- assert_eq!(s[5 * u32::BITS + 1], false);
- assert_eq!(s[5 * u32::BITS + 2], true);
+ assert_eq!(s[5 * u32::BITS as usize - 1], true);
+ assert_eq!(s[5 * u32::BITS as usize - 0], true);
+ assert_eq!(s[5 * u32::BITS as usize + 1], false);
+ assert_eq!(s[5 * u32::BITS as usize + 2], true);
}
#[test]
use super::BitVec;
- static BENCH_BITS : usize = 1 << 14;
+ const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let mut bit_vec = 0 as usize;
b.iter(|| {
for _ in 0..100 {
- bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS);
+ bit_vec |= 1 << ((r.next_u32() as usize) % u32::BITS as usize);
}
black_box(&bit_vec);
});
#[bench]
fn bench_bit_set_small(b: &mut Bencher) {
let mut r = rng();
- let mut bit_vec = BitVec::from_elem(u32::BITS, false);
+ let mut bit_vec = BitVec::from_elem(u32::BITS as usize, false);
b.iter(|| {
for _ in 0..100 {
- bit_vec.set((r.next_u32() as usize) % u32::BITS, true);
+ bit_vec.set((r.next_u32() as usize) % u32::BITS as usize, true);
}
black_box(&bit_vec);
});
#[bench]
fn bench_bit_vec_small_iter(b: &mut Bencher) {
- let bit_vec = BitVec::from_elem(u32::BITS, false);
+ let bit_vec = BitVec::from_elem(u32::BITS as usize, false);
b.iter(|| {
let mut sum = 0;
for _ in 0..10 {
use super::{BitVec, BitSet};
- static BENCH_BITS : usize = 1 << 14;
+ const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
let mut bit_vec = BitSet::new();
b.iter(|| {
for _ in 0..100 {
- bit_vec.insert((r.next_u32() as usize) % u32::BITS);
+ bit_vec.insert((r.next_u32() as usize) % u32::BITS as usize);
}
black_box(&bit_vec);
});
use core::hash::{Hash, Hasher};
use core::iter::{Map, FromIterator, IntoIterator};
use core::ops::{Index, IndexMut};
-use core::{iter, fmt, mem};
+use core::{iter, fmt, mem, usize};
use Bound::{self, Included, Excluded, Unbounded};
use borrow::Borrow;
$Range {
inner: AbsIter {
traversals: traversals,
- size: 0, // unused
+ size: usize::MAX, // unused
}
}
}
ptr::copy(
self.edges_mut().as_mut_ptr().offset(index as isize),
self.edges().as_ptr().offset(index as isize + 1),
- self.len() - index + 1
+ // index can be == len+1, so do the +1 first to avoid underflow.
+ (self.len() + 1) - index
);
edge
fn bit<E:CLike>(e: &E) -> usize {
use core::usize;
let value = e.to_usize();
- assert!(value < usize::BITS,
+ assert!(value < usize::BITS as usize,
"EnumSet only supports up to {} variants.", usize::BITS - 1);
1 << value
}
#[unstable(feature = "collections",
reason = "matches collection reform specification, waiting for dust to settle")]
pub fn len(&self) -> usize {
- self.bits.count_ones()
+ self.bits.count_ones() as usize
}
/// Returns true if the `EnumSet` is empty.
}
fn size_hint(&self) -> (usize, Option<usize>) {
- let exact = self.bits.count_ones();
+ let exact = self.bits.count_ones() as usize;
(exact, Some(exact))
}
}
//! Some examples of the output from both traits:
//!
//! ```
-//! assert_eq!(format!("{} {:?}", 3i32, 4i32), "3 4");
+//! assert_eq!(format!("{} {:?}", 3, 4), "3 4");
//! assert_eq!(format!("{} {:?}", 'a', 'b'), "a 'b'");
//! assert_eq!(format!("{} {:?}", "foo\n", "bar\n"), "foo\n \"bar\\n\"");
//! ```
#[test]
fn test_basic() {
- let mut m = LinkedList::new();
+ let mut m = LinkedList::<Box<_>>::new();
assert_eq!(m.pop_front(), None);
assert_eq!(m.pop_back(), None);
assert_eq!(m.pop_front(), None);
use core::marker::Sized;
use core::mem::size_of;
use core::mem;
+use core::num::wrapping::WrappingOps;
use core::ops::FnMut;
use core::option::Option::{self, Some, None};
use core::ptr::PtrExt;
impl Iterator for ElementSwaps {
type Item = (usize, usize);
- #[inline]
+ // #[inline]
fn next(&mut self) -> Option<(usize, usize)> {
+ fn new_pos_wrapping(i: usize, s: Direction) -> usize {
+ i.wrapping_add(match s { Pos => 1, Neg => -1 })
+ }
+
fn new_pos(i: usize, s: Direction) -> usize {
- i + match s { Pos => 1, Neg => -1 }
+ match s { Pos => i + 1, Neg => i - 1 }
}
// Find the index of the largest mobile element:
// swap should be with a smaller `size` element.
let max = self.sdir.iter().cloned().enumerate()
.filter(|&(i, sd)|
- new_pos(i, sd.dir) < self.sdir.len() &&
+ new_pos_wrapping(i, sd.dir) < self.sdir.len() &&
self.sdir[new_pos(i, sd.dir)].size < sd.size)
.max_by(|&(_, sd)| sd.size);
match max {
fn merge_sort<T, F>(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering {
// warning: this wildly uses unsafe.
- static BASE_INSERTION: usize = 32;
- static LARGE_INSERTION: usize = 16;
+ const BASE_INSERTION: usize = 32;
+ const LARGE_INSERTION: usize = 16;
// FIXME #12092: smaller insertion runs seems to make sorting
// vectors of large elements a little faster on some platforms,
#[cfg(test)]
mod tests {
+ use alloc::boxed::Box;
use core::cmp::Ordering::{Greater, Less, Equal};
use core::prelude::{Some, None, Clone};
use core::prelude::{Iterator, IteratorExt};
#[test]
fn test_swap_remove_noncopyable() {
// Tests that we don't accidentally run destructors twice.
- let mut v = Vec::new();
+ let mut v: Vec<Box<_>> = Vec::new();
v.push(box 0u8);
v.push(box 0u8);
v.push(box 0u8);
#[test]
fn test_truncate() {
- let mut v = vec![box 6,box 5,box 4];
+ let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
v.truncate(1);
let v = v;
assert_eq!(v.len(), 1);
#[test]
fn test_clear() {
- let mut v = vec![box 6,box 5,box 4];
+ let mut v: Vec<Box<_>> = vec![box 6,box 5,box 4];
v.clear();
assert_eq!(v.len(), 0);
// If the unsafe block didn't drop things properly, we blow up here.
#[test]
fn test_dedup_unique() {
- let mut v0 = vec![box 1, box 1, box 2, box 3];
+ let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
v0.dedup();
- let mut v1 = vec![box 1, box 2, box 2, box 3];
+ let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
v1.dedup();
- let mut v2 = vec![box 1, box 2, box 3, box 3];
+ let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
v2.dedup();
/*
* If the boxed pointers were leaked or otherwise misused, valgrind
#[test]
fn test_dedup_shared() {
- let mut v0 = vec![box 1, box 1, box 2, box 3];
+ let mut v0: Vec<Box<_>> = vec![box 1, box 1, box 2, box 3];
v0.dedup();
- let mut v1 = vec![box 1, box 2, box 2, box 3];
+ let mut v1: Vec<Box<_>> = vec![box 1, box 2, box 2, box 3];
v1.dedup();
- let mut v2 = vec![box 1, box 2, box 3, box 3];
+ let mut v2: Vec<Box<_>> = vec![box 1, box 2, box 3, box 3];
v2.dedup();
/*
* If the pointers were leaked or otherwise misused, valgrind and/or
fn test_connect() {
let v: [Vec<i32>; 0] = [];
assert_eq!(v.connect(&0), []);
- assert_eq!([vec![1i], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
- assert_eq!([vec![1i], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
+ assert_eq!([vec![1], vec![2, 3]].connect(&0), [1, 0, 2, 3]);
+ assert_eq!([vec![1], vec![2], vec![3]].connect(&0), [1, 0, 2, 0, 3]);
let v: [&[_]; 2] = [&[1], &[2, 3]];
assert_eq!(v.connect(&0), [1, 0, 2, 3]);
#[test]
#[should_fail]
fn test_permute_fail() {
- let v = [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
- (box 0, Rc::new(0)), (box 0, Rc::new(0))];
+ let v: [(Box<_>, Rc<_>); 4] =
+ [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
+ (box 0, Rc::new(0)), (box 0, Rc::new(0))];
let mut i = 0;
for _ in v.permutations() {
if i == 2 {
#[test]
fn test_bytes_set_memory() {
use slice::bytes::MutableByteVector;
- let mut values = [1u8,2,3,4,5];
+ let mut values = [1,2,3,4,5];
values[0..5].set_memory(0xAB);
assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
values[2..4].set_memory(0xFF);
fn test_mut_chunks() {
use core::iter::ExactSizeIterator;
- let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+ let mut v = [0, 1, 2, 3, 4, 5, 6];
assert_eq!(v.chunks_mut(2).len(), 4);
for (i, chunk) in v.chunks_mut(3).enumerate() {
for x in chunk {
*x = i as u8;
}
}
- let result = [0u8, 0, 0, 1, 1, 1, 2];
+ let result = [0, 0, 0, 1, 1, 1, 2];
assert!(v == result);
}
#[test]
fn test_mut_chunks_rev() {
- let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+ let mut v = [0, 1, 2, 3, 4, 5, 6];
for (i, chunk) in v.chunks_mut(3).rev().enumerate() {
for x in chunk {
*x = i as u8;
}
}
- let result = [2u8, 2, 2, 1, 1, 1, 0];
+ let result = [2, 2, 2, 1, 1, 1, 0];
assert!(v == result);
}
#[test]
fn test_to_vec() {
- let xs = box [1, 2, 3];
+ let xs: Box<_> = box [1, 2, 3];
let ys = xs.to_vec();
assert_eq!(ys, [1, 2, 3]);
}
//
// ignore-lexer-test FIXME #15679
-//! Unicode string manipulation (the `str` type).
+//! Unicode string manipulation (the [`str`](../primitive.str.html) type).
//!
-//! Rust's `str` type is one of the core primitive types of the language. `&str` is the borrowed
-//! string type. This type of string can only be created from other strings, unless it is a static
-//! string (see below). As the word "borrowed" implies, this type of string is owned elsewhere, and
-//! this string cannot be moved out of.
+//! Rust's [`str`](../primitive.str.html) type is one of the core primitive types of the
+//! language. `&str` is the borrowed string type. This type of string can only be created
+//! from other strings, unless it is a `&'static str` (see below). It is not possible to
+//! move out of borrowed strings because they are owned elsewhere.
+//!
+//! Basic operations are implemented directly by the compiler, but more advanced operations are
+//! defined on the [`StrExt`](trait.StrExt.html) trait.
//!
//! # Examples
//!
// return the value of $ch updated with continuation byte $byte
macro_rules! utf8_acc_cont_byte {
- ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
+ ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63) as u32)
}
#[stable(feature = "rust1", since = "1.0.0")]
/// ```
#[unstable(feature = "collections")]
#[deprecated(since = "1.0.0", reason = "use `split()` with a `&str`")]
+ #[allow(deprecated) /* for SplitStr */]
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P> {
core_str::StrExt::split_str(&self[..], pat)
}
#[test]
fn test_chars_decoding() {
- let mut bytes = [0u8; 4];
- for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
+ let mut bytes = [0; 4];
+ for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
let len = c.encode_utf8(&mut bytes).unwrap_or(0);
let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
if Some(c) != s.chars().next() {
#[test]
fn test_chars_rev_decoding() {
- let mut bytes = [0u8; 4];
- for c in (0u32..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
+ let mut bytes = [0; 4];
+ for c in (0..0x110000).filter_map(|c| ::core::char::from_u32(c)) {
let len = c.encode_utf8(&mut bytes).unwrap_or(0);
let s = ::core::str::from_utf8(&bytes[..len]).unwrap();
if Some(c) != s.chars().rev().next() {
}
}
- static TAG_CONT_U8: u8 = 128u8;
- static REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
+ const TAG_CONT_U8: u8 = 128;
+ const REPLACEMENT: &'static [u8] = b"\xEF\xBF\xBD"; // U+FFFD in UTF-8
let total = v.len();
fn unsafe_get(xs: &[u8], i: usize) -> u8 {
unsafe { *xs.get_unchecked(i) }
}
})}
- if byte < 128u8 {
+ if byte < 128 {
// subseqidx handles this
} else {
let w = unicode_str::utf8_char_width(byte);
match w {
2 => {
- if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+ if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
error!();
continue;
}
}
}
i += 1;
- if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+ if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
error!();
continue;
}
}
}
i += 1;
- if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+ if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
error!();
continue;
}
i += 1;
- if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+ if safe_get(v, i, total) & 192 != TAG_CONT_U8 {
error!();
continue;
}
fn test_from_utf16() {
let pairs =
[(String::from_str("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n"),
- vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
- 0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
- 0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
- 0xd800_u16, 0xdf30_u16, 0x000a_u16]),
+ vec![0xd800, 0xdf45, 0xd800, 0xdf3f,
+ 0xd800, 0xdf3b, 0xd800, 0xdf46,
+ 0xd800, 0xdf39, 0xd800, 0xdf3b,
+ 0xd800, 0xdf30, 0x000a]),
(String::from_str("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n"),
- vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
- 0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
- 0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
- 0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
- 0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
- 0x000a_u16]),
+ vec![0xd801, 0xdc12, 0xd801,
+ 0xdc49, 0xd801, 0xdc2e, 0xd801,
+ 0xdc40, 0xd801, 0xdc32, 0xd801,
+ 0xdc4b, 0x0020, 0xd801, 0xdc0f,
+ 0xd801, 0xdc32, 0xd801, 0xdc4d,
+ 0x000a]),
(String::from_str("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n"),
- vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
- 0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
- 0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
- 0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
- 0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
- 0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
- 0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
+ vec![0xd800, 0xdf00, 0xd800, 0xdf16,
+ 0xd800, 0xdf0b, 0xd800, 0xdf04,
+ 0xd800, 0xdf11, 0xd800, 0xdf09,
+ 0x00b7, 0xd800, 0xdf0c, 0xd800,
+ 0xdf04, 0xd800, 0xdf15, 0xd800,
+ 0xdf04, 0xd800, 0xdf0b, 0xd800,
+ 0xdf09, 0xd800, 0xdf11, 0x000a ]),
(String::from_str("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n"),
- vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
- 0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
- 0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
- 0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
- 0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
- 0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
- 0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
- 0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
- 0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
- 0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
- 0x000a_u16 ]),
+ vec![0xd801, 0xdc8b, 0xd801, 0xdc98,
+ 0xd801, 0xdc88, 0xd801, 0xdc91,
+ 0xd801, 0xdc9b, 0xd801, 0xdc92,
+ 0x0020, 0xd801, 0xdc95, 0xd801,
+ 0xdc93, 0x0020, 0xd801, 0xdc88,
+ 0xd801, 0xdc9a, 0xd801, 0xdc8d,
+ 0x0020, 0xd801, 0xdc8f, 0xd801,
+ 0xdc9c, 0xd801, 0xdc92, 0xd801,
+ 0xdc96, 0xd801, 0xdc86, 0x0020,
+ 0xd801, 0xdc95, 0xd801, 0xdc86,
+ 0x000a ]),
// Issue #12318, even-numbered non-BMP planes
(String::from_str("\u{20000}"),
vec![0xD840, 0xDC00])];
assert_eq!(1.to_string(), "1");
assert_eq!((-1).to_string(), "-1");
assert_eq!(200.to_string(), "200");
- assert_eq!(2u8.to_string(), "2");
+ assert_eq!(2.to_string(), "2");
assert_eq!(true.to_string(), "true");
assert_eq!(false.to_string(), "false");
assert_eq!(("hi".to_string()).to_string(), "hi");
#[bench]
fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
- let s = repeat(0xf5u8).take(100).collect::<Vec<_>>();
+ let s = repeat(0xf5).take(100).collect::<Vec<_>>();
b.iter(|| {
let _ = String::from_utf8_lossy(&s);
});
__impl_slice_eq1! { Vec<A>, Vec<B> }
__impl_slice_eq2! { Vec<A>, &'b [B] }
__impl_slice_eq2! { Vec<A>, &'b mut [B] }
-__impl_slice_eq2! { CowVec<'a, A>, &'b [B], Clone }
-__impl_slice_eq2! { CowVec<'a, A>, &'b mut [B], Clone }
-__impl_slice_eq2! { CowVec<'a, A>, Vec<B>, Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, &'b [B], Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B], Clone }
+__impl_slice_eq2! { Cow<'a, [A]>, Vec<B>, Clone }
macro_rules! array_impls {
($($N: expr)+) => {
__impl_slice_eq2! { Vec<A>, [B; $N] }
__impl_slice_eq2! { Vec<A>, &'b [B; $N] }
// __impl_slice_eq2! { Vec<A>, &'b mut [B; $N] }
- // __impl_slice_eq2! { CowVec<'a, A>, [B; $N], Clone }
- // __impl_slice_eq2! { CowVec<'a, A>, &'b [B; $N], Clone }
- // __impl_slice_eq2! { CowVec<'a, A>, &'b mut [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, &'b [B; $N], Clone }
+ // __impl_slice_eq2! { Cow<'a, [A]>, &'b mut [B; $N], Clone }
)+
}
}
#[test]
fn test_clone_from() {
let mut v = vec!();
- let three = vec!(box 1, box 2, box 3);
- let two = vec!(box 4, box 5);
+ let three: Vec<Box<_>> = vec!(box 1, box 2, box 3);
+ let two: Vec<Box<_>> = vec!(box 4, box 5);
// zero, long
v.clone_from(&three);
assert_eq!(v, three);
use core::iter::{self, repeat, FromIterator, IntoIterator, RandomAccessIterator};
use core::mem;
use core::num::{Int, UnsignedInt};
+use core::num::wrapping::WrappingOps;
use core::ops::{Index, IndexMut};
use core::ptr::{self, Unique};
use core::raw::Slice as RawSlice;
#[unstable(feature = "collections")]
pub use VecDeque as RingBuf;
-static INITIAL_CAPACITY: usize = 7; // 2^3 - 1
-static MINIMUM_CAPACITY: usize = 1; // 2 - 1
+const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
+const MINIMUM_CAPACITY: usize = 1; // 2 - 1
/// `VecDeque` is a growable ring buffer, which can be used as a
/// double-ended queue efficiently.
#[inline]
fn wrap_index(&self, idx: usize) -> usize { wrap_index(idx, self.cap) }
+ /// Returns the index in the underlying buffer for a given logical element
+ /// index + addend.
+ #[inline]
+ fn wrap_add(&self, idx: usize, addend: usize) -> usize {
+ wrap_index(idx.wrapping_add(addend), self.cap)
+ }
+
+ /// Returns the index in the underlying buffer for a given logical element
+ /// index - subtrahend.
+ #[inline]
+ fn wrap_sub(&self, idx: usize, subtrahend: usize) -> usize {
+ wrap_index(idx.wrapping_sub(subtrahend), self.cap)
+ }
+
/// Copies a contiguous block of memory len long from src to dst
#[inline]
unsafe fn copy(&self, dst: usize, src: usize, len: usize) {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get(&self, i: usize) -> Option<&T> {
if i < self.len() {
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
unsafe { Some(&*self.ptr.offset(idx as isize)) }
} else {
None
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self, i: usize) -> Option<&mut T> {
if i < self.len() {
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
unsafe { Some(&mut *self.ptr.offset(idx as isize)) }
} else {
None
pub fn swap(&mut self, i: usize, j: usize) {
assert!(i < self.len());
assert!(j < self.len());
- let ri = self.wrap_index(self.tail + i);
- let rj = self.wrap_index(self.tail + j);
+ let ri = self.wrap_add(self.tail, i);
+ let rj = self.wrap_add(self.tail, j);
unsafe {
ptr::swap(self.ptr.offset(ri as isize), self.ptr.offset(rj as isize))
}
// [. . . o o o o o o o . . . . . . ]
// H T
// [o o . o o o o o ]
- let len = self.wrap_index(self.head - target_cap);
+ let len = self.wrap_sub(self.head, target_cap);
unsafe {
self.copy_nonoverlapping(0, target_cap, len);
}
// [o o o o o . . . . . . . . . o o ]
// H T
// [o o o o o . o o ]
- debug_assert!(self.wrap_index(self.head - 1) < target_cap);
+ debug_assert!(self.wrap_sub(self.head, 1) < target_cap);
let len = self.cap - self.tail;
let new_tail = target_cap - len;
unsafe {
None
} else {
let tail = self.tail;
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
unsafe { Some(self.buffer_read(tail)) }
}
}
debug_assert!(!self.is_full());
}
- self.tail = self.wrap_index(self.tail - 1);
+ self.tail = self.wrap_sub(self.tail, 1);
let tail = self.tail;
unsafe { self.buffer_write(tail, t); }
}
}
let head = self.head;
- self.head = self.wrap_index(self.head + 1);
+ self.head = self.wrap_add(self.head, 1);
unsafe { self.buffer_write(head, t) }
}
if self.is_empty() {
None
} else {
- self.head = self.wrap_index(self.head - 1);
+ self.head = self.wrap_sub(self.head, 1);
let head = self.head;
unsafe { Some(self.buffer_read(head)) }
}
// A - The element that should be after the insertion point
// M - Indicates element was moved
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
let distance_to_tail = i;
let distance_to_head = self.len() - i;
// [A o o o o o o o . . . . . I]
//
- self.tail = self.wrap_index(self.tail - 1);
+ self.tail = self.wrap_sub(self.tail, 1);
},
(true, true, _) => unsafe {
// contiguous, insert closer to tail:
// [o I A o o o o o . . . . . . . o]
// M M
- let new_tail = self.wrap_index(self.tail - 1);
+ let new_tail = self.wrap_sub(self.tail, 1);
self.copy(new_tail, self.tail, 1);
// Already moved the tail, so we only copy `i - 1` elements.
// M M M
self.copy(idx + 1, idx, self.head - idx);
- self.head = self.wrap_index(self.head + 1);
+ self.head = self.wrap_add(self.head, 1);
},
(false, true, true) => unsafe {
// discontiguous, insert closer to tail, tail section:
}
// tail might've been changed so we need to recalculate
- let new_idx = self.wrap_index(self.tail + i);
+ let new_idx = self.wrap_add(self.tail, i);
unsafe {
self.buffer_write(new_idx, t);
}
// R - Indicates element that is being removed
// M - Indicates element was moved
- let idx = self.wrap_index(self.tail + i);
+ let idx = self.wrap_add(self.tail, i);
let elem = unsafe {
Some(self.buffer_read(idx))
// M M
self.copy(self.tail + 1, self.tail, i);
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
},
(false, false, false) => unsafe {
// discontiguous, remove closer to head, head section:
self.copy(0, 1, self.head - 1);
}
- self.head = self.wrap_index(self.head - 1);
+ self.head = self.wrap_sub(self.head, 1);
},
(false, true, false) => unsafe {
// discontiguous, remove closer to tail, head section:
// move elements from tail to end forward, excluding the last one
self.copy(self.tail + 1, self.tail, self.cap - self.tail - 1);
- self.tail = self.wrap_index(self.tail + 1);
+ self.tail = self.wrap_add(self.tail, 1);
}
}
}
// Cleanup where the ends of the buffers are
- self.head = self.wrap_index(self.head - other_len);
+ self.head = self.wrap_sub(self.head, other_len);
other.head = other.wrap_index(other_len);
other
#[inline]
fn count(tail: usize, head: usize, size: usize) -> usize {
// size is always a power of 2
- (head - tail) & (size - 1)
+ (head.wrapping_sub(tail)) & (size - 1)
}
/// `VecDeque` iterator.
return None;
}
let tail = self.tail;
- self.tail = wrap_index(self.tail + 1, self.ring.len());
+ self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(tail)) }
}
if self.tail == self.head {
return None;
}
- self.head = wrap_index(self.head - 1, self.ring.len());
+ self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
unsafe { Some(self.ring.get_unchecked(self.head)) }
}
}
if j >= self.indexable() {
None
} else {
- let idx = wrap_index(self.tail + j, self.ring.len());
+ let idx = wrap_index(self.tail.wrapping_add(j), self.ring.len());
unsafe { Some(self.ring.get_unchecked(idx)) }
}
}
return None;
}
let tail = self.tail;
- self.tail = wrap_index(self.tail + 1, self.ring.len());
+ self.tail = wrap_index(self.tail.wrapping_add(1), self.ring.len());
unsafe {
let elem = self.ring.get_unchecked_mut(tail);
if self.tail == self.head {
return None;
}
- self.head = wrap_index(self.head - 1, self.ring.len());
+ self.head = wrap_index(self.head.wrapping_sub(1), self.ring.len());
unsafe {
let elem = self.ring.get_unchecked_mut(self.head);
#[test]
fn test_move_iter() {
- let mut m = VecMap::new();
+ let mut m: VecMap<Box<_>> = VecMap::new();
m.insert(1, box 2);
let mut called = false;
for (k, v) in m {
v: UnsafeCell<int>,
}
+#[allow(deprecated)]
unsafe impl Sync for AtomicInt {}
#[unstable(feature = "core")]
v: UnsafeCell<uint>,
}
+#[allow(deprecated)]
unsafe impl Sync for AtomicUint {}
#[unstable(feature = "core")]
use slice::SliceExt;
// UTF-8 ranges and tags for encoding characters
-const TAG_CONT: u8 = 0b1000_0000u8;
-const TAG_TWO_B: u8 = 0b1100_0000u8;
-const TAG_THREE_B: u8 = 0b1110_0000u8;
-const TAG_FOUR_B: u8 = 0b1111_0000u8;
-const MAX_ONE_B: u32 = 0x80u32;
-const MAX_TWO_B: u32 = 0x800u32;
-const MAX_THREE_B: u32 = 0x10000u32;
+const TAG_CONT: u8 = 0b1000_0000;
+const TAG_TWO_B: u8 = 0b1100_0000;
+const TAG_THREE_B: u8 = 0b1110_0000;
+const TAG_FOUR_B: u8 = 0b1111_0000;
+const MAX_ONE_B: u32 = 0x80;
+const MAX_TWO_B: u32 = 0x800;
+const MAX_THREE_B: u32 = 0x10000;
/*
Lu Uppercase_Letter an uppercase letter
#[stable(feature = "rust1", since = "1.0.0")]
fn len_utf16(self) -> usize {
let ch = self as u32;
- if (ch & 0xFFFF_u32) == ch { 1 } else { 2 }
+ if (ch & 0xFFFF) == ch { 1 } else { 2 }
}
#[inline]
dst[0] = code as u8;
Some(1)
} else if code < MAX_TWO_B && dst.len() >= 2 {
- dst[0] = (code >> 6 & 0x1F_u32) as u8 | TAG_TWO_B;
- dst[1] = (code & 0x3F_u32) as u8 | TAG_CONT;
+ dst[0] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
+ dst[1] = (code & 0x3F) as u8 | TAG_CONT;
Some(2)
} else if code < MAX_THREE_B && dst.len() >= 3 {
- dst[0] = (code >> 12 & 0x0F_u32) as u8 | TAG_THREE_B;
- dst[1] = (code >> 6 & 0x3F_u32) as u8 | TAG_CONT;
- dst[2] = (code & 0x3F_u32) as u8 | TAG_CONT;
+ dst[0] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
+ dst[1] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ dst[2] = (code & 0x3F) as u8 | TAG_CONT;
Some(3)
} else if dst.len() >= 4 {
- dst[0] = (code >> 18 & 0x07_u32) as u8 | TAG_FOUR_B;
- dst[1] = (code >> 12 & 0x3F_u32) as u8 | TAG_CONT;
- dst[2] = (code >> 6 & 0x3F_u32) as u8 | TAG_CONT;
- dst[3] = (code & 0x3F_u32) as u8 | TAG_CONT;
+ dst[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
+ dst[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
+ dst[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ dst[3] = (code & 0x3F) as u8 | TAG_CONT;
Some(4)
} else {
None
#[unstable(feature = "core")]
pub fn encode_utf16_raw(mut ch: u32, dst: &mut [u16]) -> Option<usize> {
// Marked #[inline] to allow llvm optimizing it away
- if (ch & 0xFFFF_u32) == ch && dst.len() >= 1 {
+ if (ch & 0xFFFF) == ch && dst.len() >= 1 {
// The BMP falls through (assuming non-surrogate, as it should)
dst[0] = ch as u16;
Some(1)
} else if dst.len() >= 2 {
// Supplementary planes break into surrogates.
- ch -= 0x1_0000_u32;
- dst[0] = 0xD800_u16 | ((ch >> 10) as u16);
- dst[1] = 0xDC00_u16 | ((ch as u16) & 0x3FF_u16);
+ ch -= 0x1_0000;
+ dst[0] = 0xD800 | ((ch >> 10) as u16);
+ dst[1] = 0xDC00 | ((ch as u16) & 0x3FF);
Some(2)
} else {
None
SignNeg
}
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
/// Converts a number to its string representation as a byte vector.
/// This is meant to be a common base implementation for all numeric string
// For an f64 the exponent is in the range of [-1022, 1023] for base 2, so
// we may have up to that many digits. Give ourselves some extra wiggle room
// otherwise as well.
- let mut buf = [0u8; 1536];
+ let mut buf = [0; 1536];
let mut end = 0;
let radix_gen: T = cast(radix as int).unwrap();
let (num, exp) = match exp_format {
- ExpNone => (num, 0i32),
- ExpDec if num == _0 => (num, 0i32),
+ ExpNone => (num, 0),
+ ExpDec if num == _0 => (num, 0),
ExpDec => {
let (exp, exp_base) = match exp_format {
ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
deccum = deccum / radix_gen;
deccum = deccum.trunc();
- let c = char::from_digit(current_digit.to_int().unwrap() as u32, radix);
+ let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
buf[end] = c.unwrap() as u8;
end += 1;
// See note in first loop.
let current_digit = deccum.trunc().abs();
- let c = char::from_digit(current_digit.to_int().unwrap() as u32,
+ let c = char::from_digit(current_digit.to_isize().unwrap() as u32,
radix);
buf[end] = c.unwrap() as u8;
end += 1;
Alignment::Center => (padding / 2, (padding + 1) / 2),
};
- let mut fill = [0u8; 4];
+ let mut fill = [0; 4];
let len = self.fill.encode_utf8(&mut fill).unwrap_or(0);
let fill = unsafe { str::from_utf8_unchecked(&fill[..len]) };
#[stable(feature = "rust1", since = "1.0.0")]
impl Display for char {
fn fmt(&self, f: &mut Formatter) -> Result {
- let mut utf8 = [0u8; 4];
+ let mut utf8 = [0; 4];
let amt = self.encode_utf8(&mut utf8).unwrap_or(0);
let s: &str = unsafe { mem::transmute(&utf8[..amt]) };
Display::fmt(s, f)
// characters for a base 2 number.
let zero = Int::zero();
let is_positive = x >= zero;
- let mut buf = [0u8; 64];
+ let mut buf = [0; 64];
let mut curr = buf.len();
let base = cast(self.base()).unwrap();
if is_positive {
/// A hexadecimal (base 16) radix, formatted with upper-case characters
#[derive(Clone, PartialEq)]
-pub struct UpperHex;
+struct UpperHex;
macro_rules! radix {
($T:ident, $base:expr, $prefix:expr, $($x:pat => $conv:expr),+) => {
}
macro_rules! radix_fmt {
- ($T:ty as $U:ty, $fmt:ident, $S:expr) => {
+ ($T:ty as $U:ty, $fmt:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for RadixFmt<$T, Radix> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
}
-macro_rules! show {
- ($T:ident with $S:expr) => {
+macro_rules! debug {
+ ($T:ident) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Debug for $T {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
}
macro_rules! integer {
($Int:ident, $Uint:ident) => {
- integer! { $Int, $Uint, stringify!($Int), stringify!($Uint) }
- };
- ($Int:ident, $Uint:ident, $SI:expr, $SU:expr) => {
int_base! { Display for $Int as $Int -> Decimal }
int_base! { Binary for $Int as $Uint -> Binary }
int_base! { Octal for $Int as $Uint -> Octal }
int_base! { LowerHex for $Int as $Uint -> LowerHex }
int_base! { UpperHex for $Int as $Uint -> UpperHex }
- radix_fmt! { $Int as $Int, fmt_int, $SI }
- show! { $Int with $SI }
+ radix_fmt! { $Int as $Int, fmt_int }
+ debug! { $Int }
int_base! { Display for $Uint as $Uint -> Decimal }
int_base! { Binary for $Uint as $Uint -> Binary }
int_base! { Octal for $Uint as $Uint -> Octal }
int_base! { LowerHex for $Uint as $Uint -> LowerHex }
int_base! { UpperHex for $Uint as $Uint -> UpperHex }
- radix_fmt! { $Uint as $Uint, fmt_int, $SU }
- show! { $Uint with $SU }
+ radix_fmt! { $Uint as $Uint, fmt_int }
+ debug! { $Uint }
}
}
-integer! { isize, usize, "i", "u" }
+integer! { isize, usize }
integer! { i8, u8 }
integer! { i16, u16 }
integer! { i32, u32 }
}
fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
- let newlen = data.len() * ::$ty::BYTES;
+ let newlen = data.len() * ::$ty::BYTES as usize;
let ptr = data.as_ptr() as *const u8;
state.write(unsafe { slice::from_raw_parts(ptr, newlen) })
}
use prelude::*;
use default::Default;
-
+use num::wrapping::WrappingOps;
use super::Hasher;
/// An implementation of SipHash 2-4.
($buf:expr, $i:expr, $len:expr) =>
({
let mut t = 0;
- let mut out = 0u64;
+ let mut out = 0;
while t < $len {
out |= ($buf[t+$i] as u64) << t*8;
t += 1;
macro_rules! rotl {
($x:expr, $b:expr) =>
- (($x << $b) | ($x >> (64 - $b)))
+ (($x << $b) | ($x >> (64.wrapping_sub($b))))
}
macro_rules! compress {
($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
({
- $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
+ $v0 = $v0.wrapping_add($v1); $v1 = rotl!($v1, 13); $v1 ^= $v0;
$v0 = rotl!($v0, 32);
- $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
- $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
- $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
+ $v2 = $v2.wrapping_add($v3); $v3 = rotl!($v3, 16); $v3 ^= $v2;
+ $v0 = $v0.wrapping_add($v3); $v3 = rotl!($v3, 21); $v3 ^= $v0;
+ $v2 = $v2.wrapping_add($v1); $v1 = rotl!($v1, 17); $v1 ^= $v2;
$v2 = rotl!($v2, 32);
})
}
/// use std::mem;
///
/// let v: &[u8] = unsafe { mem::transmute("L") };
- /// assert!(v == [76u8]);
+ /// assert!(v == [76]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn transmute<T,U>(e: T) -> U;
/// Performs checked `u64` multiplication.
pub fn u64_mul_with_overflow(x: u64, y: u64) -> (u64, bool);
}
+
+// SNAP 880fb89
+#[cfg(not(stage0))]
+extern "rust-intrinsic" {
+ /// Returns (a + b) mod 2^N, where N is the width of N in bits.
+ pub fn overflowing_add<T>(a: T, b: T) -> T;
+ /// Returns (a - b) mod 2^N, where N is the width of N in bits.
+ pub fn overflowing_sub<T>(a: T, b: T) -> T;
+ /// Returns (a * b) mod 2^N, where N is the width of N in bits.
+ pub fn overflowing_mul<T>(a: T, b: T) -> T;
+}
P: FnMut(Self::Item) -> bool,
Self: ExactSizeIterator + DoubleEndedIterator
{
- let mut i = self.len() - 1;
+ let mut i = self.len();
+
while let Some(v) = self.next_back() {
if predicate(v) {
- return Some(i);
+ return Some(i - 1);
}
i -= 1;
}
#[inline]
fn idx(&mut self, index: usize) -> Option<<I as Iterator>::Item> {
let amt = self.indexable();
- self.iter.idx(amt - index - 1)
+ if amt > index {
+ self.iter.idx(amt - index - 1)
+ } else {
+ None
+ }
}
}
/// ```
/// use std::iter::AdditiveIterator;
///
- /// let a = [1i32, 2, 3, 4, 5];
+ /// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter().cloned();
/// assert!(it.sum() == 15);
/// ```
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> Iterator for Cloned<I> where
- T: Clone,
- D: Deref<Target=T>,
- I: Iterator<Item=D>,
+impl<I> Iterator for Cloned<I> where
+ I: Iterator,
+ I::Item: Deref,
+ <I::Item as Deref>::Target: Clone
{
- type Item = T;
+ type Item = <I::Item as Deref>::Target;
- fn next(&mut self) -> Option<T> {
+ fn next(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next().cloned()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> DoubleEndedIterator for Cloned<I> where
- T: Clone,
- D: Deref<Target=T>,
- I: DoubleEndedIterator<Item=D>,
+impl<I> DoubleEndedIterator for Cloned<I> where
+ I: DoubleEndedIterator,
+ I::Item: Deref,
+ <I::Item as Deref>::Target: Clone
{
- fn next_back(&mut self) -> Option<T> {
+ fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next_back().cloned()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, D, I> ExactSizeIterator for Cloned<I> where
- T: Clone,
- D: Deref<Target=T>,
- I: ExactSizeIterator<Item=D>,
+impl<I> ExactSizeIterator for Cloned<I> where
+ I: ExactSizeIterator,
+ I::Item: Deref,
+ <I::Item as Deref>::Target: Clone
{}
#[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, D, I> RandomAccessIterator for Cloned<I> where
- T: Clone,
- D: Deref<Target=T>,
- I: RandomAccessIterator<Item=D>
+impl<I> RandomAccessIterator for Cloned<I> where
+ I: RandomAccessIterator,
+ I::Item: Deref,
+ <I::Item as Deref>::Target: Clone
{
#[inline]
fn indexable(&self) -> usize {
}
#[inline]
- fn idx(&mut self, index: usize) -> Option<T> {
+ fn idx(&mut self, index: usize) -> Option<<Self as Iterator>::Item> {
self.it.idx(index).cloned()
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> {
- type Item = T;
+impl<A, B> Iterator for Chain<A, B> where
+ A: Iterator,
+ B: Iterator<Item = A::Item>
+{
+ type Item = A::Item;
#[inline]
- fn next(&mut self) -> Option<T> {
+ fn next(&mut self) -> Option<A::Item> {
if self.flag {
self.b.next()
} else {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
- A: DoubleEndedIterator<Item=T>,
- B: DoubleEndedIterator<Item=T>,
+impl<A, B> DoubleEndedIterator for Chain<A, B> where
+ A: DoubleEndedIterator,
+ B: DoubleEndedIterator<Item=A::Item>,
{
#[inline]
- fn next_back(&mut self) -> Option<T> {
+ fn next_back(&mut self) -> Option<A::Item> {
match self.b.next_back() {
Some(x) => Some(x),
None => self.a.next_back()
}
#[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, A, B> RandomAccessIterator for Chain<A, B> where
- A: RandomAccessIterator<Item=T>,
- B: RandomAccessIterator<Item=T>,
+impl<A, B> RandomAccessIterator for Chain<A, B> where
+ A: RandomAccessIterator,
+ B: RandomAccessIterator<Item = A::Item>,
{
#[inline]
fn indexable(&self) -> usize {
}
#[inline]
- fn idx(&mut self, index: usize) -> Option<T> {
+ fn idx(&mut self, index: usize) -> Option<A::Item> {
let len = self.a.indexable();
if index < len {
self.a.idx(index)
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, A, B> Iterator for Zip<A, B> where
- A: Iterator<Item = T>,
- B: Iterator<Item = U>,
+impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
{
- type Item = (T, U);
+ type Item = (A::Item, B::Item);
#[inline]
- fn next(&mut self) -> Option<(T, U)> {
+ fn next(&mut self) -> Option<(A::Item, B::Item)> {
match self.a.next() {
None => None,
Some(x) => match self.b.next() {
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
- A: DoubleEndedIterator + ExactSizeIterator<Item=T>,
- B: DoubleEndedIterator + ExactSizeIterator<Item=U>,
+impl<A, B> DoubleEndedIterator for Zip<A, B> where
+ A: DoubleEndedIterator + ExactSizeIterator,
+ B: DoubleEndedIterator + ExactSizeIterator,
{
#[inline]
- fn next_back(&mut self) -> Option<(T, U)> {
+ fn next_back(&mut self) -> Option<(A::Item, B::Item)> {
let a_sz = self.a.len();
let b_sz = self.b.len();
if a_sz != b_sz {
}
#[unstable(feature = "core", reason = "trait is experimental")]
-impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where
- A: RandomAccessIterator<Item=T>,
- B: RandomAccessIterator<Item=U>,
+impl<A, B> RandomAccessIterator for Zip<A, B> where
+ A: RandomAccessIterator,
+ B: RandomAccessIterator
{
#[inline]
fn indexable(&self) -> usize {
}
#[inline]
- fn idx(&mut self, index: usize) -> Option<(T, U)> {
+ fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> {
match self.a.idx(index) {
None => None,
Some(x) => match self.b.idx(index) {
f: F,
}
-impl<I: Iterator, F, B> Map<I, F> where F: FnMut(I::Item) -> B {
- #[inline]
- fn do_map(&mut self, elt: Option<I::Item>) -> Option<B> {
- match elt {
- Some(a) => Some((self.f)(a)),
- _ => None
- }
- }
-}
-
#[stable(feature = "rust1", since = "1.0.0")]
impl<B, I: Iterator, F> Iterator for Map<I, F> where F: FnMut(I::Item) -> B {
type Item = B;
#[inline]
fn next(&mut self) -> Option<B> {
- let next = self.iter.next();
- self.do_map(next)
+ self.iter.next().map(|a| (self.f)(a))
}
#[inline]
{
#[inline]
fn next_back(&mut self) -> Option<B> {
- let next = self.iter.next_back();
- self.do_map(next)
+ self.iter.next_back().map(|a| (self.f)(a))
}
}
#[inline]
fn idx(&mut self, index: usize) -> Option<B> {
- let elt = self.iter.idx(index);
- self.do_map(elt)
+ self.iter.idx(index).map(|a| (self.f)(a))
}
}
f: F,
/// The current internal state to be passed to the closure next.
+ #[unstable(feature = "core")]
pub state: St,
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
- F: FnMut(&mut St, A) -> Option<B>,
+impl<B, I, St, F> Iterator for Scan<I, St, F> where
+ I: Iterator,
+ F: FnMut(&mut St, I::Item) -> Option<B>,
{
type Item = B;
pub struct Unfold<St, F> {
f: F,
/// Internal state that will be passed to the closure on the next iteration
+ #[unstable(feature = "core")]
pub state: St,
}
Some(a) => {
let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
match sz {
- Some(Some(bound)) => bound.to_uint(),
+ Some(Some(bound)) => bound.to_usize(),
_ => None,
}
},
Some(a) => {
let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
match sz {
- Some(Some(bound)) => bound.to_uint(),
+ Some(Some(bound)) => bound.to_usize(),
_ => None
}
},
if self.start >= self.end {
(0, Some(0))
} else {
- let length = (self.end - self.start).to_uint();
+ let length = (self.end - self.start).to_usize();
(length.unwrap_or(0), length)
}
}
#![feature(unboxed_closures)]
#![feature(rustc_attrs)]
#![feature(optin_builtin_traits)]
+#![feature(concat_idents)]
#[macro_use]
mod macros;
/// This will invoke the `panic!` macro if the provided expression cannot be
/// evaluated to `true` at runtime.
///
-/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
-/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
-/// checks that are too expensive to be present in a release build but may be
-/// helpful during development.
+/// Unlike `assert!`, `debug_assert!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
///
/// # Example
///
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! debug_assert {
- ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+ ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
}
/// Asserts that two expressions are equal to each other, testing equality in
///
/// On panic, this macro will print the values of the expressions.
///
-/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
-/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
-/// useful for checks that are too expensive to be present in a release build
-/// but may be helpful during development.
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert_eq!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
///
/// # Example
///
/// ```
#[macro_export]
macro_rules! debug_assert_eq {
- ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
+ ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
}
/// Short circuiting evaluation on Err
///
/// ```rust
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
-/// for i in std::iter::count(0_u32, 1) {
+/// for i in std::iter::count(0, 1) {
/// if 3*i < i { panic!("u32 overflow"); }
/// if x < 3*i { return i-1; }
/// }
use option::Option;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+pub const RADIX: u32 = 2;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MANTISSA_DIGITS: uint = 24;
+pub const MANTISSA_DIGITS: u32 = 24;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 6;
+pub const DIGITS: u32 = 6;
#[stable(feature = "rust1", since = "1.0.0")]
pub const EPSILON: f32 = 1.19209290e-07_f32;
pub const MAX: f32 = 3.40282347e+38_f32;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -125;
+pub const MIN_EXP: i32 = -125;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 128;
+pub const MAX_EXP: i32 = 128;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -37;
+pub const MIN_10_EXP: i32 = -37;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 38;
+pub const MAX_10_EXP: i32 = 38;
#[stable(feature = "rust1", since = "1.0.0")]
pub const NAN: f32 = 0.0_f32/0.0_f32;
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
+ fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn digits(_: Option<f32>) -> uint { DIGITS }
+ fn digits(_: Option<f32>) -> uint { DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_exp(_: Option<f32>) -> int { MIN_EXP }
+ fn min_exp(_: Option<f32>) -> int { MIN_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_exp(_: Option<f32>) -> int { MAX_EXP }
+ fn max_exp(_: Option<f32>) -> int { MAX_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
+ fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
+ fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
// members of `Bounded` and `Float`.
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const RADIX: uint = 2;
+pub const RADIX: u32 = 2;
-pub const MANTISSA_DIGITS: uint = 53;
+pub const MANTISSA_DIGITS: u32 = 53;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const DIGITS: uint = 15;
+pub const DIGITS: u32 = 15;
#[stable(feature = "rust1", since = "1.0.0")]
pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
pub const MAX: f64 = 1.7976931348623157e+308_f64;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_EXP: int = -1021;
+pub const MIN_EXP: i32 = -1021;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_EXP: int = 1024;
+pub const MAX_EXP: i32 = 1024;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MIN_10_EXP: int = -307;
+pub const MIN_10_EXP: i32 = -307;
#[unstable(feature = "core", reason = "pending integer conventions")]
-pub const MAX_10_EXP: int = 308;
+pub const MAX_10_EXP: i32 = 308;
#[stable(feature = "rust1", since = "1.0.0")]
pub const NAN: f64 = 0.0_f64/0.0_f64;
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
+ fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn digits(_: Option<f64>) -> uint { DIGITS }
+ fn digits(_: Option<f64>) -> uint { DIGITS as uint }
#[inline]
#[unstable(feature = "core")]
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_exp(_: Option<f64>) -> int { MIN_EXP }
+ fn min_exp(_: Option<f64>) -> int { MIN_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_exp(_: Option<f64>) -> int { MAX_EXP }
+ fn max_exp(_: Option<f64>) -> int { MAX_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
+ fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0")]
- fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
+ fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP as int }
#[inline]
#[unstable(feature = "core")]
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `mem::size_of` function.
#[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `mem::size_of` function.
#[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
// FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
// calling the `Bounded::min_value` function.
#![stable(feature = "rust1", since = "1.0.0")]
#![allow(missing_docs)]
+use self::wrapping::{OverflowingOps, WrappingOps};
+
use char::CharExt;
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord};
use result::Result::{self, Ok, Err};
use str::{FromStr, StrExt};
+#[unstable(feature = "core", reason = "may be removed or relocated")]
+pub mod wrapping;
+
/// A built-in signed or unsigned integer.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Int
+ BitXor<Output=Self>
+ Shl<uint, Output=Self>
+ Shr<uint, Output=Self>
+ + WrappingOps
+ + OverflowingOps
{
/// Returns the `0` value of this integer type.
// FIXME (#5527): Should be an associated constant
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn count_ones(self) -> uint;
+ fn count_ones(self) -> u32;
/// Returns the number of zeros in the binary representation of `self`.
///
#[unstable(feature = "core",
reason = "pending integer conventions")]
#[inline]
- fn count_zeros(self) -> uint {
+ fn count_zeros(self) -> u32 {
(!self).count_ones()
}
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn leading_zeros(self) -> uint;
+ fn leading_zeros(self) -> u32;
/// Returns the number of trailing zeros in the binary representation
/// of `self`.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn trailing_zeros(self) -> uint;
+ fn trailing_zeros(self) -> u32;
/// Shifts the bits to the left by a specified amount amount, `n`, wrapping
/// the truncated bits to the end of the resulting integer.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn rotate_left(self, n: uint) -> Self;
+ fn rotate_left(self, n: u32) -> Self;
/// Shifts the bits to the right by a specified amount amount, `n`, wrapping
/// the truncated bits to the beginning of the resulting integer.
/// ```
#[unstable(feature = "core",
reason = "pending integer conventions")]
- fn rotate_right(self, n: uint) -> Self;
+ fn rotate_right(self, n: u32) -> Self;
/// Reverses the byte order of the integer.
///
let mut base = self;
let mut acc: Self = Int::one();
+ let mut prev_base = self;
+ let mut base_oflo = false;
while exp > 0 {
if (exp & 1) == 1 {
- acc = acc * base;
+ if base_oflo {
+ // ensure overflow occurs in the same manner it
+ // would have otherwise (i.e. signal any exception
+ // it would have otherwise).
+ acc = acc * (prev_base * prev_base);
+ } else {
+ acc = acc * base;
+ }
}
- base = base * base;
+ prev_base = base;
+ let (new_base, new_base_oflo) = base.overflowing_mul(base);
+ base = new_base;
+ base_oflo = new_base_oflo;
exp /= 2;
}
acc
fn max_value() -> $T { -1 }
#[inline]
- fn count_ones(self) -> uint { unsafe { $ctpop(self as $ActualT) as uint } }
+ fn count_ones(self) -> u32 { unsafe { $ctpop(self as $ActualT) as u32 } }
#[inline]
- fn leading_zeros(self) -> uint { unsafe { $ctlz(self as $ActualT) as uint } }
+ fn leading_zeros(self) -> u32 { unsafe { $ctlz(self as $ActualT) as u32 } }
#[inline]
- fn trailing_zeros(self) -> uint { unsafe { $cttz(self as $ActualT) as uint } }
+ fn trailing_zeros(self) -> u32 { unsafe { $cttz(self as $ActualT) as u32 } }
#[inline]
- fn rotate_left(self, n: uint) -> $T {
+ fn rotate_left(self, n: u32) -> $T {
// Protect against undefined behaviour for over-long bit shifts
let n = n % $BITS;
(self << n) | (self >> (($BITS - n) % $BITS))
}
#[inline]
- fn rotate_right(self, n: uint) -> $T {
+ fn rotate_right(self, n: u32) -> $T {
// Protect against undefined behaviour for over-long bit shifts
let n = n % $BITS;
(self >> n) | (self << (($BITS - n) % $BITS))
fn max_value() -> $T { let min: $T = Int::min_value(); !min }
#[inline]
- fn count_ones(self) -> uint { (self as $UnsignedT).count_ones() }
+ fn count_ones(self) -> u32 { (self as $UnsignedT).count_ones() }
#[inline]
- fn leading_zeros(self) -> uint { (self as $UnsignedT).leading_zeros() }
+ fn leading_zeros(self) -> u32 { (self as $UnsignedT).leading_zeros() }
#[inline]
- fn trailing_zeros(self) -> uint { (self as $UnsignedT).trailing_zeros() }
+ fn trailing_zeros(self) -> u32 { (self as $UnsignedT).trailing_zeros() }
#[inline]
- fn rotate_left(self, n: uint) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
+ fn rotate_left(self, n: u32) -> $T { (self as $UnsignedT).rotate_left(n) as $T }
#[inline]
- fn rotate_right(self, n: uint) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
+ fn rotate_right(self, n: u32) -> $T { (self as $UnsignedT).rotate_right(n) as $T }
#[inline]
fn swap_bytes(self) -> $T { (self as $UnsignedT).swap_bytes() as $T }
/// A built-in unsigned integer.
#[stable(feature = "rust1", since = "1.0.0")]
-pub trait UnsignedInt: Int {
+pub trait UnsignedInt: Int + WrappingOps {
/// Returns `true` iff `self == 2^k` for some `k`.
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
fn is_power_of_two(self) -> bool {
- (self - Int::one()) & self == Int::zero() && !(self == Int::zero())
+ (self.wrapping_sub(Int::one())) & self == Int::zero() && !(self == Int::zero())
}
/// Returns the smallest power of two greater than or equal to `self`.
fn next_power_of_two(self) -> Self {
let bits = size_of::<Self>() * 8;
let one: Self = Int::one();
- one << ((bits - (self - one).leading_zeros()) % bits)
+ one << ((bits - self.wrapping_sub(one).leading_zeros() as usize) % bits)
}
/// Returns the smallest power of two greater than or equal to `n`. If the
pub trait ToPrimitive {
/// Converts the value of `self` to an `int`.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use to_isize")]
fn to_int(&self) -> Option<int> {
- self.to_i64().and_then(|x| x.to_int())
+ self.to_i64().and_then(|x| x.to_isize())
+ }
+
+ /// Converts the value of `self` to an `isize`.
+ #[inline]
+ fn to_isize(&self) -> Option<isize> {
+ self.to_i64().and_then(|x| x.to_isize())
}
/// Converts the value of `self` to an `i8`.
/// Converts the value of `self` to an `uint`.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use to_usize")]
fn to_uint(&self) -> Option<uint> {
- self.to_u64().and_then(|x| x.to_uint())
+ self.to_u64().and_then(|x| x.to_usize())
+ }
+
+ /// Converts the value of `self` to a `usize`.
+ #[inline]
+ fn to_usize(&self) -> Option<usize> {
+ self.to_u64().and_then(|x| x.to_usize())
}
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
#[inline]
+ fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
#[inline]
+ fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
)
}
-impl_to_primitive_int! { int }
+impl_to_primitive_int! { isize }
impl_to_primitive_int! { i8 }
impl_to_primitive_int! { i16 }
impl_to_primitive_int! { i32 }
#[inline]
fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
#[inline]
+ fn to_isize(&self) -> Option<int> { impl_to_primitive_uint_to_int!(isize, *self) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
#[inline]
+ fn to_usize(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
)
}
-impl_to_primitive_uint! { uint }
+impl_to_primitive_uint! { usize }
impl_to_primitive_uint! { u8 }
impl_to_primitive_uint! { u16 }
impl_to_primitive_uint! { u32 }
#[inline]
fn to_int(&self) -> Option<int> { Some(*self as int) }
#[inline]
+ fn to_isize(&self) -> Option<int> { Some(*self as isize) }
+ #[inline]
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
#[inline]
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
#[inline]
fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
#[inline]
+ fn to_usize(&self) -> Option<uint> { Some(*self as usize) }
+ #[inline]
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
#[inline]
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
/// Convert an `int` to return an optional value of this type. If the
/// value cannot be represented by this value, the `None` is returned.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use from_isize")]
fn from_int(n: int) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
+ /// Convert an `isize` to return an optional value of this type. If the
+ /// value cannot be represented by this value, the `None` is returned.
+ #[inline]
+ fn from_isize(n: isize) -> Option<Self> {
+ FromPrimitive::from_i64(n as i64)
+ }
+
/// Convert an `i8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
/// Convert an `uint` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
+ #[unstable(feature = "core")]
+ #[deprecated(since = "1.0.0", reason = "use from_usize")]
fn from_uint(n: uint) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
+ /// Convert a `usize` to return an optional value of this type. If the
+ /// type cannot be represented by this value, the `None` is returned.
+ #[inline]
+ fn from_usize(n: usize) -> Option<Self> {
+ FromPrimitive::from_u64(n as u64)
+ }
+
/// Convert an `u8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned.
#[inline]
/// A utility function that just calls `FromPrimitive::from_int`.
#[unstable(feature = "core", reason = "likely to be removed")]
+#[deprecated(since = "1.0.0", reason = "use from_isize")]
pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
- FromPrimitive::from_int(n)
+ FromPrimitive::from_isize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_isize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_isize<A: FromPrimitive>(n: isize) -> Option<A> {
+ FromPrimitive::from_isize(n)
}
/// A utility function that just calls `FromPrimitive::from_i8`.
/// A utility function that just calls `FromPrimitive::from_uint`.
#[unstable(feature = "core", reason = "likely to be removed")]
+#[deprecated(since = "1.0.0", reason = "use from_uint")]
pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
- FromPrimitive::from_uint(n)
+ FromPrimitive::from_usize(n)
+}
+
+/// A utility function that just calls `FromPrimitive::from_usize`.
+#[unstable(feature = "core", reason = "likely to be removed")]
+pub fn from_usize<A: FromPrimitive>(n: usize) -> Option<A> {
+ FromPrimitive::from_usize(n)
}
/// A utility function that just calls `FromPrimitive::from_u8`.
macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => (
+ #[allow(deprecated)]
impl FromPrimitive for $T {
#[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
($T:ty, $conv:ident) => (
impl NumCast for $T {
#[inline]
+ #[allow(deprecated)]
fn from<N: ToPrimitive>(n: N) -> Option<$T> {
// `$conv` could be generated using `concat_idents!`, but that
// macro seems to be broken at the moment
}
}
}
-from_str_radix_int_impl! { int }
+from_str_radix_int_impl! { isize }
from_str_radix_int_impl! { i8 }
from_str_radix_int_impl! { i16 }
from_str_radix_int_impl! { i32 }
from_str_radix_int_impl! { i64 }
-from_str_radix_int_impl! { uint }
+from_str_radix_int_impl! { usize }
from_str_radix_int_impl! { u8 }
from_str_radix_int_impl! { u16 }
from_str_radix_int_impl! { u32 }
macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
#[unstable(feature = "core")]
-pub const BITS : uint = $bits;
+pub const BITS : u32 = $bits;
#[unstable(feature = "core")]
-pub const BYTES : uint = ($bits / 8);
+pub const BYTES : u32 = ($bits / 8);
#[stable(feature = "rust1", since = "1.0.0")]
pub const MIN: $T = 0 as $T;
#[stable(feature = "rust1", since = "1.0.0")]
-pub const MAX: $T = 0 as $T - 1 as $T;
+pub const MAX: $T = !0 as $T;
) }
--- /dev/null
+// 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.
+#![allow(missing_docs)]
+
+use ops::*;
+
+#[cfg(not(stage0))]
+use intrinsics::{overflowing_add, overflowing_sub, overflowing_mul};
+
+use intrinsics::{i8_add_with_overflow, u8_add_with_overflow};
+use intrinsics::{i16_add_with_overflow, u16_add_with_overflow};
+use intrinsics::{i32_add_with_overflow, u32_add_with_overflow};
+use intrinsics::{i64_add_with_overflow, u64_add_with_overflow};
+use intrinsics::{i8_sub_with_overflow, u8_sub_with_overflow};
+use intrinsics::{i16_sub_with_overflow, u16_sub_with_overflow};
+use intrinsics::{i32_sub_with_overflow, u32_sub_with_overflow};
+use intrinsics::{i64_sub_with_overflow, u64_sub_with_overflow};
+use intrinsics::{i8_mul_with_overflow, u8_mul_with_overflow};
+use intrinsics::{i16_mul_with_overflow, u16_mul_with_overflow};
+use intrinsics::{i32_mul_with_overflow, u32_mul_with_overflow};
+use intrinsics::{i64_mul_with_overflow, u64_mul_with_overflow};
+
+pub trait WrappingOps {
+ fn wrapping_add(self, rhs: Self) -> Self;
+ fn wrapping_sub(self, rhs: Self) -> Self;
+ fn wrapping_mul(self, rhs: Self) -> Self;
+}
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+pub trait OverflowingOps {
+ fn overflowing_add(self, rhs: Self) -> (Self, bool);
+ fn overflowing_sub(self, rhs: Self) -> (Self, bool);
+ fn overflowing_mul(self, rhs: Self) -> (Self, bool);
+}
+
+#[cfg(not(stage0))]
+macro_rules! wrapping_impl {
+ ($($t:ty)*) => ($(
+ impl WrappingOps for $t {
+ #[inline(always)]
+ fn wrapping_add(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_add(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn wrapping_sub(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_sub(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn wrapping_mul(self, rhs: $t) -> $t {
+ unsafe {
+ overflowing_mul(self, rhs)
+ }
+ }
+ }
+ )*)
+}
+
+#[cfg(stage0)]
+macro_rules! wrapping_impl {
+ ($($t:ty)*) => ($(
+ impl WrappingOps for $t {
+ #[inline(always)]
+ fn wrapping_add(self, rhs: $t) -> $t {
+ self + rhs
+ }
+ #[inline(always)]
+ fn wrapping_sub(self, rhs: $t) -> $t {
+ self - rhs
+ }
+ #[inline(always)]
+ fn wrapping_mul(self, rhs: $t) -> $t {
+ self * rhs
+ }
+ }
+ )*)
+}
+
+wrapping_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
+
+#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
+#[derive(PartialEq,Eq,PartialOrd,Ord,Clone,Copy)]
+pub struct Wrapping<T>(pub T);
+
+impl<T:WrappingOps> Add for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn add(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_add(other.0))
+ }
+}
+
+impl<T:WrappingOps> Sub for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn sub(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_sub(other.0))
+ }
+}
+
+impl<T:WrappingOps> Mul for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn mul(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0.wrapping_mul(other.0))
+ }
+}
+
+impl<T:WrappingOps+Not<Output=T>> Not for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ fn not(self) -> Wrapping<T> {
+ Wrapping(!self.0)
+ }
+}
+
+impl<T:WrappingOps+BitXor<Output=T>> BitXor for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitxor(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 ^ other.0)
+ }
+}
+
+impl<T:WrappingOps+BitOr<Output=T>> BitOr for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitor(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 | other.0)
+ }
+}
+
+impl<T:WrappingOps+BitAnd<Output=T>> BitAnd for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn bitand(self, other: Wrapping<T>) -> Wrapping<T> {
+ Wrapping(self.0 & other.0)
+ }
+}
+
+impl<T:WrappingOps+Shl<uint,Output=T>> Shl<uint> for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn shl(self, other: uint) -> Wrapping<T> {
+ Wrapping(self.0 << other)
+ }
+}
+
+impl<T:WrappingOps+Shr<uint,Output=T>> Shr<uint> for Wrapping<T> {
+ type Output = Wrapping<T>;
+
+ #[inline(always)]
+ fn shr(self, other: uint) -> Wrapping<T> {
+ Wrapping(self.0 >> other)
+ }
+}
+
+macro_rules! overflowing_impl {
+ ($($t:ident)*) => ($(
+ impl OverflowingOps for $t {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _add_with_overflow)(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _sub_with_overflow)(self, rhs)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: $t) -> ($t, bool) {
+ unsafe {
+ concat_idents!($t, _mul_with_overflow)(self, rhs)
+ }
+ }
+ }
+ )*)
+}
+
+overflowing_impl! { u8 u16 u32 u64 i8 i16 i32 i64 }
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for usize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_add_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_sub_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u64_mul_with_overflow(self as u64, rhs as u64);
+ (res.0 as usize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for usize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_add_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_sub_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: usize) -> (usize, bool) {
+ unsafe {
+ let res = u32_mul_with_overflow(self as u32, rhs as u32);
+ (res.0 as usize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "64")]
+impl OverflowingOps for isize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_add_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_sub_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i64_mul_with_overflow(self as i64, rhs as i64);
+ (res.0 as isize, res.1)
+ }
+ }
+}
+
+#[cfg(target_pointer_width = "32")]
+impl OverflowingOps for isize {
+ #[inline(always)]
+ fn overflowing_add(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_add_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_sub(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_sub_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+ #[inline(always)]
+ fn overflowing_mul(self, rhs: isize) -> (isize, bool) {
+ unsafe {
+ let res = i32_mul_with_overflow(self as i32, rhs as i32);
+ (res.0 as isize, res.1)
+ }
+ }
+}
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Index<Idx: ?Sized> {
/// The returned type after indexing
+ #[stable(feature = "rust1", since = "1.0.0")]
type Output: ?Sized;
/// The method for the indexing (`Foo[Bar]`) operation
/// # Example
///
/// ```
- /// let k = 10i32;
+ /// let k = 10;
/// assert_eq!(Some(4).unwrap_or_else(|| 2 * k), 4);
/// assert_eq!(None.unwrap_or_else(|| 2 * k), 20);
/// ```
#[deprecated(reason = "unboxed new closures do not have a universal representation; \
`&Fn` (etc) trait objects should use `TraitObject` instead",
since= "1.0.0")]
+#[allow(deprecated) /* for deriving Copy impl */]
pub struct Closure {
pub code: *mut (),
pub env: *mut (),
ChunksMut { v: self, chunk_size: chunk_size }
}
+ #[inline]
fn swap(&mut self, a: usize, b: usize) {
unsafe {
// Can't take two mutable loans from one vector, so instead just cast
forward_iterator! { RSplitNMut: T, &'a mut [T] }
/// An iterator over overlapping subslices of length `size`.
-#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Windows<'a, T:'a> {
v: &'a [T],
size: usize
}
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Windows<'a, T> {
+ fn clone(&self) -> Windows<'a, T> {
+ Windows {
+ v: self.v,
+ size: self.size,
+ }
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Windows<'a, T> {
type Item = &'a [T];
///
/// When the slice len is not evenly divided by the chunk size, the last slice
/// of the iteration will be the remainder.
-#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chunks<'a, T:'a> {
v: &'a [T],
size: usize
}
+// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T> Clone for Chunks<'a, T> {
+ fn clone(&self) -> Chunks<'a, T> {
+ Chunks {
+ v: self.v,
+ size: self.size,
+ }
+ }
+}
+
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Chunks<'a, T> {
type Item = &'a [T];
/// Parse a `bool` from a string.
///
- /// Yields an `Option<bool>`, because `s` may or may not actually be
- /// parseable.
+ /// Yields a `Result<bool, ParseBoolError>`, because `s` may or may not
+ /// actually be parseable.
///
/// # Examples
///
/// ```rust
+ /// use std::str::FromStr;
+ ///
+ /// assert_eq!(FromStr::from_str("true"), Ok(true));
+ /// assert_eq!(FromStr::from_str("false"), Ok(false));
+ /// assert!(<bool as FromStr>::from_str("not even a boolean").is_err());
+ /// ```
+ ///
+ /// Note, in many cases, the StrExt::parse() which is based on
+ /// this FromStr::from_str() is more proper.
+ ///
+ /// ```rust
/// assert_eq!("true".parse(), Ok(true));
/// assert_eq!("false".parse(), Ok(false));
/// assert!("not even a boolean".parse::<bool>().is_err());
#[inline]
#[allow(dead_code)]
fn maximal_suffix(arr: &[u8], reversed: bool) -> (usize, usize) {
+ use num::wrapping::WrappingOps;
let mut left = -1; // Corresponds to i in the paper
let mut right = 0; // Corresponds to j in the paper
let mut offset = 1; // Corresponds to k in the paper
let a;
let b;
if reversed {
- a = arr[left + offset];
+ a = arr[left.wrapping_add(offset)];
b = arr[right + offset];
} else {
a = arr[right + offset];
- b = arr[left + offset];
+ b = arr[left.wrapping_add(offset)];
}
if a < b {
// Suffix is smaller, period is entire prefix so far.
right += offset;
offset = 1;
- period = right - left;
+ period = right.wrapping_sub(left);
} else if a == b {
// Advance through repetition of the current period.
if offset == period {
period = 1;
}
}
- (left + 1, period)
+ (left.wrapping_add(1), period)
}
}
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "use `Split` with a `&str`")]
pub struct SplitStr<'a, P: Pattern<'a>>(Split<'a, P>);
+#[allow(deprecated)]
impl<'a, P: Pattern<'a>> Iterator for SplitStr<'a, P> {
type Item = &'a str;
}
/// Mask of the value bits of a continuation byte
-const CONT_MASK: u8 = 0b0011_1111u8;
+const CONT_MASK: u8 = 0b0011_1111;
/// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
-const TAG_CONT_U8: u8 = 0b1000_0000u8;
+const TAG_CONT_U8: u8 = 0b1000_0000;
/*
Section: Trait implementations
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
+ #[allow(deprecated) /* for SplitStr */]
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
fn lines<'a>(&'a self) -> Lines<'a>;
fn lines_any<'a>(&'a self) -> LinesAny<'a>;
if index == self.len() { return true; }
match self.as_bytes().get(index) {
None => false,
- Some(&b) => b < 128u8 || b >= 192u8,
+ Some(&b) => b < 128 || b >= 192,
}
}
#[inline]
#[unstable(feature = "core")]
pub fn char_range_at_raw(bytes: &[u8], i: usize) -> (u32, usize) {
- if bytes[i] < 128u8 {
+ if bytes[i] < 128 {
return (bytes[i] as u32, i + 1);
}
#[test]
fn any_downcast_mut() {
let mut a = 5_usize;
- let mut b = box 7_usize;
+ let mut b: Box<_> = box 7_usize;
let a_r = &mut a as &mut Any;
let tmp: &mut uint = &mut *b;
#[test]
fn test_encode_utf8() {
fn check(input: char, expect: &[u8]) {
- let mut buf = [0u8; 4];
+ let mut buf = [0; 4];
let n = input.encode_utf8(&mut buf).unwrap_or(0);
assert_eq!(&buf[..n], expect);
}
#[test]
fn test_encode_utf16() {
fn check(input: char, expect: &[u16]) {
- let mut buf = [0u16; 2];
+ let mut buf = [0; 2];
let n = input.encode_utf16(&mut buf).unwrap_or(0);
assert_eq!(&buf[..n], expect);
}
// FIXME (#18283) Enable test
//let s: Box<str> = box "a";
//assert_eq!(hasher.hash(& s), 97 + 0xFF);
- let cs: &[u8] = &[1u8, 2u8, 3u8];
+ let cs: &[u8] = &[1, 2, 3];
assert_eq!(hash(& cs), 9);
- let cs: Box<[u8]> = box [1u8, 2u8, 3u8];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let cs: Box<[u8]> = Box::new([1, 2, 3]);
assert_eq!(hash(& cs), 9);
// FIXME (#18248) Add tests for hashing Rc<str> and Rc<[T]>
impl Hasher for CustomHasher {
fn finish(&self) -> u64 { self.output }
- fn write(&mut self, data: &[u8]) { panic!() }
+ fn write(&mut self, _: &[u8]) { panic!() }
fn write_u64(&mut self, data: u64) { self.output = data; }
}
[ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
];
- let k0 = 0x_07_06_05_04_03_02_01_00_u64;
- let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
+ let k0 = 0x_07_06_05_04_03_02_01_00;
+ let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
let mut buf = Vec::new();
let mut t = 0;
let mut state_inc = SipState::new_with_keys(k0, k1);
assert!(s != t && t != u);
assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
- let v: (&[u8], &[u8], &[u8]) = (&[1u8], &[0u8, 0], &[0u8]);
- let w: (&[u8], &[u8], &[u8]) = (&[1u8, 0, 0, 0], &[], &[]);
+ let v: (&[u8], &[u8], &[u8]) = (&[1], &[0, 0], &[0]);
+ let w: (&[u8], &[u8], &[u8]) = (&[1, 0, 0, 0], &[], &[]);
assert!(v != w);
assert!(hash(&v) != hash(&w));
#[test]
fn test_all() {
- let v: Box<[int]> = box [1, 2, 3, 4, 5];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
assert!(v.iter().all(|&x| x < 10));
assert!(!v.iter().all(|&x| x % 2 == 0));
assert!(!v.iter().all(|&x| x > 100));
#[test]
fn test_any() {
- let v: Box<[int]> = box [1, 2, 3, 4, 5];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
assert!(v.iter().any(|&x| x < 10));
assert!(v.iter().any(|&x| x % 2 == 0));
assert!(!v.iter().any(|&x| x > 100));
#[test]
#[should_fail]
fn test_rposition_panic() {
- let v = [(box 0, box 0), (box 0, box 0),
- (box 0, box 0), (box 0, box 0)];
+ let v: [(Box<_>, Box<_>); 4] =
+ [(box 0, box 0), (box 0, box 0),
+ (box 0, box 0), (box 0, box 0)];
let mut i = 0;
v.iter().rposition(|_elt| {
if i == 2 {
assert_eq!(range_step(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15]);
assert_eq!(range_step(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5]);
assert_eq!(range_step(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
- assert_eq!(range_step(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]);
- assert_eq!(range_step(200i, -5, 1).collect::<Vec<int>>(), []);
- assert_eq!(range_step(200i, 200, 1).collect::<Vec<int>>(), []);
+ assert_eq!(range_step(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
+ assert_eq!(range_step(200, -5, 1).collect::<Vec<int>>(), []);
+ assert_eq!(range_step(200, 200, 1).collect::<Vec<int>>(), []);
}
#[test]
assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15, 20]);
assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5, 0]);
assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
- assert_eq!(range_step_inclusive(200u8, 255, 50).collect::<Vec<u8>>(), [200u8, 250]);
+ assert_eq!(range_step_inclusive(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), []);
assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), [200]);
}
}
unsafe {
- assert_eq!([76u8], transmute::<_, Vec<u8>>("L".to_string()));
+ assert_eq!([76], transmute::<_, Vec<u8>>("L".to_string()));
}
}
assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
}
- static A: $T = 0b0101100;
- static B: $T = 0b0100001;
- static C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- static _0: $T = 0;
- static _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
#[test]
fn test_count_ones() {
#[test]
fn test_int_from_str_overflow() {
- let mut i8_val: i8 = 127_i8;
+ let mut i8_val: i8 = 127;
assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
assert_eq!("128".parse::<i8>().ok(), None);
- i8_val += 1 as i8;
+ i8_val = i8_val.wrapping_add(1);
assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
assert_eq!("-129".parse::<i8>().ok(), None);
- let mut i16_val: i16 = 32_767_i16;
+ let mut i16_val: i16 = 32_767;
assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
assert_eq!("32768".parse::<i16>().ok(), None);
- i16_val += 1 as i16;
+ i16_val = i16_val.wrapping_add(1);
assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
assert_eq!("-32769".parse::<i16>().ok(), None);
- let mut i32_val: i32 = 2_147_483_647_i32;
+ let mut i32_val: i32 = 2_147_483_647;
assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
assert_eq!("2147483648".parse::<i32>().ok(), None);
- i32_val += 1 as i32;
+ i32_val = i32_val.wrapping_add(1);
assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
assert_eq!("-2147483649".parse::<i32>().ok(), None);
- let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+ let mut i64_val: i64 = 9_223_372_036_854_775_807;
assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
- i64_val += 1 as i64;
+ i64_val = i64_val.wrapping_add(1);
assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
}
assert!(MAX - (0b1011 as $T) == (0b1011 as $T).not());
}
- static A: $T = 0b0101100;
- static B: $T = 0b0100001;
- static C: $T = 0b1111001;
+ const A: $T = 0b0101100;
+ const B: $T = 0b0100001;
+ const C: $T = 0b1111001;
- static _0: $T = 0;
- static _1: $T = !0;
+ const _0: $T = 0;
+ const _1: $T = !0;
#[test]
fn test_count_ones() {
#[test]
fn test_get_ptr() {
unsafe {
- let x = box 0;
+ let x: Box<_> = box 0;
let addr_x: *const int = mem::transmute(&*x);
let opt = Some(x);
let y = opt.unwrap();
fn test_ptr_subtraction() {
unsafe {
let xs = vec![0,1,2,3,4,5,6,7,8,9];
- let mut idx = 9i8;
+ let mut idx = 9;
let ptr = xs.as_ptr();
- while idx >= 0i8 {
+ while idx >= 0 {
assert_eq!(*(ptr.offset(idx as int)), idx as int);
- idx = idx - 1i8;
+ idx = idx - 1;
}
let mut xs_mut = xs;
mod pattern {
use std::str::Pattern;
- use std::str::{Searcher, ReverseSearcher, DoubleEndedSearcher};
+ use std::str::{Searcher, ReverseSearcher};
use std::str::SearchStep::{self, Match, Reject, Done};
macro_rules! make_test {
($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
mod $name {
- use std::str::Pattern;
- use std::str::{Searcher, ReverseSearcher, DoubleEndedSearcher};
- use std::str::SearchStep::{self, Match, Reject, Done};
+ use std::str::SearchStep::{Match, Reject};
use super::{cmp_search_to_vec};
#[test]
fn fwd() {
-> *mut c_void;
}
-static LZ_NORM : c_int = 0x80; // LZ with 128 probes, "normal"
-static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
-static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
+const LZ_NORM: c_int = 0x80; // LZ with 128 probes, "normal"
+const TINFL_FLAG_PARSE_ZLIB_HEADER: c_int = 0x1; // parse zlib header and adler32 checksum
+const TDEFL_WRITE_ZLIB_HEADER: c_int = 0x01000; // write zlib header and adler32 checksum
fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
unsafe {
#![feature(collections)]
#![feature(int_uint)]
#![feature(staged_api)]
+#![feature(core)]
#![feature(str_words)]
#![cfg_attr(test, feature(rustc_private))]
//! Each node label is derived directly from the int representing the node,
//! while the edge labels are all empty strings.
//!
-//! This example also illustrates how to use `CowVec` to return
+//! This example also illustrates how to use `Cow<[T]>` to return
//! an owned vector or a borrowed slice as appropriate: we construct the
//! node vector from scratch, but borrow the edge list (rather than
//! constructing a copy of all the edges from scratch).
/// that is bound by the self lifetime `'a`.
///
/// The `nodes` and `edges` method each return instantiations of
-/// `CowVec` to leave implementers the freedom to create
+/// `Cow<[T]>` to leave implementers the freedom to create
/// entirely new vectors or to pass back slices into internally owned
/// vectors.
pub trait GraphWalk<'a, N, E> {
#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "libc"]
#![crate_type = "rlib"]
-#![cfg_attr(not(feature = "cargo-build"),
- unstable(feature = "libc"))]
-#![cfg_attr(not(feature = "cargo-build"), feature(staged_api))]
+#![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc"))]
+#![cfg_attr(not(feature = "cargo-build"), feature(staged_api, core, no_std))]
#![cfg_attr(not(feature = "cargo-build"), staged_api)]
-#![cfg_attr(not(feature = "cargo-build"), feature(core))]
-#![feature(no_std)]
-#![no_std]
+#![cfg_attr(not(feature = "cargo-build"), no_std)]
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/",
target_arch = "mips",
target_arch = "mipsel",
target_arch = "powerpc",
- target_arch = "le32"))]
+ target_arch = "le32",
+ all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix88 {
pub type off_t = i32;
pub type dev_t = u64;
pub type mode_t = u32;
pub type ssize_t = i32;
}
- #[cfg(target_arch = "arm")]
+ #[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix88 {
pub type off_t = i32;
pub type dev_t = u32;
}
#[cfg(any(target_arch = "x86",
target_arch = "le32",
- target_arch = "powerpc"))]
+ target_arch = "powerpc",
+ all(target_arch = "arm", not(target_os = "android"))))]
pub mod posix01 {
use types::os::arch::c95::{c_short, c_long, time_t};
use types::os::arch::posix88::{dev_t, gid_t, ino_t};
pub __size: [u32; 9]
}
}
- #[cfg(target_arch = "arm")]
+ #[cfg(all(target_arch = "arm", target_os = "android"))]
pub mod posix01 {
use types::os::arch::c95::{c_uchar, c_uint, c_ulong, time_t};
use types::os::arch::c99::{c_longlong, c_ulonglong};
pub const _IOFBF : c_int = 0;
pub const _IONBF : c_int = 4;
pub const _IOLBF : c_int = 64;
- pub const BUFSIZ : c_uint = 512_u32;
- pub const FOPEN_MAX : c_uint = 20_u32;
- pub const FILENAME_MAX : c_uint = 260_u32;
- pub const L_tmpnam : c_uint = 16_u32;
- pub const TMP_MAX : c_uint = 32767_u32;
+ pub const BUFSIZ : c_uint = 512;
+ pub const FOPEN_MAX : c_uint = 20;
+ pub const FILENAME_MAX : c_uint = 260;
+ pub const L_tmpnam : c_uint = 16;
+ pub const TMP_MAX : c_uint = 32767;
pub const WSAEINTR: c_int = 10004;
pub const WSAEBADF: c_int = 10009;
pub const _IOFBF : c_int = 0;
pub const _IONBF : c_int = 2;
pub const _IOLBF : c_int = 1;
- pub const BUFSIZ : c_uint = 8192_u32;
- pub const FOPEN_MAX : c_uint = 16_u32;
- pub const FILENAME_MAX : c_uint = 4096_u32;
- pub const L_tmpnam : c_uint = 20_u32;
- pub const TMP_MAX : c_uint = 238328_u32;
+ pub const BUFSIZ : c_uint = 8192;
+ pub const FOPEN_MAX : c_uint = 16;
+ pub const FILENAME_MAX : c_uint = 4096;
+ pub const L_tmpnam : c_uint = 20;
+ pub const TMP_MAX : c_uint = 238328;
}
pub mod c99 {
}
pub const _IOFBF : c_int = 0;
pub const _IONBF : c_int = 2;
pub const _IOLBF : c_int = 1;
- pub const BUFSIZ : c_uint = 1024_u32;
- pub const FOPEN_MAX : c_uint = 20_u32;
- pub const FILENAME_MAX : c_uint = 1024_u32;
- pub const L_tmpnam : c_uint = 1024_u32;
- pub const TMP_MAX : c_uint = 308915776_u32;
+ pub const BUFSIZ : c_uint = 1024;
+ pub const FOPEN_MAX : c_uint = 20;
+ pub const FILENAME_MAX : c_uint = 1024;
+ pub const L_tmpnam : c_uint = 1024;
+ pub const TMP_MAX : c_uint = 308915776;
}
pub mod c99 {
}
pub const _IOFBF : c_int = 0;
pub const _IONBF : c_int = 2;
pub const _IOLBF : c_int = 1;
- pub const BUFSIZ : c_uint = 1024_u32;
- pub const FOPEN_MAX : c_uint = 20_u32;
- pub const FILENAME_MAX : c_uint = 1024_u32;
- pub const L_tmpnam : c_uint = 1024_u32;
- pub const TMP_MAX : c_uint = 308915776_u32;
+ pub const BUFSIZ : c_uint = 1024;
+ pub const FOPEN_MAX : c_uint = 20;
+ pub const FILENAME_MAX : c_uint = 1024;
+ pub const L_tmpnam : c_uint = 1024;
+ pub const TMP_MAX : c_uint = 308915776;
}
pub mod c99 {
}
pub const _IOFBF : c_int = 0;
pub const _IONBF : c_int = 2;
pub const _IOLBF : c_int = 1;
- pub const BUFSIZ : c_uint = 1024_u32;
- pub const FOPEN_MAX : c_uint = 20_u32;
- pub const FILENAME_MAX : c_uint = 1024_u32;
- pub const L_tmpnam : c_uint = 1024_u32;
- pub const TMP_MAX : c_uint = 308915776_u32;
+ pub const BUFSIZ : c_uint = 1024;
+ pub const FOPEN_MAX : c_uint = 20;
+ pub const FILENAME_MAX : c_uint = 1024;
+ pub const L_tmpnam : c_uint = 1024;
+ pub const TMP_MAX : c_uint = 308915776;
}
pub mod c99 {
}
use types::os::arch::c95::{c_char, c_int};
use types::os::arch::posix88::mode_t;
+ mod open_shim {
+ extern {
+ #[cfg(any(target_os = "macos",
+ target_os = "ios"))]
+ pub fn open(path: *const ::c_char, oflag: ::c_int, ...)
+ -> ::c_int;
+
+ #[cfg(not(any(target_os = "macos",
+ target_os = "ios")))]
+ pub fn open(path: *const ::c_char, oflag: ::c_int, mode: ::mode_t)
+ -> ::c_int;
+ }
+ }
+
+ #[cfg(any(target_os = "macos",
+ target_os = "ios"))]
+ #[inline]
+ pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+ use types::os::arch::c95::c_uint;
+ open_shim::open(path, oflag, mode as c_uint)
+ }
+
+ #[cfg(not(any(target_os = "macos",
+ target_os = "ios")))]
+ #[inline]
+ pub unsafe extern fn open(path: *const c_char, oflag: c_int, mode: mode_t) -> c_int {
+ open_shim::open(path, oflag, mode)
+ }
+
extern {
- pub fn open(path: *const c_char, oflag: c_int, mode: mode_t)
- -> c_int;
pub fn creat(path: *const c_char, mode: mode_t) -> c_int;
pub fn fcntl(fd: c_int, cmd: c_int, ...) -> c_int;
}
/// ```
#[macro_export]
macro_rules! debug {
- ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) })
+ ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) })
}
/// A macro to test whether a log level is enabled for the current module.
macro_rules! log_enabled {
($lvl:expr) => ({
let lvl = $lvl;
- (lvl != ::log::DEBUG || cfg!(not(ndebug))) &&
+ (lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
lvl <= ::log::log_level() &&
::log::mod_enabled(lvl, module_path!())
})
use core::prelude::*;
use core::num::Int;
+use core::num::wrapping::WrappingOps;
use {Rng, SeedableRng, Rand};
const KEY_WORDS : uint = 8; // 8 words for the 256-bit key
macro_rules! quarter_round{
($a: expr, $b: expr, $c: expr, $d: expr) => {{
- $a += $b; $d ^= $a; $d = $d.rotate_left(16);
- $c += $d; $b ^= $c; $b = $b.rotate_left(12);
- $a += $b; $d ^= $a; $d = $d.rotate_left( 8);
- $c += $d; $b ^= $c; $b = $b.rotate_left( 7);
+ $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left(16);
+ $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left(12);
+ $a = $a.wrapping_add($b); $d = $d ^ $a; $d = $d.rotate_left( 8);
+ $c = $c.wrapping_add($d); $b = $b ^ $c; $b = $b.rotate_left( 7);
}}
}
}
for i in 0..STATE_WORDS {
- output[i] += input[i];
+ output[i] = output[i].wrapping_add(input[i]);
}
}
fn reseed(&mut self, seed: &'a [u32]) {
// reset state
- self.init(&[0u32; KEY_WORDS]);
+ self.init(&[0; KEY_WORDS]);
// set key in place
let key = &mut self.state[4 .. 4+KEY_WORDS];
for (k, s) in key.iter_mut().zip(seed.iter()) {
fn test_rng_true_values() {
// Test vectors 1 and 2 from
// http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-04
- let seed : &[_] = &[0u32; 8];
+ let seed : &[_] = &[0; 8];
let mut ra: ChaChaRng = SeedableRng::from_seed(seed);
let v = (0..16).map(|_| ra.next_u32()).collect::<Vec<_>>();
#[test]
fn test_rng_clone() {
- let seed : &[_] = &[0u32; 8];
+ let seed : &[_] = &[0; 8];
let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
let mut clone = rng.clone();
for _ in 0..16 {
mut pdf: P,
mut zero_case: Z)
-> f64 where P: FnMut(f64) -> f64, Z: FnMut(&mut R, f64) -> f64 {
- static SCALE: f64 = (1u64 << 53) as f64;
+ const SCALE: f64 = (1u64 << 53) as f64;
loop {
// reimplement the f64 generation as an optimisation suggested
// by the Doornik paper: we have a lot of precision-space
use core::prelude::{PartialOrd};
use core::num::Int;
+use core::num::wrapping::WrappingOps;
use Rng;
use distributions::{Sample, IndependentSample};
///
/// This gives a uniform distribution (assuming the RNG used to sample
/// it is itself uniform & the `SampleRange` implementation for the
-/// given type is correct), even for edge cases like `low = 0u8`,
-/// `high = 170u8`, for which a naive modulo operation would return
+/// given type is correct), even for edge cases like `low = 0`,
+/// `high = 170`, for which a naive modulo operation would return
/// numbers less than 85 with double the probability to those greater
/// than 85.
///
// bijection.
fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
- let range = high as $unsigned - low as $unsigned;
+ let range = (high as $unsigned).wrapping_sub(low as $unsigned);
let unsigned_max: $unsigned = Int::max_value();
// this is the largest number that fits into $unsigned
// be uniformly distributed)
if v < r.accept_zone as $unsigned {
// and return it, with some adjustments
- return r.low + (v % r.range as $unsigned) as $ty;
+ return r.low.wrapping_add((v % r.range as $unsigned) as $ty);
}
}
}
use core::prelude::*;
use core::slice;
use core::iter::{range_step, repeat};
+use core::num::wrapping::Wrapping;
use {Rng, SeedableRng, Rand};
/// of `rsl` as a seed, otherwise construct one algorithmically (not
/// randomly).
fn init(&mut self, use_rsl: bool) {
- let mut a = 0x9e3779b9;
+ let mut a = Wrapping(0x9e3779b9);
let mut b = a;
let mut c = a;
let mut d = a;
macro_rules! mix {
() => {{
- a^=b<<11; d+=a; b+=c;
- b^=c>>2; e+=b; c+=d;
- c^=d<<8; f+=c; d+=e;
- d^=e>>16; g+=d; e+=f;
- e^=f<<10; h+=e; f+=g;
- f^=g>>4; a+=f; g+=h;
- g^=h<<8; b+=g; h+=a;
- h^=a>>9; c+=h; a+=b;
+ a=a^(b<<11); d=d+a; b=b+c;
+ b=b^(c>>2); e=e+b; c=c+d;
+ c=c^(d<<8); f=f+c; d=d+e;
+ d=d^(e>>16); g=g+d; e=e+f;
+ e=e^(f<<10); h=h+e; f=f+g;
+ f=f^(g>>4); a=a+f; g=g+h;
+ g=g^(h<<8); b=b+g; h=h+a;
+ h=h^(a>>9); c=c+h; a=a+b;
}}
}
macro_rules! memloop {
($arr:expr) => {{
for i in range_step(0, RAND_SIZE as uint, 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$arr[i+7];
+ a=a+Wrapping($arr[i ]); b=b+Wrapping($arr[i+1]);
+ c=c+Wrapping($arr[i+2]); d=d+Wrapping($arr[i+3]);
+ e=e+Wrapping($arr[i+4]); f=f+Wrapping($arr[i+5]);
+ g=g+Wrapping($arr[i+6]); h=h+Wrapping($arr[i+7]);
mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
+ self.mem[i ]=a.0; self.mem[i+1]=b.0;
+ self.mem[i+2]=c.0; self.mem[i+3]=d.0;
+ self.mem[i+4]=e.0; self.mem[i+5]=f.0;
+ self.mem[i+6]=g.0; self.mem[i+7]=h.0;
}
}}
}
} else {
for i in range_step(0, RAND_SIZE as uint, 8) {
mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
+ self.mem[i ]=a.0; self.mem[i+1]=b.0;
+ self.mem[i+2]=c.0; self.mem[i+3]=d.0;
+ self.mem[i+4]=e.0; self.mem[i+5]=f.0;
+ self.mem[i+6]=g.0; self.mem[i+7]=h.0;
}
}
let mut a = self.a;
let mut b = self.b + self.c;
- static MIDPOINT: uint = (RAND_SIZE / 2) as uint;
+ const MIDPOINT: uint = (RAND_SIZE / 2) as uint;
macro_rules! ind {
- ($x:expr) => ( self.mem[(($x >> 2) as uint & ((RAND_SIZE - 1) as uint))] )
+ ($x:expr) => (Wrapping( self.mem[(($x >> 2) as uint &
+ ((RAND_SIZE - 1) as uint))] ))
}
let r = [(0, MIDPOINT), (MIDPOINT, 0)];
let mix = a << $shift as uint;
let x = self.mem[base + mr_offset];
- a = (a ^ mix) + self.mem[base + m2_offset];
- let y = ind!(x) + a + b;
- self.mem[base + mr_offset] = y;
+ a = (Wrapping(a ^ mix) + Wrapping(self.mem[base + m2_offset])).0;
+ let y = ind!(x) + Wrapping(a) + Wrapping(b);
+ self.mem[base + mr_offset] = y.0;
- b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+ b = (ind!(y.0 >> RAND_SIZE_LEN as uint) + Wrapping(x)).0;
self.rsl[base + mr_offset] = b;
}}
}
let mix = a >> $shift as uint;
let x = self.mem[base + mr_offset];
- a = (a ^ mix) + self.mem[base + m2_offset];
- let y = ind!(x) + a + b;
- self.mem[base + mr_offset] = y;
+ a = (Wrapping(a ^ mix) + Wrapping(self.mem[base + m2_offset])).0;
+ let y = ind!(x) + Wrapping(a) + Wrapping(b);
+ self.mem[base + mr_offset] = y.0;
- b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+ b = (ind!(y.0 >> RAND_SIZE_LEN as uint) + Wrapping(x)).0;
self.rsl[base + mr_offset] = b;
}}
}
fn reseed(&mut self, seed: &'a [u32]) {
// make the seed into [seed[0], seed[1], ..., seed[seed.len()
// - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().cloned().chain(repeat(0u32));
+ let seed_iter = seed.iter().cloned().chain(repeat(0));
for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
*rsl_elem = seed_elem;
fn init(&mut self, use_rsl: bool) {
macro_rules! init {
($var:ident) => (
- let mut $var = 0x9e3779b97f4a7c13;
+ let mut $var = Wrapping(0x9e3779b97f4a7c13);
)
}
init!(a); init!(b); init!(c); init!(d);
macro_rules! mix {
() => {{
- a-=e; f^=h>>9; h+=a;
- b-=f; g^=a<<9; a+=b;
- c-=g; h^=b>>23; b+=c;
- d-=h; a^=c<<15; c+=d;
- e-=a; b^=d>>14; d+=e;
- f-=b; c^=e<<20; e+=f;
- g-=c; d^=f>>17; f+=g;
- h-=d; e^=g<<14; g+=h;
+ a=a-e; f=f^h>>9; h=h+a;
+ b=b-f; g=g^a<<9; a=a+b;
+ c=c-g; h=h^b>>23; b=b+c;
+ d=d-h; a=a^c<<15; c=c+d;
+ e=e-a; b=b^d>>14; d=d+e;
+ f=f-b; c=c^e<<20; e=e+f;
+ g=g-c; d=d^f>>17; f=f+g;
+ h=h-d; e=e^g<<14; g=g+h;
}}
}
macro_rules! memloop {
($arr:expr) => {{
for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
- a+=$arr[i ]; b+=$arr[i+1];
- c+=$arr[i+2]; d+=$arr[i+3];
- e+=$arr[i+4]; f+=$arr[i+5];
- g+=$arr[i+6]; h+=$arr[i+7];
+ a=a+Wrapping($arr[i ]); b=b+Wrapping($arr[i+1]);
+ c=c+Wrapping($arr[i+2]); d=d+Wrapping($arr[i+3]);
+ e=e+Wrapping($arr[i+4]); f=f+Wrapping($arr[i+5]);
+ g=g+Wrapping($arr[i+6]); h=h+Wrapping($arr[i+7]);
mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
+ self.mem[i ]=a.0; self.mem[i+1]=b.0;
+ self.mem[i+2]=c.0; self.mem[i+3]=d.0;
+ self.mem[i+4]=e.0; self.mem[i+5]=f.0;
+ self.mem[i+6]=g.0; self.mem[i+7]=h.0;
}
}}
}
} else {
for i in (0..RAND_SIZE_64 / 8).map(|i| i * 8) {
mix!();
- self.mem[i ]=a; self.mem[i+1]=b;
- self.mem[i+2]=c; self.mem[i+3]=d;
- self.mem[i+4]=e; self.mem[i+5]=f;
- self.mem[i+6]=g; self.mem[i+7]=h;
+ self.mem[i ]=a.0; self.mem[i+1]=b.0;
+ self.mem[i+2]=c.0; self.mem[i+3]=d.0;
+ self.mem[i+4]=e.0; self.mem[i+5]=f.0;
+ self.mem[i+6]=g.0; self.mem[i+7]=h.0;
}
}
fn isaac64(&mut self) {
self.c += 1;
// abbreviations
- let mut a = self.a;
- let mut b = self.b + self.c;
+ let mut a = Wrapping(self.a);
+ let mut b = Wrapping(self.b) + Wrapping(self.c);
const MIDPOINT: uint = RAND_SIZE_64 / 2;
const MP_VEC: [(uint, uint); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
macro_rules! ind {
let mix = if $j == 0 {!mix} else {mix};
unsafe {
- let x = *self.mem.get_unchecked(base + mr_offset);
- a = mix + *self.mem.get_unchecked(base + m2_offset);
- let y = ind!(x) + a + b;
- *self.mem.get_unchecked_mut(base + mr_offset) = y;
+ let x = Wrapping(*self.mem.get_unchecked(base + mr_offset));
+ a = mix + Wrapping(*self.mem.get_unchecked(base + m2_offset));
+ let y = Wrapping(ind!(x.0)) + a + b;
+ *self.mem.get_unchecked_mut(base + mr_offset) = y.0;
- b = ind!(y >> RAND_SIZE_64_LEN) + x;
- *self.rsl.get_unchecked_mut(base + mr_offset) = b;
+ b = Wrapping(ind!(y.0 >> RAND_SIZE_64_LEN)) + x;
+ *self.rsl.get_unchecked_mut(base + mr_offset) = b.0;
}
}}
}
let mix = if $j == 0 {!mix} else {mix};
unsafe {
- let x = *self.mem.get_unchecked(base + mr_offset);
- a = mix + *self.mem.get_unchecked(base + m2_offset);
- let y = ind!(x) + a + b;
- *self.mem.get_unchecked_mut(base + mr_offset) = y;
+ let x = Wrapping(*self.mem.get_unchecked(base + mr_offset));
+ a = mix + Wrapping(*self.mem.get_unchecked(base + m2_offset));
+ let y = Wrapping(ind!(x.0)) + a + b;
+ *self.mem.get_unchecked_mut(base + mr_offset) = y.0;
- b = ind!(y >> RAND_SIZE_64_LEN) + x;
- *self.rsl.get_unchecked_mut(base + mr_offset) = b;
+ b = Wrapping(ind!(y.0 >> RAND_SIZE_64_LEN)) + x;
+ *self.rsl.get_unchecked_mut(base + mr_offset) = b.0;
}
}}
}
}
}
- self.a = a;
- self.b = b;
+ self.a = a.0;
+ self.b = b.0;
self.cnt = RAND_SIZE_64;
}
}
fn reseed(&mut self, seed: &'a [u64]) {
// make the seed into [seed[0], seed[1], ..., seed[seed.len()
// - 1], 0, 0, ...], to fill rng.rsl.
- let seed_iter = seed.iter().cloned().chain(repeat(0u64));
+ let seed_iter = seed.iter().cloned().chain(repeat(0));
for (rsl_elem, seed_elem) in self.rsl.iter_mut().zip(seed_iter) {
*rsl_elem = seed_elem;
use distributions::range::SampleRange;
#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
+const RAND_BENCH_N: u64 = 100;
pub mod distributions;
pub mod isaac;
/// ```rust
/// use std::rand::{thread_rng, Rng};
///
- /// let mut v = [0u8; 13579];
+ /// let mut v = [0; 13579];
/// thread_rng().fill_bytes(&mut v);
/// println!("{:?}", v.as_slice());
/// ```
type Item = char;
fn next(&mut self) -> Option<char> {
- static GEN_ASCII_STR_CHARSET: &'static [u8] =
+ const GEN_ASCII_STR_CHARSET: &'static [u8] =
b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789";
#[inline]
fn rand<R: Rng>(rng: &mut R) -> char {
// a char is 21 bits
- static CHAR_MASK: u32 = 0x001f_ffff;
+ const CHAR_MASK: u32 = 0x001f_ffff;
loop {
// Rejection sampling. About 0.2% of numbers with at most
// 21-bits are invalid codepoints (surrogates), so this
#[cfg(test)]
mod tests {
- use std::prelude::v1::*;
use std::rand::{Rng, thread_rng, Open01, Closed01};
struct ConstantRng(u64);
/// How many bytes of entropy the underling RNG is allowed to generate
/// before it is reseeded.
-static DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
+const DEFAULT_GENERATION_THRESHOLD: uint = 32 * 1024;
/// A wrapper around any RNG which reseeds the underlying RNG after it
/// has generated a certain number of random bytes.
assert_eq!(string1, string2);
}
- static FILL_BYTES_V_LEN: uint = 13579;
+ const FILL_BYTES_V_LEN: uint = 13579;
#[test]
fn test_rng_fill_bytes() {
- let mut v = repeat(0u8).take(FILL_BYTES_V_LEN).collect::<Vec<_>>();
+ let mut v = repeat(0).take(FILL_BYTES_V_LEN).collect::<Vec<_>>();
::test::rng().fill_bytes(&mut v);
// Sanity test: if we've gotten here, `fill_bytes` has not infinitely
use std::slice;
use std::iter::repeat;
-static BUF_CAPACITY: uint = 128;
+const BUF_CAPACITY: uint = 128;
fn combine(seek: SeekStyle, cur: uint, end: uint, offset: i64) -> IoResult<u64> {
// compute offset as signed and clamp to prevent overflow
fn test_seekable_mem_writer() {
let mut writer = SeekableMemWriter::new();
assert_eq!(writer.tell(), Ok(0));
- writer.write(&[0]).unwrap();
+ writer.write_all(&[0]).unwrap();
assert_eq!(writer.tell(), Ok(1));
- writer.write(&[1, 2, 3]).unwrap();
- writer.write(&[4, 5, 6, 7]).unwrap();
+ writer.write_all(&[1, 2, 3]).unwrap();
+ writer.write_all(&[4, 5, 6, 7]).unwrap();
assert_eq!(writer.tell(), Ok(8));
let b: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7];
assert_eq!(writer.get_ref(), b);
writer.seek(0, old_io::SeekSet).unwrap();
assert_eq!(writer.tell(), Ok(0));
- writer.write(&[3, 4]).unwrap();
+ writer.write_all(&[3, 4]).unwrap();
let b: &[_] = &[3, 4, 2, 3, 4, 5, 6, 7];
assert_eq!(writer.get_ref(), b);
writer.seek(1, old_io::SeekCur).unwrap();
- writer.write(&[0, 1]).unwrap();
+ writer.write_all(&[0, 1]).unwrap();
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 7];
assert_eq!(writer.get_ref(), b);
writer.seek(-1, old_io::SeekEnd).unwrap();
- writer.write(&[1, 2]).unwrap();
+ writer.write_all(&[1, 2]).unwrap();
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2];
assert_eq!(writer.get_ref(), b);
writer.seek(1, old_io::SeekEnd).unwrap();
- writer.write(&[1]).unwrap();
+ writer.write_all(&[1]).unwrap();
let b: &[_] = &[3, 4, 2, 0, 1, 5, 6, 1, 2, 0, 1];
assert_eq!(writer.get_ref(), b);
}
fn seek_past_end() {
let mut r = SeekableMemWriter::new();
r.seek(10, old_io::SeekSet).unwrap();
- assert!(r.write(&[3]).is_ok());
+ assert!(r.write_all(&[3]).is_ok());
}
#[test]
b.iter(|| {
let mut wr = SeekableMemWriter::new();
for _ in 0..times {
- wr.write(&src).unwrap();
+ wr.write_all(&src).unwrap();
}
let v = wr.unwrap();
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-//! Really Bad Markup Language (rbml) is a temporary measure until we migrate
-//! the rust object metadata to a better serialization format. It is not
-//! intended to be used by users.
+//! Really Bad Markup Language (rbml) is an internal serialization format of rustc.
+//! This is not intended to be used by users.
//!
-//! It is loosely based on the Extensible Binary Markup Language (ebml):
-//! http://www.matroska.org/technical/specs/rfc/index.html
+//! Originally based on the Extensible Binary Markup Language
+//! (ebml; http://www.matroska.org/technical/specs/rfc/index.html),
+//! it is now a separate format tuned for the rust object metadata.
+//!
+//! # Encoding
+//!
+//! RBML document consists of the tag, length and data.
+//! The encoded data can contain multiple RBML documents concatenated.
+//!
+//! **Tags** are a hint for the following data.
+//! Tags are a number from 0x000 to 0xfff, where 0xf0 through 0xff is reserved.
+//! Tags less than 0xf0 are encoded in one literal byte.
+//! Tags greater than 0xff are encoded in two big-endian bytes,
+//! where the tag number is ORed with 0xf000. (E.g. tag 0x123 = `f1 23`)
+//!
+//! **Lengths** encode the length of the following data.
+//! It is a variable-length unsigned int, and one of the following forms:
+//!
+//! - `80` through `fe` for lengths up to 0x7e;
+//! - `40 ff` through `7f ff` for lengths up to 0x3fff;
+//! - `20 40 00` through `3f ff ff` for lengths up to 0x1fffff;
+//! - `10 20 00 00` through `1f ff ff ff` for lengths up to 0xfffffff.
+//!
+//! The "overlong" form is allowed so that the length can be encoded
+//! without the prior knowledge of the encoded data.
+//! For example, the length 0 can be represented either by `80`, `40 00`,
+//! `20 00 00` or `10 00 00 00`.
+//! The encoder tries to minimize the length if possible.
+//! Also, some predefined tags listed below are so commonly used that
+//! their lengths are omitted ("implicit length").
+//!
+//! **Data** can be either binary bytes or zero or more nested RBML documents.
+//! Nested documents cannot overflow, and should be entirely contained
+//! within a parent document.
+//!
+//! # Predefined Tags
+//!
+//! Most RBML tags are defined by the application.
+//! (For the rust object metadata, see also `rustc::metadata::common`.)
+//! RBML itself does define a set of predefined tags however,
+//! intended for the auto-serialization implementation.
+//!
+//! Predefined tags with an implicit length:
+//!
+//! - `U8` (`00`): 1-byte unsigned integer.
+//! - `U16` (`01`): 2-byte big endian unsigned integer.
+//! - `U32` (`02`): 4-byte big endian unsigned integer.
+//! - `U64` (`03`): 8-byte big endian unsigned integer.
+//! Any of `U*` tags can be used to encode primitive unsigned integer types,
+//! as long as it is no greater than the actual size.
+//! For example, `u8` can only be represented via the `U8` tag.
+//!
+//! - `I8` (`04`): 1-byte signed integer.
+//! - `I16` (`05`): 2-byte big endian signed integer.
+//! - `I32` (`06`): 4-byte big endian signed integer.
+//! - `I64` (`07`): 8-byte big endian signed integer.
+//! Similar to `U*` tags. Always uses two's complement encoding.
+//!
+//! - `Bool` (`08`): 1-byte boolean value, `00` for false and `01` for true.
+//!
+//! - `Char` (`09`): 4-byte big endian Unicode scalar value.
+//! Surrogate pairs or out-of-bound values are invalid.
+//!
+//! - `F32` (`0a`): 4-byte big endian unsigned integer representing
+//! IEEE 754 binary32 floating-point format.
+//! - `F64` (`0b`): 8-byte big endian unsigned integer representing
+//! IEEE 754 binary64 floating-point format.
+//!
+//! - `Sub8` (`0c`): 1-byte unsigned integer for supplementary information.
+//! - `Sub32` (`0d`): 4-byte unsigned integer for supplementary information.
+//! Those two tags normally occur as the first subdocument of certain tags,
+//! namely `Enum`, `Vec` and `Map`, to provide a variant or size information.
+//! They can be used interchangably.
+//!
+//! Predefined tags with an explicit length:
+//!
+//! - `Str` (`10`): A UTF-8-encoded string.
+//!
+//! - `Enum` (`11`): An enum.
+//! The first subdocument should be `Sub*` tags with a variant ID.
+//! Subsequent subdocuments, if any, encode variant arguments.
+//!
+//! - `Vec` (`12`): A vector (sequence).
+//! - `VecElt` (`13`): A vector element.
+//! The first subdocument should be `Sub*` tags with the number of elements.
+//! Subsequent subdocuments should be `VecElt` tag per each element.
+//!
+//! - `Map` (`14`): A map (associated array).
+//! - `MapKey` (`15`): A key part of the map entry.
+//! - `MapVal` (`16`): A value part of the map entry.
+//! The first subdocument should be `Sub*` tags with the number of entries.
+//! Subsequent subdocuments should be an alternating sequence of
+//! `MapKey` and `MapVal` tags per each entry.
+//!
+//! - `Opaque` (`17`): An opaque, custom-format tag.
+//! Used to wrap ordinary custom tags or data in the auto-serialized context.
+//! Rustc typically uses this to encode type informations.
+//!
+//! First 0x20 tags are reserved by RBML; custom tags start at 0x20.
// Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
#![cfg_attr(stage0, feature(custom_attribute))]
reader::get_doc(*self, tag)
}
+ pub fn is_empty(&self) -> bool {
+ self.start == self.end
+ }
+
pub fn as_str_slice<'a>(&'a self) -> &'a str {
str::from_utf8(&self.data[self.start..self.end]).unwrap()
}
#[derive(Copy, Debug)]
pub enum EbmlEncoderTag {
- EsUint, // 0
- EsU64, // 1
- EsU32, // 2
- EsU16, // 3
- EsU8, // 4
- EsInt, // 5
- EsI64, // 6
- EsI32, // 7
- EsI16, // 8
- EsI8, // 9
- EsBool, // 10
- EsChar, // 11
- EsStr, // 12
- EsF64, // 13
- EsF32, // 14
- EsFloat, // 15
- EsEnum, // 16
- EsEnumVid, // 17
- EsEnumBody, // 18
- EsVec, // 19
- EsVecLen, // 20
- EsVecElt, // 21
- EsMap, // 22
- EsMapLen, // 23
- EsMapKey, // 24
- EsMapVal, // 25
-
- EsOpaque,
-
- EsLabel, // Used only when debugging
+ // tags 00..1f are reserved for auto-serialization.
+ // first NUM_IMPLICIT_TAGS tags are implicitly sized and lengths are not encoded.
+
+ EsU8 = 0x00, // + 1 byte
+ EsU16 = 0x01, // + 2 bytes
+ EsU32 = 0x02, // + 4 bytes
+ EsU64 = 0x03, // + 8 bytes
+ EsI8 = 0x04, // + 1 byte
+ EsI16 = 0x05, // + 2 bytes
+ EsI32 = 0x06, // + 4 bytes
+ EsI64 = 0x07, // + 8 bytes
+ EsBool = 0x08, // + 1 byte
+ EsChar = 0x09, // + 4 bytes
+ EsF32 = 0x0a, // + 4 bytes
+ EsF64 = 0x0b, // + 8 bytes
+ EsSub8 = 0x0c, // + 1 byte
+ EsSub32 = 0x0d, // + 4 bytes
+ // 0x0e and 0x0f are reserved
+
+ EsStr = 0x10,
+ EsEnum = 0x11, // encodes the variant id as the first EsSub*
+ EsVec = 0x12, // encodes the # of elements as the first EsSub*
+ EsVecElt = 0x13,
+ EsMap = 0x14, // encodes the # of pairs as the first EsSub*
+ EsMapKey = 0x15,
+ EsMapVal = 0x16,
+ EsOpaque = 0x17,
}
+const NUM_TAGS: uint = 0x1000;
+const NUM_IMPLICIT_TAGS: uint = 0x0e;
+
+static TAG_IMPLICIT_LEN: [i8; NUM_IMPLICIT_TAGS] = [
+ 1, 2, 4, 8, // EsU*
+ 1, 2, 4, 8, // ESI*
+ 1, // EsBool
+ 4, // EsChar
+ 4, 8, // EsF*
+ 1, 4, // EsSub*
+];
+
#[derive(Debug)]
pub enum Error {
IntTooBig(uint),
+ InvalidTag(uint),
Expected(String),
IoError(std::old_io::IoError),
ApplicationError(String)
use serialize;
- use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsVecLen, EsVecElt,
- EsMapLen, EsMapKey, EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64,
+ use super::{ ApplicationError, EsVec, EsMap, EsEnum, EsSub8, EsSub32,
+ EsVecElt, EsMapKey, EsU64, EsU32, EsU16, EsU8, EsI64,
EsI32, EsI16, EsI8, EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
- EsEnumBody, EsUint, EsOpaque, EsLabel, EbmlEncoderTag, Doc, TaggedDoc,
- Error, IntTooBig, Expected };
+ EsOpaque, EbmlEncoderTag, Doc, TaggedDoc,
+ Error, IntTooBig, InvalidTag, Expected, NUM_IMPLICIT_TAGS, TAG_IMPLICIT_LEN };
pub type DecodeResult<T> = Result<T, Error>;
// rbml reading
pub next: uint
}
+ pub fn tag_at(data: &[u8], start: uint) -> DecodeResult<Res> {
+ let v = data[start] as uint;
+ if v < 0xf0 {
+ Ok(Res { val: v, next: start + 1 })
+ } else if v > 0xf0 {
+ Ok(Res { val: ((v & 0xf) << 8) | data[start + 1] as uint, next: start + 2 })
+ } else {
+ // every tag starting with byte 0xf0 is an overlong form, which is prohibited.
+ Err(InvalidTag(v))
+ }
+ }
+
#[inline(never)]
fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
let a = data[start];
- if a & 0x80u8 != 0u8 {
- return Ok(Res {val: (a & 0x7fu8) as uint, next: start + 1});
+ if a & 0x80 != 0 {
+ return Ok(Res {val: (a & 0x7f) as uint, next: start + 1});
}
- if a & 0x40u8 != 0u8 {
- return Ok(Res {val: ((a & 0x3fu8) as uint) << 8 |
+ if a & 0x40 != 0 {
+ return Ok(Res {val: ((a & 0x3f) as uint) << 8 |
(data[start + 1] as uint),
next: start + 2});
}
- if a & 0x20u8 != 0u8 {
- return Ok(Res {val: ((a & 0x1fu8) as uint) << 16 |
+ if a & 0x20 != 0 {
+ return Ok(Res {val: ((a & 0x1f) as uint) << 16 |
(data[start + 1] as uint) << 8 |
(data[start + 2] as uint),
next: start + 3});
}
- if a & 0x10u8 != 0u8 {
- return Ok(Res {val: ((a & 0x0fu8) as uint) << 24 |
+ if a & 0x10 != 0 {
+ return Ok(Res {val: ((a & 0x0f) as uint) << 24 |
(data[start + 1] as uint) << 16 |
(data[start + 2] as uint) << 8 |
(data[start + 3] as uint),
}
}
+ pub fn tag_len_at(data: &[u8], tag: Res) -> DecodeResult<Res> {
+ if tag.val < NUM_IMPLICIT_TAGS && TAG_IMPLICIT_LEN[tag.val] >= 0 {
+ Ok(Res { val: TAG_IMPLICIT_LEN[tag.val] as uint, next: tag.next })
+ } else {
+ vuint_at(data, tag.next)
+ }
+ }
+
pub fn doc_at<'a>(data: &'a [u8], start: uint) -> DecodeResult<TaggedDoc<'a>> {
- let elt_tag = try!(vuint_at(data, start));
- let elt_size = try!(vuint_at(data, elt_tag.next));
+ let elt_tag = try!(tag_at(data, start));
+ let elt_size = try!(tag_len_at(data, elt_tag));
let end = elt_size.next + elt_size.val;
Ok(TaggedDoc {
tag: elt_tag.val,
pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: uint) -> Option<Doc<'a>> {
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), None);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), None);
+ let elt_tag = try_or!(tag_at(d.data, pos), None);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), None);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
return Some(Doc { data: d.data, start: elt_size.next,
{
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), false);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+ let elt_tag = try_or!(tag_at(d.data, pos), false);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
pos = elt_size.next + elt_size.val;
let doc = Doc { data: d.data, start: elt_size.next, end: pos };
if !it(elt_tag.val, doc) {
{
let mut pos = d.start;
while pos < d.end {
- let elt_tag = try_or!(vuint_at(d.data, pos), false);
- let elt_size = try_or!(vuint_at(d.data, elt_tag.next), false);
+ let elt_tag = try_or!(tag_at(d.data, pos), false);
+ let elt_size = try_or!(tag_len_at(d.data, elt_tag), false);
pos = elt_size.next + elt_size.val;
if elt_tag.val == tg {
let doc = Doc { data: d.data, start: elt_size.next,
}
}
- fn _check_label(&mut self, lbl: &str) -> DecodeResult<()> {
- if self.pos < self.parent.end {
- let TaggedDoc { tag: r_tag, doc: r_doc } =
- try!(doc_at(self.parent.data, self.pos));
-
- if r_tag == (EsLabel as uint) {
- self.pos = r_doc.end;
- let str = r_doc.as_str_slice();
- if lbl != str {
- return Err(Expected(format!("Expected label {:?} but \
- found {:?}", lbl, str)));
- }
- }
- }
- Ok(())
- }
-
fn next_doc(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<Doc<'doc>> {
debug!(". next_doc(exp_tag={:?})", exp_tag);
if self.pos >= self.parent.end {
Ok(r)
}
- fn _next_uint(&mut self, exp_tag: EbmlEncoderTag) -> DecodeResult<uint> {
- let r = doc_as_u32(try!(self.next_doc(exp_tag)));
- debug!("_next_uint exp_tag={:?} result={:?}", exp_tag, r);
- Ok(r as uint)
+ fn _next_sub(&mut self) -> DecodeResult<uint> {
+ // empty vector/map optimization
+ if self.parent.is_empty() {
+ return Ok(0);
+ }
+
+ let TaggedDoc { tag: r_tag, doc: r_doc } =
+ try!(doc_at(self.parent.data, self.pos));
+ let r = if r_tag == (EsSub8 as uint) {
+ doc_as_u8(r_doc) as uint
+ } else if r_tag == (EsSub32 as uint) {
+ doc_as_u32(r_doc) as uint
+ } else {
+ return Err(Expected(format!("expected EBML doc with tag {:?} or {:?} but \
+ found tag {:?}", EsSub8, EsSub32, r_tag)));
+ };
+ if r_doc.end > self.parent.end {
+ return Err(Expected(format!("invalid EBML, child extends to \
+ {:#x}, parent to {:#x}",
+ r_doc.end, self.parent.end)));
+ }
+ self.pos = r_doc.end;
+ debug!("_next_sub result={:?}", r);
+ Ok(r)
+ }
+
+ // variable-length unsigned integer with different tags.
+ // `first_tag` should be a tag for u8 or i8.
+ // `last_tag` should be the largest allowed integer tag with the matching signedness.
+ // all tags between them should be valid, in the order of u8, u16, u32 and u64.
+ fn _next_int(&mut self,
+ first_tag: EbmlEncoderTag,
+ last_tag: EbmlEncoderTag) -> DecodeResult<u64> {
+ if self.pos >= self.parent.end {
+ return Err(Expected(format!("no more documents in \
+ current node!")));
+ }
+
+ let TaggedDoc { tag: r_tag, doc: r_doc } =
+ try!(doc_at(self.parent.data, self.pos));
+ let r = if first_tag as uint <= r_tag && r_tag <= last_tag as uint {
+ match r_tag - first_tag as uint {
+ 0 => doc_as_u8(r_doc) as u64,
+ 1 => doc_as_u16(r_doc) as u64,
+ 2 => doc_as_u32(r_doc) as u64,
+ 3 => doc_as_u64(r_doc) as u64,
+ _ => unreachable!(),
+ }
+ } else {
+ return Err(Expected(format!("expected EBML doc with tag {:?} through {:?} but \
+ found tag {:?}", first_tag, last_tag, r_tag)));
+ };
+ if r_doc.end > self.parent.end {
+ return Err(Expected(format!("invalid EBML, child extends to \
+ {:#x}, parent to {:#x}",
+ r_doc.end, self.parent.end)));
+ }
+ self.pos = r_doc.end;
+ debug!("_next_int({:?}, {:?}) result={:?}", first_tag, last_tag, r);
+ Ok(r)
}
pub fn read_opaque<R, F>(&mut self, op: F) -> DecodeResult<R> where
type Error = Error;
fn read_nil(&mut self) -> DecodeResult<()> { Ok(()) }
- fn read_u64(&mut self) -> DecodeResult<u64> { Ok(doc_as_u64(try!(self.next_doc(EsU64)))) }
- fn read_u32(&mut self) -> DecodeResult<u32> { Ok(doc_as_u32(try!(self.next_doc(EsU32)))) }
- fn read_u16(&mut self) -> DecodeResult<u16> { Ok(doc_as_u16(try!(self.next_doc(EsU16)))) }
- fn read_u8 (&mut self) -> DecodeResult<u8 > { Ok(doc_as_u8 (try!(self.next_doc(EsU8 )))) }
+ fn read_u64(&mut self) -> DecodeResult<u64> { self._next_int(EsU8, EsU64) }
+ fn read_u32(&mut self) -> DecodeResult<u32> { Ok(try!(self._next_int(EsU8, EsU32)) as u32) }
+ fn read_u16(&mut self) -> DecodeResult<u16> { Ok(try!(self._next_int(EsU8, EsU16)) as u16) }
+ fn read_u8(&mut self) -> DecodeResult<u8> { Ok(doc_as_u8(try!(self.next_doc(EsU8)))) }
fn read_uint(&mut self) -> DecodeResult<uint> {
- let v = doc_as_u64(try!(self.next_doc(EsUint)));
+ let v = try!(self._next_int(EsU8, EsU64));
if v > (::std::usize::MAX as u64) {
Err(IntTooBig(v as uint))
} else {
}
}
- fn read_i64(&mut self) -> DecodeResult<i64> {
- Ok(doc_as_u64(try!(self.next_doc(EsI64))) as i64)
- }
- fn read_i32(&mut self) -> DecodeResult<i32> {
- Ok(doc_as_u32(try!(self.next_doc(EsI32))) as i32)
- }
- fn read_i16(&mut self) -> DecodeResult<i16> {
- Ok(doc_as_u16(try!(self.next_doc(EsI16))) as i16)
- }
- fn read_i8 (&mut self) -> DecodeResult<i8> {
- Ok(doc_as_u8(try!(self.next_doc(EsI8 ))) as i8)
- }
+ fn read_i64(&mut self) -> DecodeResult<i64> { Ok(try!(self._next_int(EsI8, EsI64)) as i64) }
+ fn read_i32(&mut self) -> DecodeResult<i32> { Ok(try!(self._next_int(EsI8, EsI32)) as i32) }
+ fn read_i16(&mut self) -> DecodeResult<i16> { Ok(try!(self._next_int(EsI8, EsI16)) as i16) }
+ fn read_i8(&mut self) -> DecodeResult<i8> { Ok(doc_as_u8(try!(self.next_doc(EsI8))) as i8) }
fn read_int(&mut self) -> DecodeResult<int> {
- let v = doc_as_u64(try!(self.next_doc(EsInt))) as i64;
+ let v = try!(self._next_int(EsI8, EsI64)) as i64;
if v > (isize::MAX as i64) || v < (isize::MIN as i64) {
debug!("FIXME \\#6122: Removing this makes this function miscompile");
Err(IntTooBig(v as uint))
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
{
debug!("read_enum({})", name);
- try!(self._check_label(name));
let doc = try!(self.next_doc(EsEnum));
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_variant()");
- let idx = try!(self._next_uint(EsEnumVid));
+ let idx = try!(self._next_sub());
debug!(" idx={}", idx);
- let doc = try!(self.next_doc(EsEnumBody));
-
- let (old_parent, old_pos) = (self.parent, self.pos);
- self.parent = doc;
- self.pos = self.parent.start;
-
- let result = try!(f(self, idx));
-
- self.parent = old_parent;
- self.pos = old_pos;
- Ok(result)
+ f(self, idx)
}
fn read_enum_variant_arg<T, F>(&mut self, idx: uint, f: F) -> DecodeResult<T> where
where F: FnMut(&mut Decoder<'doc>, uint) -> DecodeResult<T>,
{
debug!("read_enum_struct_variant()");
- let idx = try!(self._next_uint(EsEnumVid));
+ let idx = try!(self._next_sub());
debug!(" idx={}", idx);
- let doc = try!(self.next_doc(EsEnumBody));
-
- let (old_parent, old_pos) = (self.parent, self.pos);
- self.parent = doc;
- self.pos = self.parent.start;
-
- let result = try!(f(self, idx));
-
- self.parent = old_parent;
- self.pos = old_pos;
- Ok(result)
+ f(self, idx)
}
fn read_enum_struct_variant_field<T, F>(&mut self,
F: FnOnce(&mut Decoder<'doc>) -> DecodeResult<T>,
{
debug!("read_struct_field(name={}, idx={})", name, idx);
- try!(self._check_label(name));
f(self)
}
{
debug!("read_seq()");
self.push_doc(EsVec, move |d| {
- let len = try!(d._next_uint(EsVecLen));
+ let len = try!(d._next_sub());
debug!(" len={}", len);
f(d, len)
})
{
debug!("read_map()");
self.push_doc(EsMap, move |d| {
- let len = try!(d._next_uint(EsMapLen));
+ let len = try!(d._next_sub());
debug!(" len={}", len);
f(d, len)
})
use std::num::Int;
use std::old_io::{Writer, Seek};
use std::old_io;
+ use std::slice::bytes;
+ use std::num::ToPrimitive;
- use super::{ EsVec, EsMap, EsEnum, EsVecLen, EsVecElt, EsMapLen, EsMapKey,
- EsEnumVid, EsU64, EsU32, EsU16, EsU8, EsInt, EsI64, EsI32, EsI16, EsI8,
- EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal, EsEnumBody, EsUint,
- EsOpaque, EsLabel, EbmlEncoderTag };
+ use super::{ EsVec, EsMap, EsEnum, EsSub8, EsSub32, EsVecElt, EsMapKey,
+ EsU64, EsU32, EsU16, EsU8, EsI64, EsI32, EsI16, EsI8,
+ EsBool, EsF64, EsF32, EsChar, EsStr, EsMapVal,
+ EsOpaque, NUM_IMPLICIT_TAGS, NUM_TAGS };
+ use super::io::SeekableMemWriter;
use serialize;
pub type EncodeResult = old_io::IoResult<()>;
// rbml writing
- pub struct Encoder<'a, W:'a> {
- pub writer: &'a mut W,
+ pub struct Encoder<'a> {
+ pub writer: &'a mut SeekableMemWriter,
size_positions: Vec<uint>,
+ relax_limit: u64, // do not move encoded bytes before this position
+ }
+
+ fn write_tag<W: Writer>(w: &mut W, n: uint) -> EncodeResult {
+ if n < 0xf0 {
+ w.write_all(&[n as u8])
+ } else if 0x100 <= n && n < NUM_TAGS {
+ w.write_all(&[0xf0 | (n >> 8) as u8, n as u8])
+ } else {
+ Err(old_io::IoError {
+ kind: old_io::OtherIoError,
+ desc: "invalid tag",
+ detail: Some(format!("{}", n))
+ })
+ }
}
fn write_sized_vuint<W: Writer>(w: &mut W, n: uint, size: uint) -> EncodeResult {
match size {
- 1 => w.write_all(&[0x80u8 | (n as u8)]),
- 2 => w.write_all(&[0x40u8 | ((n >> 8) as u8), n as u8]),
- 3 => w.write_all(&[0x20u8 | ((n >> 16) as u8), (n >> 8) as u8,
+ 1 => w.write_all(&[0x80 | (n as u8)]),
+ 2 => w.write_all(&[0x40 | ((n >> 8) as u8), n as u8]),
+ 3 => w.write_all(&[0x20 | ((n >> 16) as u8), (n >> 8) as u8,
n as u8]),
- 4 => w.write_all(&[0x10u8 | ((n >> 24) as u8), (n >> 16) as u8,
+ 4 => w.write_all(&[0x10 | ((n >> 24) as u8), (n >> 16) as u8,
(n >> 8) as u8, n as u8]),
_ => Err(old_io::IoError {
kind: old_io::OtherIoError,
})
}
- impl<'a, W: Writer + Seek> Encoder<'a, W> {
- pub fn new(w: &'a mut W) -> Encoder<'a, W> {
+ impl<'a> Encoder<'a> {
+ pub fn new(w: &'a mut SeekableMemWriter) -> Encoder<'a> {
Encoder {
writer: w,
size_positions: vec!(),
+ relax_limit: 0,
}
}
/// FIXME(pcwalton): Workaround for badness in trans. DO NOT USE ME.
- pub unsafe fn unsafe_clone(&self) -> Encoder<'a, W> {
+ pub unsafe fn unsafe_clone(&self) -> Encoder<'a> {
Encoder {
writer: mem::transmute_copy(&self.writer),
size_positions: self.size_positions.clone(),
+ relax_limit: self.relax_limit,
}
}
pub fn start_tag(&mut self, tag_id: uint) -> EncodeResult {
debug!("Start tag {:?}", tag_id);
+ assert!(tag_id >= NUM_IMPLICIT_TAGS);
// Write the enum ID:
- try!(write_vuint(self.writer, tag_id));
+ try!(write_tag(self.writer, tag_id));
// Write a placeholder four-byte size.
self.size_positions.push(try!(self.writer.tell()) as uint);
- let zeroes: &[u8] = &[0u8, 0u8, 0u8, 0u8];
+ let zeroes: &[u8] = &[0, 0, 0, 0];
self.writer.write_all(zeroes)
}
let cur_pos = try!(self.writer.tell());
try!(self.writer.seek(last_size_pos as i64, old_io::SeekSet));
let size = cur_pos as uint - last_size_pos - 4;
- try!(write_sized_vuint(self.writer, size, 4));
- let r = try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+
+ // relax the size encoding for small tags (bigger tags are costly to move).
+ // we should never try to move the stable positions, however.
+ const RELAX_MAX_SIZE: uint = 0x100;
+ if size <= RELAX_MAX_SIZE && last_size_pos >= self.relax_limit as uint {
+ // we can't alter the buffer in place, so have a temporary buffer
+ let mut buf = [0u8; RELAX_MAX_SIZE];
+ {
+ let data = &self.writer.get_ref()[last_size_pos+4..cur_pos as uint];
+ bytes::copy_memory(&mut buf, data);
+ }
+
+ // overwrite the size and data and continue
+ try!(write_vuint(self.writer, size));
+ try!(self.writer.write_all(&buf[..size]));
+ } else {
+ // overwrite the size with an overlong encoding and skip past the data
+ try!(write_sized_vuint(self.writer, size, 4));
+ try!(self.writer.seek(cur_pos as i64, old_io::SeekSet));
+ }
debug!("End tag (size = {:?})", size);
- Ok(r)
+ Ok(())
}
pub fn wr_tag<F>(&mut self, tag_id: uint, blk: F) -> EncodeResult where
}
pub fn wr_tagged_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
- try!(write_vuint(self.writer, tag_id));
+ assert!(tag_id >= NUM_IMPLICIT_TAGS);
+ try!(write_tag(self.writer, tag_id));
try!(write_vuint(self.writer, b.len()));
self.writer.write_all(b)
}
self.wr_tagged_bytes(tag_id, v.as_bytes())
}
+ // for auto-serialization
+ fn wr_tagged_raw_bytes(&mut self, tag_id: uint, b: &[u8]) -> EncodeResult {
+ try!(write_tag(self.writer, tag_id));
+ self.writer.write_all(b)
+ }
+
+ fn wr_tagged_raw_u64(&mut self, tag_id: uint, v: u64) -> EncodeResult {
+ let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u32(&mut self, tag_id: uint, v: u32) -> EncodeResult{
+ let bytes: [u8; 4] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u16(&mut self, tag_id: uint, v: u16) -> EncodeResult {
+ let bytes: [u8; 2] = unsafe { mem::transmute(v.to_be()) };
+ self.wr_tagged_raw_bytes(tag_id, &bytes)
+ }
+
+ fn wr_tagged_raw_u8(&mut self, tag_id: uint, v: u8) -> EncodeResult {
+ self.wr_tagged_raw_bytes(tag_id, &[v])
+ }
+
+ fn wr_tagged_raw_i64(&mut self, tag_id: uint, v: i64) -> EncodeResult {
+ self.wr_tagged_raw_u64(tag_id, v as u64)
+ }
+
+ fn wr_tagged_raw_i32(&mut self, tag_id: uint, v: i32) -> EncodeResult {
+ self.wr_tagged_raw_u32(tag_id, v as u32)
+ }
+
+ fn wr_tagged_raw_i16(&mut self, tag_id: uint, v: i16) -> EncodeResult {
+ self.wr_tagged_raw_u16(tag_id, v as u16)
+ }
+
+ fn wr_tagged_raw_i8(&mut self, tag_id: uint, v: i8) -> EncodeResult {
+ self.wr_tagged_raw_bytes(tag_id, &[v as u8])
+ }
+
pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult {
debug!("Write {:?} bytes", b.len());
self.writer.write_all(b)
debug!("Write str: {:?}", s);
self.writer.write_all(s.as_bytes())
}
- }
-
- // FIXME (#2743): optionally perform "relaxations" on end_tag to more
- // efficiently encode sizes; this is a fixed point iteration
-
- // Set to true to generate more debugging in EBML code.
- // Totally lame approach.
- #[cfg(not(ndebug))]
- static DEBUG: bool = true;
- #[cfg(ndebug)]
- static DEBUG: bool = false;
- impl<'a, W: Writer + Seek> Encoder<'a, W> {
- // used internally to emit things like the vector length and so on
- fn _emit_tagged_uint(&mut self, t: EbmlEncoderTag, v: uint) -> EncodeResult {
- assert!(v <= 0xFFFF_FFFF);
- self.wr_tagged_u32(t as uint, v as u32)
+ /// Returns the current position while marking it stable, i.e.
+ /// generated bytes so far woundn't be affected by relaxation.
+ pub fn mark_stable_position(&mut self) -> u64 {
+ let pos = self.writer.tell().unwrap();
+ if self.relax_limit < pos {
+ self.relax_limit = pos;
+ }
+ pos
}
+ }
- fn _emit_label(&mut self, label: &str) -> EncodeResult {
- // There are various strings that we have access to, such as
- // the name of a record field, which do not actually appear in
- // the encoded EBML (normally). This is just for
- // efficiency. When debugging, though, we can emit such
- // labels and then they will be checked by decoder to
- // try and check panics more quickly.
- if DEBUG { self.wr_tagged_str(EsLabel as uint, label) }
- else { Ok(()) }
+ impl<'a> Encoder<'a> {
+ // used internally to emit things like the vector length and so on
+ fn _emit_tagged_sub(&mut self, v: uint) -> EncodeResult {
+ if let Some(v) = v.to_u8() {
+ self.wr_tagged_raw_u8(EsSub8 as uint, v)
+ } else if let Some(v) = v.to_u32() {
+ self.wr_tagged_raw_u32(EsSub32 as uint, v)
+ } else {
+ Err(old_io::IoError {
+ kind: old_io::OtherIoError,
+ desc: "length or variant id too big",
+ detail: Some(format!("{}", v))
+ })
+ }
}
pub fn emit_opaque<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder) -> EncodeResult,
{
try!(self.start_tag(EsOpaque as uint));
try!(f(self));
}
}
- impl<'a, W: Writer + Seek> serialize::Encoder for Encoder<'a, W> {
+ impl<'a> serialize::Encoder for Encoder<'a> {
type Error = old_io::IoError;
fn emit_nil(&mut self) -> EncodeResult {
}
fn emit_uint(&mut self, v: uint) -> EncodeResult {
- self.wr_tagged_u64(EsUint as uint, v as u64)
+ self.emit_u64(v as u64)
}
fn emit_u64(&mut self, v: u64) -> EncodeResult {
- self.wr_tagged_u64(EsU64 as uint, v)
+ match v.to_u32() {
+ Some(v) => self.emit_u32(v),
+ None => self.wr_tagged_raw_u64(EsU64 as uint, v)
+ }
}
fn emit_u32(&mut self, v: u32) -> EncodeResult {
- self.wr_tagged_u32(EsU32 as uint, v)
+ match v.to_u16() {
+ Some(v) => self.emit_u16(v),
+ None => self.wr_tagged_raw_u32(EsU32 as uint, v)
+ }
}
fn emit_u16(&mut self, v: u16) -> EncodeResult {
- self.wr_tagged_u16(EsU16 as uint, v)
+ match v.to_u8() {
+ Some(v) => self.emit_u8(v),
+ None => self.wr_tagged_raw_u16(EsU16 as uint, v)
+ }
}
fn emit_u8(&mut self, v: u8) -> EncodeResult {
- self.wr_tagged_u8(EsU8 as uint, v)
+ self.wr_tagged_raw_u8(EsU8 as uint, v)
}
fn emit_int(&mut self, v: int) -> EncodeResult {
- self.wr_tagged_i64(EsInt as uint, v as i64)
+ self.emit_i64(v as i64)
}
fn emit_i64(&mut self, v: i64) -> EncodeResult {
- self.wr_tagged_i64(EsI64 as uint, v)
+ match v.to_i32() {
+ Some(v) => self.emit_i32(v),
+ None => self.wr_tagged_raw_i64(EsI64 as uint, v)
+ }
}
fn emit_i32(&mut self, v: i32) -> EncodeResult {
- self.wr_tagged_i32(EsI32 as uint, v)
+ match v.to_i16() {
+ Some(v) => self.emit_i16(v),
+ None => self.wr_tagged_raw_i32(EsI32 as uint, v)
+ }
}
fn emit_i16(&mut self, v: i16) -> EncodeResult {
- self.wr_tagged_i16(EsI16 as uint, v)
+ match v.to_i8() {
+ Some(v) => self.emit_i8(v),
+ None => self.wr_tagged_raw_i16(EsI16 as uint, v)
+ }
}
fn emit_i8(&mut self, v: i8) -> EncodeResult {
- self.wr_tagged_i8(EsI8 as uint, v)
+ self.wr_tagged_raw_i8(EsI8 as uint, v)
}
fn emit_bool(&mut self, v: bool) -> EncodeResult {
- self.wr_tagged_u8(EsBool as uint, v as u8)
+ self.wr_tagged_raw_u8(EsBool as uint, v as u8)
}
fn emit_f64(&mut self, v: f64) -> EncodeResult {
let bits = unsafe { mem::transmute(v) };
- self.wr_tagged_u64(EsF64 as uint, bits)
+ self.wr_tagged_raw_u64(EsF64 as uint, bits)
}
fn emit_f32(&mut self, v: f32) -> EncodeResult {
let bits = unsafe { mem::transmute(v) };
- self.wr_tagged_u32(EsF32 as uint, bits)
+ self.wr_tagged_raw_u32(EsF32 as uint, bits)
}
fn emit_char(&mut self, v: char) -> EncodeResult {
- self.wr_tagged_u32(EsChar as uint, v as u32)
+ self.wr_tagged_raw_u32(EsChar as uint, v as u32)
}
fn emit_str(&mut self, v: &str) -> EncodeResult {
self.wr_tagged_str(EsStr as uint, v)
}
- fn emit_enum<F>(&mut self, name: &str, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ fn emit_enum<F>(&mut self, _name: &str, f: F) -> EncodeResult where
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_label(name));
try!(self.start_tag(EsEnum as uint));
try!(f(self));
self.end_tag()
v_id: uint,
_: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_tagged_uint(EsEnumVid, v_id));
- try!(self.start_tag(EsEnumBody as uint));
- try!(f(self));
- self.end_tag()
+ try!(self._emit_tagged_sub(v_id));
+ f(self)
}
fn emit_enum_variant_arg<F>(&mut self, _: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
f(self)
}
v_id: uint,
cnt: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant(v_name, v_id, cnt, f)
}
_: &str,
idx: uint,
f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant_arg(idx, f)
}
fn emit_struct<F>(&mut self, _: &str, _len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
f(self)
}
- fn emit_struct_field<F>(&mut self, name: &str, _: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ fn emit_struct_field<F>(&mut self, _name: &str, _: uint, f: F) -> EncodeResult where
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
- try!(self._emit_label(name));
f(self)
}
fn emit_tuple<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq(len, f)
}
fn emit_tuple_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq_elt(idx, f)
}
fn emit_tuple_struct<F>(&mut self, _: &str, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq(len, f)
}
fn emit_tuple_struct_arg<F>(&mut self, idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_seq_elt(idx, f)
}
fn emit_option<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum("Option", f)
}
self.emit_enum_variant("None", 0, 0, |_| Ok(()))
}
fn emit_option_some<F>(&mut self, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
self.emit_enum_variant("Some", 1, 1, f)
}
fn emit_seq<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
+ if len == 0 {
+ // empty vector optimization
+ return self.wr_tagged_bytes(EsVec as uint, &[]);
+ }
try!(self.start_tag(EsVec as uint));
- try!(self._emit_tagged_uint(EsVecLen, len));
+ try!(self._emit_tagged_sub(len));
try!(f(self));
self.end_tag()
}
fn emit_seq_elt<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsVecElt as uint));
}
fn emit_map<F>(&mut self, len: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
+ if len == 0 {
+ // empty map optimization
+ return self.wr_tagged_bytes(EsMap as uint, &[]);
+ }
try!(self.start_tag(EsMap as uint));
- try!(self._emit_tagged_uint(EsMapLen, len));
+ try!(self._emit_tagged_sub(len));
try!(f(self));
self.end_tag()
}
fn emit_map_elt_key<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsMapKey as uint));
}
fn emit_map_elt_val<F>(&mut self, _idx: uint, f: F) -> EncodeResult where
- F: FnOnce(&mut Encoder<'a, W>) -> EncodeResult,
+ F: FnOnce(&mut Encoder<'a>) -> EncodeResult,
{
try!(self.start_tag(EsMapVal as uint));
try!(f(self));
#[bench]
pub fn vuint_at_A_aligned(b: &mut Bencher) {
- let data = (0i32..4*100).map(|i| {
+ let data = (0..4*100).map(|i| {
match i % 2 {
- 0 => 0x80u8,
+ 0 => 0x80,
_ => i as u8,
}
}).collect::<Vec<_>>();
#[bench]
pub fn vuint_at_A_unaligned(b: &mut Bencher) {
- let data = (0i32..4*100+1).map(|i| {
+ let data = (0..4*100+1).map(|i| {
match i % 2 {
- 1 => 0x80u8,
+ 1 => 0x80,
_ => i as u8
}
}).collect::<Vec<_>>();
#[bench]
pub fn vuint_at_D_aligned(b: &mut Bencher) {
- let data = (0i32..4*100).map(|i| {
+ let data = (0..4*100).map(|i| {
match i % 4 {
- 0 => 0x10u8,
+ 0 => 0x10,
3 => i as u8,
- _ => 0u8
+ _ => 0
}
}).collect::<Vec<_>>();
let mut sum = 0;
#[bench]
pub fn vuint_at_D_unaligned(b: &mut Bencher) {
- let data = (0i32..4*100+1).map(|i| {
+ let data = (0..4*100+1).map(|i| {
match i % 4 {
- 1 => 0x10u8,
+ 1 => 0x10,
0 => i as u8,
- _ => 0u8
+ _ => 0
}
}).collect::<Vec<_>>();
let mut sum = 0;
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(os)]
+#![feature(path)]
+#![feature(io)]
+#![feature(path_ext)]
#![cfg_attr(test, feature(test))]
extern crate arena;
extern crate flate;
})
}
- // FIXME(#10894) should continue recursing
fn visit_ty(&mut self, t: &ast::Ty) {
run_lints!(self, check_ty, t);
+ visit::walk_ty(self, t);
}
fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
use back::svh::Svh;
-// EBML enum definitions and utils shared by the encoder and decoder
+// RBML enum definitions and utils shared by the encoder and decoder
+//
+// 0x00..0x1f: reserved for RBML generic type tags
+// 0x20..0xef: free for use, preferred for frequent tags
+// 0xf0..0xff: internally used by RBML to encode 0x100..0xfff in two bytes
+// 0x100..0xfff: free for use, preferred for infrequent tags
-pub const tag_items: uint = 0x00;
+pub const tag_items: uint = 0x100; // top-level only
-pub const tag_paths_data_name: uint = 0x01;
+pub const tag_paths_data_name: uint = 0x20;
-pub const tag_def_id: uint = 0x02;
+pub const tag_def_id: uint = 0x21;
-pub const tag_items_data: uint = 0x03;
+pub const tag_items_data: uint = 0x22;
-pub const tag_items_data_item: uint = 0x04;
+pub const tag_items_data_item: uint = 0x23;
-pub const tag_items_data_item_family: uint = 0x05;
+pub const tag_items_data_item_family: uint = 0x24;
-pub const tag_items_data_item_type: uint = 0x07;
+pub const tag_items_data_item_type: uint = 0x25;
-pub const tag_items_data_item_symbol: uint = 0x08;
+pub const tag_items_data_item_symbol: uint = 0x26;
-pub const tag_items_data_item_variant: uint = 0x09;
+pub const tag_items_data_item_variant: uint = 0x27;
-pub const tag_items_data_parent_item: uint = 0x0a;
+pub const tag_items_data_parent_item: uint = 0x28;
-pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x0b;
+pub const tag_items_data_item_is_tuple_struct_ctor: uint = 0x29;
-pub const tag_index: uint = 0x0c;
+pub const tag_index: uint = 0x2a;
-pub const tag_index_buckets: uint = 0x0d;
+pub const tag_index_buckets: uint = 0x2b;
-pub const tag_index_buckets_bucket: uint = 0x0e;
+pub const tag_index_buckets_bucket: uint = 0x2c;
-pub const tag_index_buckets_bucket_elt: uint = 0x0f;
+pub const tag_index_buckets_bucket_elt: uint = 0x2d;
-pub const tag_index_table: uint = 0x10;
+pub const tag_index_table: uint = 0x2e;
-pub const tag_meta_item_name_value: uint = 0x11;
+pub const tag_meta_item_name_value: uint = 0x2f;
-pub const tag_meta_item_name: uint = 0x12;
+pub const tag_meta_item_name: uint = 0x30;
-pub const tag_meta_item_value: uint = 0x13;
+pub const tag_meta_item_value: uint = 0x31;
-pub const tag_attributes: uint = 0x14;
+pub const tag_attributes: uint = 0x101; // top-level only
-pub const tag_attribute: uint = 0x15;
+pub const tag_attribute: uint = 0x32;
-pub const tag_meta_item_word: uint = 0x16;
+pub const tag_meta_item_word: uint = 0x33;
-pub const tag_meta_item_list: uint = 0x17;
+pub const tag_meta_item_list: uint = 0x34;
// The list of crates that this crate depends on
-pub const tag_crate_deps: uint = 0x18;
+pub const tag_crate_deps: uint = 0x102; // top-level only
// A single crate dependency
-pub const tag_crate_dep: uint = 0x19;
+pub const tag_crate_dep: uint = 0x35;
-pub const tag_crate_hash: uint = 0x1a;
-pub const tag_crate_crate_name: uint = 0x1b;
+pub const tag_crate_hash: uint = 0x103; // top-level only
+pub const tag_crate_crate_name: uint = 0x104; // top-level only
-pub const tag_crate_dep_crate_name: uint = 0x1d;
-pub const tag_crate_dep_hash: uint = 0x1e;
+pub const tag_crate_dep_crate_name: uint = 0x36;
+pub const tag_crate_dep_hash: uint = 0x37;
-pub const tag_mod_impl: uint = 0x1f;
+pub const tag_mod_impl: uint = 0x38;
-pub const tag_item_trait_item: uint = 0x20;
+pub const tag_item_trait_item: uint = 0x39;
-pub const tag_item_trait_ref: uint = 0x21;
-pub const tag_item_super_trait_ref: uint = 0x22;
+pub const tag_item_trait_ref: uint = 0x3a;
// discriminator value for variants
-pub const tag_disr_val: uint = 0x23;
+pub const tag_disr_val: uint = 0x3c;
// used to encode ast_map::PathElem
-pub const tag_path: uint = 0x24;
-pub const tag_path_len: uint = 0x25;
-pub const tag_path_elem_mod: uint = 0x26;
-pub const tag_path_elem_name: uint = 0x27;
-pub const tag_item_field: uint = 0x28;
-pub const tag_item_field_origin: uint = 0x29;
-
-pub const tag_item_variances: uint = 0x2a;
+pub const tag_path: uint = 0x3d;
+pub const tag_path_len: uint = 0x3e;
+pub const tag_path_elem_mod: uint = 0x3f;
+pub const tag_path_elem_name: uint = 0x40;
+pub const tag_item_field: uint = 0x41;
+pub const tag_item_field_origin: uint = 0x42;
+
+pub const tag_item_variances: uint = 0x43;
/*
trait items contain tag_item_trait_item elements,
impl items contain tag_item_impl_item elements, and classes
both, tag_item_trait_item and tag_item_impl_item have to be two
different tags.
*/
-pub const tag_item_impl_item: uint = 0x30;
-pub const tag_item_trait_method_explicit_self: uint = 0x31;
+pub const tag_item_impl_item: uint = 0x44;
+pub const tag_item_trait_method_explicit_self: uint = 0x45;
// Reexports are found within module tags. Each reexport contains def_ids
// and names.
-pub const tag_items_data_item_reexport: uint = 0x38;
-pub const tag_items_data_item_reexport_def_id: uint = 0x39;
-pub const tag_items_data_item_reexport_name: uint = 0x3a;
+pub const tag_items_data_item_reexport: uint = 0x46;
+pub const tag_items_data_item_reexport_def_id: uint = 0x47;
+pub const tag_items_data_item_reexport_name: uint = 0x48;
// used to encode crate_ctxt side tables
#[derive(Copy, PartialEq, FromPrimitive)]
#[repr(uint)]
-pub enum astencode_tag { // Reserves 0x40 -- 0x5f
- tag_ast = 0x40,
-
- tag_tree = 0x41,
-
- tag_id_range = 0x42,
-
- tag_table = 0x43,
- tag_table_id = 0x44,
- tag_table_val = 0x45,
- tag_table_def = 0x46,
- tag_table_node_type = 0x47,
- tag_table_item_subst = 0x48,
- tag_table_freevars = 0x49,
- tag_table_tcache = 0x4a,
- tag_table_param_defs = 0x4b,
- tag_table_mutbl = 0x4c,
- tag_table_last_use = 0x4d,
- tag_table_spill = 0x4e,
- tag_table_method_map = 0x4f,
- tag_table_vtable_map = 0x50,
- tag_table_adjustments = 0x51,
- tag_table_moves_map = 0x52,
- tag_table_capture_map = 0x53,
- tag_table_closure_tys = 0x54,
- tag_table_closure_kinds = 0x55,
- tag_table_upvar_capture_map = 0x56,
- tag_table_capture_modes = 0x57,
- tag_table_object_cast_map = 0x58,
- tag_table_const_qualif = 0x59,
+pub enum astencode_tag { // Reserves 0x50 -- 0x6f
+ tag_ast = 0x50,
+
+ tag_tree = 0x51,
+
+ tag_id_range = 0x52,
+
+ tag_table = 0x53,
+ // GAP 0x54, 0x55
+ tag_table_def = 0x56,
+ tag_table_node_type = 0x57,
+ tag_table_item_subst = 0x58,
+ tag_table_freevars = 0x59,
+ tag_table_tcache = 0x5a,
+ tag_table_param_defs = 0x5b,
+ tag_table_mutbl = 0x5c,
+ tag_table_last_use = 0x5d,
+ tag_table_spill = 0x5e,
+ tag_table_method_map = 0x5f,
+ tag_table_vtable_map = 0x60,
+ tag_table_adjustments = 0x61,
+ tag_table_moves_map = 0x62,
+ tag_table_capture_map = 0x63,
+ tag_table_closure_tys = 0x64,
+ tag_table_closure_kinds = 0x65,
+ tag_table_upvar_capture_map = 0x66,
+ tag_table_capture_modes = 0x67,
+ tag_table_object_cast_map = 0x68,
+ tag_table_const_qualif = 0x69,
}
-pub const tag_item_trait_item_sort: uint = 0x60;
+pub const tag_item_trait_item_sort: uint = 0x70;
-pub const tag_item_trait_parent_sort: uint = 0x61;
+pub const tag_item_trait_parent_sort: uint = 0x71;
-pub const tag_item_impl_type_basename: uint = 0x62;
+pub const tag_item_impl_type_basename: uint = 0x72;
-pub const tag_crate_triple: uint = 0x66;
+pub const tag_crate_triple: uint = 0x105; // top-level only
-pub const tag_dylib_dependency_formats: uint = 0x67;
+pub const tag_dylib_dependency_formats: uint = 0x106; // top-level only
// Language items are a top-level directory (for speed). Hierarchy:
//
// - tag_lang_items_item_id: u32
// - tag_lang_items_item_node_id: u32
-pub const tag_lang_items: uint = 0x70;
-pub const tag_lang_items_item: uint = 0x71;
-pub const tag_lang_items_item_id: uint = 0x72;
-pub const tag_lang_items_item_node_id: uint = 0x73;
-pub const tag_lang_items_missing: uint = 0x74;
+pub const tag_lang_items: uint = 0x107; // top-level only
+pub const tag_lang_items_item: uint = 0x73;
+pub const tag_lang_items_item_id: uint = 0x74;
+pub const tag_lang_items_item_node_id: uint = 0x75;
+pub const tag_lang_items_missing: uint = 0x76;
-pub const tag_item_unnamed_field: uint = 0x75;
-pub const tag_items_data_item_visibility: uint = 0x76;
+pub const tag_item_unnamed_field: uint = 0x77;
+pub const tag_items_data_item_visibility: uint = 0x78;
pub const tag_item_method_tps: uint = 0x79;
pub const tag_item_method_fty: uint = 0x7a;
pub const tag_mod_child: uint = 0x7b;
-pub const tag_misc_info: uint = 0x7c;
-pub const tag_misc_info_crate_items: uint = 0x7d;
-
-pub const tag_item_method_provided_source: uint = 0x7e;
-pub const tag_item_impl_vtables: uint = 0x7f;
-
-pub const tag_impls: uint = 0x80;
-pub const tag_impls_impl: uint = 0x81;
+pub const tag_misc_info: uint = 0x108; // top-level only
+pub const tag_misc_info_crate_items: uint = 0x7c;
-pub const tag_items_data_item_inherent_impl: uint = 0x82;
-pub const tag_items_data_item_extension_impl: uint = 0x83;
+pub const tag_item_method_provided_source: uint = 0x7d;
+pub const tag_item_impl_vtables: uint = 0x7e;
-// GAP 0x84, 0x85, 0x86
+pub const tag_impls: uint = 0x109; // top-level only
+pub const tag_impls_impl: uint = 0x7f;
-pub const tag_native_libraries: uint = 0x87;
-pub const tag_native_libraries_lib: uint = 0x88;
-pub const tag_native_libraries_name: uint = 0x89;
-pub const tag_native_libraries_kind: uint = 0x8a;
+pub const tag_items_data_item_inherent_impl: uint = 0x80;
+pub const tag_items_data_item_extension_impl: uint = 0x81;
-pub const tag_plugin_registrar_fn: uint = 0x8b;
+pub const tag_native_libraries: uint = 0x10a; // top-level only
+pub const tag_native_libraries_lib: uint = 0x82;
+pub const tag_native_libraries_name: uint = 0x83;
+pub const tag_native_libraries_kind: uint = 0x84;
-// GAP 0x8c, 0x8d
+pub const tag_plugin_registrar_fn: uint = 0x10b; // top-level only
-pub const tag_method_argument_names: uint = 0x8e;
-pub const tag_method_argument_name: uint = 0x8f;
+pub const tag_method_argument_names: uint = 0x85;
+pub const tag_method_argument_name: uint = 0x86;
-pub const tag_reachable_extern_fns: uint = 0x90;
-pub const tag_reachable_extern_fn_id: uint = 0x91;
+pub const tag_reachable_extern_fns: uint = 0x10c; // top-level only
+pub const tag_reachable_extern_fn_id: uint = 0x87;
-pub const tag_items_data_item_stability: uint = 0x92;
+pub const tag_items_data_item_stability: uint = 0x88;
-pub const tag_items_data_item_repr: uint = 0x93;
+pub const tag_items_data_item_repr: uint = 0x89;
#[derive(Clone, Debug)]
pub struct LinkMeta {
pub crate_hash: Svh,
}
-// GAP 0x94...0x98
+pub const tag_struct_fields: uint = 0x10d; // top-level only
+pub const tag_struct_field: uint = 0x8a;
+pub const tag_struct_field_id: uint = 0x8b;
-pub const tag_struct_fields: uint = 0x99;
-pub const tag_struct_field: uint = 0x9a;
-pub const tag_struct_field_id: uint = 0x9b;
+pub const tag_attribute_is_sugared_doc: uint = 0x8c;
-pub const tag_attribute_is_sugared_doc: uint = 0x9c;
+pub const tag_items_data_region: uint = 0x8e;
-pub const tag_trait_def_bounds: uint = 0x9d;
+pub const tag_region_param_def: uint = 0x8f;
+pub const tag_region_param_def_ident: uint = 0x90;
+pub const tag_region_param_def_def_id: uint = 0x91;
+pub const tag_region_param_def_space: uint = 0x92;
+pub const tag_region_param_def_index: uint = 0x93;
-pub const tag_items_data_region: uint = 0x9e;
+pub const tag_type_param_def: uint = 0x94;
-pub const tag_region_param_def: uint = 0xa0;
-pub const tag_region_param_def_ident: uint = 0xa1;
-pub const tag_region_param_def_def_id: uint = 0xa2;
-pub const tag_region_param_def_space: uint = 0xa3;
-pub const tag_region_param_def_index: uint = 0xa4;
+pub const tag_item_generics: uint = 0x95;
+pub const tag_method_ty_generics: uint = 0x96;
-pub const tag_type_param_def: uint = 0xa5;
+pub const tag_predicate: uint = 0x97;
+pub const tag_predicate_space: uint = 0x98;
+pub const tag_predicate_data: uint = 0x99;
-pub const tag_item_generics: uint = 0xa6;
-pub const tag_method_ty_generics: uint = 0xa7;
+pub const tag_unsafety: uint = 0x9a;
-pub const tag_predicate: uint = 0xa8;
-pub const tag_predicate_space: uint = 0xa9;
-pub const tag_predicate_data: uint = 0xb0;
+pub const tag_associated_type_names: uint = 0x9b;
+pub const tag_associated_type_name: uint = 0x9c;
-pub const tag_unsafety: uint = 0xb1;
+pub const tag_polarity: uint = 0x9d;
-pub const tag_associated_type_names: uint = 0xb2;
-pub const tag_associated_type_name: uint = 0xb3;
+pub const tag_macro_defs: uint = 0x10e; // top-level only
+pub const tag_macro_def: uint = 0x9e;
+pub const tag_macro_def_body: uint = 0x9f;
-pub const tag_polarity: uint = 0xb4;
+pub const tag_paren_sugar: uint = 0xa0;
-pub const tag_macro_defs: uint = 0xb5;
-pub const tag_macro_def: uint = 0xb6;
-pub const tag_macro_def_body: uint = 0xb7;
+pub const tag_codemap: uint = 0xa1;
+pub const tag_codemap_filemap: uint = 0xa2;
-pub const tag_paren_sugar: uint = 0xb8;
+pub const tag_item_super_predicates: uint = 0xa3;
use metadata::loader;
use metadata::loader::CratePaths;
+use std::path::{Path, PathBuf};
use std::rc::Rc;
use syntax::ast;
use syntax::abi;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
-use syntax::codemap::{Span, mk_sp};
+use syntax::codemap::{self, Span, mk_sp, Pos};
use syntax::parse;
use syntax::parse::token::InternedString;
use syntax::parse::token;
// Extra info about a crate loaded for plugins or exported macros.
struct ExtensionCrate {
metadata: PMDSource,
- dylib: Option<Path>,
+ dylib: Option<PathBuf>,
target_only: bool,
}
// Maintain a reference to the top most crate.
let root = if root.is_some() { root } else { &crate_paths };
- let cnum_map = self.resolve_crate_deps(root, lib.metadata.as_slice(), span);
+ let loader::Library { dylib, rlib, metadata } = lib;
- let loader::Library{ dylib, rlib, metadata } = lib;
+ let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), span);
+ let codemap_import_info = import_codemap(self.sess.codemap(), &metadata);
let cmeta = Rc::new( cstore::crate_metadata {
name: name.to_string(),
data: metadata,
cnum_map: cnum_map,
cnum: cnum,
+ codemap_import_info: codemap_import_info,
span: span,
});
// overridden in plugin/load.rs
export: false,
use_locally: false,
+ allow_internal_unstable: false,
body: body,
});
}
/// Look for a plugin registrar. Returns library path and symbol name.
- pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(Path, String)> {
+ pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
+ -> Option<(PathBuf, String)> {
let ekrate = self.read_extension_crate(span, &CrateInfo {
name: name.to_string(),
ident: name.to_string(),
.map(|id| decoder::get_symbol(ekrate.metadata.as_slice(), id));
match (ekrate.dylib.as_ref(), registrar) {
- (Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
+ (Some(dylib), Some(reg)) => Some((dylib.to_path_buf(), reg)),
(None, Some(_)) => {
let message = format!("plugin `{}` only found in rlib format, \
but must be available in dylib format",
}
}
}
+
+/// Imports the codemap from an external crate into the codemap of the crate
+/// currently being compiled (the "local crate").
+///
+/// The import algorithm works analogous to how AST items are inlined from an
+/// external crate's metadata:
+/// For every FileMap in the external codemap an 'inline' copy is created in the
+/// local codemap. The correspondence relation between external and local
+/// FileMaps is recorded in the `ImportedFileMap` objects returned from this
+/// function. When an item from an external crate is later inlined into this
+/// crate, this correspondence information is used to translate the span
+/// information of the inlined item so that it refers the correct positions in
+/// the local codemap (see `astencode::DecodeContext::tr_span()`).
+///
+/// The import algorithm in the function below will reuse FileMaps already
+/// existing in the local codemap. For example, even if the FileMap of some
+/// source file of libstd gets imported many times, there will only ever be
+/// one FileMap object for the corresponding file in the local codemap.
+///
+/// Note that imported FileMaps do not actually contain the source code of the
+/// file they represent, just information about length, line breaks, and
+/// multibyte characters. This information is enough to generate valid debuginfo
+/// for items inlined from other crates.
+fn import_codemap(local_codemap: &codemap::CodeMap,
+ metadata: &MetadataBlob)
+ -> Vec<cstore::ImportedFileMap> {
+ let external_codemap = decoder::get_imported_filemaps(metadata.as_slice());
+
+ let imported_filemaps = external_codemap.into_iter().map(|filemap_to_import| {
+ // Try to find an existing FileMap that can be reused for the filemap to
+ // be imported. A FileMap is reusable if it is exactly the same, just
+ // positioned at a different offset within the codemap.
+ let reusable_filemap = {
+ local_codemap.files
+ .borrow()
+ .iter()
+ .find(|fm| are_equal_modulo_startpos(&fm, &filemap_to_import))
+ .map(|rc| rc.clone())
+ };
+
+ match reusable_filemap {
+ Some(fm) => {
+ cstore::ImportedFileMap {
+ original_start_pos: filemap_to_import.start_pos,
+ original_end_pos: filemap_to_import.end_pos,
+ translated_filemap: fm
+ }
+ }
+ None => {
+ // We can't reuse an existing FileMap, so allocate a new one
+ // containing the information we need.
+ let codemap::FileMap {
+ name,
+ start_pos,
+ end_pos,
+ lines,
+ multibyte_chars,
+ ..
+ } = filemap_to_import;
+
+ let source_length = (end_pos - start_pos).to_usize();
+
+ // Translate line-start positions and multibyte character
+ // position into frame of reference local to file.
+ // `CodeMap::new_imported_filemap()` will then translate those
+ // coordinates to their new global frame of reference when the
+ // offset of the FileMap is known.
+ let lines = lines.into_inner().map_in_place(|pos| pos - start_pos);
+ let multibyte_chars = multibyte_chars
+ .into_inner()
+ .map_in_place(|mbc|
+ codemap::MultiByteChar {
+ pos: mbc.pos + start_pos,
+ bytes: mbc.bytes
+ });
+
+ let local_version = local_codemap.new_imported_filemap(name,
+ source_length,
+ lines,
+ multibyte_chars);
+ cstore::ImportedFileMap {
+ original_start_pos: start_pos,
+ original_end_pos: end_pos,
+ translated_filemap: local_version
+ }
+ }
+ }
+ }).collect();
+
+ return imported_filemaps;
+
+ fn are_equal_modulo_startpos(fm1: &codemap::FileMap,
+ fm2: &codemap::FileMap)
+ -> bool {
+ if fm1.name != fm2.name {
+ return false;
+ }
+
+ let lines1 = fm1.lines.borrow();
+ let lines2 = fm2.lines.borrow();
+
+ if lines1.len() != lines2.len() {
+ return false;
+ }
+
+ for (&line1, &line2) in lines1.iter().zip(lines2.iter()) {
+ if (line1 - fm1.start_pos) != (line2 - fm2.start_pos) {
+ return false;
+ }
+ }
+
+ let multibytes1 = fm1.multibyte_chars.borrow();
+ let multibytes2 = fm2.multibyte_chars.borrow();
+
+ if multibytes1.len() != multibytes2.len() {
+ return false;
+ }
+
+ for (mb1, mb2) in multibytes1.iter().zip(multibytes2.iter()) {
+ if (mb1.bytes != mb2.bytes) ||
+ ((mb1.pos - fm1.start_pos) != (mb2.pos - fm2.start_pos)) {
+ return false;
+ }
+ }
+
+ true
+ }
+}
decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
}
-pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>,
- def: ast::DefId)
- -> Vec<Rc<ty::TraitRef<'tcx>>> {
- let cstore = &tcx.sess.cstore;
- let cdata = cstore.get_crate_data(def.krate);
- decoder::get_supertraits(&*cdata, def.node, tcx)
-}
-
pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId)
-> Option<ast::Name> {
let cdata = cstore.get_crate_data(def.krate);
decoder::get_predicates(&*cdata, def.node, tcx)
}
+pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
+ -> ty::GenericPredicates<'tcx>
+{
+ let cstore = &tcx.sess.cstore;
+ let cdata = cstore.get_crate_data(def.krate);
+ decoder::get_super_predicates(&*cdata, def.node, tcx)
+}
+
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
def: ast::DefId) -> ty::TypeScheme<'tcx> {
let cstore = &tcx.sess.cstore;
use std::cell::RefCell;
use std::rc::Rc;
+use std::path::PathBuf;
use flate::Bytes;
use syntax::ast;
-use syntax::codemap::Span;
+use syntax::codemap;
use syntax::parse::token::IdentInterner;
// A map from external crate numbers (as decoded from some crate file) to
MetadataArchive(loader::ArchiveMetadata),
}
+/// Holds information about a codemap::FileMap imported from another crate.
+/// See creader::import_codemap() for more information.
+pub struct ImportedFileMap {
+ /// This FileMap's byte-offset within the codemap of its original crate
+ pub original_start_pos: codemap::BytePos,
+ /// The end of this FileMap within the codemap of its original crate
+ pub original_end_pos: codemap::BytePos,
+ /// The imported FileMap's representation within the local codemap
+ pub translated_filemap: Rc<codemap::FileMap>
+}
+
pub struct crate_metadata {
pub name: String,
pub data: MetadataBlob,
pub cnum_map: cnum_map,
pub cnum: ast::CrateNum,
- pub span: Span,
+ pub codemap_import_info: Vec<ImportedFileMap>,
+ pub span: codemap::Span,
}
#[derive(Copy, Debug, PartialEq, Clone)]
// must be non-None.
#[derive(PartialEq, Clone)]
pub struct CrateSource {
- pub dylib: Option<(Path, PathKind)>,
- pub rlib: Option<(Path, PathKind)>,
+ pub dylib: Option<(PathBuf, PathKind)>,
+ pub rlib: Option<(PathBuf, PathKind)>,
pub cnum: ast::CrateNum,
}
// topological sort of all crates putting the leaves at the right-most
// positions.
pub fn get_used_crates(&self, prefer: LinkagePreference)
- -> Vec<(ast::CrateNum, Option<Path>)> {
+ -> Vec<(ast::CrateNum, Option<PathBuf>)> {
let mut ordering = Vec::new();
fn visit(cstore: &CStore, cnum: ast::CrateNum,
ordering: &mut Vec<ast::CrateNum>) {
use metadata::csearch;
use metadata::cstore;
use metadata::tydecode::{parse_ty_data, parse_region_data, parse_def_id,
- parse_type_param_def_data, parse_bounds_data,
- parse_bare_fn_ty_data, parse_trait_ref_data,
- parse_predicate_data};
+ parse_type_param_def_data, parse_bare_fn_ty_data,
+ parse_trait_ref_data, parse_predicate_data};
use middle::def;
use middle::lang_items;
use middle::subst;
use std::collections::HashMap;
use std::hash::{self, Hash, SipHasher};
-use std::num::FromPrimitive;
-use std::num::Int;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::num::{FromPrimitive, Int};
use std::rc::Rc;
use std::slice::bytes;
use std::str;
doc_trait_ref(tp, tcx, cdata)
}
-fn doc_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
- -> ty::ParamBounds<'tcx> {
- parse_bounds_data(doc.data, cdata.cnum, doc.start, tcx,
- |_, did| translate_def_id(cdata, did))
-}
-
-fn trait_def_bounds<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
- -> ty::ParamBounds<'tcx> {
- let d = reader::get_doc(doc, tag_trait_def_bounds);
- doc_bounds(d, tcx, cdata)
-}
-
fn enum_variant_ids(item: rbml::Doc, cdata: Cmd) -> Vec<ast::DefId> {
let mut ids: Vec<ast::DefId> = Vec::new();
let v = tag_items_data_item_variant;
{
let item_doc = lookup_item(item_id, cdata.data());
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
- let bounds = trait_def_bounds(item_doc, tcx, cdata);
let unsafety = parse_unsafety(item_doc);
let associated_type_names = parse_associated_type_names(item_doc);
let paren_sugar = parse_paren_sugar(item_doc);
paren_sugar: paren_sugar,
unsafety: unsafety,
generics: generics,
- bounds: bounds,
trait_ref: item_trait_ref(item_doc, tcx, cdata),
associated_type_names: associated_type_names,
}
doc_predicates(item_doc, tcx, cdata, tag_item_generics)
}
+pub fn get_super_predicates<'tcx>(cdata: Cmd,
+ item_id: ast::NodeId,
+ tcx: &ty::ctxt<'tcx>)
+ -> ty::GenericPredicates<'tcx>
+{
+ let item_doc = lookup_item(item_id, cdata.data());
+ doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
+}
+
pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
-> ty::TypeScheme<'tcx>
{
_ => { /* empty */ }
}
let old_disr_val = disr_val;
- disr_val += 1;
+ disr_val = disr_val.wrapping_add(1);
Rc::new(ty::VariantInfo {
args: arg_tys,
arg_names: arg_names,
return result;
}
-/// Returns the supertraits of the given trait.
-pub fn get_supertraits<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
- -> Vec<Rc<ty::TraitRef<'tcx>>> {
- let mut results = Vec::new();
- let item_doc = lookup_item(id, cdata.data());
- reader::tagged_docs(item_doc, tag_item_super_trait_ref, |trait_doc| {
- // NB. Only reads the ones that *aren't* builtin-bounds. See also
- // get_trait_def() for collecting the builtin bounds.
- // FIXME(#8559): The builtin bounds shouldn't be encoded in the first place.
- let trait_ref = doc_trait_ref(trait_doc, tcx, cdata);
- if tcx.lang_items.to_builtin_kind(trait_ref.def_id).is_none() {
- results.push(trait_ref);
- }
- true
- });
- return results;
-}
-
pub fn get_type_name_if_impl(cdata: Cmd,
node_id: ast::NodeId) -> Option<ast::Name> {
let item = lookup_item(node_id, cdata.data());
}
fn list_crate_attributes(md: rbml::Doc, hash: &Svh,
- out: &mut old_io::Writer) -> old_io::IoResult<()> {
+ out: &mut io::Write) -> io::Result<()> {
try!(write!(out, "=Crate Attributes ({})=\n", *hash));
let r = get_attributes(md);
return deps;
}
-fn list_crate_deps(data: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
+fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> {
try!(write!(out, "=External Dependencies=\n"));
for dep in &get_crate_deps(data) {
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.name, dep.hash));
maybe_get_crate_name(data).expect("no crate name in crate")
}
-pub fn list_crate_metadata(bytes: &[u8], out: &mut old_io::Writer) -> old_io::IoResult<()> {
+pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> {
let hash = get_crate_hash(bytes);
let md = rbml::Doc::new(bytes);
try!(list_crate_attributes(md, &hash, out));
}
}
-
pub fn is_default_trait<'tcx>(cdata: Cmd, id: ast::NodeId) -> bool {
let item_doc = lookup_item(id, cdata.data());
match item_family(item_doc) {
_ => false
}
}
+
+pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
+ let crate_doc = rbml::Doc::new(metadata);
+ let cm_doc = reader::get_doc(crate_doc, tag_codemap);
+
+ let mut filemaps = vec![];
+
+ reader::tagged_docs(cm_doc, tag_codemap_filemap, |filemap_doc| {
+ let mut decoder = reader::Decoder::new(filemap_doc);
+ let filemap: codemap::FileMap = Decodable::decode(&mut decoder).unwrap();
+ filemaps.push(filemap);
+ true
+ });
+
+ return filemaps;
+}
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
use syntax::visit::Visitor;
use syntax::visit;
use syntax;
-use rbml::writer;
+use rbml::writer::Encoder;
use rbml::io::SeekableMemWriter;
/// A borrowed version of `ast::InlinedItem`.
IIForeignRef(&'a ast::ForeignItem)
}
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
pub type EncodeInlinedItem<'a> =
Box<FnMut(&EncodeContext, &mut Encoder, InlinedItemRef) + 'a>;
};
rbml_w.start_tag(tag);
- tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+ tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
rbml_w.end_tag();
}
// Item info table encoding
fn encode_family(rbml_w: &mut Encoder, c: char) {
- rbml_w.start_tag(tag_items_data_item_family);
- rbml_w.writer.write_all(&[c as u8]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_items_data_item_family, c as u8);
}
pub fn def_to_string(did: DefId) -> String {
}
fn encode_variant_id(rbml_w: &mut Encoder, vid: DefId) {
- rbml_w.start_tag(tag_items_data_item_variant);
let s = def_to_string(vid);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
-
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&s[..]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_variant, &s[..]);
+ rbml_w.wr_tagged_str(tag_mod_child, &s[..]);
}
pub fn write_closure_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_closure_ty(rbml_w.writer, ty_str_ctxt, closure_type);
+ tyencode::enc_closure_ty(rbml_w, ty_str_ctxt, closure_type);
}
pub fn write_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_ty(rbml_w.writer, ty_str_ctxt, typ);
+ tyencode::enc_ty(rbml_w, ty_str_ctxt, typ);
}
pub fn write_trait_ref<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_trait_ref(rbml_w.writer, ty_str_ctxt, trait_ref);
+ tyencode::enc_trait_ref(rbml_w, ty_str_ctxt, trait_ref);
}
pub fn write_region(ecx: &EncodeContext,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_region(rbml_w.writer, ty_str_ctxt, r);
-}
-
-fn encode_bounds<'a, 'tcx>(rbml_w: &mut Encoder,
- ecx: &EncodeContext<'a, 'tcx>,
- bounds: &ty::ParamBounds<'tcx>,
- tag: uint) {
- rbml_w.start_tag(tag);
-
- let ty_str_ctxt = &tyencode::ctxt { diag: ecx.diag,
- ds: def_to_string,
- tcx: ecx.tcx,
- abbrevs: &ecx.type_abbrevs };
- tyencode::enc_bounds(rbml_w.writer, ty_str_ctxt, bounds);
-
- rbml_w.end_tag();
+ tyencode::enc_region(rbml_w, ty_str_ctxt, r);
}
fn encode_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
- tyencode::enc_bare_fn_ty(rbml_w.writer, ty_str_ctxt, typ);
+ tyencode::enc_bare_fn_ty(rbml_w, ty_str_ctxt, typ);
rbml_w.end_tag();
}
fn encode_symbol(ecx: &EncodeContext,
rbml_w: &mut Encoder,
id: NodeId) {
- rbml_w.start_tag(tag_items_data_item_symbol);
match ecx.item_symbols.borrow().get(&id) {
Some(x) => {
debug!("encode_symbol(id={}, str={})", id, *x);
- rbml_w.writer.write_all(x.as_bytes());
+ rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
}
None => {
ecx.diag.handler().bug(
&format!("encode_symbol: id not found {}", id));
}
}
- rbml_w.end_tag();
}
fn encode_disr_val(_: &EncodeContext,
rbml_w: &mut Encoder,
disr_val: ty::Disr) {
- rbml_w.start_tag(tag_disr_val);
- let s = disr_val.to_string();
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_disr_val, &disr_val.to_string());
}
fn encode_parent_item(rbml_w: &mut Encoder, id: DefId) {
- rbml_w.start_tag(tag_items_data_parent_item);
- let s = def_to_string(id);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_parent_item, &def_to_string(id));
}
fn encode_struct_fields(rbml_w: &mut Encoder,
}
encode_struct_field_family(rbml_w, f.vis);
encode_def_id(rbml_w, f.id);
- rbml_w.start_tag(tag_item_field_origin);
- let s = def_to_string(origin);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_item_field_origin, &def_to_string(origin));
rbml_w.end_tag();
}
}
let def_id = local_def(variant.node.id);
index.push(entry {
val: variant.node.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
encode_def_id(rbml_w, def_id);
ecx.tcx.map.with_path(variant.node.id, |path| encode_path(rbml_w, path));
rbml_w.end_tag();
- disr_val += 1;
+ disr_val = disr_val.wrapping_add(1);
i += 1;
}
}
debug!("(encode reexported static method) {}::{}",
exp.name, token::get_name(method_name));
rbml_w.start_tag(tag_items_data_item_reexport);
- rbml_w.start_tag(tag_items_data_item_reexport_def_id);
- rbml_w.wr_str(&def_to_string(method_def_id));
- rbml_w.end_tag();
- rbml_w.start_tag(tag_items_data_item_reexport_name);
- rbml_w.wr_str(&format!("{}::{}",
- exp.name,
- token::get_name(method_name)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+ &def_to_string(method_def_id));
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+ &format!("{}::{}", exp.name,
+ token::get_name(method_name)));
rbml_w.end_tag();
}
exp.def_id.node,
id);
rbml_w.start_tag(tag_items_data_item_reexport);
- rbml_w.start_tag(tag_items_data_item_reexport_def_id);
- rbml_w.wr_str(&def_to_string(exp.def_id));
- rbml_w.end_tag();
- rbml_w.start_tag(tag_items_data_item_reexport_name);
- rbml_w.wr_str(exp.name.as_str());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_def_id,
+ &def_to_string(exp.def_id));
+ rbml_w.wr_tagged_str(tag_items_data_item_reexport_name,
+ exp.name.as_str());
rbml_w.end_tag();
encode_reexported_static_methods(ecx, rbml_w, path.clone(), exp);
}
// Encode info about all the module children.
for item in &md.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(item.id)));
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(
- auxiliary_node_id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(auxiliary_node_id)));
true
});
token::get_ident(ident),
did, ecx.tcx.map.node_to_string(did));
- rbml_w.start_tag(tag_mod_impl);
- rbml_w.wr_str(&def_to_string(local_def(did)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_impl,
+ &def_to_string(local_def(did)));
}
}
}
fn encode_visibility(rbml_w: &mut Encoder, visibility: ast::Visibility) {
- rbml_w.start_tag(tag_items_data_item_visibility);
let ch = match visibility {
ast::Public => 'y',
ast::Inherited => 'i',
};
- rbml_w.wr_str(&ch.to_string());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_items_data_item_visibility, ch as u8);
}
fn encode_explicit_self(rbml_w: &mut Encoder,
explicit_self: &ty::ExplicitSelfCategory) {
- rbml_w.start_tag(tag_item_trait_method_explicit_self);
+ let tag = tag_item_trait_method_explicit_self;
// Encode the base self type.
match *explicit_self {
ty::StaticExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ 's' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['s' as u8]);
}
ty::ByValueExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ 'v' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['v' as u8]);
}
ty::ByBoxExplicitSelfCategory => {
- rbml_w.writer.write_all(&[ '~' as u8 ]);
+ rbml_w.wr_tagged_bytes(tag, &['~' as u8]);
}
ty::ByReferenceExplicitSelfCategory(_, m) => {
// FIXME(#4846) encode custom lifetime
- rbml_w.writer.write_all(&['&' as u8]);
- encode_mutability(rbml_w, m);
+ let ch = encode_mutability(m);
+ rbml_w.wr_tagged_bytes(tag, &['&' as u8, ch]);
}
}
- rbml_w.end_tag();
-
- fn encode_mutability(rbml_w: &mut Encoder,
- m: ast::Mutability) {
+ fn encode_mutability(m: ast::Mutability) -> u8 {
match m {
- ast::MutImmutable => { rbml_w.writer.write_all(&[ 'i' as u8 ]); }
- ast::MutMutable => { rbml_w.writer.write_all(&[ 'm' as u8 ]); }
+ ast::MutImmutable => 'i' as u8,
+ ast::MutMutable => 'm' as u8,
}
}
}
fn encode_item_sort(rbml_w: &mut Encoder, sort: char) {
- rbml_w.start_tag(tag_item_trait_item_sort);
- rbml_w.writer.write_all(&[ sort as u8 ]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_item_trait_item_sort, sort as u8);
}
fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
- rbml_w.start_tag(tag_item_trait_parent_sort);
- rbml_w.writer.write_all(&[ sort as u8 ]);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
}
fn encode_provided_source(rbml_w: &mut Encoder,
source_opt: Option<DefId>) {
if let Some(source) = source_opt {
- rbml_w.start_tag(tag_item_method_provided_source);
- let s = def_to_string(source);
- rbml_w.writer.write_all(s.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_item_method_provided_source,
+ &def_to_string(source));
}
}
let nm = field.name;
let id = field.id.node;
- index.push(entry {val: id as i64, pos: rbml_w.writer.tell().unwrap()});
+ let pos = rbml_w.mark_stable_position();
+ index.push(entry {val: id as i64, pos: pos});
global_index.push(entry {
val: id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: pos,
});
rbml_w.start_tag(tag_items_data_item);
debug!("encode_info_for_struct: doing {} {}",
struct_id: NodeId) {
index.push(entry {
val: ctor_id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
// indicate that this is a tuple struct ctor, because downstream users will normally want
// the tuple struct definition, but without this there is no way for them to tell that
// they actually have a ctor rather than a normal function
- rbml_w.start_tag(tag_items_data_item_is_tuple_struct_ctor);
- rbml_w.end_tag();
+ rbml_w.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]);
rbml_w.end_tag();
}
tcx: ecx.tcx,
abbrevs: &ecx.type_abbrevs
};
+
for param in generics.types.iter() {
rbml_w.start_tag(tag_type_param_def);
- tyencode::enc_type_param_def(rbml_w.writer, ty_str_ctxt, param);
+ tyencode::enc_type_param_def(rbml_w, ty_str_ctxt, param);
rbml_w.end_tag();
}
rbml_w.end_tag();
}
+ encode_predicates_in_current_doc(rbml_w, ecx, predicates);
+
+ rbml_w.end_tag();
+}
+
+fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
+ ecx: &EncodeContext<'a,'tcx>,
+ predicates: &ty::GenericPredicates<'tcx>)
+{
+ let ty_str_ctxt = &tyencode::ctxt {
+ diag: ecx.diag,
+ ds: def_to_string,
+ tcx: ecx.tcx,
+ abbrevs: &ecx.type_abbrevs
+ };
+
for (space, _, predicate) in predicates.predicates.iter_enumerated() {
rbml_w.start_tag(tag_predicate);
rbml_w.wr_tagged_u8(tag_predicate_space, space as u8);
rbml_w.start_tag(tag_predicate_data);
- tyencode::enc_predicate(rbml_w.writer, ty_str_ctxt, predicate);
+ tyencode::enc_predicate(rbml_w, ty_str_ctxt, predicate);
rbml_w.end_tag();
rbml_w.end_tag();
}
+}
+fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
+ ecx: &EncodeContext<'a,'tcx>,
+ predicates: &ty::GenericPredicates<'tcx>,
+ tag: uint)
+{
+ rbml_w.start_tag(tag);
+ encode_predicates_in_current_doc(rbml_w, ecx, predicates);
rbml_w.end_tag();
}
decl: &ast::FnDecl) {
rbml_w.start_tag(tag_method_argument_names);
for arg in &decl.inputs {
- rbml_w.start_tag(tag_method_argument_name);
+ let tag = tag_method_argument_name;
if let ast::PatIdent(_, ref path1, _) = arg.pat.node {
let name = token::get_ident(path1.node);
- rbml_w.writer.write_all(name.as_bytes());
+ rbml_w.wr_tagged_bytes(tag, name.as_bytes());
+ } else {
+ rbml_w.wr_tagged_bytes(tag, &[]);
}
- rbml_w.end_tag();
}
rbml_w.end_tag();
}
vis: ast::Visibility) {
let tcx = ecx.tcx;
- fn add_to_index(item: &ast::Item, rbml_w: &Encoder,
+ fn add_to_index(item: &ast::Item, rbml_w: &mut Encoder,
index: &mut Vec<entry<i64>>) {
index.push(entry {
val: item.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
}
// Encode all the items in this module.
for foreign_item in &fm.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(foreign_item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(foreign_item.id)));
}
encode_visibility(rbml_w, vis);
encode_stability(rbml_w, stab);
index.push(entry {
val: trait_item_def_id.def_id().node as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
let trait_item_type =
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates, tag_item_generics);
+ encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
+ tag_item_super_predicates);
encode_trait_ref(rbml_w, ecx, &*trait_def.trait_ref, tag_item_trait_ref);
encode_name(rbml_w, item.ident.name);
encode_attributes(rbml_w, &item.attrs);
}
rbml_w.end_tag();
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(method_def_id.def_id()));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(method_def_id.def_id()));
}
encode_path(rbml_w, path.clone());
- encode_bounds(rbml_w, ecx, &trait_def.bounds, tag_trait_def_bounds);
-
// Encode the implementations of this trait.
encode_extension_implementations(ecx, rbml_w, def_id);
index.push(entry {
val: item_def_id.def_id().node as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
abi: abi::Abi) {
index.push(entry {
val: nitem.id as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item);
rbml_w.start_tag(tag_items_data);
index.push(entry {
val: ast::CRATE_NODE_ID as i64,
- pos: rbml_w.writer.tell().unwrap(),
+ pos: rbml_w.mark_stable_position(),
});
encode_info_for_mod(ecx,
rbml_w,
let mut bucket_locs = Vec::new();
rbml_w.start_tag(tag_index_buckets);
for bucket in &buckets {
- bucket_locs.push(rbml_w.writer.tell().unwrap());
+ bucket_locs.push(rbml_w.mark_stable_position());
rbml_w.start_tag(tag_index_buckets_bucket);
for elt in bucket {
rbml_w.start_tag(tag_index_buckets_bucket_elt);
match mi.node {
ast::MetaWord(ref name) => {
rbml_w.start_tag(tag_meta_item_word);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
rbml_w.end_tag();
}
ast::MetaNameValue(ref name, ref value) => {
match value.node {
ast::LitStr(ref value, _) => {
rbml_w.start_tag(tag_meta_item_name_value);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
- rbml_w.start_tag(tag_meta_item_value);
- rbml_w.writer.write_all(value.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
+ rbml_w.wr_tagged_str(tag_meta_item_value, value);
rbml_w.end_tag();
}
_ => {/* FIXME (#623): encode other variants */ }
}
ast::MetaList(ref name, ref items) => {
rbml_w.start_tag(tag_meta_item_list);
- rbml_w.start_tag(tag_meta_item_name);
- rbml_w.writer.write_all(name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_meta_item_name, name);
for inner_item in items {
encode_meta_item(rbml_w, &**inner_item);
}
if let Some(id) = def_id {
if id.krate == ast::LOCAL_CRATE {
rbml_w.start_tag(tag_lang_items_item);
-
- rbml_w.start_tag(tag_lang_items_item_id);
- {
- let wr: &mut SeekableMemWriter = rbml_w.writer;
- wr.write_be_u32(i as u32);
- }
- rbml_w.end_tag(); // tag_lang_items_item_id
-
- rbml_w.start_tag(tag_lang_items_item_node_id);
- {
- let wr: &mut SeekableMemWriter = rbml_w.writer;
- wr.write_be_u32(id.node as u32);
- }
- rbml_w.end_tag(); // tag_lang_items_item_node_id
-
- rbml_w.end_tag(); // tag_lang_items_item
+ rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
+ rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id.node as u32);
+ rbml_w.end_tag();
}
}
}
cstore::NativeStatic => {} // these libraries are not propagated
cstore::NativeFramework | cstore::NativeUnknown => {
rbml_w.start_tag(tag_native_libraries_lib);
-
- rbml_w.start_tag(tag_native_libraries_kind);
- rbml_w.writer.write_be_u32(kind as u32);
- rbml_w.end_tag();
-
- rbml_w.start_tag(tag_native_libraries_name);
- rbml_w.writer.write_all(lib.as_bytes());
- rbml_w.end_tag();
-
+ rbml_w.wr_tagged_u32(tag_native_libraries_kind, kind as u32);
+ rbml_w.wr_tagged_str(tag_native_libraries_name, lib);
rbml_w.end_tag();
}
}
}
}
+fn encode_codemap(ecx: &EncodeContext, rbml_w: &mut Encoder) {
+ rbml_w.start_tag(tag_codemap);
+ let codemap = ecx.tcx.sess.codemap();
+
+ for filemap in &codemap.files.borrow()[..] {
+
+ if filemap.lines.borrow().len() == 0 || filemap.is_imported() {
+ // No need to export empty filemaps, as they can't contain spans
+ // that need translation.
+ // Also no need to re-export imported filemaps, as any downstream
+ // crate will import them from their original source.
+ continue;
+ }
+
+ rbml_w.start_tag(tag_codemap_filemap);
+ filemap.encode(rbml_w);
+ rbml_w.end_tag();
+ }
+
+ rbml_w.end_tag();
+}
+
/// Serialize the text of the exported macros
fn encode_macro_defs(rbml_w: &mut Encoder,
krate: &ast::Crate) {
encode_name(rbml_w, def.ident.name);
encode_attributes(rbml_w, &def.attrs);
- rbml_w.start_tag(tag_macro_def_body);
- rbml_w.wr_str(&pprust::tts_to_string(&def.body));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_macro_def_body,
+ &pprust::tts_to_string(&def.body));
rbml_w.end_tag();
}
rbml_w.start_tag(tag_misc_info);
rbml_w.start_tag(tag_misc_info_crate_items);
for item in &krate.module.items {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(item.id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(item.id)));
each_auxiliary_node_id(&**item, |auxiliary_node_id| {
- rbml_w.start_tag(tag_mod_child);
- rbml_w.wr_str(&def_to_string(local_def(
- auxiliary_node_id)));
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_mod_child,
+ &def_to_string(local_def(auxiliary_node_id)));
true
});
}
fn encode_crate_dep(rbml_w: &mut Encoder,
dep: decoder::CrateDep) {
rbml_w.start_tag(tag_crate_dep);
- rbml_w.start_tag(tag_crate_dep_crate_name);
- rbml_w.writer.write_all(dep.name.as_bytes());
- rbml_w.end_tag();
- rbml_w.start_tag(tag_crate_dep_hash);
- rbml_w.writer.write_all(dep.hash.as_str().as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_dep_crate_name, &dep.name);
+ rbml_w.wr_tagged_str(tag_crate_dep_hash, dep.hash.as_str());
rbml_w.end_tag();
}
fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
- rbml_w.start_tag(tag_crate_hash);
- rbml_w.writer.write_all(hash.as_str().as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
}
fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
- rbml_w.start_tag(tag_crate_crate_name);
- rbml_w.writer.write_all(crate_name.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
}
fn encode_crate_triple(rbml_w: &mut Encoder, triple: &str) {
- rbml_w.start_tag(tag_crate_triple);
- rbml_w.writer.write_all(triple.as_bytes());
- rbml_w.end_tag();
+ rbml_w.wr_tagged_str(tag_crate_triple, triple);
}
fn encode_dylib_dependency_formats(rbml_w: &mut Encoder, ecx: &EncodeContext) {
- rbml_w.start_tag(tag_dylib_dependency_formats);
+ let tag = tag_dylib_dependency_formats;
match ecx.tcx.dependency_formats.borrow().get(&config::CrateTypeDylib) {
Some(arr) => {
let s = arr.iter().enumerate().filter_map(|(i, slot)| {
cstore::RequireStatic => "s",
})).to_string())
}).collect::<Vec<String>>();
- rbml_w.writer.write_all(s.connect(",").as_bytes());
+ rbml_w.wr_tagged_str(tag, &s.connect(","));
+ }
+ None => {
+ rbml_w.wr_tagged_str(tag, "");
}
- None => {}
}
- rbml_w.end_tag();
}
// NB: Increment this as you change the metadata encoding version.
#[allow(non_upper_case_globals)]
-pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 1 ];
+pub const metadata_encoding_version : &'static [u8] = &[b'r', b'u', b's', b't', 0, 0, 0, 2 ];
pub fn encode_metadata(parms: EncodeParams, krate: &ast::Crate) -> Vec<u8> {
let mut wr = SeekableMemWriter::new();
encode_metadata_inner(&mut wr, parms, krate);
+
+ // RBML compacts the encoded bytes whenever appropriate,
+ // so there are some garbages left after the end of the data.
+ let metalen = wr.tell().unwrap() as uint;
let mut v = wr.unwrap();
+ v.truncate(metalen);
+ assert_eq!(v.len(), metalen);
// And here we run into yet another obscure archive bug: in which metadata
// loaded from archives may have trailing garbage bytes. Awhile back one of
lang_item_bytes: u64,
native_lib_bytes: u64,
plugin_registrar_fn_bytes: u64,
+ codemap_bytes: u64,
macro_defs_bytes: u64,
impl_bytes: u64,
misc_bytes: u64,
lang_item_bytes: 0,
native_lib_bytes: 0,
plugin_registrar_fn_bytes: 0,
+ codemap_bytes: 0,
macro_defs_bytes: 0,
impl_bytes: 0,
misc_bytes: 0,
reachable: reachable,
};
- let mut rbml_w = writer::Encoder::new(wr);
+ let mut rbml_w = Encoder::new(wr);
encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
encode_crate_triple(&mut rbml_w,
encode_plugin_registrar_fn(&ecx, &mut rbml_w);
stats.plugin_registrar_fn_bytes = rbml_w.writer.tell().unwrap() - i;
+ // Encode codemap
+ i = rbml_w.writer.tell().unwrap();
+ encode_codemap(&ecx, &mut rbml_w);
+ stats.codemap_bytes = rbml_w.writer.tell().unwrap() - i;
+
// Encode macro definitions
i = rbml_w.writer.tell().unwrap();
encode_macro_defs(&mut rbml_w, krate);
println!(" lang item bytes: {}", stats.lang_item_bytes);
println!(" native bytes: {}", stats.native_lib_bytes);
println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes);
+ println!(" codemap bytes: {}", stats.codemap_bytes);
println!(" macro def bytes: {}", stats.macro_defs_bytes);
println!(" impl bytes: {}", stats.impl_bytes);
println!(" misc bytes: {}", stats.misc_bytes);
// Get the encoded string for a type
pub fn encoded_ty<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> String {
let mut wr = SeekableMemWriter::new();
- tyencode::enc_ty(&mut wr, &tyencode::ctxt {
+ tyencode::enc_ty(&mut Encoder::new(&mut wr), &tyencode::ctxt {
diag: tcx.sess.diagnostic(),
ds: def_to_string,
tcx: tcx,
use std::collections::HashSet;
use std::env;
-use std::os;
-use std::old_io::fs::PathExtensions;
-use std::old_io::fs;
+use std::fs;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
use util::fs as myfs;
use session::search_paths::{SearchPaths, PathKind};
FileMatches => found = true,
FileDoesntMatch => ()
}
- visited_dirs.insert(path.as_vec().to_vec());
+ visited_dirs.insert(path.to_path_buf());
}
debug!("filesearch: searching lib path");
let tlib_path = make_target_lib_path(self.sysroot,
self.triple);
- if !visited_dirs.contains(tlib_path.as_vec()) {
+ if !visited_dirs.contains(&tlib_path) {
match f(&tlib_path, PathKind::All) {
FileMatches => found = true,
FileDoesntMatch => ()
}
}
- visited_dirs.insert(tlib_path.as_vec().to_vec());
+ visited_dirs.insert(tlib_path);
// Try RUST_PATH
if !found {
let rustpath = rust_path();
let tlib_path = make_rustpkg_lib_path(
self.sysroot, path, self.triple);
debug!("is {} in visited_dirs? {}", tlib_path.display(),
- visited_dirs.contains(&tlib_path.as_vec().to_vec()));
+ visited_dirs.contains(&tlib_path));
- if !visited_dirs.contains(tlib_path.as_vec()) {
- visited_dirs.insert(tlib_path.as_vec().to_vec());
+ if !visited_dirs.contains(&tlib_path) {
+ visited_dirs.insert(tlib_path.clone());
// Don't keep searching the RUST_PATH if one match turns up --
// if we did, we'd get a "multiple matching crates" error
match f(&tlib_path, PathKind::All) {
}
}
- pub fn get_lib_path(&self) -> Path {
+ pub fn get_lib_path(&self) -> PathBuf {
make_target_lib_path(self.sysroot, self.triple)
}
{
self.for_each_lib_search_path(|lib_search_path, kind| {
debug!("searching {}", lib_search_path.display());
- match fs::readdir(lib_search_path) {
+ match fs::read_dir(lib_search_path) {
Ok(files) => {
+ let files = files.filter_map(|p| p.ok().map(|s| s.path()))
+ .collect::<Vec<_>>();
let mut rslt = FileDoesntMatch;
- fn is_rlib(p: & &Path) -> bool {
- p.extension_str() == Some("rlib")
+ fn is_rlib(p: &Path) -> bool {
+ p.extension().and_then(|s| s.to_str()) == Some("rlib")
}
// Reading metadata out of rlibs is faster, and if we find both
// an rlib and a dylib we only read one of the files of
}
// Returns a list of directories where target-specific dylibs might be located.
- pub fn get_dylib_search_paths(&self) -> Vec<Path> {
+ pub fn get_dylib_search_paths(&self) -> Vec<PathBuf> {
let mut paths = Vec::new();
self.for_each_lib_search_path(|lib_search_path, _| {
- paths.push(lib_search_path.clone());
+ paths.push(lib_search_path.to_path_buf());
FileDoesntMatch
});
paths
}
// Returns a list of directories where target-specific tool binaries are located.
- pub fn get_tools_search_paths(&self) -> Vec<Path> {
- let mut p = Path::new(self.sysroot);
- p.push(find_libdir(self.sysroot));
- p.push(rustlibdir());
- p.push(self.triple);
+ pub fn get_tools_search_paths(&self) -> Vec<PathBuf> {
+ let mut p = PathBuf::new(self.sysroot);
+ p.push(&find_libdir(self.sysroot));
+ p.push(&rustlibdir());
+ p.push(&self.triple);
p.push("bin");
vec![p]
}
}
-pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> Path {
- let mut p = Path::new(find_libdir(sysroot));
+pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
+ let mut p = PathBuf::new(&find_libdir(sysroot));
assert!(p.is_relative());
- p.push(rustlibdir());
+ p.push(&rustlibdir());
p.push(target_triple);
p.push("lib");
p
}
fn make_target_lib_path(sysroot: &Path,
- target_triple: &str) -> Path {
+ target_triple: &str) -> PathBuf {
sysroot.join(&relative_target_lib_path(sysroot, target_triple))
}
fn make_rustpkg_lib_path(sysroot: &Path,
dir: &Path,
- triple: &str) -> Path {
- let mut p = dir.join(find_libdir(sysroot));
+ triple: &str) -> PathBuf {
+ let mut p = dir.join(&find_libdir(sysroot));
p.push(triple);
p
}
-pub fn get_or_default_sysroot() -> Path {
+pub fn get_or_default_sysroot() -> PathBuf {
// Follow symlinks. If the resolved path is relative, make it absolute.
- fn canonicalize(path: Option<Path>) -> Option<Path> {
- path.and_then(|path|
+ fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
+ path.and_then(|path| {
match myfs::realpath(&path) {
Ok(canon) => Some(canon),
Err(e) => panic!("failed to get realpath: {}", e),
- })
+ }
+ })
}
- match canonicalize(os::self_exe_name()) {
+ match canonicalize(env::current_exe().ok()) {
Some(mut p) => { p.pop(); p.pop(); p }
None => panic!("can't determine value for sysroot")
}
}
#[cfg(windows)]
-static PATH_ENTRY_SEPARATOR: &'static str = ";";
+const PATH_ENTRY_SEPARATOR: char = ';';
#[cfg(not(windows))]
-static PATH_ENTRY_SEPARATOR: &'static str = ":";
+const PATH_ENTRY_SEPARATOR: char = ':';
/// Returns RUST_PATH as a string, without default paths added
pub fn get_rust_path() -> Option<String> {
/// $HOME/.rust
/// DIR/.rust for any DIR that's the current working directory
/// or an ancestor of it
-pub fn rust_path() -> Vec<Path> {
- let mut env_rust_path: Vec<Path> = match get_rust_path() {
+pub fn rust_path() -> Vec<PathBuf> {
+ let mut env_rust_path: Vec<PathBuf> = match get_rust_path() {
Some(env_path) => {
let env_path_components =
env_path.split(PATH_ENTRY_SEPARATOR);
- env_path_components.map(|s| Path::new(s)).collect()
+ env_path_components.map(|s| PathBuf::new(s)).collect()
}
None => Vec::new()
};
- let mut cwd = os::getcwd().unwrap();
+ let cwd = env::current_dir().unwrap();
// now add in default entries
let cwd_dot_rust = cwd.join(".rust");
if !env_rust_path.contains(&cwd_dot_rust) {
if !env_rust_path.contains(&cwd) {
env_rust_path.push(cwd.clone());
}
- loop {
- if { let f = cwd.filename(); f.is_none() || f.unwrap() == b".." } {
- break
- }
- cwd.set_filename(".rust");
- if !env_rust_path.contains(&cwd) && cwd.exists() {
- env_rust_path.push(cwd.clone());
+ let mut cur = &*cwd;
+ while let Some(parent) = cur.parent() {
+ let candidate = parent.join(".rust");
+ if !env_rust_path.contains(&candidate) && candidate.exists() {
+ env_rust_path.push(candidate.clone());
}
- cwd.pop();
+ cur = parent;
}
- if let Some(h) = os::homedir() {
+ if let Some(h) = env::home_dir() {
let p = h.join(".rust");
if !env_rust_path.contains(&p) && p.exists() {
env_rust_path.push(p);
match option_env!("CFG_LIBDIR_RELATIVE") {
Some(libdir) if libdir != "lib" => return libdir.to_string(),
- _ => if sysroot.join(primary_libdir_name()).join(rustlibdir()).exists() {
+ _ => if sysroot.join(&primary_libdir_name()).join(&rustlibdir()).exists() {
return primary_libdir_name();
} else {
return secondary_libdir_name();
use syntax::codemap::Span;
use syntax::diagnostic::SpanHandler;
use util::fs;
+use util::common;
use rustc_back::target::Target;
-use std::ffi::CString;
use std::cmp;
use std::collections::HashMap;
-use std::old_io::fs::PathExtensions;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
+use std::path::{Path, PathBuf};
use std::ptr;
use std::slice;
use std::time::Duration;
use flate;
pub struct CrateMismatch {
- path: Path,
+ path: PathBuf,
got: String,
}
}
pub struct Library {
- pub dylib: Option<(Path, PathKind)>,
- pub rlib: Option<(Path, PathKind)>,
+ pub dylib: Option<(PathBuf, PathKind)>,
+ pub rlib: Option<(PathBuf, PathKind)>,
pub metadata: MetadataBlob,
}
pub struct CratePaths {
pub ident: String,
- pub dylib: Option<Path>,
- pub rlib: Option<Path>
+ pub dylib: Option<PathBuf>,
+ pub rlib: Option<PathBuf>
}
impl CratePaths {
- fn paths(&self) -> Vec<Path> {
+ fn paths(&self) -> Vec<PathBuf> {
match (&self.dylib, &self.rlib) {
(&None, &None) => vec!(),
(&Some(ref p), &None) |
}
}
if self.rejected_via_kind.len() > 0 {
- self.sess.span_help(self.span, "please recompile this crate using \
+ self.sess.fileline_help(self.span, "please recompile this crate using \
--crate-type lib");
let mismatches = self.rejected_via_kind.iter();
for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
//
// The goal of this step is to look at as little metadata as possible.
self.filesearch.search(|path, kind| {
- let file = match path.filename_str() {
+ let file = match path.file_name().and_then(|s| s.to_str()) {
None => return FileDoesntMatch,
Some(file) => file,
};
if file.starts_with(&staticlib_prefix[..]) &&
file.ends_with(".a") {
staticlibs.push(CrateMismatch {
- path: path.clone(),
+ path: path.to_path_buf(),
got: "static".to_string()
});
}
// read the metadata from it if `*slot` is `None`. If the metadata couldn't
// be read, it is assumed that the file isn't a valid rust library (no
// errors are emitted).
- fn extract_one(&mut self, m: HashMap<Path, PathKind>, flavor: &str,
- slot: &mut Option<MetadataBlob>) -> Option<(Path, PathKind)> {
- let mut ret = None::<(Path, PathKind)>;
+ fn extract_one(&mut self, m: HashMap<PathBuf, PathKind>, flavor: &str,
+ slot: &mut Option<MetadataBlob>) -> Option<(PathBuf, PathKind)> {
+ let mut ret = None::<(PathBuf, PathKind)>;
let mut error = 0;
if slot.is_some() {
if triple != self.triple {
info!("Rejecting via crate triple: expected {} got {}", self.triple, triple);
self.rejected_via_triple.push(CrateMismatch {
- path: libpath.clone(),
+ path: libpath.to_path_buf(),
got: triple.to_string()
});
return false;
if *myhash != hash {
info!("Rejecting via hash: expected {} got {}", *myhash, hash);
self.rejected_via_hash.push(CrateMismatch {
- path: libpath.clone(),
+ path: libpath.to_path_buf(),
got: myhash.as_str().to_string()
});
false
let mut rlibs = HashMap::new();
let mut dylibs = HashMap::new();
{
- let locs = locs.iter().map(|l| Path::new(&l[..])).filter(|loc| {
+ let locs = locs.iter().map(|l| PathBuf::new(&l[..])).filter(|loc| {
if !loc.exists() {
sess.err(&format!("extern location for {} does not exist: {}",
self.crate_name, loc.display()));
return false;
}
- let file = match loc.filename_str() {
+ let file = match loc.file_name().and_then(|s| s.to_str()) {
Some(file) => file,
None => {
sess.err(&format!("extern location for {} is not a file: {}",
// Now that we have an iterator of good candidates, make sure
// there's at most one rlib and at most one dylib.
for loc in locs {
- if loc.filename_str().unwrap().ends_with(".rlib") {
+ if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
rlibs.insert(fs::realpath(&loc).unwrap(),
PathKind::ExternFlag);
} else {
let dur = Duration::span(|| {
ret = Some(get_metadata_section_imp(is_osx, filename));
});
- info!("reading {} => {}ms", filename.filename_display(),
+ info!("reading {:?} => {}ms", filename.file_name().unwrap(),
dur.num_milliseconds());
return ret.unwrap();;
}
if !filename.exists() {
return Err(format!("no such file: '{}'", filename.display()));
}
- if filename.filename_str().unwrap().ends_with(".rlib") {
+ if filename.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
// Use ArchiveRO for speed here, it's backed by LLVM and uses mmap
// internally to read the file. We also avoid even using a memcpy by
// just keeping the archive along while the metadata is in use.
};
}
unsafe {
- let buf = CString::new(filename.as_vec()).unwrap();
+ let buf = common::path2cstr(filename);
let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
if mb as int == 0 {
return Err(format!("error reading library: '{}'",
// A diagnostic function for dumping crate metadata to an output stream
pub fn list_file_metadata(is_osx: bool, path: &Path,
- out: &mut old_io::Writer) -> old_io::IoResult<()> {
+ out: &mut io::Write) -> io::Result<()> {
match get_metadata_section(is_osx, path) {
Ok(bytes) => decoder::list_crate_metadata(bytes.as_slice(), out),
Err(msg) => {
}
"plugin" => {
self.sess.span_err(attr.span, "#[plugin] on `extern crate` is deprecated");
- self.sess.span_help(attr.span, &format!("use a crate attribute instead, \
+ self.sess.fileline_help(attr.span, &format!("use a crate attribute instead, \
i.e. #![plugin({})]",
item.ident.as_str()));
}
Some(sel) => sel.contains_key(&name),
};
def.export = reexport.contains_key(&name);
+ def.allow_internal_unstable = attr::contains_name(&def.attrs,
+ "allow_internal_unstable");
+ debug!("load_macros: loaded: {:?}", def);
self.macros.push(def);
}
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
use syntax::diagnostic::SpanHandler;
use syntax::parse::token;
-use rbml::io::SeekableMemWriter;
+use rbml::writer::Encoder;
-macro_rules! mywrite { ($($arg:tt)*) => ({ write!($($arg)*); }) }
+macro_rules! mywrite { ($w:expr, $($arg:tt)*) => ({ write!($w.writer, $($arg)*); }) }
pub struct ctxt<'a, 'tcx: 'a> {
pub diag: &'a SpanHandler,
pub type abbrev_map<'tcx> = RefCell<FnvHashMap<Ty<'tcx>, ty_abbrev>>;
-pub fn enc_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
+pub fn enc_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx>) {
match cx.abbrevs.borrow_mut().get(&t) {
- Some(a) => { w.write_all(a.s.as_bytes()); return; }
+ Some(a) => { w.writer.write_all(a.s.as_bytes()); return; }
None => {}
}
- let pos = w.tell().unwrap();
+
+ // type abbreviations needs a stable position
+ let pos = w.mark_stable_position();
match t.sty {
ty::ty_bool => mywrite!(w, "b"),
}
}
- let end = w.tell().unwrap();
+ let end = w.mark_stable_position();
let len = end - pos;
fn estimate_sz(u: u64) -> u64 {
let mut n = u;
}
}
-fn enc_mutability(w: &mut SeekableMemWriter, mt: ast::Mutability) {
+fn enc_mutability(w: &mut Encoder, mt: ast::Mutability) {
match mt {
ast::MutImmutable => (),
ast::MutMutable => mywrite!(w, "m"),
}
}
-fn enc_mt<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_mt<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
mt: ty::mt<'tcx>) {
enc_mutability(w, mt.mutbl);
enc_ty(w, cx, mt.ty);
}
-fn enc_opt<T, F>(w: &mut SeekableMemWriter, t: Option<T>, enc_f: F) where
- F: FnOnce(&mut SeekableMemWriter, T),
+fn enc_opt<T, F>(w: &mut Encoder, t: Option<T>, enc_f: F) where
+ F: FnOnce(&mut Encoder, T),
{
match t {
None => mywrite!(w, "n"),
}
}
-fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut SeekableMemWriter,
+fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
v: &VecPerParamSpace<T>,
mut op: F) where
- F: FnMut(&mut SeekableMemWriter, &ctxt<'a, 'tcx>, &T),
+ F: FnMut(&mut Encoder, &ctxt<'a, 'tcx>, &T),
{
for &space in &subst::ParamSpace::all() {
mywrite!(w, "[");
}
}
-pub fn enc_substs<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_substs<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
substs: &subst::Substs<'tcx>) {
enc_region_substs(w, cx, &substs.regions);
enc_vec_per_param_space(w, cx, &substs.types,
|w, cx, &ty| enc_ty(w, cx, ty));
}
-fn enc_region_substs(w: &mut SeekableMemWriter, cx: &ctxt, substs: &subst::RegionSubsts) {
+fn enc_region_substs(w: &mut Encoder, cx: &ctxt, substs: &subst::RegionSubsts) {
match *substs {
subst::ErasedRegions => {
mywrite!(w, "e");
}
}
-pub fn enc_region(w: &mut SeekableMemWriter, cx: &ctxt, r: ty::Region) {
+pub fn enc_region(w: &mut Encoder, cx: &ctxt, r: ty::Region) {
match r {
ty::ReLateBound(id, br) => {
mywrite!(w, "b[{}|", id.depth);
}
}
-fn enc_scope(w: &mut SeekableMemWriter, _cx: &ctxt, scope: region::CodeExtent) {
+fn enc_scope(w: &mut Encoder, _cx: &ctxt, scope: region::CodeExtent) {
match scope {
region::CodeExtent::Misc(node_id) => mywrite!(w, "M{}", node_id),
region::CodeExtent::Remainder(region::BlockRemainder {
}
}
-fn enc_destruction_scope_data(w: &mut SeekableMemWriter,
+fn enc_destruction_scope_data(w: &mut Encoder,
d: region::DestructionScopeData) {
mywrite!(w, "{}", d.node_id);
}
-fn enc_bound_region(w: &mut SeekableMemWriter, cx: &ctxt, br: ty::BoundRegion) {
+fn enc_bound_region(w: &mut Encoder, cx: &ctxt, br: ty::BoundRegion) {
match br {
ty::BrAnon(idx) => {
mywrite!(w, "a{}|", idx);
}
}
-pub fn enc_trait_ref<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_trait_ref<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
s: &ty::TraitRef<'tcx>) {
mywrite!(w, "{}|", (cx.ds)(s.def_id));
enc_substs(w, cx, s.substs);
}
-fn enc_unsafety(w: &mut SeekableMemWriter, p: ast::Unsafety) {
+fn enc_unsafety(w: &mut Encoder, p: ast::Unsafety) {
match p {
ast::Unsafety::Normal => mywrite!(w, "n"),
ast::Unsafety::Unsafe => mywrite!(w, "u"),
}
}
-fn enc_abi(w: &mut SeekableMemWriter, abi: Abi) {
+fn enc_abi(w: &mut Encoder, abi: Abi) {
mywrite!(w, "[");
mywrite!(w, "{}", abi.name());
mywrite!(w, "]")
}
-pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bare_fn_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
ft: &ty::BareFnTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_abi(w, ft.abi);
enc_fn_sig(w, cx, &ft.sig);
}
-pub fn enc_closure_ty<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_closure_ty<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
ft: &ty::ClosureTy<'tcx>) {
enc_unsafety(w, ft.unsafety);
enc_fn_sig(w, cx, &ft.sig);
enc_abi(w, ft.abi);
}
-fn enc_fn_sig<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+fn enc_fn_sig<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
fsig: &ty::PolyFnSig<'tcx>) {
mywrite!(w, "[");
for ty in &fsig.0.inputs {
}
}
-pub fn enc_builtin_bounds(w: &mut SeekableMemWriter, _cx: &ctxt, bs: &ty::BuiltinBounds) {
+pub fn enc_builtin_bounds(w: &mut Encoder, _cx: &ctxt, bs: &ty::BuiltinBounds) {
for bound in bs {
match bound {
ty::BoundSend => mywrite!(w, "S"),
mywrite!(w, ".");
}
-pub fn enc_existential_bounds<'a,'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_existential_bounds<'a,'tcx>(w: &mut Encoder,
cx: &ctxt<'a,'tcx>,
bs: &ty::ExistentialBounds<'tcx>) {
let param_bounds = ty::ParamBounds { trait_bounds: vec!(),
enc_bounds(w, cx, ¶m_bounds);
}
-pub fn enc_bounds<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_bounds<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
bs: &ty::ParamBounds<'tcx>) {
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
mywrite!(w, ".");
}
-pub fn enc_region_bounds<'a, 'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_region_bounds<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
rs: &[ty::Region]) {
for &r in rs {
mywrite!(w, ".");
}
-pub fn enc_type_param_def<'a, 'tcx>(w: &mut SeekableMemWriter, cx: &ctxt<'a, 'tcx>,
+pub fn enc_type_param_def<'a, 'tcx>(w: &mut Encoder, cx: &ctxt<'a, 'tcx>,
v: &ty::TypeParameterDef<'tcx>) {
mywrite!(w, "{}:{}|{}|{}|",
token::get_name(v.name), (cx.ds)(v.def_id),
enc_object_lifetime_default(w, cx, v.object_lifetime_default);
}
-fn enc_object_lifetime_default<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_object_lifetime_default<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
default: Option<ty::ObjectLifetimeDefault>)
{
}
}
-pub fn enc_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+pub fn enc_predicate<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
p: &ty::Predicate<'tcx>)
{
}
}
-fn enc_projection_predicate<'a, 'tcx>(w: &mut SeekableMemWriter,
+fn enc_projection_predicate<'a, 'tcx>(w: &mut Encoder,
cx: &ctxt<'a, 'tcx>,
data: &ty::ProjectionPredicate<'tcx>) {
enc_trait_ref(w, cx, &*data.projection_ty.trait_ref);
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
use std::old_io::Seek;
use std::num::FromPrimitive;
use std::rc::Rc;
+use std::cell::Cell;
-use rbml::io::SeekableMemWriter;
-use rbml::{reader, writer};
+use rbml::reader;
+use rbml::writer::Encoder;
use rbml;
use serialize;
use serialize::{Decodable, Decoder, DecoderHelpers, Encodable};
use serialize::{EncoderHelpers};
+#[cfg(test)] use rbml::io::SeekableMemWriter;
#[cfg(test)] use syntax::parse;
#[cfg(test)] use syntax::print::pprust;
tcx: &'a ty::ctxt<'tcx>,
cdata: &'b cstore::crate_metadata,
from_id_range: ast_util::IdRange,
- to_id_range: ast_util::IdRange
+ to_id_range: ast_util::IdRange,
+ // Cache the last used filemap for translating spans as an optimization.
+ last_filemap_index: Cell<usize>,
}
trait tr {
fn tr_intern(&self, dcx: &DecodeContext) -> ast::DefId;
}
-pub type Encoder<'a> = writer::Encoder<'a, SeekableMemWriter>;
-
// ______________________________________________________________________
// Top-level methods.
}
}
+/// Decodes an item from its AST in the cdata's metadata and adds it to the
+/// ast-map.
pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>,
cdata: cdata,
tcx: tcx,
from_id_range: from_id_range,
- to_id_range: to_id_range
+ to_id_range: to_id_range,
+ last_filemap_index: Cell::new(0)
};
let raw_ii = decode_ast(ast_doc);
let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx);
pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId {
// from_id_range should be non-empty
assert!(!self.from_id_range.empty());
- (id - self.from_id_range.min + self.to_id_range.min)
+ // Use wrapping arithmetic because otherwise it introduces control flow.
+ // Maybe we should just have the control flow? -- aatch
+ (id.wrapping_sub(self.from_id_range.min).wrapping_add(self.to_id_range.min))
}
/// Translates an EXTERNAL def-id, converting the crate number from the one used in the encoded
assert_eq!(did.krate, ast::LOCAL_CRATE);
ast::DefId { krate: ast::LOCAL_CRATE, node: self.tr_id(did.node) }
}
- pub fn tr_span(&self, _span: Span) -> Span {
- codemap::DUMMY_SP // FIXME (#1972): handle span properly
+
+ /// Translates a `Span` from an extern crate to the corresponding `Span`
+ /// within the local crate's codemap. `creader::import_codemap()` will
+ /// already have allocated any additionally needed FileMaps in the local
+ /// codemap as a side-effect of creating the crate_metadata's
+ /// `codemap_import_info`.
+ pub fn tr_span(&self, span: Span) -> Span {
+ let imported_filemaps = &self.cdata.codemap_import_info[..];
+
+ let filemap_index = {
+ // Optimize for the case that most spans within a translated item
+ // originate from the same filemap.
+ let last_filemap_index = self.last_filemap_index.get();
+
+ if span.lo >= imported_filemaps[last_filemap_index].original_start_pos &&
+ span.hi <= imported_filemaps[last_filemap_index].original_end_pos {
+ last_filemap_index
+ } else {
+ let mut a = 0;
+ let mut b = imported_filemaps.len();
+
+ while b - a > 1 {
+ let m = (a + b) / 2;
+ if imported_filemaps[m].original_start_pos > span.lo {
+ b = m;
+ } else {
+ a = m;
+ }
+ }
+
+ self.last_filemap_index.set(a);
+ a
+ }
+ };
+
+ let lo = (span.lo - imported_filemaps[filemap_index].original_start_pos) +
+ imported_filemaps[filemap_index].translated_filemap.start_pos;
+ let hi = (span.hi - imported_filemaps[filemap_index].original_start_pos) +
+ imported_filemaps[filemap_index].translated_filemap.start_pos;
+
+ codemap::mk_sp(lo, hi)
}
}
// ______________________________________________________________________
// Encoding and decoding of ast::def
-fn decode_def(dcx: &DecodeContext, doc: rbml::Doc) -> def::Def {
- let mut dsr = reader::Decoder::new(doc);
- let def: def::Def = Decodable::decode(&mut dsr).unwrap();
+fn decode_def(dcx: &DecodeContext, dsr: &mut reader::Decoder) -> def::Def {
+ let def: def::Def = Decodable::decode(dsr).unwrap();
def.tr(dcx)
}
fn emit_type_param_def<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
type_param_def: &ty::TypeParameterDef<'tcx>) {
self.emit_opaque(|this| {
- Ok(tyencode::enc_type_param_def(this.writer,
+ Ok(tyencode::enc_type_param_def(this,
&ecx.ty_str_ctxt(),
type_param_def))
});
fn emit_predicate<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
predicate: &ty::Predicate<'tcx>) {
self.emit_opaque(|this| {
- Ok(tyencode::enc_predicate(this.writer,
+ Ok(tyencode::enc_predicate(this,
&ecx.ty_str_ctxt(),
predicate))
});
fn emit_existential_bounds<'b>(&mut self, ecx: &e::EncodeContext<'b,'tcx>,
bounds: &ty::ExistentialBounds<'tcx>) {
- self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_existential_bounds(this,
&ecx.ty_str_ctxt(),
bounds)));
}
fn emit_builtin_bounds(&mut self, ecx: &e::EncodeContext, bounds: &ty::BuiltinBounds) {
- self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_builtin_bounds(this,
&ecx.ty_str_ctxt(),
bounds)));
}
fn emit_substs<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>,
substs: &subst::Substs<'tcx>) {
- self.emit_opaque(|this| Ok(tyencode::enc_substs(this.writer,
+ self.emit_opaque(|this| Ok(tyencode::enc_substs(this,
&ecx.ty_str_ctxt(),
substs)));
}
}
fn id(&mut self, id: ast::NodeId) {
- self.wr_tagged_u64(c::tag_table_id as uint, id as u64);
+ id.encode(self).unwrap();
}
}
if let Some(def) = tcx.def_map.borrow().get(&id).map(|d| d.full_def()) {
rbml_w.tag(c::tag_table_def, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| def.encode(rbml_w).unwrap());
+ def.encode(rbml_w).unwrap();
})
}
if let Some(ty) = tcx.node_types.borrow().get(&id) {
rbml_w.tag(c::tag_table_node_type, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_ty(ecx, *ty);
- })
+ rbml_w.emit_ty(ecx, *ty);
})
}
if let Some(item_substs) = tcx.item_substs.borrow().get(&id) {
rbml_w.tag(c::tag_table_item_subst, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_substs(ecx, &item_substs.substs);
- })
+ rbml_w.emit_substs(ecx, &item_substs.substs);
})
}
if let Some(fv) = tcx.freevars.borrow().get(&id) {
rbml_w.tag(c::tag_table_freevars, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
- Ok(encode_freevar_entry(rbml_w, fv_entry))
- });
- })
+ rbml_w.emit_from_vec(fv, |rbml_w, fv_entry| {
+ Ok(encode_freevar_entry(rbml_w, fv_entry))
+ });
});
for freevar in fv {
rbml_w.tag(c::tag_table_upvar_capture_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- let var_id = freevar.def.def_id().node;
- let upvar_id = ty::UpvarId {
- var_id: var_id,
- closure_expr_id: id
- };
- let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
- var_id.encode(rbml_w);
- upvar_capture.encode(rbml_w);
- })
+
+ let var_id = freevar.def.def_id().node;
+ let upvar_id = ty::UpvarId {
+ var_id: var_id,
+ closure_expr_id: id
+ };
+ let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
+ var_id.encode(rbml_w);
+ upvar_capture.encode(rbml_w);
})
}
}
if let Some(type_scheme) = tcx.tcache.borrow().get(&lid) {
rbml_w.tag(c::tag_table_tcache, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_type_scheme(ecx, type_scheme.clone());
- })
+ rbml_w.emit_type_scheme(ecx, type_scheme.clone());
})
}
if let Some(type_param_def) = tcx.ty_param_defs.borrow().get(&id) {
rbml_w.tag(c::tag_table_param_defs, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_type_param_def(ecx, type_param_def)
- })
+ rbml_w.emit_type_param_def(ecx, type_param_def)
})
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
})
}
if let Some(trait_ref) = tcx.object_cast_map.borrow().get(&id) {
rbml_w.tag(c::tag_table_object_cast_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
- })
+ rbml_w.emit_trait_ref(ecx, &*trait_ref.0);
})
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w, method_call.adjustment, method)
})
}
}
if let Some(method) = tcx.method_map.borrow().get(&method_call) {
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_method_callee(ecx, rbml_w,
- method_call.adjustment, method)
- })
+ encode_method_callee(ecx, rbml_w,
+ method_call.adjustment, method)
})
}
}
rbml_w.tag(c::tag_table_adjustments, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_auto_adjustment(ecx, adjustment);
- })
+ rbml_w.emit_auto_adjustment(ecx, adjustment);
})
}
if let Some(closure_type) = tcx.closure_tys.borrow().get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- rbml_w.emit_closure_type(ecx, closure_type);
- })
+ rbml_w.emit_closure_type(ecx, closure_type);
})
}
if let Some(closure_kind) = tcx.closure_kinds.borrow().get(&ast_util::local_def(id)) {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- encode_closure_kind(rbml_w, *closure_kind)
- })
+ encode_closure_kind(rbml_w, *closure_kind)
})
}
for &qualif in tcx.const_qualif_map.borrow().get(&id).iter() {
rbml_w.tag(c::tag_table_const_qualif, |rbml_w| {
rbml_w.id(id);
- rbml_w.tag(c::tag_table_val, |rbml_w| {
- qualif.encode(rbml_w).unwrap()
- })
+ qualif.encode(rbml_w).unwrap()
})
}
}
ast_doc: rbml::Doc) {
let tbl_doc = ast_doc.get(c::tag_table as uint);
reader::docs(tbl_doc, |tag, entry_doc| {
- let id0 = entry_doc.get(c::tag_table_id as uint).as_int();
- let id = dcx.tr_id(id0 as ast::NodeId);
+ let mut entry_dsr = reader::Decoder::new(entry_doc);
+ let id0: ast::NodeId = Decodable::decode(&mut entry_dsr).unwrap();
+ let id = dcx.tr_id(id0);
debug!(">> Side table document with tag 0x{:x} \
found for id {} (orig {})",
tag, id, id0);
- let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_uint(tag);
+ let decoded_tag: Option<c::astencode_tag> = FromPrimitive::from_usize(tag);
match decoded_tag {
None => {
dcx.tcx.sess.bug(
tag));
}
Some(value) => {
- let val_doc = entry_doc.get(c::tag_table_val as uint);
- let mut val_dsr = reader::Decoder::new(val_doc);
- let val_dsr = &mut val_dsr;
+ let val_dsr = &mut entry_dsr;
match value {
c::tag_table_def => {
- let def = decode_def(dcx, val_doc);
+ let def = decode_def(dcx, val_dsr);
dcx.tcx.def_map.borrow_mut().insert(id, def::PathResolution {
base_def: def,
// This doesn't matter cross-crate.
fn roundtrip(in_item: Option<P<ast::Item>>) {
let in_item = in_item.unwrap();
let mut wr = SeekableMemWriter::new();
- encode_item_ast(&mut writer::Encoder::new(&mut wr), &*in_item);
+ encode_item_ast(&mut Encoder::new(&mut wr), &*in_item);
let rbml_doc = rbml::Doc::new(wr.get_ref());
let out_item = decode_item_ast(rbml_doc);
match const_eval::eval_const_expr_partial(self.tcx, ex, None) {
Ok(_) => {}
Err(msg) => {
- span_err!(self.tcx.sess, ex.span, E0020,
- "{} in a constant expression", msg)
+ span_err!(self.tcx.sess, msg.span, E0020,
+ "{} in a constant expression",
+ msg.description())
}
}
}
use self::WitnessPreference::*;
use middle::const_eval::{compare_const_vals, const_bool, const_float, const_val};
-use middle::const_eval::{const_expr_to_pat, eval_const_expr, lookup_const_by_id};
+use middle::const_eval::{eval_const_expr, eval_const_expr_partial};
+use middle::const_eval::{const_expr_to_pat, lookup_const_by_id};
use middle::def::*;
use middle::expr_use_visitor::{ConsumeMode, Delegate, ExprUseVisitor, Init};
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
}
}
-fn is_expr_const_nan(tcx: &ty::ctxt, expr: &ast::Expr) -> bool {
- match eval_const_expr(tcx, expr) {
- const_float(f) => f.is_nan(),
- _ => false
- }
-}
-
fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
match p.node {
"pattern binding `{}` is named the same as one \
of the variants of the type `{}`",
&token::get_ident(ident.node), ty_to_string(cx.tcx, pat_ty));
- span_help!(cx.tcx.sess, p.span,
+ fileline_help!(cx.tcx.sess, p.span,
"if you meant to match on a variant, \
consider making the path in the pattern qualified: `{}::{}`",
ty_to_string(cx.tcx, pat_ty), &token::get_ident(ident.node));
// Check that we do not match against a static NaN (#6804)
fn check_for_static_nan(cx: &MatchCheckCtxt, pat: &Pat) {
ast_util::walk_pat(pat, |p| {
- match p.node {
- ast::PatLit(ref expr) if is_expr_const_nan(cx.tcx, &**expr) => {
- span_warn!(cx.tcx.sess, p.span, E0003,
- "unmatchable NaN in pattern, \
- use the is_nan method in a guard instead");
+ if let ast::PatLit(ref expr) = p.node {
+ match eval_const_expr_partial(cx.tcx, &**expr, None) {
+ Ok(const_float(f)) if f.is_nan() => {
+ span_warn!(cx.tcx.sess, p.span, E0003,
+ "unmatchable NaN in pattern, \
+ use the is_nan method in a guard instead");
+ }
+ Ok(_) => {}
+
+ Err(err) => {
+ let subspan = p.span.lo <= err.span.lo && err.span.hi <= p.span.hi;
+ cx.tcx.sess.span_err(err.span,
+ &format!("constant evaluation error: {}",
+ err.description().as_slice()));
+ if !subspan {
+ cx.tcx.sess.span_note(p.span,
+ "in pattern here")
+ }
+ }
}
- _ => ()
}
true
});
use syntax::ptr::P;
use syntax::{ast_map, ast_util, codemap};
+use std::borrow::{Cow, IntoCow};
+use std::num::wrapping::OverflowingOps;
use std::cmp::Ordering;
use std::collections::hash_map::Entry::Vacant;
use std::{i8, i16, i32, i64};
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, enum_def,
- box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+ Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
ast::ItemEnum(ast::EnumDef { ref variants }, _) => {
// NOTE this doesn't do the right thing, it compares inlined
None => {}
}
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
- box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+ Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
csearch::FoundAst::Found(&ast::IIItem(ref item)) => match item.node {
ast::ItemConst(_, ref const_expr) => Some(const_expr.id),
_ => None
pub fn eval_const_expr(tcx: &ty::ctxt, e: &Expr) -> const_val {
match eval_const_expr_partial(tcx, e, None) {
Ok(r) => r,
- Err(s) => tcx.sess.span_fatal(e.span, &s[..])
+ Err(s) => tcx.sess.span_fatal(s.span, s.description().as_slice())
}
}
+
+#[derive(Clone)]
+pub struct ConstEvalErr {
+ pub span: Span,
+ pub kind: ErrKind,
+}
+
+#[derive(Clone)]
+pub enum ErrKind {
+ CannotCast,
+ CannotCastTo(&'static str),
+ InvalidOpForBools(ast::BinOp_),
+ InvalidOpForFloats(ast::BinOp_),
+ InvalidOpForIntUint(ast::BinOp_),
+ InvalidOpForUintInt(ast::BinOp_),
+ NegateOnString,
+ NegateOnBoolean,
+ NegateOnBinary,
+ NotOnFloat,
+ NotOnString,
+ NotOnBinary,
+
+ AddiWithOverflow(i64, i64),
+ SubiWithOverflow(i64, i64),
+ MuliWithOverflow(i64, i64),
+ AdduWithOverflow(u64, u64),
+ SubuWithOverflow(u64, u64),
+ MuluWithOverflow(u64, u64),
+ DivideByZero,
+ DivideWithOverflow,
+ ModuloByZero,
+ ModuloWithOverflow,
+ MissingStructField,
+ NonConstPath,
+ NonConstStruct,
+ TupleIndexOutOfBounds,
+
+ MiscBinaryOp,
+ MiscCatchAll,
+}
+
+impl ConstEvalErr {
+ pub fn description(&self) -> Cow<str> {
+ use self::ErrKind::*;
+ match self.kind {
+ CannotCast => "can't cast this type".into_cow(),
+ CannotCastTo(s) => format!("can't cast this type to {}", s).into_cow(),
+ InvalidOpForBools(_) => "can't do this op on bools".into_cow(),
+ InvalidOpForFloats(_) => "can't do this op on floats".into_cow(),
+ InvalidOpForIntUint(..) => "can't do this op on an int and uint".into_cow(),
+ InvalidOpForUintInt(..) => "can't do this op on a uint and int".into_cow(),
+ NegateOnString => "negate on string".into_cow(),
+ NegateOnBoolean => "negate on boolean".into_cow(),
+ NegateOnBinary => "negate on binary literal".into_cow(),
+ NotOnFloat => "not on float or string".into_cow(),
+ NotOnString => "not on float or string".into_cow(),
+ NotOnBinary => "not on binary literal".into_cow(),
+
+ AddiWithOverflow(..) => "attempted to add with overflow".into_cow(),
+ SubiWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+ MuliWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+ AdduWithOverflow(..) => "attempted to add with overflow".into_cow(),
+ SubuWithOverflow(..) => "attempted to sub with overflow".into_cow(),
+ MuluWithOverflow(..) => "attempted to mul with overflow".into_cow(),
+ DivideByZero => "attempted to divide by zero".into_cow(),
+ DivideWithOverflow => "attempted to divide with overflow".into_cow(),
+ ModuloByZero => "attempted remainder with a divisor of zero".into_cow(),
+ ModuloWithOverflow => "attempted remainder with overflow".into_cow(),
+ MissingStructField => "nonexistent struct field".into_cow(),
+ NonConstPath => "non-constant path in constant expr".into_cow(),
+ NonConstStruct => "non-constant struct in constant expr".into_cow(),
+ TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
+
+ MiscBinaryOp => "bad operands for binary".into_cow(),
+ MiscCatchAll => "unsupported constant expr".into_cow(),
+ }
+ }
+}
+
+macro_rules! signal {
+ ($e:expr, $ctor:ident) => {
+ return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor })
+ };
+
+ ($e:expr, $ctor:ident($($arg:expr),*)) => {
+ return Err(ConstEvalErr { span: $e.span, kind: ErrKind::$ctor($($arg),*) })
+ }
+}
+
+fn checked_add_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_add(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, AddiWithOverflow(a, b)) }
+}
+fn checked_sub_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_sub(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, SubiWithOverflow(a, b)) }
+}
+fn checked_mul_int(e: &Expr, a: i64, b: i64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_mul(b);
+ if !oflo { Ok(const_int(ret)) } else { signal!(e, MuliWithOverflow(a, b)) }
+}
+
+fn checked_add_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_add(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, AdduWithOverflow(a, b)) }
+}
+fn checked_sub_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_sub(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, SubuWithOverflow(a, b)) }
+}
+fn checked_mul_uint(e: &Expr, a: u64, b: u64) -> Result<const_val, ConstEvalErr> {
+ let (ret, oflo) = a.overflowing_mul(b);
+ if !oflo { Ok(const_uint(ret)) } else { signal!(e, MuluWithOverflow(a, b)) }
+}
+
+
pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
e: &Expr,
ty_hint: Option<Ty<'tcx>>)
- -> Result<const_val, String> {
- fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
+ -> Result<const_val, ConstEvalErr> {
+ fn fromb(b: bool) -> const_val { const_int(b as i64) }
let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
- match e.node {
+ let result = match e.node {
ast::ExprUnary(ast::UnNeg, ref inner) => {
- match eval_const_expr_partial(tcx, &**inner, ety) {
- Ok(const_float(f)) => Ok(const_float(-f)),
- Ok(const_int(i)) => Ok(const_int(-i)),
- Ok(const_uint(i)) => Ok(const_uint(-i)),
- Ok(const_str(_)) => Err("negate on string".to_string()),
- Ok(const_bool(_)) => Err("negate on boolean".to_string()),
- ref err => ((*err).clone())
+ match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+ const_float(f) => const_float(-f),
+ const_int(i) => const_int(-i),
+ const_uint(i) => const_uint(-i),
+ const_str(_) => signal!(e, NegateOnString),
+ const_bool(_) => signal!(e, NegateOnBoolean),
+ const_binary(_) => signal!(e, NegateOnBinary),
}
}
ast::ExprUnary(ast::UnNot, ref inner) => {
- match eval_const_expr_partial(tcx, &**inner, ety) {
- Ok(const_int(i)) => Ok(const_int(!i)),
- Ok(const_uint(i)) => Ok(const_uint(!i)),
- Ok(const_bool(b)) => Ok(const_bool(!b)),
- _ => Err("not on float or string".to_string())
+ match try!(eval_const_expr_partial(tcx, &**inner, ety)) {
+ const_int(i) => const_int(!i),
+ const_uint(i) => const_uint(!i),
+ const_bool(b) => const_bool(!b),
+ const_str(_) => signal!(e, NotOnString),
+ const_float(_) => signal!(e, NotOnFloat),
+ const_binary(_) => signal!(e, NotOnBinary),
}
}
ast::ExprBinary(op, ref a, ref b) => {
ast::BiShl | ast::BiShr => Some(tcx.types.uint),
_ => ety
};
- match (eval_const_expr_partial(tcx, &**a, ety),
- eval_const_expr_partial(tcx, &**b, b_ty)) {
- (Ok(const_float(a)), Ok(const_float(b))) => {
+ match (try!(eval_const_expr_partial(tcx, &**a, ety)),
+ try!(eval_const_expr_partial(tcx, &**b, b_ty))) {
+ (const_float(a), const_float(b)) => {
match op.node {
- ast::BiAdd => Ok(const_float(a + b)),
- ast::BiSub => Ok(const_float(a - b)),
- ast::BiMul => Ok(const_float(a * b)),
- ast::BiDiv => Ok(const_float(a / b)),
- ast::BiRem => Ok(const_float(a % b)),
+ ast::BiAdd => const_float(a + b),
+ ast::BiSub => const_float(a - b),
+ ast::BiMul => const_float(a * b),
+ ast::BiDiv => const_float(a / b),
+ ast::BiRem => const_float(a % b),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiNe => fromb(a != b),
ast::BiGe => fromb(a >= b),
ast::BiGt => fromb(a > b),
- _ => Err("can't do this op on floats".to_string())
+ _ => signal!(e, InvalidOpForFloats(op.node))
}
}
- (Ok(const_int(a)), Ok(const_int(b))) => {
+ (const_int(a), const_int(b)) => {
let is_a_min_value = || {
let int_ty = match ty::expr_ty_opt(tcx, e).map(|ty| &ty.sty) {
Some(&ty::ty_int(int_ty)) => int_ty,
}
};
match op.node {
- ast::BiAdd => Ok(const_int(a + b)),
- ast::BiSub => Ok(const_int(a - b)),
- ast::BiMul => Ok(const_int(a * b)),
+ ast::BiAdd => try!(checked_add_int(e, a, b)),
+ ast::BiSub => try!(checked_sub_int(e, a, b)),
+ ast::BiMul => try!(checked_mul_int(e, a, b)),
ast::BiDiv => {
if b == 0 {
- Err("attempted to divide by zero".to_string())
+ signal!(e, DivideByZero);
} else if b == -1 && is_a_min_value() {
- Err("attempted to divide with overflow".to_string())
+ signal!(e, DivideWithOverflow);
} else {
- Ok(const_int(a / b))
+ const_int(a / b)
}
}
ast::BiRem => {
if b == 0 {
- Err("attempted remainder with a divisor of zero".to_string())
+ signal!(e, ModuloByZero)
} else if b == -1 && is_a_min_value() {
- Err("attempted remainder with overflow".to_string())
+ signal!(e, ModuloWithOverflow)
} else {
- Ok(const_int(a % b))
+ const_int(a % b)
}
}
- ast::BiAnd | ast::BiBitAnd => Ok(const_int(a & b)),
- ast::BiOr | ast::BiBitOr => Ok(const_int(a | b)),
- ast::BiBitXor => Ok(const_int(a ^ b)),
- ast::BiShl => Ok(const_int(a << b as uint)),
- ast::BiShr => Ok(const_int(a >> b as uint)),
+ ast::BiAnd | ast::BiBitAnd => const_int(a & b),
+ ast::BiOr | ast::BiBitOr => const_int(a | b),
+ ast::BiBitXor => const_int(a ^ b),
+ ast::BiShl => const_int(a << b as uint),
+ ast::BiShr => const_int(a >> b as uint),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
ast::BiGt => fromb(a > b)
}
}
- (Ok(const_uint(a)), Ok(const_uint(b))) => {
+ (const_uint(a), const_uint(b)) => {
match op.node {
- ast::BiAdd => Ok(const_uint(a + b)),
- ast::BiSub => Ok(const_uint(a - b)),
- ast::BiMul => Ok(const_uint(a * b)),
- ast::BiDiv if b == 0 => {
- Err("attempted to divide by zero".to_string())
- }
- ast::BiDiv => Ok(const_uint(a / b)),
- ast::BiRem if b == 0 => {
- Err("attempted remainder with a divisor of \
- zero".to_string())
- }
- ast::BiRem => Ok(const_uint(a % b)),
- ast::BiAnd | ast::BiBitAnd => Ok(const_uint(a & b)),
- ast::BiOr | ast::BiBitOr => Ok(const_uint(a | b)),
- ast::BiBitXor => Ok(const_uint(a ^ b)),
- ast::BiShl => Ok(const_uint(a << b as uint)),
- ast::BiShr => Ok(const_uint(a >> b as uint)),
+ ast::BiAdd => try!(checked_add_uint(e, a, b)),
+ ast::BiSub => try!(checked_sub_uint(e, a, b)),
+ ast::BiMul => try!(checked_mul_uint(e, a, b)),
+ ast::BiDiv if b == 0 => signal!(e, DivideByZero),
+ ast::BiDiv => const_uint(a / b),
+ ast::BiRem if b == 0 => signal!(e, ModuloByZero),
+ ast::BiRem => const_uint(a % b),
+ ast::BiAnd | ast::BiBitAnd => const_uint(a & b),
+ ast::BiOr | ast::BiBitOr => const_uint(a | b),
+ ast::BiBitXor => const_uint(a ^ b),
+ ast::BiShl => const_uint(a << b as uint),
+ ast::BiShr => const_uint(a >> b as uint),
ast::BiEq => fromb(a == b),
ast::BiLt => fromb(a < b),
ast::BiLe => fromb(a <= b),
}
}
// shifts can have any integral type as their rhs
- (Ok(const_int(a)), Ok(const_uint(b))) => {
+ (const_int(a), const_uint(b)) => {
match op.node {
- ast::BiShl => Ok(const_int(a << b as uint)),
- ast::BiShr => Ok(const_int(a >> b as uint)),
- _ => Err("can't do this op on an int and uint".to_string())
+ ast::BiShl => const_int(a << b as uint),
+ ast::BiShr => const_int(a >> b as uint),
+ _ => signal!(e, InvalidOpForIntUint(op.node)),
}
}
- (Ok(const_uint(a)), Ok(const_int(b))) => {
+ (const_uint(a), const_int(b)) => {
match op.node {
- ast::BiShl => Ok(const_uint(a << b as uint)),
- ast::BiShr => Ok(const_uint(a >> b as uint)),
- _ => Err("can't do this op on a uint and int".to_string())
+ ast::BiShl => const_uint(a << b as uint),
+ ast::BiShr => const_uint(a >> b as uint),
+ _ => signal!(e, InvalidOpForUintInt(op.node)),
}
}
- (Ok(const_bool(a)), Ok(const_bool(b))) => {
- Ok(const_bool(match op.node {
+ (const_bool(a), const_bool(b)) => {
+ const_bool(match op.node {
ast::BiAnd => a && b,
ast::BiOr => a || b,
ast::BiBitXor => a ^ b,
ast::BiBitOr => a | b,
ast::BiEq => a == b,
ast::BiNe => a != b,
- _ => return Err("can't do this op on bools".to_string())
- }))
+ _ => signal!(e, InvalidOpForBools(op.node)),
+ })
}
- _ => Err("bad operands for binary".to_string())
+
+ _ => signal!(e, MiscBinaryOp),
}
}
ast::ExprCast(ref base, ref target_ty) => {
// Prefer known type to noop, but always have a type hint.
let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
- cast_const(val, ety)
+ match cast_const(val, ety) {
+ Ok(val) => val,
+ Err(kind) => return Err(ConstEvalErr { span: e.span, kind: kind }),
+ }
}
ast::ExprPath(..) => {
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
};
let const_expr = match const_expr {
Some(actual_e) => actual_e,
- None => return Err("non-constant path in constant expr".to_string())
+ None => signal!(e, NonConstPath)
};
let ety = ety.or_else(|| const_ty.and_then(|ty| ast_ty_to_prim_ty(tcx, ty)));
- eval_const_expr_partial(tcx, const_expr, ety)
+ try!(eval_const_expr_partial(tcx, const_expr, ety))
}
ast::ExprLit(ref lit) => {
- Ok(lit_to_const(&**lit, ety))
+ lit_to_const(&**lit, ety)
}
- ast::ExprParen(ref e) => eval_const_expr_partial(tcx, &**e, ety),
+ ast::ExprParen(ref e) => try!(eval_const_expr_partial(tcx, &**e, ety)),
ast::ExprBlock(ref block) => {
match block.expr {
- Some(ref expr) => eval_const_expr_partial(tcx, &**expr, ety),
- None => Ok(const_int(0i64))
+ Some(ref expr) => try!(eval_const_expr_partial(tcx, &**expr, ety)),
+ None => const_int(0)
}
}
ast::ExprTupField(ref base, index) => {
if let Some(&ast::ExprTup(ref fields)) = lookup_const(tcx, &**base).map(|s| &s.node) {
// Check that the given index is within bounds and evaluate its value
if fields.len() > index.node {
- return eval_const_expr_partial(tcx, &*fields[index.node], None)
+ return eval_const_expr_partial(tcx, &*fields[index.node], None);
} else {
- return Err("tuple index out of bounds".to_string())
+ signal!(e, TupleIndexOutOfBounds);
}
}
- Err("non-constant struct in constant expr".to_string())
+ signal!(e, NonConstStruct);
}
ast::ExprField(ref base, field_name) => {
// Get the base expression if it is a struct and it is constant
// Check that the given field exists and evaluate it
if let Some(f) = fields.iter().find(|f|
f.ident.node.as_str() == field_name.node.as_str()) {
- return eval_const_expr_partial(tcx, &*f.expr, None)
+ return eval_const_expr_partial(tcx, &*f.expr, None);
} else {
- return Err("nonexistent struct field".to_string())
+ signal!(e, MissingStructField);
}
}
- Err("non-constant struct in constant expr".to_string())
+ signal!(e, NonConstStruct);
}
- _ => Err("unsupported constant expr".to_string())
- }
+ _ => signal!(e, MiscCatchAll)
+ };
+
+ Ok(result)
}
-fn cast_const(val: const_val, ty: Ty) -> Result<const_val, String> {
+fn cast_const(val: const_val, ty: Ty) -> Result<const_val, ErrKind> {
macro_rules! define_casts {
($($ty_pat:pat => (
$intermediate_ty:ty,
const_uint(u) => Ok($const_type(u as $intermediate_ty as $target_ty)),
const_int(i) => Ok($const_type(i as $intermediate_ty as $target_ty)),
const_float(f) => Ok($const_type(f as $intermediate_ty as $target_ty)),
- _ => Err(concat!("can't cast this type to ",
- stringify!($const_type)).to_string())
+ _ => Err(ErrKind::CannotCastTo(stringify!($const_type))),
}
},)*
- _ => Err("can't cast this type".to_string())
+ _ => Err(ErrKind::CannotCast),
})
}
-> Option<Ordering> {
let a = match eval_const_expr_partial(tcx, a, ty_hint) {
Ok(a) => a,
- Err(s) => {
- tcx.sess.span_err(a.span, &s[..]);
+ Err(e) => {
+ tcx.sess.span_err(a.span, e.description().as_slice());
return None;
}
};
let b = match eval_const_expr_partial(tcx, b, ty_hint) {
Ok(b) => b,
- Err(s) => {
- tcx.sess.span_err(b.span, &s[..]);
+ Err(e) => {
+ tcx.sess.span_err(b.span, e.description().as_slice());
return None;
}
};
use middle::cfg;
use middle::cfg::CFGIndex;
use middle::ty;
-use std::old_io;
+use std::io;
use std::usize;
use std::iter::repeat;
use syntax::ast;
impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O> {
fn pre(&self,
ps: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
let id = match node {
pprust::NodeIdent(_) | pprust::NodeName(_) => 0,
pprust::NodeExpr(expr) => expr.id,
oper: O,
id_range: IdRange,
bits_per_id: uint) -> DataFlowContext<'a, 'tcx, O> {
- let words_per_id = (bits_per_id + usize::BITS - 1) / usize::BITS;
+ let words_per_id = (bits_per_id + usize::BITS as usize - 1) / usize::BITS as usize;
let num_nodes = cfg.graph.all_nodes().len();
debug!("DataFlowContext::new(analysis_name: {}, id_range={:?}, \
for (word_index, &word) in words.iter().enumerate() {
if word != 0 {
- let base_index = word_index * usize::BITS;
+ let base_index = word_index * usize::BITS as usize;
for offset in 0..usize::BITS {
let bit = 1 << offset;
if (word & bit) != 0 {
// whether the bit_index is greater than the
// actual value the user specified and stop
// iterating if so.
- let bit_index = base_index + offset;
+ let bit_index = base_index + offset as usize;
if bit_index >= self.bits_per_id {
return true;
} else if !f(bit_index) {
debug!("Dataflow result for {}:", self.analysis_name);
debug!("{}", {
- self.pretty_print_to(box old_io::stderr(), blk).unwrap();
+ let mut v = Vec::new();
+ self.pretty_print_to(box &mut v, blk).unwrap();
+ println!("{}", String::from_utf8(v).unwrap());
""
});
}
- fn pretty_print_to(&self, wr: Box<old_io::Writer+'static>,
- blk: &ast::Block) -> old_io::IoResult<()> {
+ fn pretty_print_to<'b>(&self, wr: Box<io::Write + 'b>,
+ blk: &ast::Block) -> io::Result<()> {
let mut ps = pprust::rust_printer_annotated(wr, self);
try!(ps.cbox(pprust::indent_unit));
try!(ps.ibox(0));
fn set_bit(words: &mut [uint], bit: uint) -> bool {
debug!("set_bit: words={} bit={}",
mut_bits_to_string(words), bit_str(bit));
- let word = bit / usize::BITS;
- let bit_in_word = bit % usize::BITS;
+ let word = bit / usize::BITS as usize;
+ let bit_in_word = bit % usize::BITS as usize;
let bit_mask = 1 << bit_in_word;
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, word);
let oldv = words[word];
// Does the required lifetime have a nice name we can print?
span_err!(self.tcx.sess, origin.span(), E0309,
"{} may not live long enough", labeled_user_string);
- self.tcx.sess.span_help(
+ self.tcx.sess.fileline_help(
origin.span(),
&format!(
"consider adding an explicit lifetime bound `{}: {}`...",
// Does the required lifetime have a nice name we can print?
span_err!(self.tcx.sess, origin.span(), E0310,
"{} may not live long enough", labeled_user_string);
- self.tcx.sess.span_help(
+ self.tcx.sess.fileline_help(
origin.span(),
&format!(
"consider adding an explicit lifetime bound `{}: 'static`...",
span_err!(self.tcx.sess, origin.span(), E0311,
"{} may not live long enough",
labeled_user_string);
- self.tcx.sess.span_help(
+ self.tcx.sess.fileline_help(
origin.span(),
&format!(
"consider adding an explicit lifetime bound for `{}`",
use std::borrow::Cow;
use std::collections::hash_map::Entry::Vacant;
-use std::old_io::{self, File};
use std::env;
+use std::fs::File;
+use std::io;
+use std::io::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use syntax::ast;
fn dump_region_constraints_to<'a, 'tcx:'a >(tcx: &'a ty::ctxt<'tcx>,
map: &ConstraintMap<'tcx>,
- path: &str) -> old_io::IoResult<()> {
+ path: &str) -> io::Result<()> {
debug!("dump_region_constraints map (len: {}) path: {}", map.len(), path);
let g = ConstraintGraph::new(tcx, format!("region_constraints"), map);
- let mut f = File::create(&Path::new(path));
debug!("dump_region_constraints calling render");
- dot::render(&g, &mut f)
+ let mut v = Vec::new();
+ dot::render(&g, &mut v).unwrap();
+ File::create(path).and_then(|mut f| f.write_all(&v))
}
}
pub fn item_name(index: uint) -> &'static str {
- let item: Option<LangItem> = FromPrimitive::from_uint(index);
+ let item: Option<LangItem> = FromPrimitive::from_usize(index);
match item {
$( Some($variant) => $name, )*
None => "???"
clean_exit_var: Variable
}
-static ACC_READ: u32 = 1;
-static ACC_WRITE: u32 = 2;
-static ACC_USE: u32 = 4;
+const ACC_READ: u32 = 1;
+const ACC_WRITE: u32 = 2;
+const ACC_USE: u32 = 4;
struct Liveness<'a, 'tcx: 'a> {
ir: &'a mut IrMaps<'a, 'tcx>,
/// Helper for discovering nodes to check for stability
pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
- if is_internal(tcx, e.span) { return; }
-
let span;
let id = match e.node {
ast::ExprMethodCall(i, _, _) => {
fn maybe_do_stability_check(tcx: &ty::ctxt, id: ast::DefId, span: Span,
cb: &mut FnMut(ast::DefId, Span, &Option<Stability>)) {
if !is_staged_api(tcx, id) { return }
+ if is_internal(tcx, span) { return }
let ref stability = lookup(tcx, id);
cb(id, span, stability);
}
fn is_internal(tcx: &ty::ctxt, span: Span) -> bool {
- tcx.sess.codemap().span_is_internal(span)
+ tcx.sess.codemap().span_allows_unstable(span)
}
fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool {
/// for the object type `Foo`.
#[derive(PartialEq,Eq,Clone)]
pub struct VtableObjectData<'tcx> {
+ /// the object type `Foo`.
pub object_ty: Ty<'tcx>,
+
+ /// `Foo` upcast to the obligation trait. This will be some supertrait of `Foo`.
+ pub upcast_trait_ref: ty::PolyTraitRef<'tcx>,
}
/// Creates predicate obligations from the generic bounds.
use middle::subst::{self, SelfSpace, TypeSpace};
use middle::traits;
-use middle::ty::{self, Ty};
+use middle::ty::{self, ToPolyTraitRef, Ty};
use std::rc::Rc;
use syntax::ast;
use util::ppaux::Repr;
{
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
let trait_ref = trait_def.trait_ref.clone();
- let predicates = ty::predicates_for_trait_ref(tcx, &ty::Binder(trait_ref));
+ let trait_ref = trait_ref.to_poly_trait_ref();
+ let predicates = ty::lookup_super_predicates(tcx, trait_def_id);
predicates
+ .predicates
.into_iter()
+ .map(|predicate| predicate.subst_supertrait(tcx, &trait_ref))
.any(|predicate| {
match predicate {
ty::Predicate::Trait(ref data) => {
poly_trait_ref.repr(self.tcx()));
// see whether the object trait can be upcast to the trait we are looking for
- let obligation_def_id = obligation.predicate.def_id();
- let upcast_trait_ref = match util::upcast(self.tcx(), poly_trait_ref, obligation_def_id) {
- Some(r) => r,
- None => { return; }
- };
-
- debug!("assemble_candidates_from_object_ty: upcast_trait_ref={}",
- upcast_trait_ref.repr(self.tcx()));
-
- // check whether the upcast version of the trait-ref matches what we are looking for
- if let Ok(()) = self.infcx.probe(|_| self.match_poly_trait_ref(obligation,
- upcast_trait_ref.clone())) {
- debug!("assemble_candidates_from_object_ty: matched, pushing candidate");
+ let upcast_trait_refs = self.upcast(poly_trait_ref, obligation);
+ if upcast_trait_refs.len() > 1 {
+ // can be upcast in many ways; need more type information
+ candidates.ambiguous = true;
+ } else if upcast_trait_refs.len() == 1 {
candidates.vec.push(ObjectCandidate);
}
}
let principal =
data.principal_trait_ref_with_self_ty(self.tcx(),
self.tcx().types.err);
+ let desired_def_id = obligation.predicate.def_id();
for tr in util::supertraits(self.tcx(), principal) {
- let td = ty::lookup_trait_def(self.tcx(), tr.def_id());
- if td.bounds.builtin_bounds.contains(&bound) {
+ if tr.def_id() == desired_def_id {
return Ok(If(Vec::new()))
}
}
}
};
- let obligation_def_id = obligation.predicate.def_id();
- let upcast_trait_ref = match util::upcast(self.tcx(),
- poly_trait_ref.clone(),
- obligation_def_id) {
- Some(r) => r,
- None => {
- self.tcx().sess.span_bug(obligation.cause.span,
- &format!("unable to upcast from {} to {}",
- poly_trait_ref.repr(self.tcx()),
- obligation_def_id.repr(self.tcx())));
- }
- };
+ // Upcast the object type to the obligation type. There must
+ // be exactly one applicable trait-reference; if this were not
+ // the case, we would have reported an ambiguity error rather
+ // than successfully selecting one of the candidates.
+ let upcast_trait_refs = self.upcast(poly_trait_ref.clone(), obligation);
+ assert_eq!(upcast_trait_refs.len(), 1);
+ let upcast_trait_ref = upcast_trait_refs.into_iter().next().unwrap();
- match self.match_poly_trait_ref(obligation, upcast_trait_ref) {
+ match self.match_poly_trait_ref(obligation, upcast_trait_ref.clone()) {
Ok(()) => { }
Err(()) => {
self.tcx().sess.span_bug(obligation.cause.span,
}
}
- VtableObjectData { object_ty: self_ty }
+ VtableObjectData { object_ty: self_ty,
+ upcast_trait_ref: upcast_trait_ref }
}
fn confirm_fn_pointer_candidate(&mut self,
obligation.cause.clone()
}
}
+
+ /// Upcasts an object trait-reference into those that match the obligation.
+ fn upcast(&mut self, obj_trait_ref: ty::PolyTraitRef<'tcx>, obligation: &TraitObligation<'tcx>)
+ -> Vec<ty::PolyTraitRef<'tcx>>
+ {
+ debug!("upcast(obj_trait_ref={}, obligation={})",
+ obj_trait_ref.repr(self.tcx()),
+ obligation.repr(self.tcx()));
+
+ let obligation_def_id = obligation.predicate.def_id();
+ let mut upcast_trait_refs = util::upcast(self.tcx(), obj_trait_ref, obligation_def_id);
+
+ // Retain only those upcast versions that match the trait-ref
+ // we are looking for. In particular, we know that all of
+ // `upcast_trait_refs` apply to the correct trait, but
+ // possibly with incorrect type parameters. For example, we
+ // may be trying to upcast `Foo` to `Bar<i32>`, but `Foo` is
+ // declared as `trait Foo : Bar<u32>`.
+ upcast_trait_refs.retain(|upcast_trait_ref| {
+ let upcast_trait_ref = upcast_trait_ref.clone();
+ self.infcx.probe(|_| self.match_poly_trait_ref(obligation, upcast_trait_ref)).is_ok()
+ });
+
+ debug!("upcast: upcast_trait_refs={}", upcast_trait_refs.repr(self.tcx()));
+ upcast_trait_refs
+ }
}
impl<'tcx> Repr<'tcx> for SelectionCandidate<'tcx> {
/// 'static`.
pub struct Elaborator<'cx, 'tcx:'cx> {
tcx: &'cx ty::ctxt<'tcx>,
- stack: Vec<StackEntry<'tcx>>,
+ stack: Vec<ty::Predicate<'tcx>>,
visited: PredicateSet<'cx,'tcx>,
}
-struct StackEntry<'tcx> {
- position: uint,
- predicates: Vec<ty::Predicate<'tcx>>,
-}
-
pub fn elaborate_trait_ref<'cx, 'tcx>(
tcx: &'cx ty::ctxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>)
{
let mut visited = PredicateSet::new(tcx);
predicates.retain(|pred| visited.insert(pred));
- let entry = StackEntry { position: 0, predicates: predicates };
- Elaborator { tcx: tcx, stack: vec![entry], visited: visited }
+ Elaborator { tcx: tcx, stack: predicates, visited: visited }
}
impl<'cx, 'tcx> Elaborator<'cx, 'tcx> {
- pub fn filter_to_traits(self) -> Supertraits<'cx, 'tcx> {
- Supertraits { elaborator: self }
+ pub fn filter_to_traits(self) -> FilterToTraits<Elaborator<'cx, 'tcx>> {
+ FilterToTraits::new(self)
}
fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
match *predicate {
ty::Predicate::Trait(ref data) => {
- let mut predicates =
- ty::predicates_for_trait_ref(self.tcx,
- &data.to_poly_trait_ref());
+ // Predicates declared on the trait.
+ let predicates = ty::lookup_super_predicates(self.tcx, data.def_id());
+
+ let mut predicates: Vec<_> =
+ predicates.predicates
+ .iter()
+ .map(|p| p.subst_supertrait(self.tcx, &data.to_poly_trait_ref()))
+ .collect();
+
+ debug!("super_predicates: data={} predicates={}",
+ data.repr(self.tcx), predicates.repr(self.tcx));
// Only keep those bounds that we haven't already
// seen. This is necessary to prevent infinite
// Sized { }`.
predicates.retain(|r| self.visited.insert(r));
- self.stack.push(StackEntry { position: 0,
- predicates: predicates });
+ self.stack.extend(predicates.into_iter());
}
ty::Predicate::Equate(..) => {
// Currently, we do not "elaborate" predicates like
type Item = ty::Predicate<'tcx>;
fn next(&mut self) -> Option<ty::Predicate<'tcx>> {
- loop {
- // Extract next item from top-most stack frame, if any.
- let next_predicate = match self.stack.last_mut() {
- None => {
- // No more stack frames. Done.
- return None;
- }
- Some(entry) => {
- let p = entry.position;
- if p < entry.predicates.len() {
- // Still more predicates left in the top stack frame.
- entry.position += 1;
-
- let next_predicate =
- entry.predicates[p].clone();
-
- Some(next_predicate)
- } else {
- None
- }
- }
- };
-
- match next_predicate {
- Some(next_predicate) => {
- self.push(&next_predicate);
- return Some(next_predicate);
- }
-
- None => {
- // Top stack frame is exhausted, pop it.
- self.stack.pop();
- }
+ // Extract next item from top-most stack frame, if any.
+ let next_predicate = match self.stack.pop() {
+ Some(predicate) => predicate,
+ None => {
+ // No more stack frames. Done.
+ return None;
}
- }
+ };
+ self.push(&next_predicate);
+ return Some(next_predicate);
}
}
// Supertrait iterator
///////////////////////////////////////////////////////////////////////////
-/// A filter around the `Elaborator` that just yields up supertrait references,
-/// not other kinds of predicates.
-pub struct Supertraits<'cx, 'tcx:'cx> {
- elaborator: Elaborator<'cx, 'tcx>,
-}
+pub type Supertraits<'cx, 'tcx> = FilterToTraits<Elaborator<'cx, 'tcx>>;
pub fn supertraits<'cx, 'tcx>(tcx: &'cx ty::ctxt<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>)
elaborate_trait_refs(tcx, bounds).filter_to_traits()
}
-impl<'cx, 'tcx> Iterator for Supertraits<'cx, 'tcx> {
+///////////////////////////////////////////////////////////////////////////
+// Other
+///////////////////////////////////////////////////////////////////////////
+
+/// A filter around an iterator of predicates that makes it yield up
+/// just trait references.
+pub struct FilterToTraits<I> {
+ base_iterator: I
+}
+
+impl<I> FilterToTraits<I> {
+ fn new(base: I) -> FilterToTraits<I> {
+ FilterToTraits { base_iterator: base }
+ }
+}
+
+impl<'tcx,I:Iterator<Item=ty::Predicate<'tcx>>> Iterator for FilterToTraits<I> {
type Item = ty::PolyTraitRef<'tcx>;
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
loop {
- match self.elaborator.next() {
+ match self.base_iterator.next() {
None => {
return None;
}
}
}
+
///////////////////////////////////////////////////////////////////////////
// Other
///////////////////////////////////////////////////////////////////////////
pub fn upcast<'tcx>(tcx: &ty::ctxt<'tcx>,
source_trait_ref: ty::PolyTraitRef<'tcx>,
target_trait_def_id: ast::DefId)
- -> Option<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::PolyTraitRef<'tcx>>
{
if source_trait_ref.def_id() == target_trait_def_id {
- return Some(source_trait_ref); // shorcut the most common case
- }
-
- for super_trait_ref in supertraits(tcx, source_trait_ref) {
- if super_trait_ref.def_id() == target_trait_def_id {
- return Some(super_trait_ref);
- }
+ return vec![source_trait_ref]; // shorcut the most common case
}
- None
+ supertraits(tcx, source_trait_ref)
+ .filter(|r| r.def_id() == target_trait_def_id)
+ .collect()
}
/// Given an object of type `object_trait_ref`, returns the index of
pub use self::InferRegion::*;
pub use self::ImplOrTraitItemId::*;
pub use self::ClosureKind::*;
-pub use self::ast_ty_to_ty_cache_entry::*;
pub use self::Variance::*;
pub use self::AutoAdjustment::*;
pub use self::Representability::*;
use std::mem;
use std::ops;
use std::rc::Rc;
-use std::vec::{CowVec, IntoIter};
+use std::vec::IntoIter;
use collections::enum_set::{EnumSet, CLike};
use std::collections::{HashMap, HashSet};
use syntax::abi;
pub len: uint
}
-#[derive(Copy)]
-pub enum ast_ty_to_ty_cache_entry<'tcx> {
- atttce_unresolved, /* not resolved yet */
- atttce_resolved(Ty<'tcx>) /* resolved to a type, irrespective of region */
-}
-
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable)]
pub struct ItemVariances {
pub types: VecPerParamSpace<Variance>,
/// associated predicates.
pub predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
+ /// Maps from the def-id of a trait to the list of
+ /// super-predicates. This is a subset of the full list of
+ /// predicates. We store these in a separate map because we must
+ /// evaluate them even during type conversion, often before the
+ /// full predicates are available (note that supertraits have
+ /// additional acyclicity requirements).
+ pub super_predicates: RefCell<DefIdMap<GenericPredicates<'tcx>>>,
+
/// Maps from node-id of a trait object cast (like `foo as
/// Box<Trait>`) to the trait reference.
pub object_cast_map: ObjectCastMap<'tcx>,
pub rcache: RefCell<FnvHashMap<creader_cache_key, Ty<'tcx>>>,
pub short_names_cache: RefCell<FnvHashMap<Ty<'tcx>, String>>,
pub tc_cache: RefCell<FnvHashMap<Ty<'tcx>, TypeContents>>,
- pub ast_ty_to_ty_cache: RefCell<NodeMap<ast_ty_to_ty_cache_entry<'tcx>>>,
+ pub ast_ty_to_ty_cache: RefCell<NodeMap<Ty<'tcx>>>,
pub enum_var_cache: RefCell<DefIdMap<Rc<Vec<Rc<VariantInfo<'tcx>>>>>>,
pub ty_param_defs: RefCell<NodeMap<TypeParameterDef<'tcx>>>,
pub adjustments: RefCell<NodeMap<AutoAdjustment<'tcx>>>,
/// definition and not a concrete use of it. To get the correct `ty_enum`
/// from the tcx, use the `NodeId` from the `ast::Ty` and look it up in
/// the `ast_ty_to_ty_cache`. This is probably true for `ty_struct` as
- /// well.`
+ /// well.
ty_enum(DefId, &'tcx Substs<'tcx>),
ty_uniq(Ty<'tcx>),
ty_str,
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct Binder<T>(pub T);
+impl<T> Binder<T> {
+ /// Skips the binder and returns the "bound" value. This is a
+ /// risky thing to do because it's easy to get confused about
+ /// debruijn indices and the like. It is usually better to
+ /// discharge the binder using `no_late_bound_regions` or
+ /// `replace_late_bound_regions` or something like
+ /// that. `skip_binder` is only valid when you are either
+ /// extracting data that has nothing to do with bound regions, you
+ /// are doing some sort of test that does not involve bound
+ /// regions, or you are being very careful about your depth
+ /// accounting.
+ ///
+ /// Some examples where `skip_binder` is reasonable:
+ /// - extracting the def-id from a PolyTraitRef;
+ /// - comparing the self type of a PolyTraitRef to see if it is equal to
+ /// a type parameter `X`, since the type `X` does not reference any regions
+ pub fn skip_binder(&self) -> &T {
+ &self.0
+ }
+}
+
#[derive(Clone, Copy, PartialEq)]
pub enum IntVarValue {
IntType(ast::IntTy),
predicates: self.predicates.subst(tcx, substs),
}
}
+
+ pub fn instantiate_supertrait(&self,
+ tcx: &ty::ctxt<'tcx>,
+ poly_trait_ref: &ty::PolyTraitRef<'tcx>)
+ -> InstantiatedPredicates<'tcx>
+ {
+ InstantiatedPredicates {
+ predicates: self.predicates.map(|pred| pred.subst_supertrait(tcx, poly_trait_ref))
+ }
+ }
}
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
Projection(PolyProjectionPredicate<'tcx>),
}
+impl<'tcx> Predicate<'tcx> {
+ /// Performs a substituion suitable for going from a
+ /// poly-trait-ref to supertraits that must hold if that
+ /// poly-trait-ref holds. This is slightly different from a normal
+ /// substitution in terms of what happens with bound regions. See
+ /// lengthy comment below for details.
+ pub fn subst_supertrait(&self,
+ tcx: &ty::ctxt<'tcx>,
+ trait_ref: &ty::PolyTraitRef<'tcx>)
+ -> ty::Predicate<'tcx>
+ {
+ // The interaction between HRTB and supertraits is not entirely
+ // obvious. Let me walk you (and myself) through an example.
+ //
+ // Let's start with an easy case. Consider two traits:
+ //
+ // trait Foo<'a> : Bar<'a,'a> { }
+ // trait Bar<'b,'c> { }
+ //
+ // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
+ // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
+ // knew that `Foo<'x>` (for any 'x) then we also know that
+ // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
+ // normal substitution.
+ //
+ // In terms of why this is sound, the idea is that whenever there
+ // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
+ // holds. So if there is an impl of `T:Foo<'a>` that applies to
+ // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
+ // `'a`.
+ //
+ // Another example to be careful of is this:
+ //
+ // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
+ // trait Bar1<'b,'c> { }
+ //
+ // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
+ // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
+ // reason is similar to the previous example: any impl of
+ // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
+ // basically we would want to collapse the bound lifetimes from
+ // the input (`trait_ref`) and the supertraits.
+ //
+ // To achieve this in practice is fairly straightforward. Let's
+ // consider the more complicated scenario:
+ //
+ // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
+ // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
+ // where both `'x` and `'b` would have a DB index of 1.
+ // The substitution from the input trait-ref is therefore going to be
+ // `'a => 'x` (where `'x` has a DB index of 1).
+ // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
+ // early-bound parameter and `'b' is a late-bound parameter with a
+ // DB index of 1.
+ // - If we replace `'a` with `'x` from the input, it too will have
+ // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
+ // just as we wanted.
+ //
+ // There is only one catch. If we just apply the substitution `'a
+ // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
+ // adjust the DB index because we substituting into a binder (it
+ // tries to be so smart...) resulting in `for<'x> for<'b>
+ // Bar1<'x,'b>` (we have no syntax for this, so use your
+ // imagination). Basically the 'x will have DB index of 2 and 'b
+ // will have DB index of 1. Not quite what we want. So we apply
+ // the substitution to the *contents* of the trait reference,
+ // rather than the trait reference itself (put another way, the
+ // substitution code expects equal binding levels in the values
+ // from the substitution and the value being substituted into, and
+ // this trick achieves that).
+
+ let substs = &trait_ref.0.substs;
+ match *self {
+ Predicate::Trait(ty::Binder(ref data)) =>
+ Predicate::Trait(ty::Binder(data.subst(tcx, substs))),
+ Predicate::Equate(ty::Binder(ref data)) =>
+ Predicate::Equate(ty::Binder(data.subst(tcx, substs))),
+ Predicate::RegionOutlives(ty::Binder(ref data)) =>
+ Predicate::RegionOutlives(ty::Binder(data.subst(tcx, substs))),
+ Predicate::TypeOutlives(ty::Binder(ref data)) =>
+ Predicate::TypeOutlives(ty::Binder(data.subst(tcx, substs))),
+ Predicate::Projection(ty::Binder(ref data)) =>
+ Predicate::Projection(ty::Binder(data.subst(tcx, substs))),
+ }
+ }
+}
+
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: Rc<TraitRef<'tcx>>
/// implements the trait.
pub generics: Generics<'tcx>,
- /// The "supertrait" bounds.
- pub bounds: ParamBounds<'tcx>,
-
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
/// A list of the associated types defined in this trait. Useful
impl_trait_refs: RefCell::new(NodeMap()),
trait_defs: RefCell::new(DefIdMap()),
predicates: RefCell::new(DefIdMap()),
+ super_predicates: RefCell::new(DefIdMap()),
object_cast_map: RefCell::new(NodeMap()),
map: map,
intrinsic_defs: RefCell::new(DefIdMap()),
pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
-> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
+ use std::num::Int; // For checked_add
memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
if ast::LOCAL_CRATE != id.krate {
Rc::new(csearch::get_enum_variants(cx, id))
let mut last_discriminant: Option<Disr> = None;
Rc::new(enum_definition.variants.iter().map(|variant| {
- let mut discriminant = match last_discriminant {
- Some(val) => val + 1,
- None => INITIAL_DISCRIMINANT_VALUE
- };
-
+ let mut discriminant = INITIAL_DISCRIMINANT_VALUE;
if let Some(ref e) = variant.node.disr_expr {
// Preserve all values, and prefer signed.
let ty = Some(cx.types.i64);
"expected signed integer constant");
}
Err(err) => {
- span_err!(cx.sess, e.span, E0305,
- "expected constant: {}", err);
+ span_err!(cx.sess, err.span, E0305,
+ "constant evaluation error: {}",
+ err.description().as_slice());
}
}
- };
+ } else {
+ if let Some(val) = last_discriminant {
+ if let Some(v) = val.checked_add(1) {
+ discriminant = v
+ } else {
+ cx.sess.span_err(
+ variant.span,
+ &format!("Discriminant overflowed!"));
+ }
+ } else {
+ discriminant = INITIAL_DISCRIMINANT_VALUE;
+ }
+ }
last_discriminant = Some(discriminant);
Rc::new(VariantInfo::from_ast_variant(cx, &**variant,
})
}
-/// Given the did of a trait, returns its full set of predicates.
+/// Given the did of an item, returns its full set of predicates.
pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
-> GenericPredicates<'tcx>
{
})
}
-/// Given a reference to a trait, returns the "superbounds" declared
-/// on the trait, with appropriate substitutions applied. Basically,
-/// this applies a filter to the where clauses on the trait, returning
-/// those that have the form:
-///
-/// Self : SuperTrait<...>
-/// Self : 'region
-pub fn predicates_for_trait_ref<'tcx>(tcx: &ctxt<'tcx>,
- trait_ref: &PolyTraitRef<'tcx>)
- -> Vec<ty::Predicate<'tcx>>
+/// Given the did of a trait, returns its superpredicates.
+pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
+ -> GenericPredicates<'tcx>
{
- let trait_def = lookup_trait_def(tcx, trait_ref.def_id());
-
- debug!("bounds_for_trait_ref(trait_def={:?}, trait_ref={:?})",
- trait_def.repr(tcx), trait_ref.repr(tcx));
-
- // The interaction between HRTB and supertraits is not entirely
- // obvious. Let me walk you (and myself) through an example.
- //
- // Let's start with an easy case. Consider two traits:
- //
- // trait Foo<'a> : Bar<'a,'a> { }
- // trait Bar<'b,'c> { }
- //
- // Now, if we have a trait reference `for<'x> T : Foo<'x>`, then
- // we can deduce that `for<'x> T : Bar<'x,'x>`. Basically, if we
- // knew that `Foo<'x>` (for any 'x) then we also know that
- // `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
- // normal substitution.
- //
- // In terms of why this is sound, the idea is that whenever there
- // is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
- // holds. So if there is an impl of `T:Foo<'a>` that applies to
- // all `'a`, then we must know that `T:Bar<'a,'a>` holds for all
- // `'a`.
- //
- // Another example to be careful of is this:
- //
- // trait Foo1<'a> : for<'b> Bar1<'a,'b> { }
- // trait Bar1<'b,'c> { }
- //
- // Here, if we have `for<'x> T : Foo1<'x>`, then what do we know?
- // The answer is that we know `for<'x,'b> T : Bar1<'x,'b>`. The
- // reason is similar to the previous example: any impl of
- // `T:Foo1<'x>` must show that `for<'b> T : Bar1<'x, 'b>`. So
- // basically we would want to collapse the bound lifetimes from
- // the input (`trait_ref`) and the supertraits.
- //
- // To achieve this in practice is fairly straightforward. Let's
- // consider the more complicated scenario:
- //
- // - We start out with `for<'x> T : Foo1<'x>`. In this case, `'x`
- // has a De Bruijn index of 1. We want to produce `for<'x,'b> T : Bar1<'x,'b>`,
- // where both `'x` and `'b` would have a DB index of 1.
- // The substitution from the input trait-ref is therefore going to be
- // `'a => 'x` (where `'x` has a DB index of 1).
- // - The super-trait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
- // early-bound parameter and `'b' is a late-bound parameter with a
- // DB index of 1.
- // - If we replace `'a` with `'x` from the input, it too will have
- // a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
- // just as we wanted.
- //
- // There is only one catch. If we just apply the substitution `'a
- // => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
- // adjust the DB index because we substituting into a binder (it
- // tries to be so smart...) resulting in `for<'x> for<'b>
- // Bar1<'x,'b>` (we have no syntax for this, so use your
- // imagination). Basically the 'x will have DB index of 2 and 'b
- // will have DB index of 1. Not quite what we want. So we apply
- // the substitution to the *contents* of the trait reference,
- // rather than the trait reference itself (put another way, the
- // substitution code expects equal binding levels in the values
- // from the substitution and the value being substituted into, and
- // this trick achieves that).
-
- // Carefully avoid the binder introduced by each trait-ref by
- // substituting over the substs, not the trait-refs themselves,
- // thus achieving the "collapse" described in the big comment
- // above.
- let trait_bounds: Vec<_> =
- trait_def.bounds.trait_bounds
- .iter()
- .map(|poly_trait_ref| ty::Binder(poly_trait_ref.0.subst(tcx, trait_ref.substs())))
- .collect();
-
- let projection_bounds: Vec<_> =
- trait_def.bounds.projection_bounds
- .iter()
- .map(|poly_proj| ty::Binder(poly_proj.0.subst(tcx, trait_ref.substs())))
- .collect();
-
- debug!("bounds_for_trait_ref: trait_bounds={} projection_bounds={}",
- trait_bounds.repr(tcx),
- projection_bounds.repr(tcx));
-
- // The region bounds and builtin bounds do not currently introduce
- // binders so we can just substitute in a straightforward way here.
- let region_bounds =
- trait_def.bounds.region_bounds.subst(tcx, trait_ref.substs());
- let builtin_bounds =
- trait_def.bounds.builtin_bounds.subst(tcx, trait_ref.substs());
-
- let bounds = ty::ParamBounds {
- trait_bounds: trait_bounds,
- region_bounds: region_bounds,
- builtin_bounds: builtin_bounds,
- projection_bounds: projection_bounds,
- };
-
- predicates(tcx, trait_ref.self_ty(), &bounds)
+ memoized(&cx.super_predicates, did, |did: DefId| {
+ assert!(did.krate != ast::LOCAL_CRATE);
+ csearch::get_super_predicates(cx, did)
+ })
}
pub fn predicates<'tcx>(
/// Get the attributes of a definition.
pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
- -> CowVec<'tcx, ast::Attribute> {
+ -> Cow<'tcx, [ast::Attribute]> {
if is_local(did) {
let item = tcx.map.expect_item(did.node);
Cow::Borrowed(&item.attrs)
pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
#![allow(non_upper_case_globals)]
- static tycat_other: int = 0;
- static tycat_bool: int = 1;
- static tycat_char: int = 2;
- static tycat_int: int = 3;
- static tycat_float: int = 4;
- static tycat_raw_ptr: int = 6;
-
- static opcat_add: int = 0;
- static opcat_sub: int = 1;
- static opcat_mult: int = 2;
- static opcat_shift: int = 3;
- static opcat_rel: int = 4;
- static opcat_eq: int = 5;
- static opcat_bit: int = 6;
- static opcat_logic: int = 7;
- static opcat_mod: int = 8;
+ const tycat_other: int = 0;
+ const tycat_bool: int = 1;
+ const tycat_char: int = 2;
+ const tycat_int: int = 3;
+ const tycat_float: int = 4;
+ const tycat_raw_ptr: int = 6;
+
+ const opcat_add: int = 0;
+ const opcat_sub: int = 1;
+ const opcat_mult: int = 2;
+ const opcat_shift: int = 3;
+ const opcat_rel: int = 4;
+ const opcat_eq: int = 5;
+ const opcat_bit: int = 6;
+ const opcat_logic: int = 7;
+ const opcat_mod: int = 8;
fn opcat(op: ast::BinOp) -> int {
match op.node {
}
}
- static t: bool = true;
- static f: bool = false;
+ const t: bool = true;
+ const f: bool = false;
let tbl = [
// +, -, *, shift, rel, ==, bit, logic, mod
impl<'tcx> TypeFoldable<'tcx> for traits::VtableObjectData<'tcx> {
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> traits::VtableObjectData<'tcx> {
traits::VtableObjectData {
- object_ty: self.object_ty.fold_with(folder)
+ object_ty: self.object_ty.fold_with(folder),
+ upcast_trait_ref: self.upcast_trait_ref.fold_with(folder),
}
}
}
use metadata::creader::CrateReader;
use plugin::registry::Registry;
-use std::mem;
-use std::os;
-use std::dynamic_lib::DynamicLibrary;
use std::borrow::ToOwned;
+use std::dynamic_lib::DynamicLibrary;
+use std::env;
+use std::mem;
+use std::old_path;
+use std::path::PathBuf;
use syntax::ast;
use syntax::codemap::{Span, COMMAND_LINE_SP};
use syntax::ptr::P;
// Dynamically link a registrar function into the compiler process.
fn dylink_registrar(&mut self,
span: Span,
- path: Path,
+ path: PathBuf,
symbol: String) -> PluginRegistrarFun {
// Make sure the path contains a / or the linker will search for it.
- let path = os::getcwd().unwrap().join(&path);
+ let path = env::current_dir().unwrap().join(&path);
+ let path = old_path::Path::new(path.to_str().unwrap());
let lib = match DynamicLibrary::open(Some(&path)) {
Ok(lib) => lib,
/// This is the most general hook into `libsyntax`'s expansion behavior.
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
self.syntax_exts.push((name, match extension {
- NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)),
- IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
+ NormalTT(ext, _, allow_internal_unstable) => {
+ NormalTT(ext, Some(self.krate_span), allow_internal_unstable)
+ }
+ IdentTT(ext, _, allow_internal_unstable) => {
+ IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
+ }
Decorator(ext) => Decorator(ext),
Modifier(ext) => Modifier(ext),
MultiModifier(ext) => MultiModifier(ext),
/// It builds for you a `NormalTT` that calls `expander`,
/// and also takes care of interning the macro's name.
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
- self.register_syntax_extension(token::intern(name), NormalTT(box expander, None));
+ self.register_syntax_extension(token::intern(name),
+ NormalTT(Box::new(expander), None, false));
}
/// Register a compiler lint pass.
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::env;
use std::fmt;
+use std::path::PathBuf;
use llvm;
pub gc: bool,
pub optimize: OptLevel,
+ pub debug_assertions: bool,
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
// this.
pub search_paths: SearchPaths,
pub libs: Vec<(String, cstore::NativeLibraryKind)>,
- pub maybe_sysroot: Option<Path>,
+ pub maybe_sysroot: Option<PathBuf>,
pub target_triple: String,
// User-specified cfg meta items. The compiler itself will add additional
// items to the crate config, and during parsing the entire crate config
pub no_analysis: bool,
pub debugging_opts: DebuggingOptions,
/// Whether to write dependency files. It's (enabled, optional filename).
- pub write_dependency_info: (bool, Option<Path>),
+ pub write_dependency_info: (bool, Option<PathBuf>),
pub prints: Vec<PrintRequest>,
pub cg: CodegenOptions,
pub color: ColorConfig,
pub enum Input {
/// Load source from file
- File(Path),
+ File(PathBuf),
/// The string is the source
Str(String)
}
impl Input {
pub fn filestem(&self) -> String {
match *self {
- Input::File(ref ifile) => ifile.filestem_str().unwrap().to_string(),
+ Input::File(ref ifile) => ifile.file_stem().unwrap()
+ .to_str().unwrap().to_string(),
Input::Str(_) => "rust_out".to_string(),
}
}
#[derive(Clone)]
pub struct OutputFilenames {
- pub out_directory: Path,
+ pub out_directory: PathBuf,
pub out_filestem: String,
- pub single_output_file: Option<Path>,
+ pub single_output_file: Option<PathBuf>,
pub extra: String,
}
impl OutputFilenames {
- pub fn path(&self, flavor: OutputType) -> Path {
+ pub fn path(&self, flavor: OutputType) -> PathBuf {
match self.single_output_file {
Some(ref path) => return path.clone(),
None => {}
self.temp_path(flavor)
}
- pub fn temp_path(&self, flavor: OutputType) -> Path {
- let base = self.out_directory.join(self.filestem());
+ pub fn temp_path(&self, flavor: OutputType) -> PathBuf {
+ let base = self.out_directory.join(&self.filestem());
match flavor {
OutputTypeBitcode => base.with_extension("bc"),
OutputTypeAssembly => base.with_extension("s"),
}
}
- pub fn with_extension(&self, extension: &str) -> Path {
- self.out_directory.join(self.filestem()).with_extension(extension)
+ pub fn with_extension(&self, extension: &str) -> PathBuf {
+ self.out_directory.join(&self.filestem()).with_extension(extension)
}
pub fn filestem(&self) -> String {
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
- unstable_features: UnstableFeatures::Disallow
+ unstable_features: UnstableFeatures::Disallow,
+ debug_assertions: true,
}
}
CrateTypeStaticlib,
}
-
#[derive(Clone)]
pub enum Passes {
SomePasses(Vec<String>),
#[allow(non_upper_case_globals, dead_code)]
mod $mod_desc {
pub const parse_bool: Option<&'static str> = None;
- pub const parse_opt_bool: Option<&'static str> = None;
+ pub const parse_opt_bool: Option<&'static str> =
+ Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
pub const parse_string: Option<&'static str> = Some("a string");
pub const parse_opt_string: Option<&'static str> = Some("a string");
pub const parse_list: Option<&'static str> = Some("a space-separated list of strings");
fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
match v {
- Some(..) => false,
+ Some(s) => {
+ match s {
+ "n" | "no" | "off" => {
+ *slot = Some(false);
+ }
+ "y" | "yes" | "on" => {
+ *slot = Some(true);
+ }
+ _ => { return false; }
+ }
+
+ true
+ },
None => { *slot = Some(true); true }
}
}
2 = full debug info with variable and type information"),
opt_level: Option<uint> = (None, parse_opt_uint,
"Optimize with possible levels 0-3"),
+ debug_assertions: Option<bool> = (None, parse_opt_bool,
+ "explicitly enable the cfg(debug_assertions) directive"),
}
"Adds unstable command line options to rustc interface"),
print_enum_sizes: bool = (false, parse_bool,
"Print the size of enums and their variants"),
+ force_overflow_checks: Option<bool> = (None, parse_opt_bool,
+ "Force overflow checks on or off"),
}
pub fn default_lib_output() -> CrateType {
};
let mk = attr::mk_name_value_item_str;
- return vec!(// Target bindings.
+ let mut ret = vec![ // Target bindings.
attr::mk_word_item(fam.clone()),
mk(InternedString::new("target_os"), intern(os)),
mk(InternedString::new("target_family"), fam),
mk(InternedString::new("target_endian"), intern(end)),
mk(InternedString::new("target_pointer_width"),
intern(wordsz))
- );
+ ];
+ if sess.opts.debug_assertions {
+ ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
+ }
+ return ret;
}
pub fn append_configuration(cfg: &mut ast::CrateConfig,
let cg = build_codegen_options(matches);
- let sysroot_opt = matches.opt_str("sysroot").map(|m| Path::new(m));
+ let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::new(&m));
let target = matches.opt_str("target").unwrap_or(
host_triple().to_string());
let opt_level = {
}
}
};
+ let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No);
let gc = debugging_opts.gc;
let debuginfo = if matches.opt_present("g") {
if cg.debuginfo.is_some() {
alt_std_name: None,
libs: libs,
unstable_features: get_unstable_features_setting(),
+ debug_assertions: debug_assertions,
}
}
use rustc_back::target::Target;
+use std::path::{Path, PathBuf};
use std::cell::{Cell, RefCell};
-use std::os;
+use std::env;
pub mod config;
pub mod search_paths;
pub entry_fn: RefCell<Option<(NodeId, codemap::Span)>>,
pub entry_type: Cell<Option<config::EntryFnType>>,
pub plugin_registrar_fn: Cell<Option<ast::NodeId>>,
- pub default_sysroot: Option<Path>,
+ pub default_sysroot: Option<PathBuf>,
// The name of the root source file of the crate, in the local file system. The path is always
// expected to be absolute. `None` means that there is no source file.
- pub local_crate_source_file: Option<Path>,
- pub working_dir: Path,
+ pub local_crate_source_file: Option<PathBuf>,
+ pub working_dir: PathBuf,
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, codemap::Span, String)>>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
impl Session {
pub fn span_fatal(&self, sp: Span, msg: &str) -> ! {
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
self.diagnostic().span_fatal(sp, msg)
}
pub fn span_fatal_with_code(&self, sp: Span, msg: &str, code: &str) -> ! {
+ if self.opts.treat_err_as_bug {
+ self.span_bug(sp, msg);
+ }
self.diagnostic().span_fatal_with_code(sp, msg, code)
}
pub fn fatal(&self, msg: &str) -> ! {
+ if self.opts.treat_err_as_bug {
+ self.bug(msg);
+ }
self.diagnostic().handler().fatal(msg)
}
pub fn span_err(&self, sp: Span, msg: &str) {
}
pub fn build_session(sopts: config::Options,
- local_crate_source_file: Option<Path>,
+ local_crate_source_file: Option<PathBuf>,
registry: diagnostics::registry::Registry)
-> Session {
// FIXME: This is not general enough to make the warning lint completely override
}
pub fn build_session_(sopts: config::Options,
- local_crate_source_file: Option<Path>,
+ local_crate_source_file: Option<PathBuf>,
span_diagnostic: diagnostic::SpanHandler)
-> Session {
let host = match Target::search(config::host_triple()) {
if path.is_absolute() {
path.clone()
} else {
- os::getcwd().unwrap().join(&path)
+ env::current_dir().unwrap().join(&path)
}
);
plugin_registrar_fn: Cell::new(None),
default_sysroot: default_sysroot,
local_crate_source_file: local_crate_source_file,
- working_dir: os::getcwd().unwrap(),
+ working_dir: env::current_dir().unwrap(),
lint_store: RefCell::new(lint::LintStore::new()),
lints: RefCell::new(NodeMap()),
crate_types: RefCell::new(Vec::new()),
// except according to those terms.
use std::slice;
+use std::path::{Path, PathBuf};
#[derive(Clone, Debug)]
pub struct SearchPaths {
- paths: Vec<(PathKind, Path)>,
+ paths: Vec<(PathKind, PathBuf)>,
}
pub struct Iter<'a> {
kind: PathKind,
- iter: slice::Iter<'a, (PathKind, Path)>,
+ iter: slice::Iter<'a, (PathKind, PathBuf)>,
}
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
} else {
(PathKind::All, path)
};
- self.paths.push((kind, Path::new(path)));
+ self.paths.push((kind, PathBuf::new(path)));
}
pub fn iter(&self, kind: PathKind) -> Iter {
use std::cell::{RefCell, Cell};
use std::collections::HashMap;
+use std::collections::hash_state::HashState;
+use std::ffi::CString;
use std::fmt::Debug;
use std::hash::Hash;
use std::iter::repeat;
+use std::path::Path;
use std::time::Duration;
-use std::collections::hash_state::HashState;
use syntax::ast;
use syntax::visit;
}
}
}
+
+#[cfg(unix)]
+pub fn path2cstr(p: &Path) -> CString {
+ use std::os::unix::prelude::*;
+ use std::ffi::AsOsStr;
+ CString::new(p.as_os_str().as_bytes()).unwrap()
+}
+#[cfg(windows)]
+pub fn path2cstr(p: &Path) -> CString {
+ CString::new(p.to_str().unwrap()).unwrap()
+}
fn test_lev_distance() {
use std::char::{ from_u32, MAX };
// Test bytelength agnosticity
- for c in (0u32..MAX as u32)
+ for c in (0..MAX as u32)
.filter_map(|i| from_u32(i))
.map(|i| i.to_string()) {
assert_eq!(lev_distance(&c[..], &c[..]), 0);
let FnvHasher(mut hash) = *self;
for byte in bytes {
hash = hash ^ (*byte as u64);
- hash = hash * 0x100000001b3;
+ hash = hash.wrapping_mul(0x100000001b3);
}
*self = FnvHasher(hash);
}
impl<'tcx> Repr<'tcx> for ty::TraitDef<'tcx> {
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
- format!("TraitDef(generics={}, bounds={}, trait_ref={})",
+ format!("TraitDef(generics={}, trait_ref={})",
self.generics.repr(tcx),
- self.bounds.repr(tcx),
self.trait_ref.repr(tcx))
}
}
//! A helper class for dealing with static archives
-use std::old_io::fs::PathExtensions;
-use std::old_io::process::{Command, ProcessOutput};
-use std::old_io::{fs, TempDir};
-use std::old_io;
-use std::os;
+use std::env;
+use std::fs;
+use std::io::prelude::*;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output, Stdio};
use std::str;
use syntax::diagnostic::Handler as ErrorHandler;
-pub static METADATA_FILENAME: &'static str = "rust.metadata.bin";
+use tempdir::TempDir;
+
+pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
pub struct ArchiveConfig<'a> {
pub handler: &'a ErrorHandler,
- pub dst: Path,
- pub lib_search_paths: Vec<Path>,
+ pub dst: PathBuf,
+ pub lib_search_paths: Vec<PathBuf>,
pub slib_prefix: String,
pub slib_suffix: String,
pub maybe_ar_prog: Option<String>
pub struct Archive<'a> {
handler: &'a ErrorHandler,
- dst: Path,
- lib_search_paths: Vec<Path>,
+ dst: PathBuf,
+ lib_search_paths: Vec<PathBuf>,
slib_prefix: String,
slib_suffix: String,
maybe_ar_prog: Option<String>
archive: Archive<'a>,
work_dir: TempDir,
/// Filename of each member that should be added to the archive.
- members: Vec<Path>,
+ members: Vec<PathBuf>,
should_update_symbols: bool,
}
fn run_ar(handler: &ErrorHandler, maybe_ar_prog: &Option<String>,
args: &str, cwd: Option<&Path>,
- paths: &[&Path]) -> ProcessOutput {
+ paths: &[&Path]) -> Output {
let ar = match *maybe_ar_prog {
Some(ref ar) => &ar[..],
None => "ar"
};
let mut cmd = Command::new(ar);
- cmd.arg(args).args(paths);
+ cmd.arg(args).args(paths).stdout(Stdio::piped()).stderr(Stdio::piped());
debug!("{:?}", cmd);
match cwd {
Some(p) => {
- cmd.cwd(p);
+ cmd.current_dir(p);
debug!("inside {:?}", p.display());
}
None => {}
if !o.status.success() {
handler.err(&format!("{:?} failed with: {}", cmd, o.status));
handler.note(&format!("stdout ---\n{}",
- str::from_utf8(&o.output).unwrap()));
+ str::from_utf8(&o.stdout).unwrap()));
handler.note(&format!("stderr ---\n{}",
- str::from_utf8(&o.error).unwrap())
+ str::from_utf8(&o.stderr).unwrap())
);
handler.abort_if_errors();
}
}
pub fn find_library(name: &str, osprefix: &str, ossuffix: &str,
- search_paths: &[Path], handler: &ErrorHandler) -> Path {
+ search_paths: &[PathBuf],
+ handler: &ErrorHandler) -> PathBuf {
// On Windows, static libraries sometimes show up as libfoo.a and other
// times show up as foo.lib
let oslibname = format!("{}{}{}", osprefix, name, ossuffix);
let unixlibname = format!("lib{}.a", name);
for path in search_paths {
- debug!("looking for {} inside {:?}", name, path.display());
+ debug!("looking for {} inside {:?}", name, path);
let test = path.join(&oslibname[..]);
if test.exists() { return test }
if oslibname != unixlibname {
/// Lists all files in an archive
pub fn files(&self) -> Vec<String> {
let output = run_ar(self.handler, &self.maybe_ar_prog, "t", None, &[&self.dst]);
- let output = str::from_utf8(&output.output).unwrap();
+ let output = str::from_utf8(&output.stdout).unwrap();
// use lines_any because windows delimits output with `\r\n` instead of
// just `\n`
output.lines_any().map(|s| s.to_string()).collect()
/// Adds all of the contents of a native library to this archive. This will
/// search in the relevant locations for a library named `name`.
- pub fn add_native_library(&mut self, name: &str) -> old_io::IoResult<()> {
+ pub fn add_native_library(&mut self, name: &str) -> io::Result<()> {
let location = find_library(name,
&self.archive.slib_prefix,
&self.archive.slib_suffix,
/// This ignores adding the bytecode from the rlib, and if LTO is enabled
/// then the object file also isn't added.
pub fn add_rlib(&mut self, rlib: &Path, name: &str,
- lto: bool) -> old_io::IoResult<()> {
+ lto: bool) -> io::Result<()> {
// Ignoring obj file starting with the crate name
// as simple comparison is not enough - there
// might be also an extra name suffix
}
/// Adds an arbitrary file to this archive
- pub fn add_file(&mut self, file: &Path) -> old_io::IoResult<()> {
- let filename = Path::new(file.filename().unwrap());
+ pub fn add_file(&mut self, file: &Path) -> io::Result<()> {
+ let filename = Path::new(file.file_name().unwrap());
let new_file = self.work_dir.path().join(&filename);
try!(fs::copy(file, &new_file));
- self.members.push(filename);
+ self.members.push(filename.to_path_buf());
Ok(())
}
pub fn build(self) -> Archive<'a> {
// Get an absolute path to the destination, so `ar` will work even
// though we run it from `self.work_dir`.
- let abs_dst = os::getcwd().unwrap().join(&self.archive.dst);
+ let abs_dst = env::current_dir().unwrap().join(&self.archive.dst);
assert!(!abs_dst.is_relative());
- let mut args = vec![&abs_dst];
- let mut total_len = abs_dst.as_vec().len();
+ let mut args = vec![&*abs_dst];
+ let mut total_len = abs_dst.to_string_lossy().len();
if self.members.is_empty() {
// OSX `ar` does not allow using `r` with no members, but it does
// Don't allow the total size of `args` to grow beyond 32,000 bytes.
// Windows will raise an error if the argument string is longer than
// 32,768, and we leave a bit of extra space for the program name.
- static ARG_LENGTH_LIMIT: uint = 32000;
+ const ARG_LENGTH_LIMIT: uint = 32_000;
for member_name in &self.members {
- let len = member_name.as_vec().len();
+ let len = member_name.to_string_lossy().len();
// `len + 1` to account for the space that's inserted before each
// argument. (Windows passes command-line arguments as a single
args.clear();
args.push(&abs_dst);
- total_len = abs_dst.as_vec().len();
+ total_len = abs_dst.to_string_lossy().len();
}
args.push(member_name);
}
fn add_archive<F>(&mut self, archive: &Path, name: &str,
- mut skip: F) -> old_io::IoResult<()>
+ mut skip: F) -> io::Result<()>
where F: FnMut(&str) -> bool,
{
let loc = TempDir::new("rsar").unwrap();
// First, extract the contents of the archive to a temporary directory.
// We don't unpack directly into `self.work_dir` due to the possibility
// of filename collisions.
- let archive = os::getcwd().unwrap().join(archive);
+ let archive = env::current_dir().unwrap().join(archive);
run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
"x", Some(loc.path()), &[&archive]);
// We skip any files explicitly desired for skipping, and we also skip
// all SYMDEF files as these are just magical placeholders which get
// re-created when we make a new archive anyway.
- let files = try!(fs::readdir(loc.path()));
- for file in &files {
- let filename = file.filename_str().unwrap();
+ let files = try!(fs::read_dir(loc.path()));
+ for file in files {
+ let file = try!(file).path();
+ let filename = file.file_name().unwrap().to_str().unwrap();
if skip(filename) { continue }
if filename.contains(".SYMDEF") { continue }
filename
};
let new_filename = self.work_dir.path().join(&filename[..]);
- try!(fs::rename(file, &new_filename));
- self.members.push(Path::new(filename));
+ try!(fs::rename(&file, &new_filename));
+ self.members.push(PathBuf::new(&filename));
}
Ok(())
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::old_io;
+use std::io;
use std::old_io::fs;
+use std::old_io;
+use std::old_path;
use std::os;
+use std::path::{Path, PathBuf};
/// Returns an absolute path in the filesystem that `path` points to. The
/// returned path does not contain any symlinks in its hierarchy.
-pub fn realpath(original: &Path) -> old_io::IoResult<Path> {
- static MAX_LINKS_FOLLOWED: uint = 256;
+#[allow(deprecated)] // readlink is deprecated
+pub fn realpath(original: &Path) -> io::Result<PathBuf> {
+ let old = old_path::Path::new(original.to_str().unwrap());
+ match old_realpath(&old) {
+ Ok(p) => Ok(PathBuf::new(p.as_str().unwrap())),
+ Err(e) => Err(io::Error::new(io::ErrorKind::Other,
+ "realpath error",
+ Some(e.to_string())))
+ }
+}
+
+#[allow(deprecated)]
+fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> {
+ const MAX_LINKS_FOLLOWED: usize = 256;
let original = try!(os::getcwd()).join(original);
// Right now lstat on windows doesn't work quite well
mod test {
use std::old_io;
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive};
- use super::realpath;
+ use super::old_realpath as realpath;
use std::old_io::TempDir;
#[test]
#![feature(box_syntax)]
#![feature(collections)]
#![feature(core)]
+#![feature(old_fs)]
#![feature(hash)]
#![feature(int_uint)]
+#![feature(io)]
#![feature(old_io)]
-#![feature(os)]
#![feature(old_path)]
+#![feature(os)]
+#![feature(path)]
#![feature(rustc_private)]
#![feature(staged_api)]
-#![feature(path)]
+#![feature(rand)]
+#![feature(path_ext)]
extern crate syntax;
extern crate serialize;
pub mod abi;
pub mod archive;
+pub mod tempdir;
pub mod arm;
pub mod fs;
pub mod mips;
use std::collections::HashSet;
use std::env;
-use std::old_io::IoError;
-use std::os;
+use std::io;
+use std::path::{Path, PathBuf};
use syntax::ast;
-pub struct RPathConfig<F, G> where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
- pub used_crates: Vec<(ast::CrateNum, Option<Path>)>,
- pub out_filename: Path,
+pub struct RPathConfig<'a> {
+ pub used_crates: Vec<(ast::CrateNum, Option<PathBuf>)>,
+ pub out_filename: PathBuf,
pub is_like_osx: bool,
pub has_rpath: bool,
- pub get_install_prefix_lib_path: F,
- pub realpath: G,
+ pub get_install_prefix_lib_path: &'a mut FnMut() -> PathBuf,
+ pub realpath: &'a mut FnMut(&Path) -> io::Result<PathBuf>,
}
-pub fn get_rpath_flags<F, G>(config: RPathConfig<F, G>) -> Vec<String> where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
+pub fn get_rpath_flags(config: &mut RPathConfig) -> Vec<String> {
// No rpath on windows
if !config.has_rpath {
return Vec::new();
return ret;
}
-fn get_rpaths<F, G>(mut config: RPathConfig<F, G>, libs: &[Path]) -> Vec<String> where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpaths(config: &mut RPathConfig, libs: &[PathBuf]) -> Vec<String> {
debug!("output: {:?}", config.out_filename.display());
debug!("libs:");
for libpath in libs {
// Use relative paths to the libraries. Binaries can be moved
// as long as they maintain the relative relationship to the
// crates they depend on.
- let rel_rpaths = get_rpaths_relative_to_output(&mut config, libs);
+ let rel_rpaths = get_rpaths_relative_to_output(config, libs);
// And a final backup rpath to the global library location.
let fallback_rpaths = vec!(get_install_prefix_rpath(config));
return rpaths;
}
-fn get_rpaths_relative_to_output<F, G>(config: &mut RPathConfig<F, G>,
- libs: &[Path]) -> Vec<String> where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpaths_relative_to_output(config: &mut RPathConfig,
+ libs: &[PathBuf]) -> Vec<String> {
libs.iter().map(|a| get_rpath_relative_to_output(config, a)).collect()
}
-fn get_rpath_relative_to_output<F, G>(config: &mut RPathConfig<F, G>, lib: &Path) -> String where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String {
// Mac doesn't appear to support $ORIGIN
let prefix = if config.is_like_osx {
"@loader_path"
"$ORIGIN"
};
- let cwd = os::getcwd().unwrap();
+ let cwd = env::current_dir().unwrap();
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
lib.pop();
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap();
output.pop();
- let relative = lib.path_relative_from(&output);
- let relative = relative.expect("could not create rpath relative to output");
+ let relative = relativize(&lib, &output);
// FIXME (#9639): This needs to handle non-utf8 paths
- format!("{}/{}",
- prefix,
- relative.as_str().expect("non-utf8 component in path"))
+ format!("{}/{}", prefix,
+ relative.to_str().expect("non-utf8 component in path"))
}
-fn get_install_prefix_rpath<F, G>(config: RPathConfig<F, G>) -> String where
- F: FnOnce() -> Path,
- G: FnMut(&Path) -> Result<Path, IoError>,
-{
+fn relativize(path: &Path, rel: &Path) -> PathBuf {
+ let mut res = PathBuf::new("");
+ let mut cur = rel;
+ while !path.starts_with(cur) {
+ res.push("..");
+ match cur.parent() {
+ Some(p) => cur = p,
+ None => panic!("can't create relative paths across filesystems"),
+ }
+ }
+ match path.relative_from(cur) {
+ Some(s) => { res.push(s); res }
+ None => panic!("couldn't create relative path from {:?} to {:?}",
+ rel, path),
+ }
+
+}
+
+fn get_install_prefix_rpath(config: &mut RPathConfig) -> String {
let path = (config.get_install_prefix_lib_path)();
let path = env::current_dir().unwrap().join(&path);
// FIXME (#9639): This needs to handle non-utf8 paths
mod test {
use super::{RPathConfig};
use super::{minimize_rpaths, rpaths_to_flags, get_rpath_relative_to_output};
+ use std::path::{Path, PathBuf};
#[test]
fn test_rpaths_to_flags() {
}
#[test]
- #[cfg(any(target_os = "linux", target_os = "android"))]
fn test_rpath_relative() {
- let config = &mut RPathConfig {
- used_crates: Vec::new(),
- out_filename: Path::new("bin/rustc"),
- get_install_prefix_lib_path: || panic!(),
- has_rpath: true,
- is_like_osx: false,
- realpath: |p| Ok(p.clone())
- };
- let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
- assert_eq!(res, "$ORIGIN/../lib");
- }
-
- #[test]
- #[cfg(any(target_os = "freebsd",
- target_os = "dragonfly",
- target_os = "bitrig",
- target_os = "openbsd"))]
- fn test_rpath_relative() {
- let config = &mut RPathConfig {
- used_crates: Vec::new(),
- has_rpath: true,
- is_like_osx: false,
- out_filename: Path::new("bin/rustc"),
- get_install_prefix_lib_path: || panic!(),
- realpath: |p| Ok(p.clone())
- };
- let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
- assert_eq!(res, "$ORIGIN/../lib");
- }
-
- #[test]
- #[cfg(target_os = "macos")]
- fn test_rpath_relative() {
- let config = &mut RPathConfig {
- used_crates: Vec::new(),
- has_rpath: true,
- is_like_osx: true,
- out_filename: Path::new("bin/rustc"),
- get_install_prefix_lib_path: || panic!(),
- realpath: |p| Ok(p.clone())
- };
- let res = get_rpath_relative_to_output(config, &Path::new("lib/libstd.so"));
- assert_eq!(res, "@loader_path/../lib");
+ if cfg!(target_os = "macos") {
+ let config = &mut RPathConfig {
+ used_crates: Vec::new(),
+ has_rpath: true,
+ is_like_osx: true,
+ out_filename: PathBuf::new("bin/rustc"),
+ get_install_prefix_lib_path: &mut || panic!(),
+ realpath: &mut |p| Ok(p.to_path_buf()),
+ };
+ let res = get_rpath_relative_to_output(config,
+ Path::new("lib/libstd.so"));
+ assert_eq!(res, "@loader_path/../lib");
+ } else {
+ let config = &mut RPathConfig {
+ used_crates: Vec::new(),
+ out_filename: PathBuf::new("bin/rustc"),
+ get_install_prefix_lib_path: &mut || panic!(),
+ has_rpath: true,
+ is_like_osx: false,
+ realpath: &mut |p| Ok(p.to_path_buf()),
+ };
+ let res = get_rpath_relative_to_output(config,
+ Path::new("lib/libstd.so"));
+ assert_eq!(res, "$ORIGIN/../lib");
+ }
}
}
/// Create a new FixedBuffer64
fn new() -> FixedBuffer64 {
return FixedBuffer64 {
- buffer: [0u8; 64],
+ buffer: [0; 64],
buffer_idx: 0
};
}
/// Convenience function that retrieves the result of a digest as a
/// newly allocated vec of bytes.
fn result_bytes(&mut self) -> Vec<u8> {
- let mut buf: Vec<u8> = repeat(0u8).take((self.output_bits()+7)/8).collect();
+ let mut buf: Vec<u8> = repeat(0).take((self.output_bits()+7)/8).collect();
self.result(&mut buf);
buf
}
let mut g = self.h6;
let mut h = self.h7;
- let mut w = [0u32; 64];
+ let mut w = [0; 64];
// Sha-512 and Sha-256 use basically the same calculations which are implemented
// by these macros. Inlining the calculations seems to result in better generated code.
macro_rules! schedule_round { ($t:expr) => (
- w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
- )
+ w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7])
+ .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]);
+ )
}
macro_rules! sha2_round {
($A:ident, $B:ident, $C:ident, $D:ident,
$E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
{
- $H += sum1($E) + ch($E, $F, $G) + $K[$t] + w[$t];
- $D += $H;
- $H += sum0($A) + maj($A, $B, $C);
+ $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G))
+ .wrapping_add($K[$t]).wrapping_add(w[$t]);
+ $D = $D.wrapping_add($H);
+ $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C));
}
)
}
sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
}
- self.h0 += a;
- self.h1 += b;
- self.h2 += c;
- self.h3 += d;
- self.h4 += e;
- self.h5 += f;
- self.h6 += g;
- self.h7 += h;
+ self.h0 = self.h0.wrapping_add(a);
+ self.h1 = self.h1.wrapping_add(b);
+ self.h2 = self.h2.wrapping_add(c);
+ self.h3 = self.h3.wrapping_add(d);
+ self.h4 = self.h4.wrapping_add(e);
+ self.h5 = self.h5.wrapping_add(f);
+ self.h6 = self.h6.wrapping_add(g);
+ self.h7 = self.h7.wrapping_add(h);
}
}
let tests = wikipedia_tests;
- let mut sh = box Sha256::new();
+ let mut sh: Box<_> = box Sha256::new();
test_hash(&mut *sh, &tests);
}
#[bench]
pub fn sha256_10(b: &mut Bencher) {
let mut sh = Sha256::new();
- let bytes = [1u8; 10];
+ let bytes = [1; 10];
b.iter(|| {
sh.input(&bytes);
});
#[bench]
pub fn sha256_1k(b: &mut Bencher) {
let mut sh = Sha256::new();
- let bytes = [1u8; 1024];
+ let bytes = [1; 1024];
b.iter(|| {
sh.input(&bytes);
});
#[bench]
pub fn sha256_64k(b: &mut Bencher) {
let mut sh = Sha256::new();
- let bytes = [1u8; 65536];
+ let bytes = [1; 65536];
b.iter(|| {
sh.input(&bytes);
});
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::old_io::{Command, IoError, OtherIoError};
+use std::io;
+use std::process::Command;
use target::TargetOptions;
use self::Arch::*;
.arg("--show-sdk-path")
.arg("-sdk")
.arg(sdk_name)
- .spawn()
- .and_then(|c| c.wait_with_output())
+ .output()
.and_then(|output| {
if output.status.success() {
- Ok(String::from_utf8(output.output).unwrap())
+ Ok(String::from_utf8(output.stdout).unwrap())
} else {
- Err(IoError {
- kind: OtherIoError,
- desc: "process exit with error",
- detail: String::from_utf8(output.error).ok()})
+ let error = String::from_utf8(output.stderr);
+ Err(io::Error::new(io::ErrorKind::Other,
+ "process exit with error",
+ error.ok()))
}
});
use serialize::json::Json;
use syntax::{diagnostic, abi};
use std::default::Default;
-use std::old_io::fs::PathExtensions;
+use std::io::prelude::*;
mod windows_base;
mod linux_base;
base
}
- /// Search RUST_TARGET_PATH for a JSON file specifying the given target triple. Note that it
- /// could also just be a bare filename already, so also check for that. If one of the hardcoded
- /// targets we know about, just return it directly.
+ /// Search RUST_TARGET_PATH for a JSON file specifying the given target
+ /// triple. Note that it could also just be a bare filename already, so also
+ /// check for that. If one of the hardcoded targets we know about, just
+ /// return it directly.
///
- /// The error string could come from any of the APIs called, including filesystem access and
- /// JSON decoding.
+ /// The error string could come from any of the APIs called, including
+ /// filesystem access and JSON decoding.
pub fn search(target: &str) -> Result<Target, String> {
use std::env;
- use std::os;
use std::ffi::OsString;
- use std::old_io::File;
- use std::old_path::Path;
+ use std::fs::File;
+ use std::path::{Path, PathBuf};
use serialize::json;
fn load_file(path: &Path) -> Result<Target, String> {
- let mut f = try!(File::open(path).map_err(|e| format!("{:?}", e)));
- let obj = try!(json::from_reader(&mut f).map_err(|e| format!("{:?}", e)));
+ let mut f = try!(File::open(path).map_err(|e| e.to_string()));
+ let mut contents = Vec::new();
+ try!(f.read_to_end(&mut contents).map_err(|e| e.to_string()));
+ let obj = try!(json::from_reader(&mut &contents[..])
+ .map_err(|e| e.to_string()));
Ok(Target::from_json(obj))
}
let path = {
let mut target = target.to_string();
target.push_str(".json");
- Path::new(target)
+ PathBuf::new(&target)
};
- let target_path = env::var_os("RUST_TARGET_PATH").unwrap_or(OsString::from_str(""));
+ let target_path = env::var_os("RUST_TARGET_PATH")
+ .unwrap_or(OsString::from_str(""));
// FIXME 16351: add a sane default search path?
- for dir in os::split_paths(target_path.to_str().unwrap()).iter() {
- let p = dir.join(path.clone());
+ for dir in env::split_paths(&target_path) {
+ let p = dir.join(&path);
if p.is_file() {
return load_file(&p);
}
--- /dev/null
+// Copyright 2015 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::env;
+use std::io::{self, Error, ErrorKind};
+use std::fs;
+use std::path::{self, PathBuf, AsPath};
+use std::rand::{thread_rng, Rng};
+
+/// A wrapper for a path to temporary directory implementing automatic
+/// scope-based deletion.
+pub struct TempDir {
+ path: Option<PathBuf>,
+}
+
+// How many times should we (re)try finding an unused random name? It should be
+// enough that an attacker will run out of luck before we run out of patience.
+const NUM_RETRIES: u32 = 1 << 31;
+// How many characters should we include in a random file name? It needs to
+// be enough to dissuade an attacker from trying to preemptively create names
+// of that length, but not so huge that we unnecessarily drain the random number
+// generator of entropy.
+const NUM_RAND_CHARS: uint = 12;
+
+impl TempDir {
+ /// Attempts to make a temporary directory inside of `tmpdir` whose name
+ /// will have the prefix `prefix`. The directory will be automatically
+ /// deleted once the returned wrapper is destroyed.
+ ///
+ /// If no directory can be created, `Err` is returned.
+ #[allow(deprecated)] // rand usage
+ pub fn new_in<P: AsPath + ?Sized>(tmpdir: &P, prefix: &str)
+ -> io::Result<TempDir> {
+ let storage;
+ let mut tmpdir = tmpdir.as_path();
+ if !tmpdir.is_absolute() {
+ let cur_dir = try!(env::current_dir());
+ storage = cur_dir.join(tmpdir);
+ tmpdir = &storage;
+ // return TempDir::new_in(&cur_dir.join(tmpdir), prefix);
+ }
+
+ let mut rng = thread_rng();
+ for _ in 0..NUM_RETRIES {
+ let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect();
+ let leaf = if prefix.len() > 0 {
+ format!("{}.{}", prefix, suffix)
+ } else {
+ // If we're given an empty string for a prefix, then creating a
+ // directory starting with "." would lead to it being
+ // semi-invisible on some systems.
+ suffix
+ };
+ let path = tmpdir.join(&leaf);
+ match fs::create_dir(&path) {
+ Ok(_) => return Ok(TempDir { path: Some(path) }),
+ Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {}
+ Err(e) => return Err(e)
+ }
+ }
+
+ Err(Error::new(ErrorKind::PathAlreadyExists,
+ "too many temporary directories already exist",
+ None))
+ }
+
+ /// Attempts to make a temporary directory inside of `env::temp_dir()` whose
+ /// name will have the prefix `prefix`. The directory will be automatically
+ /// deleted once the returned wrapper is destroyed.
+ ///
+ /// If no directory can be created, `Err` is returned.
+ #[allow(deprecated)]
+ pub fn new(prefix: &str) -> io::Result<TempDir> {
+ TempDir::new_in(&env::temp_dir(), prefix)
+ }
+
+ /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
+ /// This discards the wrapper so that the automatic deletion of the
+ /// temporary directory is prevented.
+ pub fn into_path(mut self) -> PathBuf {
+ self.path.take().unwrap()
+ }
+
+ /// Access the wrapped `std::path::Path` to the temporary directory.
+ pub fn path(&self) -> &path::Path {
+ self.path.as_ref().unwrap()
+ }
+
+ /// Close and remove the temporary directory
+ ///
+ /// Although `TempDir` removes the directory on drop, in the destructor
+ /// any errors are ignored. To detect errors cleaning up the temporary
+ /// directory, call `close` instead.
+ pub fn close(mut self) -> io::Result<()> {
+ self.cleanup_dir()
+ }
+
+ fn cleanup_dir(&mut self) -> io::Result<()> {
+ match self.path {
+ Some(ref p) => fs::remove_dir_all(p),
+ None => Ok(())
+ }
+ }
+}
+
+impl Drop for TempDir {
+ fn drop(&mut self) {
+ let _ = self.cleanup_dir();
+ }
+}
+
+// the tests for this module need to change the path using change_dir,
+// and this doesn't play nicely with other tests so these unit tests are located
+// in src/test/run-pass/tempfile.rs
bitflags! {
flags AnotherSetOfFlags: i8 {
- const AnotherFlag = -1_i8,
+ const AnotherFlag = -1,
}
}
assert_eq!(FlagABC.bits(), 0b00000111);
assert_eq!(AnotherSetOfFlags::empty().bits(), 0b00);
- assert_eq!(AnotherFlag.bits(), !0_i8);
+ assert_eq!(AnotherFlag.bits(), !0);
}
#[test]
assert!(Flags::from_bits(0b11) == Some(FlagA | FlagB));
assert!(Flags::from_bits(0b1000) == None);
- assert!(AnotherSetOfFlags::from_bits(!0_i8) == Some(AnotherFlag));
+ assert!(AnotherSetOfFlags::from_bits(!0) == Some(AnotherFlag));
}
#[test]
assert!(Flags::from_bits_truncate(0b1000) == Flags::empty());
assert!(Flags::from_bits_truncate(0b1001) == FlagA);
- assert!(AnotherSetOfFlags::from_bits_truncate(0_i8) == AnotherSetOfFlags::empty());
+ assert!(AnotherSetOfFlags::from_bits_truncate(0) == AnotherSetOfFlags::empty());
}
#[test]
bccx.span_note(
move_to_span,
"attempting to move value to here");
- bccx.span_help(
+ bccx.fileline_help(
move_to_span,
&format!("to prevent the move, \
use `ref {0}` or `ref mut {0}` to capture value by \
// FIXME (pnkfelix): See discussion here
// https://github.com/pnkfelix/rust/commit/
// b2b39e8700e37ad32b486b9a8409b50a8a53aa51#commitcomment-7892003
-static DOWNCAST_PRINTED_OPERATOR : &'static str = " as ";
+const DOWNCAST_PRINTED_OPERATOR: &'static str = " as ";
// A local, "cleaned" version of `mc::InteriorKind` that drops
// information that is not relevant to loan-path analysis. (In
ol,
moved_lp_msg,
pat_ty.user_string(self.tcx)));
- self.tcx.sess.span_help(span,
+ self.tcx.sess.fileline_help(span,
"use `ref` to override");
}
moved_lp_msg,
expr_ty.user_string(self.tcx),
suggestion));
- self.tcx.sess.span_help(expr_span, help);
+ self.tcx.sess.fileline_help(expr_span, help);
}
}
self.tcx.sess.span_help(s, m);
}
+ pub fn fileline_help(&self, s: Span, m: &str) {
+ self.tcx.sess.fileline_help(s, m);
+ }
+
pub fn bckerr_to_string(&self, err: &BckError<'tcx>) -> String {
match err.code {
err_mutbl => {
}
if is_closure {
- self.tcx.sess.span_help(
+ self.tcx.sess.fileline_help(
span,
"closures behind references must be called via `&mut`");
}
}
#[allow(non_upper_case_globals)]
-static InvalidMovePathIndex: MovePathIndex =
- MovePathIndex(usize::MAX);
+const InvalidMovePathIndex: MovePathIndex = MovePathIndex(usize::MAX);
/// Index into `MoveData.moves`, used like a pointer
#[derive(Copy, PartialEq)]
}
#[allow(non_upper_case_globals)]
-static InvalidMoveIndex: MoveIndex =
- MoveIndex(usize::MAX);
+const InvalidMoveIndex: MoveIndex = MoveIndex(usize::MAX);
pub struct MovePath<'tcx> {
/// Loan path corresponding to this move path
use serialize::json;
use std::env;
-use std::os;
use std::ffi::OsString;
-use std::old_io::fs;
-use std::old_io;
+use std::fs;
+use std::io::{self, Write};
+use std::path::{Path, PathBuf};
use syntax::ast;
use syntax::ast_map;
use syntax::attr;
pub fn compile_input(sess: Session,
cfg: ast::CrateConfig,
input: &Input,
- outdir: &Option<Path>,
- output: &Option<Path>,
+ outdir: &Option<PathBuf>,
+ output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: CompileController) {
macro_rules! controller_entry_point{($point: ident, $make_state: expr) => ({
pub fn source_name(input: &Input) -> String {
match *input {
// FIXME (#9639): This needs to handle non-utf8 paths
- Input::File(ref ifile) => ifile.as_str().unwrap().to_string(),
+ Input::File(ref ifile) => ifile.to_str().unwrap().to_string(),
Input::Str(_) => anon_src()
}
}
impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
fn empty(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>)
+ out_dir: &'a Option<PathBuf>)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
input: input,
session: session,
- out_dir: out_dir.as_ref(),
+ out_dir: out_dir.as_ref().map(|s| &**s),
cfg: None,
krate: None,
crate_name: None,
fn state_after_parse(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>,
+ out_dir: &'a Option<PathBuf>,
krate: &'a ast::Crate)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
fn state_after_expand(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>,
+ out_dir: &'a Option<PathBuf>,
expanded_crate: &'a ast::Crate,
crate_name: &'a str)
-> CompileState<'a, 'ast, 'tcx> {
fn state_after_write_deps(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>,
+ out_dir: &'a Option<PathBuf>,
ast_map: &'a ast_map::Map<'ast>,
expanded_crate: &'a ast::Crate,
crate_name: &'a str)
fn state_after_analysis(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>,
+ out_dir: &'a Option<PathBuf>,
expanded_crate: &'a ast::Crate,
analysis: &'a ty::CrateAnalysis<'tcx>,
tcx: &'a ty::ctxt<'tcx>)
fn state_after_llvm(input: &'a Input,
session: &'a Session,
- out_dir: &'a Option<Path>,
+ out_dir: &'a Option<PathBuf>,
trans: &'a trans::CrateTranslation)
-> CompileState<'a, 'ast, 'tcx> {
CompileState {
if cfg!(windows) {
_old_path = env::var_os("PATH").unwrap_or(_old_path);
let mut new_path = sess.host_filesearch(PathKind::All).get_dylib_search_paths();
- new_path.extend(os::split_paths(_old_path.to_str().unwrap()).into_iter());
+ new_path.extend(env::split_paths(&_old_path));
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
}
let features = sess.features.borrow();
}
);
- // Needs to go *after* expansion to be able to check the results of macro expansion.
- time(time_passes, "complete gated feature checking", (), |_| {
+ // Needs to go *after* expansion to be able to check the results
+ // of macro expansion. This runs before #[cfg] to try to catch as
+ // much as possible (e.g. help the programmer avoid platform
+ // specific differences)
+ time(time_passes, "complete gated feature checking 1", (), |_| {
let features =
syntax::feature_gate::check_crate(sess.codemap(),
- &sess.parse_sess.span_diagnostic,
- &krate);
+ &sess.parse_sess.span_diagnostic,
+ &krate,
+ true);
*sess.features.borrow_mut() = features;
sess.abort_if_errors();
});
time(time_passes, "checking that all macro invocations are gone", &krate, |krate|
syntax::ext::expand::check_for_macros(&sess.parse_sess, krate));
+ // One final feature gating of the true AST that gets compiled
+ // later, to make sure we've got everything (e.g. configuration
+ // can insert new attributes via `cfg_attr`)
+ time(time_passes, "complete gated feature checking 2", (), |_| {
+ let features =
+ syntax::feature_gate::check_crate(sess.codemap(),
+ &sess.parse_sess.span_diagnostic,
+ &krate,
+ false);
+ *sess.features.borrow_mut() = features;
+ sess.abort_if_errors();
+ });
+
Some(krate)
}
// Remove assembly source, unless --save-temps was specified
if !sess.opts.cg.save_temps {
- fs::unlink(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
+ fs::remove_file(&outputs.temp_path(config::OutputTypeAssembly)).unwrap();
}
} else {
time(sess.time_passes(), "LLVM passes", (), |_|
outputs: &OutputFilenames) {
let old_path = env::var_os("PATH").unwrap_or(OsString::from_str(""));
let mut new_path = sess.host_filesearch(PathKind::All).get_tools_search_paths();
- new_path.extend(os::split_paths(old_path.to_str().unwrap()).into_iter());
+ new_path.extend(env::split_paths(&old_path));
env::set_var("PATH", &env::join_paths(new_path.iter()).unwrap());
time(sess.time_passes(), "linking", (), |_|
_ => return,
};
- let result = (|| -> old_io::IoResult<()> {
+ let result = (|| -> io::Result<()> {
// Build a list of files used to compile the output and
// write Makefile-compatible dependency rules
let files: Vec<String> = sess.codemap().files.borrow()
- .iter().filter(|fmap| fmap.is_real_file())
+ .iter()
+ .filter(|fmap| fmap.is_real_file())
+ .filter(|fmap| !fmap.is_imported())
.map(|fmap| escape_dep_filename(&fmap.name))
.collect();
- let mut file = try!(old_io::File::create(&deps_filename));
+ let mut file = try!(fs::File::create(&deps_filename));
for path in &out_filenames {
- try!(write!(&mut file as &mut Writer,
- "{}: {}\n\n", path.display(), files.connect(" ")));
+ try!(write!(&mut file,
+ "{}: {}\n\n", path.display(), files.connect(" ")));
}
Ok(())
})();
}
pub fn build_output_filenames(input: &Input,
- odir: &Option<Path>,
- ofile: &Option<Path>,
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>,
attrs: &[ast::Attribute],
sess: &Session)
-> OutputFilenames {
// We want to toss everything after the final '.'
let dirpath = match *odir {
Some(ref d) => d.clone(),
- None => Path::new(".")
+ None => PathBuf::new(".")
};
// If a crate name is present, we use it as the link name
sess.warn("ignoring --out-dir flag due to -o flag.");
}
OutputFilenames {
- out_directory: out_file.dir_path(),
- out_filestem: out_file.filestem_str().unwrap().to_string(),
+ out_directory: out_file.parent().unwrap().to_path_buf(),
+ out_filestem: out_file.file_stem().unwrap()
+ .to_str().unwrap().to_string(),
single_output_file: ofile,
extra: sess.opts.cg.extra_filename.clone(),
}
#![feature(old_io)]
#![feature(libc)]
#![feature(os)]
-#![feature(old_path)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(unicode)]
#![feature(exit_status)]
+#![feature(path)]
+#![feature(io)]
extern crate arena;
extern crate flate;
use rustc::util::common::time;
use std::cmp::Ordering::Equal;
-use std::old_io::{self, stdio};
-use std::iter::repeat;
use std::env;
+use std::iter::repeat;
+use std::old_io::{self, stdio};
+use std::path::PathBuf;
use std::sync::mpsc::channel;
use std::thread;
pub mod pretty;
-static BUG_REPORT_URL: &'static str =
+const BUG_REPORT_URL: &'static str =
"https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports";
}
// Extract output directory and file from matches.
-fn make_output(matches: &getopts::Matches) -> (Option<Path>, Option<Path>) {
- let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
- let ofile = matches.opt_str("o").map(|o| Path::new(o));
+fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
+ let odir = matches.opt_str("out-dir").map(|o| PathBuf::new(&o));
+ let ofile = matches.opt_str("o").map(|o| PathBuf::new(&o));
(odir, ofile)
}
// Extract input (string or file and optional path) from matches.
-fn make_input(free_matches: &[String]) -> Option<(Input, Option<Path>)> {
+fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
if free_matches.len() == 1 {
let ifile = &free_matches[0][..];
if ifile == "-" {
let src = String::from_utf8(contents).unwrap();
Some((Input::Str(src), None))
} else {
- Some((Input::File(Path::new(ifile)), Some(Path::new(ifile))))
+ Some((Input::File(PathBuf::new(ifile)), Some(PathBuf::new(ifile))))
}
} else {
None
&getopts::Matches,
&Session,
&Input,
- &Option<Path>,
- &Option<Path>)
+ &Option<PathBuf>,
+ &Option<PathBuf>)
-> Compilation;
// Called after we extract the input from the arguments. Gives the implementer
// an opportunity to change the inputs or to add some custom input handling.
// The default behaviour is to simply pass through the inputs.
- fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
+ fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
+ -> (Input, Option<PathBuf>) {
(input, input_path)
}
fn no_input(&mut self,
&getopts::Matches,
&config::Options,
- &Option<Path>,
- &Option<Path>,
+ &Option<PathBuf>,
+ &Option<PathBuf>,
&diagnostics::registry::Registry)
- -> Option<(Input, Option<Path>)>;
+ -> Option<(Input, Option<PathBuf>)>;
// Parse pretty printing information from the arguments. The implementer can
// choose to ignore this (the default will return None) which will skip pretty
fn no_input(&mut self,
matches: &getopts::Matches,
sopts: &config::Options,
- odir: &Option<Path>,
- ofile: &Option<Path>,
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>,
descriptions: &diagnostics::registry::Registry)
- -> Option<(Input, Option<Path>)> {
+ -> Option<(Input, Option<PathBuf>)> {
match matches.free.len() {
0 => {
if sopts.describe_lints {
matches: &getopts::Matches,
sess: &Session,
input: &Input,
- odir: &Option<Path>,
- ofile: &Option<Path>)
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>)
-> Compilation {
RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then(
|| RustcDefaultCalls::list_metadata(sess, matches, input))
if r.contains(&("ls".to_string())) {
match input {
&Input::File(ref ifile) => {
- let mut stdout = old_io::stdout();
let path = &(*ifile);
+ let mut v = Vec::new();
metadata::loader::list_file_metadata(sess.target.target.options.is_like_osx,
path,
- &mut stdout).unwrap();
+ &mut v).unwrap();
+ println!("{}", String::from_utf8(v).unwrap());
}
&Input::Str(_) => {
early_error("cannot list metadata for stdin");
fn print_crate_info(sess: &Session,
input: Option<&Input>,
- odir: &Option<Path>,
- ofile: &Option<Path>)
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>)
-> Compilation {
if sess.opts.prints.len() == 0 {
return Compilation::Continue;
style,
&id,
&t_outputs.with_extension(""));
- println!("{}", fname.filename_display());
+ println!("{}", fname.file_name().unwrap()
+ .to_string_lossy());
}
}
}
///
/// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler.
+#[allow(deprecated)]
pub fn monitor<F:FnOnce()+Send+'static>(f: F) {
- static STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
+ const STACK_SIZE: uint = 8 * 1024 * 1024; // 8MB
let (tx, rx) = channel();
let w = old_io::ChanWriter::new(tx);
use graphviz as dot;
-use std::old_io::{self, MemReader};
+use std::fs::File;
+use std::io::{self, Write};
+use std::old_io;
use std::option;
+use std::path::PathBuf;
use std::str::FromStr;
#[derive(Copy, PartialEq, Debug)]
impl<'ast> pprust::PpAnn for IdentifiedAnnotation<'ast> {
fn pre(&self,
s: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
match node {
pprust::NodeExpr(_) => s.popen(),
_ => Ok(())
}
fn post(&self,
s: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
match node {
pprust::NodeIdent(_) | pprust::NodeName(_) => Ok(()),
impl<'ast> pprust::PpAnn for HygieneAnnotation<'ast> {
fn post(&self,
s: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
match node {
pprust::NodeIdent(&ast::Ident { name: ast::Name(nm), ctxt }) => {
try!(pp::space(&mut s.s));
impl<'tcx> pprust::PpAnn for TypedAnnotation<'tcx> {
fn pre(&self,
s: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
match node {
pprust::NodeExpr(_) => s.popen(),
_ => Ok(())
}
fn post(&self,
s: &mut pprust::State,
- node: pprust::AnnNode) -> old_io::IoResult<()> {
+ node: pprust::AnnNode) -> io::Result<()> {
let tcx = &self.analysis.ty_cx;
match node {
pprust::NodeExpr(expr) => {
input: &Input,
ppm: PpMode,
opt_uii: Option<UserIdentifiedItem>,
- ofile: Option<Path>) {
+ ofile: Option<PathBuf>) {
let krate = driver::phase_1_parse_input(&sess, cfg, input);
let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
let src_name = driver::source_name(input);
let src = sess.codemap().get_filemap(&src_name[..])
- .src.as_bytes().to_vec();
- let mut rdr = MemReader::new(src);
+ .src
+ .as_ref()
+ .unwrap()
+ .as_bytes()
+ .to_vec();
+ let mut rdr = &src[..];
- let out = match ofile {
- None => box old_io::stdout() as Box<Writer+'static>,
- Some(p) => {
- let r = old_io::File::create(&p);
- match r {
- Ok(w) => box w as Box<Writer+'static>,
- Err(e) => panic!("print-print failed to open {} due to {}",
- p.display(), e),
- }
- }
- };
+ let mut out = Vec::new();
match (ppm, opt_uii) {
- (PpmSource(s), None) =>
+ (PpmSource(s), None) => {
+ let out: &mut Write = &mut out;
s.call_with_pp_support(
- sess, ast_map, &arenas, id, out, |annotation, out| {
+ sess, ast_map, &arenas, id, box out, |annotation, out| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
pprust::print_crate(sess.codemap(),
out,
annotation.pp_ann(),
is_expanded)
- }),
+ })
+ }
- (PpmSource(s), Some(uii)) =>
+ (PpmSource(s), Some(uii)) => {
+ let out: &mut Write = &mut out;
s.call_with_pp_support(
sess, ast_map, &arenas, id, (out,uii), |annotation, (out,uii)| {
debug!("pretty printing source code {:?}", s);
sess.diagnostic(),
src_name.to_string(),
&mut rdr,
- out,
+ box out,
annotation.pp_ann(),
is_expanded);
for node_id in uii.all_matching_node_ids(ast_map) {
try!(pp::hardbreak(&mut pp_state.s));
}
pp::eof(&mut pp_state.s)
- }),
+ })
+ }
(PpmFlowGraph(mode), opt_uii) => {
debug!("pretty printing flow graph for {:?}", opt_uii);
});
let code = blocks::Code::from_node(node);
+ let out: &mut Writer = &mut out;
match code {
Some(code) => {
let variants = gather_flowgraph_variants(&sess);
}
}
}
- }.unwrap()
+ }.unwrap();
+
+ match ofile {
+ None => print!("{}", String::from_utf8(out).unwrap()),
+ Some(p) => {
+ match File::create(&p) {
+ Ok(mut w) => w.write_all(&out).unwrap(),
+ Err(e) => panic!("print-print failed to open {} due to {}",
+ p.display(), e),
+ }
+ }
+ }
}
fn print_flowgraph<W:old_io::Writer>(variants: Vec<borrowck_dot::Variant>,
analysis: ty::CrateAnalysis,
code: blocks::Code,
mode: PpFlowGraphMode,
- mut out: W) -> old_io::IoResult<()> {
+ mut out: W) -> io::Result<()> {
let ty_cx = &analysis.ty_cx;
let cfg = match code {
blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
}
}
- fn expand_err_details(r: old_io::IoResult<()>) -> old_io::IoResult<()> {
+ fn expand_err_details(r: old_io::IoResult<()>) -> io::Result<()> {
r.map_err(|ioerr| {
- let orig_detail = ioerr.detail.clone();
- let m = "graphviz::render failed";
- old_io::IoError {
- detail: Some(match orig_detail {
- None => m.to_string(),
- Some(d) => format!("{}: {}", m, d)
- }),
- ..ioerr
- }
+ io::Error::new(io::ErrorKind::Other, "graphviz::render failed",
+ Some(ioerr.to_string()))
})
}
}
sub: &'a [RH<'a>]
}
-static EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
+const EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
struct ExpectErrorEmitter {
messages: Vec<String>
}
def::DefTy(..) => {
let tty = match self.cx.tcx.ast_ty_to_ty_cache.borrow().get(&id) {
- Some(&ty::atttce_resolved(t)) => t,
- _ => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
+ Some(&t) => t,
+ None => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
};
if !ty::is_ffi_safe(self.cx.tcx, tty) {
impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
- static MSG: &'static str = "use of `#[derive]` with a raw pointer";
+ const MSG: &'static str = "use of `#[derive]` with a raw pointer";
if let ast::TyPtr(..) = ty.node {
self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
}
for call in &self_call_spans {
sess.span_note(*call, "recursive call site")
}
- sess.span_help(sp, "a `loop` may express intention better if this is on purpose")
+ sess.fileline_help(sp, "a `loop` may express intention \
+ better if this is on purpose")
}
}
use std::ffi::CString;
use std::mem;
use std::raw;
+use std::path::Path;
pub struct ArchiveRO {
ptr: ArchiveRef,
/// If this archive is used with a mutable method, then an error will be
/// raised.
pub fn open(dst: &Path) -> Option<ArchiveRO> {
- unsafe {
- let s = CString::new(dst.as_vec()).unwrap();
+ return unsafe {
+ let s = path2cstr(dst);
let ar = ::LLVMRustOpenArchive(s.as_ptr());
if ar.is_null() {
None
} else {
Some(ArchiveRO { ptr: ar })
}
+ };
+
+ #[cfg(unix)]
+ fn path2cstr(p: &Path) -> CString {
+ use std::os::unix::prelude::*;
+ use std::ffi::AsOsStr;
+ CString::new(p.as_os_str().as_bytes()).unwrap()
+ }
+ #[cfg(windows)]
+ fn path2cstr(p: &Path) -> CString {
+ CString::new(p.to_str().unwrap()).unwrap()
}
}
#![feature(int_uint)]
#![feature(libc)]
#![feature(link_args)]
-#![feature(old_path)]
#![feature(staged_api)]
#![feature(std_misc)]
+#![feature(path)]
extern crate libc;
#[macro_use] #[no_link] extern crate rustc_bitflags;
}
}
Some(ref tr) => {
- // Any private types in a trait impl fall into two
+ // Any private types in a trait impl fall into three
// categories.
// 1. mentioned in the trait definition
// 2. mentioned in the type params/generics
+ // 3. mentioned in the associated types of the impl
//
// Those in 1. can only occur if the trait is in
// this crate and will've been warned about on the
// Those in 2. are warned via walk_generics and this
// call here.
visit::walk_path(self, &tr.path);
+
+ // Those in 3. are warned with this call.
+ for impl_item in impl_items {
+ match *impl_item {
+ ast::MethodImplItem(..) => {},
+ ast::TypeImplItem(ref typedef) => {
+ self.visit_ty(&typedef.typ);
+ }
+ }
+ }
}
}
} else if trait_ref.is_none() && self_is_public_path {
uses it like a function name",
path_name));
- self.session.span_help(expr.span,
- &format!("Did you mean to write: \
- `{} {{ /* fields */ }}`?",
- path_name));
+ let msg = format!("Did you mean to write: \
+ `{} {{ /* fields */ }}`?",
+ path_name);
+ if self.emit_errors {
+ self.session.fileline_help(expr.span, &msg);
+ } else {
+ self.session.span_help(expr.span, &msg);
+ }
} else {
// Write the result into the def map.
debug!("(resolving expr) resolved `{}`",
match type_res.map(|r| r.base_def) {
Some(DefTy(struct_id, _))
if self.structs.contains_key(&struct_id) => {
- self.resolve_error(expr.span,
+ self.resolve_error(expr.span,
&format!("`{}` is a structure name, but \
this expression \
uses it like a function name",
path_name));
- self.session.span_help(expr.span,
- &format!("Did you mean to write: \
- `{} {{ /* fields */ }}`?",
- path_name));
-
- }
+ let msg = format!("Did you mean to write: \
+ `{} {{ /* fields */ }}`?",
+ path_name);
+ if self.emit_errors {
+ self.session.fileline_help(expr.span, &msg);
+ } else {
+ self.session.span_help(expr.span, &msg);
+ }
+ }
_ => {
// Keep reporting some errors even if they're ignored above.
self.resolve_path(expr.id, path, 0, ValueNS, true);
use util::common::time;
use util::ppaux;
use util::sha2::{Digest, Sha256};
+use rustc_back::tempdir::TempDir;
-use std::old_io::fs::PathExtensions;
-use std::old_io::{fs, TempDir, Command};
-use std::old_io;
+use std::ffi::{AsOsStr, OsString};
+use std::fs::{self, PathExt};
+use std::io::{self, Read, Write};
use std::mem;
+use std::path::{Path, PathBuf};
+use std::process::Command;
use std::str;
-use std::string::String;
use flate;
use serialize::hex::ToHex;
use syntax::ast;
return validate(s.to_string(), Some(attr.span));
}
if let Input::File(ref path) = *input {
- if let Some(s) = path.filestem_str() {
+ if let Some(s) = path.file_stem().and_then(|s| s.to_str()) {
return validate(s.to_string(), None);
}
}
// e.g. `fn foo() { { fn a() {} } { fn a() {} } }`, so we
// generate unique characters from the node id. For now
// hopefully 3 characters is enough to avoid collisions.
- static EXTRA_CHARS: &'static str =
+ const EXTRA_CHARS: &'static str =
"abcdefghijklmnopqrstuvwxyz\
ABCDEFGHIJKLMNOPQRSTUVWXYZ\
0123456789";
}
pub fn remove(sess: &Session, path: &Path) {
- match fs::unlink(path) {
+ match fs::remove_file(path) {
Ok(..) => {}
Err(e) => {
sess.err(&format!("failed to remove {}: {}",
pub fn link_binary(sess: &Session,
trans: &CrateTranslation,
outputs: &OutputFilenames,
- crate_name: &str) -> Vec<Path> {
+ crate_name: &str) -> Vec<PathBuf> {
let mut out_filenames = Vec::new();
for &crate_type in &*sess.crate_types.borrow() {
if invalid_output_for_target(sess, crate_type) {
}
fn is_writeable(p: &Path) -> bool {
- match p.stat() {
+ match p.metadata() {
Err(..) => true,
- Ok(m) => m.perm & old_io::USER_WRITE == old_io::USER_WRITE
+ Ok(m) => !m.permissions().readonly()
}
}
pub fn filename_for_input(sess: &Session,
crate_type: config::CrateType,
name: &str,
- out_filename: &Path) -> Path {
+ out_filename: &Path) -> PathBuf {
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
match crate_type {
config::CrateTypeRlib => {
- out_filename.with_filename(format!("lib{}.rlib", libname))
+ out_filename.with_file_name(&format!("lib{}.rlib", libname))
}
config::CrateTypeDylib => {
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
&sess.target.target.options.dll_suffix);
- out_filename.with_filename(format!("{}{}{}",
- prefix,
- libname,
- suffix))
+ out_filename.with_file_name(&format!("{}{}{}",
+ prefix,
+ libname,
+ suffix))
}
config::CrateTypeStaticlib => {
- out_filename.with_filename(format!("lib{}.a", libname))
+ out_filename.with_file_name(&format!("lib{}.a", libname))
}
config::CrateTypeExecutable => {
let suffix = &sess.target.target.options.exe_suffix;
- out_filename.with_filename(format!("{}{}", libname, suffix))
+ out_filename.with_file_name(&format!("{}{}", libname, suffix))
}
}
}
trans: &CrateTranslation,
crate_type: config::CrateType,
outputs: &OutputFilenames,
- crate_name: &str) -> Path {
+ crate_name: &str) -> PathBuf {
let obj_filename = outputs.temp_path(OutputTypeObject);
let out_filename = match outputs.single_output_file {
Some(ref file) => file.clone(),
out_filename
}
-fn archive_search_paths(sess: &Session) -> Vec<Path> {
+fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
let mut search = Vec::new();
sess.target_filesearch(PathKind::Native).for_each_lib_search_path(|path, _| {
- search.push(path.clone());
+ search.push(path.to_path_buf());
FileDoesntMatch
});
return search;
let handler = &sess.diagnostic().handler;
let config = ArchiveConfig {
handler: handler,
- dst: out_filename.clone(),
+ dst: out_filename.to_path_buf(),
lib_search_paths: archive_search_paths(sess),
slib_prefix: sess.target.target.options.staticlib_prefix.clone(),
slib_suffix: sess.target.target.options.staticlib_suffix.clone(),
// the same filename for metadata (stomping over one another)
let tmpdir = TempDir::new("rustc").ok().expect("needs a temp dir");
let metadata = tmpdir.path().join(METADATA_FILENAME);
- match fs::File::create(&metadata).write_all(&trans.metadata) {
+ match fs::File::create(&metadata).and_then(|mut f| {
+ f.write_all(&trans.metadata)
+ }) {
Ok(..) => {}
Err(e) => {
sess.err(&format!("failed to write {}: {}",
let bc_deflated_filename = obj_filename.with_extension(
&format!("{}.bytecode.deflate", i));
- let bc_data = match fs::File::open(&bc_filename).read_to_end() {
- Ok(buffer) => buffer,
+ let mut bc_data = Vec::new();
+ match fs::File::open(&bc_filename).and_then(|mut f| {
+ f.read_to_end(&mut bc_data)
+ }) {
+ Ok(..) => {}
Err(e) => sess.fatal(&format!("failed to read bytecode: {}",
e))
- };
+ }
let bc_data_deflated = match flate::deflate_bytes(&bc_data[..]) {
Some(compressed) => compressed,
- None => sess.fatal(&format!("failed to compress bytecode from {}",
- bc_filename.display()))
+ None => sess.fatal(&format!("failed to compress bytecode \
+ from {}",
+ bc_filename.display()))
};
let mut bc_file_deflated = match fs::File::create(&bc_deflated_filename) {
Ok(file) => file,
Err(e) => {
- sess.fatal(&format!("failed to create compressed bytecode \
- file: {}", e))
+ sess.fatal(&format!("failed to create compressed \
+ bytecode file: {}", e))
}
};
match write_rlib_bytecode_object_v1(&mut bc_file_deflated,
- bc_data_deflated.as_slice()) {
+ &bc_data_deflated) {
Ok(()) => {}
Err(e) => {
sess.err(&format!("failed to write compressed bytecode: \
ab
}
-fn write_rlib_bytecode_object_v1<T: Writer>(writer: &mut T,
- bc_data_deflated: &[u8])
- -> ::std::old_io::IoResult<()> {
+fn write_rlib_bytecode_object_v1(writer: &mut Write,
+ bc_data_deflated: &[u8]) -> io::Result<()> {
let bc_data_deflated_size: u64 = bc_data_deflated.len() as u64;
- try! { writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC) };
- try! { writer.write_le_u32(1) };
- try! { writer.write_le_u64(bc_data_deflated_size) };
- try! { writer.write_all(&bc_data_deflated[..]) };
+ try!(writer.write_all(RLIB_BYTECODE_OBJECT_MAGIC));
+ try!(writer.write_all(&[1, 0, 0, 0]));
+ try!(writer.write_all(&[
+ (bc_data_deflated_size >> 0) as u8,
+ (bc_data_deflated_size >> 8) as u8,
+ (bc_data_deflated_size >> 16) as u8,
+ (bc_data_deflated_size >> 24) as u8,
+ (bc_data_deflated_size >> 32) as u8,
+ (bc_data_deflated_size >> 40) as u8,
+ (bc_data_deflated_size >> 48) as u8,
+ (bc_data_deflated_size >> 56) as u8,
+ ]));
+ try!(writer.write_all(&bc_data_deflated));
let number_of_bytes_written_so_far =
RLIB_BYTECODE_OBJECT_MAGIC.len() + // magic id
// padding byte to make it even. This works around a crash bug in LLDB
// (see issue #15950)
if number_of_bytes_written_so_far % 2 == 1 {
- try! { writer.write_u8(0) };
+ try!(writer.write_all(&[0]));
}
return Ok(());
pname,
prog.status));
sess.note(&format!("{:?}", &cmd));
- let mut output = prog.error.clone();
- output.push_all(&prog.output);
+ let mut output = prog.stderr.clone();
+ output.push_all(&prog.stdout);
sess.note(str::from_utf8(&output[..]).unwrap());
sess.abort_if_errors();
}
- debug!("linker stderr:\n{}", String::from_utf8(prog.error).unwrap());
- debug!("linker stdout:\n{}", String::from_utf8(prog.output).unwrap());
+ debug!("linker stderr:\n{}", String::from_utf8(prog.stderr).unwrap());
+ debug!("linker stdout:\n{}", String::from_utf8(prog.stdout).unwrap());
},
Err(e) => {
sess.err(&format!("could not exec the linker `{}`: {}",
if t.options.is_like_osx {
let morestack = lib_path.join("libmorestack.a");
- let mut v = b"-Wl,-force_load,".to_vec();
- v.push_all(morestack.as_vec());
- cmd.arg(&v[..]);
+ let mut v = OsString::from_str("-Wl,-force_load,");
+ v.push_os_str(morestack.as_os_str());
+ cmd.arg(&v);
} else {
cmd.args(&["-Wl,--whole-archive", "-lmorestack", "-Wl,--no-whole-archive"]);
}
// executable. This metadata is in a separate object file from the main
// object file, so we link that in here.
if dylib {
- cmd.arg(obj_filename.with_extension("metadata.o"));
+ cmd.arg(&obj_filename.with_extension("metadata.o"));
}
if t.options.is_like_osx {
cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
if sess.opts.cg.rpath {
- let mut v = "-Wl,-install_name,@rpath/".as_bytes().to_vec();
- v.push_all(out_filename.filename().unwrap());
- cmd.arg(&v[..]);
+ let mut v = OsString::from_str("-Wl,-install_name,@rpath/");
+ v.push_os_str(out_filename.file_name().unwrap());
+ cmd.arg(&v);
}
} else {
cmd.arg("-shared");
if sess.opts.cg.rpath {
let sysroot = sess.sysroot();
let target_triple = &sess.opts.target_triple;
- let get_install_prefix_lib_path = || {
+ let mut get_install_prefix_lib_path = || {
let install_prefix = option_env!("CFG_PREFIX").expect("CFG_PREFIX");
let tlib = filesearch::relative_target_lib_path(sysroot, target_triple);
- let mut path = Path::new(install_prefix);
+ let mut path = PathBuf::new(install_prefix);
path.push(&tlib);
path
};
- let rpath_config = RPathConfig {
+ let mut rpath_config = RPathConfig {
used_crates: sess.cstore.get_used_crates(cstore::RequireDynamic),
- out_filename: out_filename.clone(),
+ out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.target.options.has_rpath,
is_like_osx: sess.target.target.options.is_like_osx,
- get_install_prefix_lib_path: get_install_prefix_lib_path,
- realpath: ::util::fs::realpath
+ get_install_prefix_lib_path: &mut get_install_prefix_lib_path,
+ realpath: &mut ::util::fs::realpath
};
- cmd.args(&rpath::get_rpath_flags(rpath_config));
+ cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
}
// Finally add all the linker arguments provided on the command line along
let search_path = archive_search_paths(sess);
for l in staticlibs {
if takes_hints {
- cmd.arg(format!("-l{}", l));
+ cmd.arg(&format!("-l{}", l));
} else {
// -force_load is the OSX equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
&sess.target.target.options.staticlib_suffix,
&search_path[..],
&sess.diagnostic().handler);
- let mut v = b"-Wl,-force_load,".to_vec();
- v.push_all(lib.as_vec());
- cmd.arg(&v[..]);
+ let mut v = OsString::from_str("-Wl,-force_load,");
+ v.push_os_str(lib.as_os_str());
+ cmd.arg(&v);
}
}
if takes_hints {
for &(ref l, kind) in others {
match kind {
cstore::NativeUnknown => {
- cmd.arg(format!("-l{}", l));
+ cmd.arg(&format!("-l{}", l));
}
cstore::NativeFramework => {
cmd.arg("-framework").arg(&l[..]);
let src = sess.cstore.get_used_crate_source(cnum).unwrap();
match kind {
cstore::RequireDynamic => {
- add_dynamic_crate(cmd, sess, src.dylib.unwrap().0)
+ add_dynamic_crate(cmd, sess, &src.dylib.unwrap().0)
}
cstore::RequireStatic => {
- add_static_crate(cmd, sess, tmpdir, src.rlib.unwrap().0)
+ add_static_crate(cmd, sess, tmpdir, &src.rlib.unwrap().0)
}
}
}
// Converts a library file-stem into a cc -l argument
- fn unlib<'a>(config: &config::Config, stem: &'a [u8]) -> &'a [u8] {
- if stem.starts_with("lib".as_bytes()) && !config.target.options.is_like_windows {
+ fn unlib<'a>(config: &config::Config, stem: &'a str) -> &'a str {
+ if stem.starts_with("lib") && !config.target.options.is_like_windows {
&stem[3..]
} else {
stem
// Adds the static "rlib" versions of all crates to the command line.
fn add_static_crate(cmd: &mut Command, sess: &Session, tmpdir: &Path,
- cratepath: Path) {
+ cratepath: &Path) {
// When performing LTO on an executable output, all of the
// bytecode from the upstream libraries has already been
// included in our object file output. We need to modify all of
// If we're not doing LTO, then our job is simply to just link
// against the archive.
if sess.lto() {
- let name = cratepath.filename_str().unwrap();
+ let name = cratepath.file_name().unwrap().to_str().unwrap();
let name = &name[3..name.len() - 5]; // chop off lib/.rlib
time(sess.time_passes(),
&format!("altering {}.rlib", name),
(), |()| {
- let dst = tmpdir.join(cratepath.filename().unwrap());
+ let dst = tmpdir.join(cratepath.file_name().unwrap());
match fs::copy(&cratepath, &dst) {
Ok(..) => {}
Err(e) => {
// Fix up permissions of the copy, as fs::copy() preserves
// permissions, but the original file may have been installed
// by a package manager and may be read-only.
- match fs::chmod(&dst, old_io::USER_READ | old_io::USER_WRITE) {
+ match fs::metadata(&dst).and_then(|m| {
+ let mut perms = m.permissions();
+ perms.set_readonly(false);
+ fs::set_permissions(&dst, perms)
+ }) {
Ok(..) => {}
Err(e) => {
sess.err(&format!("failed to chmod {} when preparing \
archive.remove_file(&format!("{}.o", name));
let files = archive.files();
if files.iter().any(|s| s.ends_with(".o")) {
- cmd.arg(dst);
+ cmd.arg(&dst);
}
});
} else {
}
// Same thing as above, but for dynamic crates instead of static crates.
- fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: Path) {
+ fn add_dynamic_crate(cmd: &mut Command, sess: &Session, cratepath: &Path) {
// If we're performing LTO, then it should have been previously required
// that all upstream rust dependencies were available in an rlib format.
assert!(!sess.lto());
// Just need to tell the linker about where the library lives and
// what its name is
- let dir = cratepath.dirname();
- if !dir.is_empty() { cmd.arg("-L").arg(dir); }
-
- let mut v = "-l".as_bytes().to_vec();
- v.push_all(unlib(&sess.target, cratepath.filestem().unwrap()));
- cmd.arg(&v[..]);
+ if let Some(dir) = cratepath.parent() {
+ cmd.arg("-L").arg(dir);
+ }
+ let filestem = cratepath.file_stem().unwrap().to_str().unwrap();
+ cmd.arg(&format!("-l{}", unlib(&sess.target, filestem)));
}
}
for &(kind, ref lib) in &libs {
match kind {
cstore::NativeUnknown => {
- cmd.arg(format!("-l{}", *lib));
+ cmd.arg(&format!("-l{}", *lib));
}
cstore::NativeFramework => {
cmd.arg("-framework");
};
let archive = ArchiveRO::open(&path).expect("wanted an rlib");
- let file = path.filename_str().unwrap();
+ let file = path.file_name().unwrap().to_str().unwrap();
let file = &file[3..file.len() - 5]; // chop off lib/.rlib
debug!("reading {}", file);
for i in iter::count(0, 1) {
use llvm::SMDiagnosticRef;
use trans::{CrateTranslation, ModuleTranslation};
use util::common::time;
+use util::common::path2cstr;
use syntax::codemap;
use syntax::diagnostic;
use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
use std::ffi::{CStr, CString};
-use std::old_io::Command;
-use std::old_io::fs;
+use std::fs;
use std::iter::Unfold;
+use std::mem;
+use std::path::Path;
+use std::process::{Command, Stdio};
use std::ptr;
use std::str;
-use std::mem;
use std::sync::{Arc, Mutex};
use std::sync::mpsc::channel;
use std::thread;
output: &Path,
file_type: llvm::FileType) {
unsafe {
- let output_c = CString::new(output.as_vec()).unwrap();
+ let output_c = path2cstr(output);
let result = llvm::LLVMRustWriteOutputFile(
target, pm, m, output_c.as_ptr(), file_type);
if !result {
if config.emit_no_opt_bc {
let ext = format!("{}.no-opt.bc", name_extra);
let out = output_names.with_extension(&ext);
- let out = CString::new(out.as_vec()).unwrap();
+ let out = path2cstr(&out);
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
if config.emit_lto_bc {
let name = format!("{}.lto.bc", name_extra);
let out = output_names.with_extension(&name);
- let out = CString::new(out.as_vec()).unwrap();
+ let out = path2cstr(&out);
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
},
if config.emit_bc {
let ext = format!("{}.bc", name_extra);
let out = output_names.with_extension(&ext);
- let out = CString::new(out.as_vec()).unwrap();
+ let out = path2cstr(&out);
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
}
if config.emit_ir {
let ext = format!("{}.ll", name_extra);
let out = output_names.with_extension(&ext);
- let out = CString::new(out.as_vec()).unwrap();
+ let out = path2cstr(&out);
with_codegen(tm, llmod, config.no_builtins, |cpm| {
llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
})
cmd.arg("-nostdlib");
for index in 0..trans.modules.len() {
- cmd.arg(crate_output.with_extension(&format!("{}.o", index)));
+ cmd.arg(&crate_output.with_extension(&format!("{}.o", index)));
}
- cmd.arg("-r")
- .arg("-o")
- .arg(windows_output_path.as_ref().unwrap_or(output_path));
+ cmd.arg("-r").arg("-o")
+ .arg(windows_output_path.as_ref().map(|s| &**s).unwrap_or(output_path));
cmd.args(&sess.target.target.options.post_link_args);
println!("{:?}", &cmd);
}
- cmd.stdin(::std::old_io::process::Ignored)
- .stdout(::std::old_io::process::InheritFd(1))
- .stderr(::std::old_io::process::InheritFd(2));
+ cmd.stdin(Stdio::null());
match cmd.status() {
Ok(status) => {
if !status.success() {
let pname = get_cc_prog(sess);
let mut cmd = Command::new(&pname[..]);
- cmd.arg("-c").arg("-o").arg(outputs.path(config::OutputTypeObject))
- .arg(outputs.temp_path(config::OutputTypeAssembly));
- debug!("{:?}", &cmd);
+ cmd.arg("-c").arg("-o").arg(&outputs.path(config::OutputTypeObject))
+ .arg(&outputs.temp_path(config::OutputTypeAssembly));
+ debug!("{:?}", cmd);
match cmd.output() {
Ok(prog) => {
pname,
prog.status));
sess.note(&format!("{:?}", &cmd));
- let mut note = prog.error.clone();
- note.push_all(&prog.output);
+ let mut note = prog.stderr.clone();
+ note.push_all(&prog.stdout);
sess.note(str::from_utf8(¬e[..]).unwrap());
sess.abort_if_errors();
}
#![feature(collections)]
#![feature(core)]
#![feature(int_uint)]
-#![feature(old_io)]
#![feature(libc)]
-#![feature(old_path)]
#![feature(quote)]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
+#![feature(io)]
+#![feature(path)]
+#![feature(os)]
+#![feature(path_ext)]
+#![feature(fs)]
extern crate arena;
extern crate flate;
use middle::ty::{self, Ty};
use std::cell::Cell;
-use std::old_io::{self, File, fs};
use std::env;
+use std::fs::{self, File};
+use std::path::{Path, PathBuf};
use syntax::ast_util::{self, PostExpansionMethod};
use syntax::ast::{self, NodeId, DefId};
}
}
+#[allow(deprecated)]
pub fn process_crate(sess: &Session,
krate: &ast::Crate,
analysis: &ty::CrateAnalysis,
info!("Dumping crate {}", cratename);
// find a path to dump our data to
- let mut root_path = match env::var("DXR_RUST_TEMP_FOLDER") {
- Ok(val) => Path::new(val),
- Err(..) => match odir {
+ let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") {
+ Some(val) => PathBuf::new(&val),
+ None => match odir {
Some(val) => val.join("dxr"),
- None => Path::new("dxr-temp"),
+ None => PathBuf::new("dxr-temp"),
},
};
- match fs::mkdir_recursive(&root_path, old_io::USER_RWX) {
+ match fs::create_dir_all(&root_path) {
Err(e) => sess.err(&format!("Could not create directory {}: {}",
root_path.display(), e)),
_ => (),
// Create output file.
let mut out_name = cratename.clone();
out_name.push_str(".csv");
- root_path.push(out_name);
+ root_path.push(&out_name);
let output_file = match File::create(&root_path) {
Ok(f) => box f,
Err(e) => {
collected_paths: vec!(),
collecting: false,
fmt: FmtStrs::new(box Recorder {
- out: output_file as Box<Writer+'static>,
+ out: output_file,
dump_spans: false,
},
SpanUtils {
use super::escape;
use super::span_utils::SpanUtils;
-use std::vec::Vec;
+use std::io::Write;
use syntax::ast;
use syntax::ast::{NodeId,DefId};
pub struct Recorder {
// output file
- pub out: Box<Writer+'static>,
+ pub out: Box<Write+'static>,
pub dump_spans: bool,
}
debug!("range_to_inttype: {:?} {:?}", hint, bounds);
// Lists of sizes to try. u64 is always allowed as a fallback.
#[allow(non_upper_case_globals)]
- static choose_shortest: &'static[IntType] = &[
+ const choose_shortest: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU8), attr::SignedInt(ast::TyI8),
attr::UnsignedInt(ast::TyU16), attr::SignedInt(ast::TyI16),
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
#[allow(non_upper_case_globals)]
- static at_least_32: &'static[IntType] = &[
+ const at_least_32: &'static [IntType] = &[
attr::UnsignedInt(ast::TyU32), attr::SignedInt(ast::TyI32)];
let attempts;
assert!(bits <= 64);
let bits = bits as uint;
let mask = (-1u64 >> (64 - bits)) as Disr;
- if (max + 1) & mask == min & mask {
+ // For a (max) discr of -1, max will be `-1 as usize`, which overflows.
+ // However, that is fine here (it would still represent the full range),
+ if (max.wrapping_add(1)) & mask == min & mask {
// i.e., if the range is everything. The lo==hi case would be
// rejected by the LLVM verifier (it would mean either an
// empty set, which is impossible, or the entire range of the
} else {
// llvm::ConstantRange can deal with ranges that wrap around,
// so an overflow on (max + 1) is fine.
- LoadRangeAssert(bcx, ptr, min, (max+1), /* signed: */ True)
+ LoadRangeAssert(bcx, ptr, min, (max.wrapping_add(1)), /* signed: */ True)
}
}
let fcx = bcx.fcx;
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
let scratch = unpack_datum!(bcx, datum::lvalue_scratch_datum(
- bcx, tcx.types.bool, "drop_flag", false,
+ bcx, tcx.types.bool, "drop_flag",
cleanup::CustomScope(custom_cleanup_scope), (), |_, bcx, _| bcx
));
bcx = fold_variants(bcx, r, val, |variant_cx, st, value| {
let (is_zero, is_signed) = match rhs_t.sty {
ty::ty_int(t) => {
- let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false);
+ let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0, false);
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), true)
}
ty::ty_uint(t) => {
- let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false);
+ let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false);
(ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false)
}
_ => {
Alloca(cx, ty, name)
}
-pub fn alloca_zeroed<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
- name: &str) -> ValueRef {
- let llty = type_of::type_of(cx.ccx(), ty);
- if cx.unreachable.get() {
- unsafe {
- return llvm::LLVMGetUndef(llty.ptr_to().to_ref());
- }
- }
- let p = alloca_no_lifetime(cx, llty, name);
- let b = cx.fcx.ccx.builder();
- b.position_before(cx.fcx.alloca_insert_pt.get().unwrap());
- memzero(&b, p, ty);
- p
-}
-
// Creates the alloca slot which holds the pointer to the slot for the final return value
pub fn make_return_slot_pointer<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
output_type: Ty<'tcx>) -> ValueRef {
datum::lvalue_scratch_datum(bcx,
arg_ty,
"tupled_args",
- false,
tuple_args_scope_id,
(),
|(),
}
let encode_inlined_item: encoder::EncodeInlinedItem =
- box |ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii);
+ Box::new(|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii));
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let metadata = encoder::encode_metadata(encode_parms, krate);
let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
let krate = tcx.map.krate();
+ let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
+ v
+ } else {
+ tcx.sess.opts.debug_assertions
+ };
+
// Before we touch LLVM, make sure that multithreading is enabled.
unsafe {
use std::sync::{Once, ONCE_INIT};
export_map,
Sha256::new(),
link_meta.clone(),
- reachable);
+ reachable,
+ check_overflow);
{
let ccx = shared_ccx.get_ccx(0);
let size = ty_size(ty);
if size <= 16 {
let llty = if size == 0 {
- Type::array(&Type::i64(ccx), 0u64)
+ Type::array(&Type::i64(ccx), 0)
} else if size == 1 {
Type::i8(ccx)
} else if size == 2 {
&**expr
} else {
ccx.sess().span_bug(ref_expr.span,
- &format!("get_const_val given non-constant item {}",
+ &format!("get_const_expr given non-constant item {}",
item.repr(ccx.tcx())));
}
}
ast::ExprIndex(ref base, ref index) => {
let (bv, bt) = const_expr(cx, &**base, param_substs);
- let iv = match const_eval::eval_const_expr(cx.tcx(), &**index) {
- const_eval::const_int(i) => i as u64,
- const_eval::const_uint(u) => u,
+ let iv = match const_eval::eval_const_expr_partial(cx.tcx(), &**index, None) {
+ Ok(const_eval::const_int(i)) => i as u64,
+ Ok(const_eval::const_uint(u)) => u,
_ => cx.sess().span_bug(index.span,
"index is not an integer-constant expression")
};
ast::ExprRepeat(ref elem, ref count) => {
let unit_ty = ty::sequence_element_type(cx.tcx(), ety);
let llunitty = type_of::type_of(cx, unit_ty);
- let n = match const_eval::eval_const_expr(cx.tcx(), &**count) {
- const_eval::const_int(i) => i as uint,
- const_eval::const_uint(i) => i as uint,
+ let n = match const_eval::eval_const_expr_partial(cx.tcx(), &**count, None) {
+ Ok(const_eval::const_int(i)) => i as uint,
+ Ok(const_eval::const_uint(i)) => i as uint,
_ => cx.sess().span_bug(count.span, "count must be integral const expression.")
};
let unit_val = const_expr(cx, &**elem, param_substs).0;
symbol_hasher: RefCell<Sha256>,
tcx: ty::ctxt<'tcx>,
stats: Stats,
+ check_overflow: bool,
available_monomorphizations: RefCell<FnvHashSet<String>>,
available_drop_glues: RefCell<FnvHashMap<Ty<'tcx>, String>>,
export_map: ExportMap,
symbol_hasher: Sha256,
link_meta: LinkMeta,
- reachable: NodeSet)
+ reachable: NodeSet,
+ check_overflow: bool)
-> SharedCrateContext<'tcx> {
let (metadata_llcx, metadata_llmod) = unsafe {
create_context_and_module(&tcx.sess, "metadata")
llvm_insns: RefCell::new(FnvHashMap()),
fn_stats: RefCell::new(Vec::new()),
},
+ check_overflow: check_overflow,
available_monomorphizations: RefCell::new(FnvHashSet()),
available_drop_glues: RefCell::new(FnvHashMap()),
};
&format!("the type `{}` is too big for the current architecture",
obj.repr(self.tcx())))
}
+
+ pub fn check_overflow(&self) -> bool {
+ self.shared.check_overflow
+ }
}
fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
/// Allocates temporary space on the stack using alloca() and returns a by-ref Datum pointing to
/// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
-/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
-/// is not necessary unless `bcx` does not dominate the end of `scope`.
+/// initialize the memory.
pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
ty: Ty<'tcx>,
name: &str,
- zero: bool,
scope: cleanup::ScopeId,
arg: A,
populate: F)
-> DatumBlock<'blk, 'tcx, Lvalue> where
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
{
- let scratch = if zero {
- alloca_zeroed(bcx, ty, name)
- } else {
- let llty = type_of::type_of(bcx.ccx(), ty);
- alloca(bcx, llty, name)
- };
+ let llty = type_of::type_of(bcx.ccx(), ty);
+ let scratch = alloca(bcx, llty, name);
// Subtle. Populate the scratch memory *before* scheduling cleanup.
let bcx = populate(arg, bcx, scratch);
ByValue => {
lvalue_scratch_datum(
- bcx, self.ty, name, false, scope, self,
+ bcx, self.ty, name, scope, self,
|this, bcx, llval| this.store_to(bcx, llval))
}
}
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
use util::ppaux;
+use util::common::path2cstr;
use libc::{c_uint, c_longlong};
-use std::ffi::CString;
use std::cell::{Cell, RefCell};
+use std::ffi::CString;
+use std::path::Path;
use std::ptr;
use std::rc::{Rc, Weak};
use syntax::util::interner::Interner;
fn_metadata: DISubprogram,
argument_counter: Cell<uint>,
source_locations_enabled: Cell<bool>,
+ source_location_override: Cell<bool>,
}
enum VariableAccess<'a> {
return;
}
FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+ if function_debug_context.source_location_override.get() {
+ // Just ignore any attempts to set a new debug location while
+ // the override is active.
+ return;
+ }
+
let cx = fcx.ccx;
debug!("set_source_location: {}", cx.sess().codemap().span_to_string(span));
}
}
+/// This function makes sure that all debug locations emitted while executing
+/// `wrapped_function` are set to the given `debug_loc`.
+pub fn with_source_location_override<F, R>(fcx: &FunctionContext,
+ debug_loc: DebugLoc,
+ wrapped_function: F) -> R
+ where F: FnOnce() -> R
+{
+ match fcx.debug_context {
+ FunctionDebugContext::DebugInfoDisabled => {
+ wrapped_function()
+ }
+ FunctionDebugContext::FunctionWithoutDebugInfo => {
+ set_debug_location(fcx.ccx, UnknownLocation);
+ wrapped_function()
+ }
+ FunctionDebugContext::RegularContext(box ref function_debug_context) => {
+ if function_debug_context.source_location_override.get() {
+ wrapped_function()
+ } else {
+ debug_loc.apply(fcx);
+ function_debug_context.source_location_override.set(true);
+ let result = wrapped_function();
+ function_debug_context.source_location_override.set(false);
+ result
+ }
+ }
+ }
+}
+
/// Clears the current debug location.
///
/// Instructions generated hereafter won't be assigned a source location.
fn_metadata: fn_metadata,
argument_counter: Cell::new(1),
source_locations_enabled: Cell::new(false),
+ source_location_override: Cell::new(false),
};
cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
fallback_path(cx)
} else {
- match abs_path.path_relative_from(work_dir) {
+ match abs_path.relative_from(work_dir) {
Some(ref p) if p.is_relative() => {
- // prepend "./" if necessary
- let dotdot = b"..";
- let prefix: &[u8] = &[dotdot[0], ::std::old_path::SEP_BYTE];
- let mut path_bytes = p.as_vec().to_vec();
-
- if &path_bytes[..2] != prefix &&
- &path_bytes[..2] != dotdot {
- path_bytes.insert(0, prefix[0]);
- path_bytes.insert(1, prefix[1]);
+ if p.starts_with(Path::new("./")) {
+ path2cstr(p)
+ } else {
+ path2cstr(&Path::new(".").join(p))
}
-
- CString::new(path_bytes).unwrap()
}
_ => fallback_path(cx)
}
(option_env!("CFG_VERSION")).expect("CFG_VERSION"));
let compile_unit_name = compile_unit_name.as_ptr();
- let work_dir = CString::new(work_dir.as_vec()).unwrap();
+ let work_dir = path2cstr(&work_dir);
let producer = CString::new(producer).unwrap();
let flags = "\0";
let split_name = "\0";
debug!("file_metadata: {}", full_path);
// FIXME (#9639): This needs to handle non-utf8 paths
- let work_dir = cx.sess().working_dir.as_str().unwrap();
+ let work_dir = cx.sess().working_dir.to_str().unwrap();
let file_name =
if full_path.starts_with(work_dir) {
&full_path[work_dir.len() + 1..full_path.len()]
use trans::type_::Type;
use syntax::{ast, ast_util, codemap};
+use syntax::parse::token::InternedString;
use syntax::ptr::P;
use syntax::parse::token;
use std::iter::repeat;
ast::ExprPath(..) => {
match bcx.def(expr.id) {
def::DefConst(did) => {
- let expr = consts::get_const_expr(bcx.ccx(), did, expr);
+ let const_expr = consts::get_const_expr(bcx.ccx(), did, expr);
// Temporarily get cleanup scopes out of the way,
// as they require sub-expressions to be contained
// inside the current AST scope.
// can't have destructors.
let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
vec![]);
- bcx = trans_into(bcx, expr, dest);
+ // Lock emitted debug locations to the location of
+ // the constant reference expression.
+ debuginfo::with_source_location_override(bcx.fcx,
+ expr.debug_loc(),
+ || {
+ bcx = trans_into(bcx, const_expr, dest)
+ });
let scopes = mem::replace(&mut *bcx.fcx.scopes.borrow_mut(),
scopes);
assert!(scopes.is_empty());
};
let is_float = ty::type_is_fp(intype);
let is_signed = ty::type_is_signed(intype);
-
let rhs = base::cast_shift_expr_rhs(bcx, op, lhs, rhs);
+ let info = expr_info(binop_expr);
let binop_debug_loc = binop_expr.debug_loc();
if is_float {
FAdd(bcx, lhs, rhs, binop_debug_loc)
} else {
- Add(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Add, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiSub => {
if is_float {
FSub(bcx, lhs, rhs, binop_debug_loc)
} else {
- Sub(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Sub, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiMul => {
if is_float {
FMul(bcx, lhs, rhs, binop_debug_loc)
} else {
- Mul(bcx, lhs, rhs, binop_debug_loc)
+ let (newbcx, res) = with_overflow_check(
+ bcx, OverflowOp::Mul, info, lhs_t, lhs, rhs, binop_debug_loc);
+ bcx = newbcx;
+ res
}
}
ast::BiDiv => {
DatumBlock { bcx: bcx, datum: datum }
}
}
+
+enum OverflowOp {
+ Add,
+ Sub,
+ Mul,
+}
+
+impl OverflowOp {
+ fn to_intrinsic_name(&self, tcx: &ty::ctxt, ty: Ty) -> &'static str {
+ use syntax::ast::IntTy::*;
+ use syntax::ast::UintTy::*;
+ use middle::ty::{ty_int, ty_uint};
+
+ let new_sty = match ty.sty {
+ ty_int(TyIs(_)) => match &tcx.sess.target.target.target_pointer_width[..] {
+ "32" => ty_int(TyI32),
+ "64" => ty_int(TyI64),
+ _ => panic!("unsupported target word size")
+ },
+ ty_uint(TyUs(_)) => match &tcx.sess.target.target.target_pointer_width[..] {
+ "32" => ty_uint(TyU32),
+ "64" => ty_uint(TyU64),
+ _ => panic!("unsupported target word size")
+ },
+ ref t @ ty_uint(_) | ref t @ ty_int(_) => t.clone(),
+ _ => panic!("tried to get overflow intrinsic for non-int type")
+ };
+
+ match *self {
+ OverflowOp::Add => match new_sty {
+ ty_int(TyI8) => "llvm.sadd.with.overflow.i8",
+ ty_int(TyI16) => "llvm.sadd.with.overflow.i16",
+ ty_int(TyI32) => "llvm.sadd.with.overflow.i32",
+ ty_int(TyI64) => "llvm.sadd.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.uadd.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.uadd.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.uadd.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.uadd.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ OverflowOp::Sub => match new_sty {
+ ty_int(TyI8) => "llvm.ssub.with.overflow.i8",
+ ty_int(TyI16) => "llvm.ssub.with.overflow.i16",
+ ty_int(TyI32) => "llvm.ssub.with.overflow.i32",
+ ty_int(TyI64) => "llvm.ssub.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.usub.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.usub.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.usub.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.usub.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ OverflowOp::Mul => match new_sty {
+ ty_int(TyI8) => "llvm.smul.with.overflow.i8",
+ ty_int(TyI16) => "llvm.smul.with.overflow.i16",
+ ty_int(TyI32) => "llvm.smul.with.overflow.i32",
+ ty_int(TyI64) => "llvm.smul.with.overflow.i64",
+
+ ty_uint(TyU8) => "llvm.umul.with.overflow.i8",
+ ty_uint(TyU16) => "llvm.umul.with.overflow.i16",
+ ty_uint(TyU32) => "llvm.umul.with.overflow.i32",
+ ty_uint(TyU64) => "llvm.umul.with.overflow.i64",
+
+ _ => unreachable!(),
+ },
+ }
+ }
+}
+
+
+fn with_overflow_check<'a, 'b>(bcx: Block<'a, 'b>, oop: OverflowOp, info: NodeIdAndSpan,
+ lhs_t: Ty, lhs: ValueRef, rhs: ValueRef, binop_debug_loc: DebugLoc)
+ -> (Block<'a, 'b>, ValueRef) {
+ if bcx.unreachable.get() { return (bcx, _Undef(lhs)); }
+ if bcx.ccx().check_overflow() {
+ let name = oop.to_intrinsic_name(bcx.tcx(), lhs_t);
+ let llfn = bcx.ccx().get_intrinsic(&name);
+
+ let val = Call(bcx, llfn, &[lhs, rhs], None, binop_debug_loc);
+ let result = ExtractValue(bcx, val, 0); // iN operation result
+ let overflow = ExtractValue(bcx, val, 1); // i1 "did it overflow?"
+
+ let cond = ICmp(bcx, llvm::IntEQ, overflow, C_integral(Type::i1(bcx.ccx()), 1, false),
+ binop_debug_loc);
+
+ let expect = bcx.ccx().get_intrinsic(&"llvm.expect.i1");
+ Call(bcx, expect, &[cond, C_integral(Type::i1(bcx.ccx()), 0, false)],
+ None, binop_debug_loc);
+
+ let bcx =
+ base::with_cond(bcx, cond, |bcx|
+ controlflow::trans_fail(bcx, info,
+ InternedString::new("arithmetic operation overflowed")));
+
+ (bcx, result)
+ } else {
+ let res = match oop {
+ OverflowOp::Add => Add(bcx, lhs, rhs, binop_debug_loc),
+ OverflowOp::Sub => Sub(bcx, lhs, rhs, binop_debug_loc),
+ OverflowOp::Mul => Mul(bcx, lhs, rhs, binop_debug_loc),
+ };
+ (bcx, res)
+ }
+}
&format!("use of SIMD type `{}` in FFI is highly experimental and \
may result in invalid code",
pprust::ty_to_string(ast_ty)));
- tcx.sess.span_help(ast_ty.span,
+ tcx.sess.fileline_help(ast_ty.span,
"add #![feature(simd_ffi)] to the crate attributes to enable");
}
};
let csearch_result =
csearch::maybe_get_item_ast(
ccx.tcx(), fn_id,
- box |a,b,c,d| astencode::decode_inlined_item(a, b, c, d));
+ Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
let inline_def = match csearch_result {
csearch::FoundAst::NotFound => {
llargs[0],
llargs[1],
call_debug_location),
+
+ (_, "overflowing_add") => Add(bcx, llargs[0], llargs[1], call_debug_location),
+ (_, "overflowing_sub") => Sub(bcx, llargs[0], llargs[1], call_debug_location),
+ (_, "overflowing_mul") => Mul(bcx, llargs[0], llargs[1], call_debug_location),
+
(_, "return_address") => {
if !fcx.caller_expects_out_pointer {
tcx.sess.span_err(call_info.span,
use syntax::codemap::DUMMY_SP;
// drop_glue pointer, size, align.
-static VTABLE_OFFSET: uint = 3;
+const VTABLE_OFFSET: uint = 3;
/// The main "translation" pass for methods. Generates code
/// for non-monomorphized methods only. Other methods will
.position(|item| item.def_id() == method_id)
.unwrap();
let (llfn, ty) =
- trans_object_shim(ccx, data.object_ty, trait_id, method_offset_in_trait);
+ trans_object_shim(ccx,
+ data.object_ty,
+ data.upcast_trait_ref.clone(),
+ method_offset_in_trait);
immediate_rvalue(llfn, ty)
}
_ => {
Callee { bcx: bcx, data: Fn(llfn) }
}
traits::VtableObject(ref data) => {
- let (llfn, _) = trans_object_shim(bcx.ccx(), data.object_ty, trait_id, n_method);
+ let (llfn, _) = trans_object_shim(bcx.ccx(),
+ data.object_ty,
+ data.upcast_trait_ref.clone(),
+ n_method);
Callee { bcx: bcx, data: Fn(llfn) }
}
traits::VtableBuiltin(..) |
pub fn trans_object_shim<'a, 'tcx>(
ccx: &'a CrateContext<'a, 'tcx>,
object_ty: Ty<'tcx>,
- trait_id: ast::DefId,
+ upcast_trait_ref: ty::PolyTraitRef<'tcx>,
method_offset_in_trait: uint)
-> (ValueRef, Ty<'tcx>)
{
let _icx = push_ctxt("trans_object_shim");
let tcx = ccx.tcx();
+ let trait_id = upcast_trait_ref.def_id();
- debug!("trans_object_shim(object_ty={}, trait_id={}, method_offset_in_trait={})",
+ debug!("trans_object_shim(object_ty={}, upcast_trait_ref={}, method_offset_in_trait={})",
object_ty.repr(tcx),
- trait_id.repr(tcx),
+ upcast_trait_ref.repr(tcx),
method_offset_in_trait);
let object_trait_ref =
};
// Upcast to the trait in question and extract out the substitutions.
- let upcast_trait_ref = traits::upcast(ccx.tcx(), object_trait_ref.clone(), trait_id).unwrap();
let upcast_trait_ref = ty::erase_late_bound_regions(tcx, &upcast_trait_ref);
let object_substs = upcast_trait_ref.substs.clone().erase_regions();
debug!("trans_object_shim: object_substs={}", object_substs.repr(tcx));
use rscope::{self, UnelidableRscope, RegionScope, ElidableRscope,
ObjectLifetimeDefaultRscope, ShiftedRscope, BindingRscope};
use util::common::{ErrorReported, FN_OUTPUT_NAME};
-use util::nodemap::DefIdMap;
use util::ppaux::{self, Repr, UserString};
use std::iter::{repeat, AdditiveIterator};
pub trait AstConv<'tcx> {
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
+ /// Identify the type scheme for an item with a type, like a type
+ /// alias, fn, or struct. This allows you to figure out the set of
+ /// type parameters defined on the item.
fn get_item_type_scheme(&self, span: Span, id: ast::DefId)
-> Result<ty::TypeScheme<'tcx>, ErrorReported>;
+ /// Returns the `TraitDef` for a given trait. This allows you to
+ /// figure out the set of type parameters defined on the trait.
fn get_trait_def(&self, span: Span, id: ast::DefId)
-> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>;
+ /// Ensure that the super-predicates for the trait with the given
+ /// id are available and also for the transitive set of
+ /// super-predicates.
+ fn ensure_super_predicates(&self, span: Span, id: ast::DefId)
+ -> Result<(), ErrorReported>;
+
+ /// Returns the set of bounds in scope for the type parameter with
+ /// the given id.
fn get_type_parameter_bounds(&self, span: Span, def_id: ast::NodeId)
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>;
+ /// Returns true if the trait with id `trait_def_id` defines an
+ /// associated type with the name `name`.
+ fn trait_defines_associated_type_named(&self, trait_def_id: ast::DefId, name: ast::Name)
+ -> bool;
+
/// Return an (optional) substitution to convert bound type parameters that
/// are in scope into free ones. This function should only return Some
/// within a fn body.
if len == 2 && i == 0 {
m.push_str(" or ");
- } else if i == len - 2 {
+ } else if i + 2 == len {
m.push_str(", or ");
- } else if i != len - 1 {
+ } else if i + 1 != len {
m.push_str(", ");
}
}
if len == 1 {
- span_help!(this.tcx().sess, default_span,
+ fileline_help!(this.tcx().sess, default_span,
"this function's return type contains a borrowed value, but \
the signature does not say which {} it is borrowed from",
m);
} else if len == 0 {
- span_help!(this.tcx().sess, default_span,
+ fileline_help!(this.tcx().sess, default_span,
"this function's return type contains a borrowed value, but \
there is no value for it to be borrowed from");
- span_help!(this.tcx().sess, default_span,
+ fileline_help!(this.tcx().sess, default_span,
"consider giving it a 'static lifetime");
} else {
- span_help!(this.tcx().sess, default_span,
+ fileline_help!(this.tcx().sess, default_span,
"this function's return type contains a borrowed value, but \
the signature does not say whether it is borrowed from {}",
m);
span_err!(this.tcx().sess, span, E0215,
"angle-bracket notation is not stable when \
used with the `Fn` family of traits, use parentheses");
- span_help!(this.tcx().sess, span,
+ fileline_help!(this.tcx().sess, span,
"add `#![feature(unboxed_closures)]` to \
the crate attributes to enable");
}
span_err!(this.tcx().sess, span, E0216,
"parenthetical notation is only stable when \
used with the `Fn` family of traits");
- span_help!(this.tcx().sess, span,
+ fileline_help!(this.tcx().sess, span,
"add `#![feature(unboxed_closures)]` to \
the crate attributes to enable");
}
// We want to produce `<B as SuperTrait<int>>::T == foo`.
// Simple case: X is defined in the current trait.
- if trait_defines_associated_type_named(this, trait_ref.def_id, binding.item_name) {
+ if this.trait_defines_associated_type_named(trait_ref.def_id, binding.item_name) {
return Ok(ty::ProjectionPredicate {
projection_ty: ty::ProjectionTy {
trait_ref: trait_ref,
tcx.mk_substs(dummy_substs)));
}
+ try!(this.ensure_super_predicates(binding.span, trait_ref.def_id));
+
let mut candidates: Vec<ty::PolyTraitRef> =
traits::supertraits(tcx, trait_ref.to_poly_trait_ref())
- .filter(|r| trait_defines_associated_type_named(this, r.def_id(), binding.item_name))
+ .filter(|r| this.trait_defines_associated_type_named(r.def_id(), binding.item_name))
.collect();
// If converting for an object type, then remove the dummy-ty from `Self` now.
pprust::ty_to_string(ty));
match ty.node {
ast::TyRptr(None, ref mut_ty) => {
- span_help!(this.tcx().sess, ty.span,
+ fileline_help!(this.tcx().sess, ty.span,
"perhaps you meant `&{}({} +{})`? (per RFC 438)",
ppaux::mutability_to_string(mut_ty.mutbl),
pprust::ty_to_string(&*mut_ty.ty),
pprust::bounds_to_string(bounds));
}
ast::TyRptr(Some(ref lt), ref mut_ty) => {
- span_help!(this.tcx().sess, ty.span,
+ fileline_help!(this.tcx().sess, ty.span,
"perhaps you meant `&{} {}({} +{})`? (per RFC 438)",
pprust::lifetime_to_string(lt),
ppaux::mutability_to_string(mut_ty.mutbl),
}
_ => {
- span_help!(this.tcx().sess, ty.span,
+ fileline_help!(this.tcx().sess, ty.span,
"perhaps you forgot parentheses? (per RFC 438)");
}
}
let ty_param_name = tcx.ty_param_defs.borrow()[ty_param_node_id].name;
- // FIXME(#20300) -- search where clauses, not bounds
- let bounds =
- this.get_type_parameter_bounds(span, ty_param_node_id)
- .unwrap_or(Vec::new());
+ let bounds = match this.get_type_parameter_bounds(span, ty_param_node_id) {
+ Ok(v) => v,
+ Err(ErrorReported) => { return (tcx.types.err, ty_path_def); }
+ };
+
+ // ensure the super predicates and stop if we encountered an error
+ if bounds.iter().any(|b| this.ensure_super_predicates(span, b.def_id()).is_err()) {
+ return (this.tcx().types.err, ty_path_def);
+ }
let mut suitable_bounds: Vec<_> =
traits::transitive_bounds(tcx, &bounds)
- .filter(|b| trait_defines_associated_type_named(this, b.def_id(), assoc_name))
+ .filter(|b| this.trait_defines_associated_type_named(b.def_id(), assoc_name))
.collect();
if suitable_bounds.len() == 0 {
(ty, def::DefAssociatedTy(trait_did, item_did))
}
-fn trait_defines_associated_type_named(this: &AstConv,
- trait_def_id: ast::DefId,
- assoc_name: ast::Name)
- -> bool
-{
- let tcx = this.tcx();
- let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
- trait_def.associated_type_names.contains(&assoc_name)
-}
-
fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
rscope: &RegionScope,
span: Span,
if segments.is_empty() {
opt_self_ty.expect("missing T in <T>::a::b::c")
} else {
- tcx.sess.span_bug(span,
- &format!("found module name used as a type: {}",
- tcx.map.node_to_string(id.node)));
+ span_err!(tcx.sess, span, E0247, "found module name used as a type: {}",
+ tcx.map.node_to_string(id.node));
+ return this.tcx().types.err;
}
}
def::DefPrimTy(prim_ty) => {
prim_ty_to_ty(tcx, segments, prim_ty)
}
_ => {
- span_fatal!(tcx.sess, span, E0248,
- "found value name used as a type: {:?}", *def);
+ span_err!(tcx.sess, span, E0248,
+ "found value name used as a type: {:?}", *def);
+ return this.tcx().types.err;
}
};
let tcx = this.tcx();
- let mut ast_ty_to_ty_cache = tcx.ast_ty_to_ty_cache.borrow_mut();
- match ast_ty_to_ty_cache.get(&ast_ty.id) {
- Some(&ty::atttce_resolved(ty)) => return ty,
- Some(&ty::atttce_unresolved) => {
- span_fatal!(tcx.sess, ast_ty.span, E0246,
- "illegal recursive type; insert an enum \
- or struct in the cycle, if this is \
- desired");
- }
- None => { /* go on */ }
+ if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&ast_ty.id) {
+ return ty;
}
- ast_ty_to_ty_cache.insert(ast_ty.id, ty::atttce_unresolved);
- drop(ast_ty_to_ty_cache);
let typ = match ast_ty.node {
ast::TyVec(ref ty) => {
ty::mk_vec(tcx, ast_ty_to_ty(this, rscope, &**ty),
Some(i as uint)),
_ => {
- span_fatal!(tcx.sess, ast_ty.span, E0249,
- "expected constant expr for array length");
+ span_err!(tcx.sess, ast_ty.span, E0249,
+ "expected constant expr for array length");
+ this.tcx().types.err
}
}
}
- Err(r) => {
- span_fatal!(tcx.sess, ast_ty.span, E0250,
- "expected constant expr for array length: {}", r);
+ Err(ref r) => {
+ let subspan =
+ ast_ty.span.lo <= r.span.lo && r.span.hi <= ast_ty.span.hi;
+ span_err!(tcx.sess, r.span, E0250,
+ "array length constant evaluation error: {}",
+ r.description().as_slice());
+ if !subspan {
+ span_note!(tcx.sess, ast_ty.span, "for array length here")
+ }
+ this.tcx().types.err
}
}
}
}
};
- tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, ty::atttce_resolved(typ));
+ tcx.ast_ty_to_ty_cache.borrow_mut().insert(ast_ty.id, typ);
return typ;
}
return ast_region_to_region(tcx, r);
}
+ if let Err(ErrorReported) = this.ensure_super_predicates(span,principal_trait_ref.def_id()) {
+ return ty::ReStatic;
+ }
+
// No explicit region bound specified. Therefore, examine trait
// bounds and see if we can derive region bounds from those.
let derived_region_bounds =
let mut builtin_bounds = ty::empty_builtin_bounds();
let mut region_bounds = Vec::new();
let mut trait_bounds = Vec::new();
- let mut trait_def_ids = DefIdMap();
for ast_bound in ast_bounds {
match *ast_bound {
ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => {
match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
def::DefTrait(trait_did) => {
- match trait_def_ids.get(&trait_did) {
- // Already seen this trait. We forbid
- // duplicates in the list (for some
- // reason).
- Some(span) => {
- span_err!(
- tcx.sess, b.trait_ref.path.span, E0127,
- "trait `{}` already appears in the \
- list of bounds",
- b.trait_ref.path.user_string(tcx));
- tcx.sess.span_note(
- *span,
- "previous appearance is here");
-
- continue;
- }
-
- None => { }
- }
-
- trait_def_ids.insert(trait_did, b.trait_ref.path.span);
-
if ty::try_add_builtin_trait(tcx,
trait_did,
&mut builtin_bounds) {
span_err!(tcx.sess, span, E0174,
"explicit use of unboxed closure method `{}` is experimental",
method);
- span_help!(tcx.sess, span,
+ fileline_help!(tcx.sess, span,
"add `#![feature(unboxed_closures)]` to the crate attributes to enable");
}
}
&closure_ty.sig).0;
fcx.record_deferred_call_resolution(
def_id,
- box CallResolution {call_expr: call_expr,
- callee_expr: callee_expr,
- adjusted_ty: adjusted_ty,
- autoderefref: autoderefref,
- fn_sig: fn_sig.clone(),
- closure_def_id: def_id});
+ Box::new(CallResolution {call_expr: call_expr,
+ callee_expr: callee_expr,
+ adjusted_ty: adjusted_ty,
+ autoderefref: autoderefref,
+ fn_sig: fn_sig.clone(),
+ closure_def_id: def_id}));
return Some(CallStep::DeferredClosure(fn_sig));
}
}
use syntax::codemap::Span;
use util::common::ErrorReported;
+use util::nodemap::FnvHashSet;
use util::ppaux::Repr;
// Helper functions related to manipulating region types.
stack: Vec<(ty::Region, Option<Ty<'tcx>>)>,
span: Span,
out: Vec<Implication<'tcx>>,
+ visited: FnvHashSet<Ty<'tcx>>,
}
/// This routine computes the well-formedness constraints that must hold for the type `ty` to
body_id: body_id,
span: span,
stack: stack,
- out: Vec::new() };
+ out: Vec::new(),
+ visited: FnvHashSet() };
wf.accumulate_from_ty(ty);
debug!("implications: out={}", wf.out.repr(closure_typer.tcx()));
wf.out
debug!("accumulate_from_ty(ty={})",
ty.repr(self.tcx()));
+ // When expanding out associated types, we can visit a cyclic
+ // set of types. Issue #23003.
+ if !self.visited.insert(ty) {
+ return;
+ }
+
match ty.sty {
ty::ty_bool |
ty::ty_char |
target_trait_def_id: ast::DefId)
-> ty::PolyTraitRef<'tcx>
{
- match traits::upcast(self.tcx(), source_trait_ref.clone(), target_trait_def_id) {
- Some(super_trait_ref) => super_trait_ref,
- None => {
- self.tcx().sess.span_bug(
- self.span,
- &format!("cannot upcast `{}` to `{}`",
- source_trait_ref.repr(self.tcx()),
- target_trait_def_id.repr(self.tcx())));
- }
+ let upcast_trait_refs = traits::upcast(self.tcx(),
+ source_trait_ref.clone(),
+ target_trait_def_id);
+
+ // must be exactly one trait ref or we'd get an ambig error etc
+ if upcast_trait_refs.len() != 1 {
+ self.tcx().sess.span_bug(
+ self.span,
+ &format!("cannot uniquely upcast `{}` to `{}`: `{}`",
+ source_trait_ref.repr(self.tcx()),
+ target_trait_def_id.repr(self.tcx()),
+ upcast_trait_refs.repr(self.tcx())));
}
+
+ upcast_trait_refs.into_iter().next().unwrap()
}
fn replace_late_bound_regions_with_fresh_var<T>(&self, value: &ty::Binder<T>) -> T
debug!("elaborate_bounds(bounds={})", bounds.repr(self.tcx()));
let tcx = self.tcx();
- let mut cache = HashSet::new();
for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
- // Already visited this trait, skip it.
- if !cache.insert(bound_trait_ref.def_id()) {
- continue;
- }
-
let (pos, method) = match trait_method(tcx,
bound_trait_ref.def_id(),
self.method_name) {
fn to_trait_data(&self) -> Option<(ast::DefId,MethodIndex)> {
match self.kind {
- InherentImplCandidate(..) |
- ObjectCandidate(..) => {
+ InherentImplCandidate(..) => {
None
}
+ ObjectCandidate(trait_def_id, method_num, _) => {
+ Some((trait_def_id, method_num))
+ }
ClosureCandidate(trait_def_id, method_num) => {
Some((trait_def_id, method_num))
}
Ok(ty::lookup_trait_def(self.tcx(), id))
}
+ fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
+ // all super predicates are ensured during collect pass
+ Ok(())
+ }
+
fn get_free_substs(&self) -> Option<&Substs<'tcx>> {
Some(&self.inh.param_env.free_substs)
}
Ok(r)
}
+ fn trait_defines_associated_type_named(&self,
+ trait_def_id: ast::DefId,
+ assoc_name: ast::Name)
+ -> bool
+ {
+ let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id);
+ trait_def.associated_type_names.contains(&assoc_name)
+ }
+
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
self.infcx().next_ty_var()
}
match self.inh.locals.borrow().get(&nid) {
Some(&t) => t,
None => {
- self.tcx().sess.span_bug(
+ self.tcx().sess.span_err(
span,
- &format!("no type for local variable {}",
- nid));
+ &format!("no type for local variable {}", nid));
+ self.tcx().types.err
}
}
}
},
expr_t, None);
- tcx.sess.span_help(field.span,
+ tcx.sess.fileline_help(field.span,
"maybe a `()` to call it is missing? \
If not, try an anonymous function");
} else {
span_err!(tcx.sess, sp, E0073,
"this type cannot be instantiated without an \
instance of itself");
- span_help!(tcx.sess, sp, "consider using `Option<{}>`",
+ fileline_help!(tcx.sess, sp, "consider using `Option<{}>`",
ppaux::ty_to_string(tcx, item_ty));
false
} else {
id: ast::NodeId,
hint: attr::ReprAttr)
-> Vec<Rc<ty::VariantInfo<'tcx>>> {
+ use std::num::Int;
let rty = ty::node_id_to_type(ccx.tcx, id);
let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
// If the discriminant value is specified explicitly in the enum check whether the
// initialization expression is valid, otherwise use the last value plus one.
let mut current_disr_val = match prev_disr_val {
- Some(prev_disr_val) => prev_disr_val + 1,
+ Some(prev_disr_val) => {
+ if let Some(v) = prev_disr_val.checked_add(1) {
+ v
+ } else {
+ ty::INITIAL_DISCRIMINANT_VALUE
+ }
+ }
None => ty::INITIAL_DISCRIMINANT_VALUE
};
"expected signed integer constant");
}
Err(ref err) => {
- span_err!(ccx.tcx.sess, e.span, E0080,
- "expected constant: {}", *err);
+ span_err!(ccx.tcx.sess, err.span, E0080,
+ "constant evaluation error: {}",
+ err.description().as_slice());
}
}
},
(0, vec!(tcx.types.u64, tcx.types.u64),
ty::mk_tup(tcx, vec!(tcx.types.u64, tcx.types.bool))),
+ "overflowing_add" | "overflowing_sub" | "overflowing_mul" =>
+ (1, vec![param(ccx, 0), param(ccx, 0)], param(ccx, 0)),
+
"return_address" => (0, vec![], ty::mk_imm_ptr(tcx, tcx.types.u8)),
"assume" => (0, vec![tcx.types.bool], ty::mk_nil(tcx)),
// Find the supertrait bounds. This will add `int:Bar`.
let poly_trait_ref = ty::Binder(trait_ref);
- let predicates = ty::predicates_for_trait_ref(fcx.tcx(), &poly_trait_ref);
+ let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id());
+ let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
let predicates = {
let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx);
traits::normalize(selcx, cause.clone(), &predicates)
};
- for predicate in predicates.value {
+ for predicate in predicates.value.predicates {
fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate));
}
for obligation in predicates.obligations {
match suggested_marker_id {
Some(def_id) => {
- self.tcx().sess.span_help(
+ self.tcx().sess.fileline_help(
span,
format!("consider removing `{}` or using a marker such as `{}`",
param_name.user_string(self.tcx()),
return // everything OK
};
span_err!(tcx.sess, sp, E0183, "manual implementations of `{}` are experimental", trait_name);
- span_help!(tcx.sess, sp,
+ fileline_help!(tcx.sess, sp,
"add `#![feature(unboxed_closures)]` to the crate attributes to enable");
}
core type along with a list of the bounds for each parameter. Type
parameters themselves are represented as `ty_param()` instances.
-The phasing of type conversion is somewhat complicated. There are a
-number of possible cycles that can arise.
-
-Converting types can require:
-
-1. `Foo<X>` where `Foo` is a type alias, or trait requires knowing:
- - number of region / type parameters
- - for type parameters, `T:'a` annotations to control defaults for object lifetimes
- - defaults for type parameters (which are themselves types!)
-2. `Foo<X>` where `Foo` is a type alias requires knowing what `Foo` expands to
-3. Translating `SomeTrait` with no explicit lifetime bound requires knowing
- - supertraits of `SomeTrait`
-4. Translating `T::X` (vs `<T as Trait>::X`) requires knowing
- - bounds on `T`
- - supertraits of those bounds
-
-So as you can see, in general translating types requires knowing the
-trait hierarchy. But this gets a bit tricky because translating the
-trait hierarchy requires converting the types that appear in trait
-references. One potential saving grace is that in general knowing the
-trait hierarchy is only necessary for shorthands like `T::X` or
-handling omitted lifetime bounds on object types. Therefore, if we are
-lazy about expanding out the trait hierachy, users can sever cycles if
-necessary. Lazy expansion is also needed for type aliases.
-
-This system is not perfect yet. Currently, we "convert" types and
-traits in three phases (note that conversion only affects the types of
-items / enum variants / methods; it does not e.g. compute the types of
-individual expressions):
+The phasing of type conversion is somewhat complicated. There is no
+clear set of phases we can enforce (e.g., converting traits first,
+then types, or something like that) because the user can introduce
+arbitrary interdependencies. So instead we generally convert things
+lazilly and on demand, and include logic that checks for cycles.
+Demand is driven by calls to `AstConv::get_item_type_scheme` or
+`AstConv::lookup_trait_def`.
+
+Currently, we "convert" types and traits in three phases (note that
+conversion only affects the types of items / enum variants / methods;
+it does not e.g. compute the types of individual expressions):
0. Intrinsics
1. Trait definitions
and invoking an appropriate function (e.g., `trait_def_of_item` or
`convert_item`). However, it is possible that while converting an
item, we may need to compute the *type scheme* or *trait definition*
-for other items. This is a kind of shallow conversion that is
-triggered on demand by calls to `AstConv::get_item_type_scheme` or
-`AstConv::lookup_trait_def`. It is possible for cycles to result from
-this (e.g., `type A = B; type B = A;`), in which case astconv
-(currently) reports the error.
+for other items.
There are some shortcomings in this design:
-- Cycles through trait definitions (e.g. supertraits) are not currently
- detected by astconv. (#12511)
+- Before walking the set of supertraits for a given trait, you must
+ call `ensure_super_predicates` on that trait def-id. Otherwise,
+ `lookup_super_predicates` will result in ICEs.
- Because the type scheme includes defaults, cycles through type
parameter defaults are illegal even if those defaults are never
employed. This is not necessarily a bug.
enum AstConvRequest {
GetItemTypeScheme(ast::DefId),
GetTraitDef(ast::DefId),
+ EnsureSuperPredicates(ast::DefId),
GetTypeParameterBounds(ast::NodeId),
}
request: AstConvRequest,
code: F)
-> Result<R,ErrorReported>
- where F: FnOnce() -> R
+ where F: FnOnce() -> Result<R,ErrorReported>
{
{
let mut stack = self.stack.borrow_mut();
let result = code();
self.stack.borrow_mut().pop();
- Ok(result)
+ result
}
fn report_cycle(&self,
&format!("the cycle begins when processing `{}`...",
ty::item_path_str(tcx, def_id)));
}
+ AstConvRequest::EnsureSuperPredicates(def_id) => {
+ tcx.sess.note(
+ &format!("the cycle begins when computing the supertraits of `{}`...",
+ ty::item_path_str(tcx, def_id)));
+ }
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
tcx.sess.note(
&format!("...which then requires processing `{}`...",
ty::item_path_str(tcx, def_id)));
}
+ AstConvRequest::EnsureSuperPredicates(def_id) => {
+ tcx.sess.note(
+ &format!("...which then requires computing the supertraits of `{}`...",
+ ty::item_path_str(tcx, def_id)));
+ }
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
tcx.sess.note(
&format!("...which then again requires processing `{}`, completing the cycle.",
ty::item_path_str(tcx, def_id)));
}
+ AstConvRequest::EnsureSuperPredicates(def_id) => {
+ tcx.sess.note(
+ &format!("...which then again requires computing the supertraits of `{}`, \
+ completing the cycle.",
+ ty::item_path_str(tcx, def_id)));
+ }
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
tcx.sess.note(
}
}
}
+
+ /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
+ fn get_trait_def(&self, trait_id: ast::DefId)
+ -> Rc<ty::TraitDef<'tcx>>
+ {
+ let tcx = self.tcx;
+
+ if trait_id.krate != ast::LOCAL_CRATE {
+ return ty::lookup_trait_def(tcx, trait_id)
+ }
+
+ let item = match tcx.map.get(trait_id.node) {
+ ast_map::NodeItem(item) => item,
+ _ => tcx.sess.bug(&format!("get_trait_def({}): not an item", trait_id.repr(tcx)))
+ };
+
+ trait_def_of_item(self, &*item)
+ }
+
+ /// Ensure that the (transitive) super predicates for
+ /// `trait_def_id` are available. This will report a cycle error
+ /// if a trait `X` (transitively) extends itself in some form.
+ fn ensure_super_predicates(&self, span: Span, trait_def_id: ast::DefId)
+ -> Result<(), ErrorReported>
+ {
+ self.cycle_check(span, AstConvRequest::EnsureSuperPredicates(trait_def_id), || {
+ let def_ids = ensure_super_predicates_step(self, trait_def_id);
+
+ for def_id in def_ids {
+ try!(self.ensure_super_predicates(span, def_id));
+ }
+
+ Ok(())
+ })
+ }
}
impl<'a,'tcx> ItemCtxt<'a,'tcx> {
-> Result<ty::TypeScheme<'tcx>, ErrorReported>
{
self.ccx.cycle_check(span, AstConvRequest::GetItemTypeScheme(id), || {
- type_scheme_of_def_id(self.ccx, id)
+ Ok(type_scheme_of_def_id(self.ccx, id))
})
}
-> Result<Rc<ty::TraitDef<'tcx>>, ErrorReported>
{
self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
- get_trait_def(self.ccx, id)
+ Ok(self.ccx.get_trait_def(id))
})
}
+ fn ensure_super_predicates(&self,
+ span: Span,
+ trait_def_id: ast::DefId)
+ -> Result<(), ErrorReported>
+ {
+ debug!("ensure_super_predicates(trait_def_id={})",
+ trait_def_id.repr(self.tcx()));
+
+ self.ccx.ensure_super_predicates(span, trait_def_id)
+ }
+
+
fn get_type_parameter_bounds(&self,
span: Span,
node_id: ast::NodeId)
-> Result<Vec<ty::PolyTraitRef<'tcx>>, ErrorReported>
{
self.ccx.cycle_check(span, AstConvRequest::GetTypeParameterBounds(node_id), || {
- self.param_bounds.get_type_parameter_bounds(self, span, node_id)
+ let v = self.param_bounds.get_type_parameter_bounds(self, span, node_id)
+ .into_iter()
+ .filter_map(|p| p.to_opt_poly_trait_ref())
+ .collect();
+ Ok(v)
})
}
+ fn trait_defines_associated_type_named(&self,
+ trait_def_id: ast::DefId,
+ assoc_name: ast::Name)
+ -> bool
+ {
+ if trait_def_id.krate == ast::LOCAL_CRATE {
+ trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
+ } else {
+ let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ trait_def.associated_type_names.contains(&assoc_name)
+ }
+ }
+
fn ty_infer(&self, span: Span) -> Ty<'tcx> {
span_err!(self.tcx().sess, span, E0121,
"the type placeholder `_` is not allowed within types on item signatures");
astconv: &AstConv<'tcx>,
span: Span,
node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>;
+ -> Vec<ty::Predicate<'tcx>>;
}
/// Find bounds from both elements of the tuple.
astconv: &AstConv<'tcx>,
span: Span,
node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::Predicate<'tcx>>
{
let mut v = self.0.get_type_parameter_bounds(astconv, span, node_id);
v.extend(self.1.get_type_parameter_bounds(astconv, span, node_id).into_iter());
_astconv: &AstConv<'tcx>,
_span: Span,
_node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::Predicate<'tcx>>
{
Vec::new()
}
astconv: &AstConv<'tcx>,
_span: Span,
node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::Predicate<'tcx>>
{
let def = astconv.tcx().type_parameter_def(node_id);
self.predicates
.iter()
- .filter_map(|predicate| {
- match *predicate {
+ .filter(|predicate| {
+ match **predicate {
ty::Predicate::Trait(ref data) => {
- if data.0.self_ty().is_param(def.space, def.index) {
- Some(data.to_poly_trait_ref())
- } else {
- None
- }
+ data.skip_binder().self_ty().is_param(def.space, def.index)
+ }
+ ty::Predicate::TypeOutlives(ref data) => {
+ data.skip_binder().0.is_param(def.space, def.index)
}
ty::Predicate::Equate(..) |
ty::Predicate::RegionOutlives(..) |
- ty::Predicate::TypeOutlives(..) |
ty::Predicate::Projection(..) => {
- None
+ false
}
}
})
+ .cloned()
.collect()
}
}
astconv: &AstConv<'tcx>,
_: Span,
node_id: ast::NodeId)
- -> Vec<ty::PolyTraitRef<'tcx>>
+ -> Vec<ty::Predicate<'tcx>>
{
// In the AST, bounds can derive from two places. Either
// written inline like `<T:Foo>` or in a where clause like
.iter()
.filter(|p| p.id == node_id)
.flat_map(|p| p.bounds.iter())
- .filter_map(|b| poly_trait_ref_from_bound(astconv, ty, b, &mut Vec::new()));
+ .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter());
let from_where_clauses =
self.where_clause
})
.filter(|bp| is_param(astconv.tcx(), &bp.bounded_ty, node_id))
.flat_map(|bp| bp.bounds.iter())
- .filter_map(|b| poly_trait_ref_from_bound(astconv, ty, b, &mut Vec::new()));
+ .flat_map(|b| predicates_from_bound(astconv, ty, b).into_iter());
from_ty_params.chain(from_where_clauses).collect()
}
{
if let ast::TyPath(None, _) = ast_ty.node {
let path_res = tcx.def_map.borrow()[ast_ty.id];
- if let def::DefTyParam(_, _, def_id, _) = path_res.base_def {
- path_res.depth == 0 && def_id == local_def(param_id)
- } else {
- false
+ match path_res.base_def {
+ def::DefSelfTy(node_id) =>
+ path_res.depth == 0 && node_id == param_id,
+
+ def::DefTyParam(_, _, def_id, _) =>
+ path_res.depth == 0 && def_id == local_def(param_id),
+
+ _ =>
+ false,
}
} else {
false
rcvr_visibility: ast::Visibility)
where I: Iterator<Item=&'i ast::Method>
{
- debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={})",
+ debug!("convert_methods(untransformed_rcvr_ty={}, rcvr_ty_generics={}, rcvr_ty_predicates={})",
untransformed_rcvr_ty.repr(ccx.tcx),
- rcvr_ty_generics.repr(ccx.tcx));
+ rcvr_ty_generics.repr(ccx.tcx),
+ rcvr_ty_predicates.repr(ccx.tcx));
let tcx = ccx.tcx;
let mut seen_methods = FnvHashSet();
},
ast::ItemTrait(_, _, _, ref trait_items) => {
let trait_def = trait_def_of_item(ccx, it);
+ let _: Result<(), ErrorReported> = // any error is already reported, can ignore
+ ccx.ensure_super_predicates(it.span, local_def(it.id));
convert_trait_predicates(ccx, it);
let trait_predicates = ty::lookup_predicates(ccx.tcx, local_def(it.id));
}
}
-fn get_trait_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
- trait_id: ast::DefId)
- -> Rc<ty::TraitDef<'tcx>> {
+/// Ensures that the super-predicates of the trait with def-id
+/// trait_def_id are converted and stored. This does NOT ensure that
+/// the transitive super-predicates are converted; that is the job of
+/// the `ensure_super_predicates()` method in the `AstConv` impl
+/// above. Returns a list of trait def-ids that must be ensured as
+/// well to guarantee that the transitive superpredicates are
+/// converted.
+fn ensure_super_predicates_step(ccx: &CrateCtxt,
+ trait_def_id: ast::DefId)
+ -> Vec<ast::DefId>
+{
let tcx = ccx.tcx;
- if trait_id.krate != ast::LOCAL_CRATE {
- return ty::lookup_trait_def(tcx, trait_id)
- }
+ debug!("ensure_super_predicates_step(trait_def_id={})", trait_def_id.repr(tcx));
- match tcx.map.get(trait_id.node) {
- ast_map::NodeItem(item) => trait_def_of_item(ccx, &*item),
- _ => {
- tcx.sess.bug(&format!("get_trait_def({}): not an item",
- trait_id.node))
- }
+ if trait_def_id.krate != ast::LOCAL_CRATE {
+ // If this trait comes from an external crate, then all of the
+ // supertraits it may depend on also must come from external
+ // crates, and hence all of them already have their
+ // super-predicates "converted" (and available from crate
+ // meta-data), so there is no need to transitively test them.
+ return Vec::new();
}
+
+ let superpredicates = tcx.super_predicates.borrow().get(&trait_def_id).cloned();
+ let superpredicates = superpredicates.unwrap_or_else(|| {
+ let trait_node_id = trait_def_id.node;
+
+ let item = match ccx.tcx.map.get(trait_node_id) {
+ ast_map::NodeItem(item) => item,
+ _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
+ };
+
+ let (generics, bounds) = match item.node {
+ ast::ItemTrait(_, ref generics, ref supertraits, _) => (generics, supertraits),
+ _ => tcx.sess.span_bug(item.span,
+ "ensure_super_predicates_step invoked on non-trait"),
+ };
+
+ // In-scope when converting the superbounds for `Trait` are
+ // that `Self:Trait` as well as any bounds that appear on the
+ // generic types:
+ let trait_def = trait_def_of_item(ccx, item);
+ let self_predicate = ty::GenericPredicates {
+ predicates: VecPerParamSpace::new(vec![],
+ vec![trait_def.trait_ref.as_predicate()],
+ vec![])
+ };
+ let scope = &(generics, &self_predicate);
+
+ // Convert the bounds that follow the colon, e.g. `Bar+Zed` in `trait Foo : Bar+Zed`.
+ let self_param_ty = ty::mk_self_type(tcx);
+ let superbounds1 = compute_bounds(&ccx.icx(scope), self_param_ty, bounds,
+ SizedByDefault::No, item.span);
+ let superbounds1 = ty::predicates(tcx, self_param_ty, &superbounds1);
+
+ // Convert any explicit superbounds in the where clause,
+ // e.g. `trait Foo where Self : Bar`:
+ let superbounds2 = generics.get_type_parameter_bounds(&ccx.icx(scope), item.span, item.id);
+
+ // Combine the two lists to form the complete set of superbounds:
+ let superbounds = superbounds1.into_iter().chain(superbounds2.into_iter()).collect();
+ let superpredicates = ty::GenericPredicates {
+ predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
+ };
+ debug!("superpredicates for trait {} = {}",
+ local_def(item.id).repr(ccx.tcx),
+ superpredicates.repr(ccx.tcx));
+
+ tcx.super_predicates.borrow_mut().insert(trait_def_id, superpredicates.clone());
+
+ superpredicates
+ });
+
+ let def_ids: Vec<_> = superpredicates.predicates
+ .iter()
+ .filter_map(|p| p.to_opt_poly_trait_ref())
+ .map(|tr| tr.def_id())
+ .collect();
+
+ debug!("ensure_super_predicates_step: def_ids={}", def_ids.repr(tcx));
+
+ def_ids
}
fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
return def.clone();
}
- let (unsafety, generics, bounds, items) = match it.node {
- ast::ItemTrait(unsafety,
- ref generics,
- ref supertraits,
- ref items) => {
- (unsafety, generics, supertraits, items)
- }
- ref s => {
- tcx.sess.span_bug(
- it.span,
- &format!("trait_def_of_item invoked on {:?}", s));
- }
+ let (unsafety, generics, items) = match it.node {
+ ast::ItemTrait(unsafety, ref generics, _, ref items) => (unsafety, generics, items),
+ _ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
};
let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar");
it.span,
"the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
which traits can use parenthetical notation");
- span_help!(ccx.tcx.sess, it.span,
+ fileline_help!(ccx.tcx.sess, it.span,
"add `#![feature(unboxed_closures)]` to \
the crate attributes to use it");
}
let ty_generics = ty_generics_for_trait(ccx, it.id, substs, generics);
- let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx);
-
- // supertraits:
- let bounds = compute_bounds(&ccx.icx(generics),
- self_param_ty,
- bounds,
- SizedByDefault::No,
- it.span);
-
let associated_type_names: Vec<_> =
items.iter()
.filter_map(|item| {
paren_sugar: paren_sugar,
unsafety: unsafety,
generics: ty_generics,
- bounds: bounds,
trait_ref: trait_ref,
associated_type_names: associated_type_names,
});
}
}
+fn trait_defines_associated_type_named(ccx: &CrateCtxt,
+ trait_node_id: ast::NodeId,
+ assoc_name: ast::Name)
+ -> bool
+{
+ let item = match ccx.tcx.map.get(trait_node_id) {
+ ast_map::NodeItem(item) => item,
+ _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not an item", trait_node_id))
+ };
+
+ let trait_items = match item.node {
+ ast::ItemTrait(_, _, _, ref trait_items) => trait_items,
+ _ => ccx.tcx.sess.bug(&format!("trait_node_id {} is not a trait", trait_node_id))
+ };
+
+ trait_items.iter()
+ .any(|trait_item| {
+ match *trait_item {
+ ast::TypeTraitItem(ref t) => t.ty_param.ident.name == assoc_name,
+ ast::RequiredMethod(..) | ast::ProvidedMethod(..) => false,
+ }
+ })
+}
+
fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &ast::Item) {
let tcx = ccx.tcx;
let trait_def = trait_def_of_item(ccx, it);
}
};
- let self_param_ty = ty::ParamTy::for_self().to_ty(ccx.tcx);
-
- let super_predicates = ty::predicates(ccx.tcx, self_param_ty, &trait_def.bounds);
+ let super_predicates = ty::lookup_super_predicates(ccx.tcx, def_id);
// `ty_generic_predicates` below will consider the bounds on the type
// parameters (including `Self`) and the explicit where-clauses,
// but to get the full set of predicates on a trait we need to add
// in the supertrait bounds and anything declared on the
// associated types.
- let mut base_predicates =
- ty::GenericPredicates {
- predicates: VecPerParamSpace::new(super_predicates, vec![], vec![])
- };
+ let mut base_predicates = super_predicates;
// Add in a predicate that `Self:Trait` (where `Trait` is the
// current trait). This is needed for builtin bounds.
}
}
-enum SizedByDefault { Yes, No }
+enum SizedByDefault { Yes, No, }
/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped Ty or
/// a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the
&mut param_bounds.builtin_bounds,
ast_bounds,
span);
-
- check_bounds_compatible(astconv,
- param_ty,
- ¶m_bounds,
- span);
}
param_bounds.trait_bounds.sort_by(|a,b| a.def_id().cmp(&b.def_id()));
param_bounds
}
-fn check_bounds_compatible<'tcx>(astconv: &AstConv<'tcx>,
- param_ty: Ty<'tcx>,
- param_bounds: &ty::ParamBounds<'tcx>,
- span: Span) {
- let tcx = astconv.tcx();
- if !param_bounds.builtin_bounds.contains(&ty::BoundSized) {
- ty::each_bound_trait_and_supertraits(
- tcx,
- ¶m_bounds.trait_bounds,
- |trait_ref| {
- match astconv.get_trait_def(span, trait_ref.def_id()) {
- Ok(trait_def) => {
- if trait_def.bounds.builtin_bounds.contains(&ty::BoundSized) {
- span_err!(tcx.sess, span, E0129,
- "incompatible bounds on `{}`, \
- bound `{}` does not allow unsized type",
- param_ty.user_string(tcx),
- trait_ref.user_string(tcx));
- }
- }
- Err(ErrorReported) => { }
- }
- true
- });
- }
-}
-
-/// Converts a specific TyParamBound from the AST into the
-/// appropriate poly-trait-reference.
-fn poly_trait_ref_from_bound<'tcx>(astconv: &AstConv<'tcx>,
- param_ty: Ty<'tcx>,
- bound: &ast::TyParamBound,
- projections: &mut Vec<ty::PolyProjectionPredicate<'tcx>>)
- -> Option<ty::PolyTraitRef<'tcx>>
+/// Converts a specific TyParamBound from the AST into a set of
+/// predicates that apply to the self-type. A vector is returned
+/// because this can be anywhere from 0 predicates (`T:?Sized` adds no
+/// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
+/// and `<T as Bar>::X == i32`).
+fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx>,
+ param_ty: Ty<'tcx>,
+ bound: &ast::TyParamBound)
+ -> Vec<ty::Predicate<'tcx>>
{
match *bound {
ast::TraitTyParamBound(ref tr, ast::TraitBoundModifier::None) => {
- Some(conv_poly_trait_ref(astconv, param_ty, tr, projections))
+ let mut projections = Vec::new();
+ let pred = conv_poly_trait_ref(astconv, param_ty, tr, &mut projections);
+ projections.into_iter()
+ .map(|p| p.as_predicate())
+ .chain(Some(pred.as_predicate()).into_iter())
+ .collect()
}
- ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) |
- ast::RegionTyParamBound(_) => {
- None
+ ast::RegionTyParamBound(ref lifetime) => {
+ let region = ast_region_to_region(astconv.tcx(), lifetime);
+ let pred = ty::Binder(ty::OutlivesPredicate(param_ty, region));
+ vec![ty::Predicate::TypeOutlives(pred)]
+ }
+ ast::TraitTyParamBound(_, ast::TraitBoundModifier::Maybe) => {
+ Vec::new()
}
}
}
ast::ItemTrait(..) => {
let trait_def = ty::lookup_trait_def(tcx, did);
- let predicates = ty::predicates(tcx, ty::mk_self_type(tcx), &trait_def.bounds);
+ let predicates = ty::lookup_super_predicates(tcx, did);
self.add_constraints_from_predicates(&trait_def.generics,
- &predicates,
+ predicates.predicates.as_slice(),
self.covariant);
let trait_items = ty::trait_items(tcx, did);
_ => unreachable!()
}
});
- let trait_def = ty::lookup_trait_def(tcx, did);
let predicates = ty::lookup_predicates(tcx, did);
- let bounds = trait_def.bounds.clean(cx);
clean::Trait {
unsafety: def.unsafety,
generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
items: items.collect(),
- bounds: bounds,
+ bounds: vec![], // supertraits can be found in the list of predicates
}
}
use std::rc::Rc;
use std::u32;
-use std::old_path::Path as FsPath; // Conflicts with Path struct
+use std::path::PathBuf;
use core::DocContext;
use doctree;
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Crate {
pub name: String,
- pub src: FsPath,
+ pub src: PathBuf,
pub module: Option<Item>,
pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
pub primitives: Vec<PrimitiveType>,
let src = match cx.input {
Input::File(ref path) => path.clone(),
- Input::Str(_) => FsPath::new("") // FIXME: this is wrong
+ Input::Str(_) => PathBuf::new("") // FIXME: this is wrong
};
Crate {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use std::{old_io, str};
+use std::fs::File;
+use std::io::prelude::*;
+use std::io;
+use std::old_io;
+use std::path::{PathBuf, Path};
+use std::str;
#[derive(Clone)]
pub struct ExternalHtml{
}
}
-pub fn load_string(input: &Path) -> old_io::IoResult<Option<String>> {
- let mut f = try!(old_io::File::open(input));
- let d = try!(f.read_to_end());
+pub fn load_string(input: &Path) -> io::Result<Option<String>> {
+ let mut f = try!(File::open(input));
+ let mut d = Vec::new();
+ try!(f.read_to_end(&mut d));
Ok(str::from_utf8(&d).map(|s| s.to_string()).ok())
}
macro_rules! load_or_return {
($input: expr, $cant_read: expr, $not_utf8: expr) => {
{
- let input = Path::new($input);
+ let input = PathBuf::new($input);
match ::externalfiles::load_string(&input) {
Err(e) => {
let _ = writeln!(&mut old_io::stderr(),
#[cfg(unix)]
mod imp {
- use std::ffi::CString;
+ use std::ffi::{AsOsStr, CString};
+ use std::os::unix::prelude::*;
+ use std::path::Path;
use libc;
use std::os as stdos;
impl Lock {
pub fn new(p: &Path) -> Lock {
- let buf = CString::new(p.as_vec()).unwrap();
+ let buf = CString::new(p.as_os_str().as_bytes()).unwrap();
let fd = unsafe {
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
libc::S_IRWXU)
#[cfg(windows)]
mod imp {
use libc;
+ use std::ffi::AsOsStr;
use std::mem;
+ use std::os::windows::prelude::*;
use std::os;
+ use std::path::Path;
use std::ptr;
- static LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
+ const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
#[allow(non_snake_case)]
extern "system" {
impl Lock {
pub fn new(p: &Path) -> Lock {
- let mut p_16: Vec<u16> = p.as_str().unwrap().utf16_units().collect();
+ let mut p_16: Vec<_> = p.as_os_str().encode_wide().collect();
p_16.push(0);
let handle = unsafe {
libc::CreateFileW(p_16.as_ptr(),
// except according to those terms.
use std::fmt;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
use externalfiles::ExternalHtml;
}
pub fn render<T: fmt::Display, S: fmt::Display>(
- dst: &mut old_io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
- -> old_io::IoResult<()>
+ dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
+ -> io::Result<()>
{
write!(dst,
r##"<!DOCTYPE html>
)
}
-pub fn redirect(dst: &mut old_io::Writer, url: &str) -> old_io::IoResult<()> {
+pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
// <script> triggers a redirect before refresh, so this is fine.
write!(dst,
r##"<!DOCTYPE html>
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::default::Default;
+use std::ffi::OsStr;
use std::fmt;
-use std::old_io::fs::PathExtensions;
-use std::old_io::{fs, File, BufferedWriter, BufferedReader};
-use std::old_io;
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::io::{self, BufWriter, BufReader};
use std::iter::repeat;
+use std::path::{PathBuf, Path};
use std::str;
use std::sync::Arc;
use html::layout;
use html::markdown::Markdown;
use html::markdown;
-use html::escape::Escape;
use stability_summary;
/// A pair of name and its optional document.
-#[derive(Clone, Eq, Ord, PartialEq, PartialOrd)]
-pub struct NameDoc(String, Option<String>);
+pub type NameDoc = (String, Option<String>);
/// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls
pub root_path: String,
/// The path to the crate root source minus the file name.
/// Used for simplifying paths to the highlighted source code files.
- pub src_root: Path,
+ pub src_root: PathBuf,
/// The current destination folder of where HTML artifacts should be placed.
/// This changes as the context descends into the module hierarchy.
- pub dst: Path,
+ pub dst: PathBuf,
/// This describes the layout of each page, and is not modified after
/// creation of the context (contains info like the favicon and added html).
pub layout: layout::Layout,
- /// This map is a list of what should be displayed on the sidebar of the
- /// current page. The key is the section header (traits, modules,
- /// functions), and the value is the list of containers belonging to this
- /// header. This map will change depending on the surrounding context of the
- /// page.
- pub sidebar: HashMap<String, Vec<NameDoc>>,
/// This flag indicates whether [src] links should be generated or not. If
/// the source files are present in the html rendering, then this will be
/// `true`.
/// Processed source-file paths
seen: HashSet<String>,
/// Root destination to place all HTML output into
- dst: Path,
+ dst: PathBuf,
}
/// Wrapper struct to render the source code of a file. This will do things like
/// Generates the documentation for `crate` into the directory `dst`
pub fn run(mut krate: clean::Crate,
external_html: &ExternalHtml,
- dst: Path,
- passes: HashSet<String>) -> old_io::IoResult<()> {
+ dst: PathBuf,
+ passes: HashSet<String>) -> io::Result<()> {
+ let src_root = match krate.src.parent() {
+ Some(p) => p.to_path_buf(),
+ None => PathBuf::new(""),
+ };
let mut cx = Context {
dst: dst,
- src_root: krate.src.dir_path(),
+ src_root: src_root,
passes: passes,
current: Vec::new(),
root_path: String::new(),
- sidebar: HashMap::new(),
layout: layout::Layout {
logo: "".to_string(),
favicon: "".to_string(),
cx.krate(krate, summary)
}
-fn build_index(krate: &clean::Crate, cache: &mut Cache) -> old_io::IoResult<String> {
+fn build_index(krate: &clean::Crate, cache: &mut Cache) -> io::Result<String> {
// Build the search index from the collected metadata
let mut nodeid_to_pathid = HashMap::new();
let mut pathid_to_nodeid = Vec::new();
}
// Collect the index into a string
- let mut w = Vec::new();
+ let mut w = io::Cursor::new(Vec::new());
try!(write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name));
let mut lastpath = "".to_string();
try!(write!(&mut w, "]}};"));
- Ok(String::from_utf8(w).unwrap())
+ Ok(String::from_utf8(w.into_inner()).unwrap())
}
fn write_shared(cx: &Context,
krate: &clean::Crate,
cache: &Cache,
- search_index: String) -> old_io::IoResult<()> {
+ search_index: String) -> io::Result<()> {
// Write out the shared files. Note that these are shared among all rustdoc
// docs placed in the output directory, so this needs to be a synchronized
// operation with respect to all other rustdocs running around.
include_bytes!("static/SourceCodePro-Semibold.woff")));
fn collect(path: &Path, krate: &str,
- key: &str) -> old_io::IoResult<Vec<String>> {
+ key: &str) -> io::Result<Vec<String>> {
let mut ret = Vec::new();
if path.exists() {
- for line in BufferedReader::new(File::open(path)).lines() {
+ for line in BufReader::new(try!(File::open(path))).lines() {
let line = try!(line);
if !line.starts_with(key) {
continue
mydst.push(part);
try!(mkdir(&mydst));
}
- mydst.push(format!("{}.{}.js",
- remote_item_type.to_static_str(),
- remote_path[remote_path.len() - 1]));
+ mydst.push(&format!("{}.{}.js",
+ remote_item_type.to_static_str(),
+ remote_path[remote_path.len() - 1]));
let all_implementors = try!(collect(&mydst, &krate.name,
"implementors"));
- try!(mkdir(&mydst.dir_path()));
- let mut f = BufferedWriter::new(try!(File::create(&mydst)));
+ try!(mkdir(mydst.parent().unwrap()));
+ let mut f = BufWriter::new(try!(File::create(&mydst)));
try!(writeln!(&mut f, "(function() {{var implementors = {{}};"));
for implementor in &all_implementors {
}
fn render_sources(cx: &mut Context,
- krate: clean::Crate) -> old_io::IoResult<clean::Crate> {
+ krate: clean::Crate) -> io::Result<clean::Crate> {
info!("emitting source files");
let dst = cx.dst.join("src");
try!(mkdir(&dst));
/// Writes the entire contents of a string to a destination, not attempting to
/// catch any errors.
-fn write(dst: Path, contents: &[u8]) -> old_io::IoResult<()> {
- File::create(&dst).write_all(contents)
+fn write(dst: PathBuf, contents: &[u8]) -> io::Result<()> {
+ try!(File::create(&dst)).write_all(contents)
}
/// Makes a directory on the filesystem, failing the task if an error occurs and
/// skipping if the directory already exists.
-fn mkdir(path: &Path) -> old_io::IoResult<()> {
+fn mkdir(path: &Path) -> io::Result<()> {
if !path.exists() {
- fs::mkdir(path, old_io::USER_RWX)
+ fs::create_dir(path)
} else {
Ok(())
}
/// static HTML tree.
// FIXME (#9639): The closure should deal with &[u8] instead of &str
// FIXME (#9639): This is too conservative, rejecting non-UTF-8 paths
-fn clean_srcpath<F>(src_root: &Path, src: &[u8], mut f: F) where
+fn clean_srcpath<F>(src_root: &Path, p: &Path, mut f: F) where
F: FnMut(&str),
{
- let p = Path::new(src);
-
// make it relative, if possible
- let p = p.path_relative_from(src_root).unwrap_or(p);
+ let p = p.relative_from(src_root).unwrap_or(p);
- if p.as_vec() != b"." {
- for c in p.str_components().map(|x|x.unwrap()) {
- if ".." == c {
- f("up");
- } else {
- f(c)
- }
+ for c in p.iter().map(|x| x.to_str().unwrap()) {
+ if ".." == c {
+ f("up");
+ } else {
+ f(c)
}
}
}
impl<'a> SourceCollector<'a> {
/// Renders the given filename into its corresponding HTML source file.
- fn emit_source(&mut self, filename: &str) -> old_io::IoResult<()> {
- let p = Path::new(filename);
+ fn emit_source(&mut self, filename: &str) -> io::Result<()> {
+ let p = PathBuf::new(filename);
// If we couldn't open this file, then just returns because it
// probably means that it's some standard library macro thing and we
// can't have the source to it anyway.
- let contents = match File::open(&p).read_to_end() {
+ let mut contents = Vec::new();
+ match File::open(&p).and_then(|mut f| f.read_to_end(&mut contents)) {
Ok(r) => r,
// macros from other libraries get special filenames which we can
// safely ignore
// Create the intermediate directories
let mut cur = self.dst.clone();
let mut root_path = String::from_str("../../");
- clean_srcpath(&self.cx.src_root, p.dirname(), |component| {
+ clean_srcpath(&self.cx.src_root, &p, |component| {
cur.push(component);
mkdir(&cur).unwrap();
root_path.push_str("../");
});
- let mut fname = p.filename().expect("source has no filename").to_vec();
- fname.extend(".html".bytes());
- cur.push(fname);
- let mut w = BufferedWriter::new(try!(File::create(&cur)));
+ let mut fname = p.file_name().expect("source has no filename")
+ .to_os_string();
+ fname.push_os_str(OsStr::from_str(".html"));
+ cur.push(&fname);
+ let mut w = BufWriter::new(try!(File::create(&cur)));
- let title = format!("{} -- source", cur.filename_display());
+ let title = format!("{} -- source", cur.file_name().unwrap()
+ .to_string_lossy());
let desc = format!("Source to the Rust file `{}`.", filename);
let page = layout::Page {
title: &title,
description: &desc,
keywords: get_basic_keywords(),
};
- try!(layout::render(&mut w as &mut Writer, &self.cx.layout,
+ try!(layout::render(&mut w, &self.cx.layout,
&page, &(""), &Source(contents)));
try!(w.flush());
return Ok(());
/// This currently isn't parallelized, but it'd be pretty easy to add
/// parallelization to this function.
fn krate(mut self, mut krate: clean::Crate,
- stability: stability_summary::ModuleSummary) -> old_io::IoResult<()> {
+ stability: stability_summary::ModuleSummary) -> io::Result<()> {
let mut item = match krate.module.take() {
Some(i) => i,
None => return Ok(())
// render stability dashboard
try!(self.recurse(stability.name.clone(), |this| {
let json_dst = &this.dst.join("stability.json");
- let mut json_out = BufferedWriter::new(try!(File::create(json_dst)));
+ let mut json_out = BufWriter::new(try!(File::create(json_dst)));
try!(write!(&mut json_out, "{}", json::as_json(&stability)));
let mut title = stability.name.clone();
keywords: get_basic_keywords(),
};
let html_dst = &this.dst.join("stability.html");
- let mut html_out = BufferedWriter::new(try!(File::create(html_dst)));
+ let mut html_out = BufWriter::new(try!(File::create(html_dst)));
layout::render(&mut html_out, &this.layout, &page,
&Sidebar{ cx: this, item: &item },
&stability)
/// all sub-items which need to be rendered.
///
/// The rendering driver uses this closure to queue up more work.
- fn item<F>(&mut self, item: clean::Item, mut f: F) -> old_io::IoResult<()> where
+ fn item<F>(&mut self, item: clean::Item, mut f: F) -> io::Result<()> where
F: FnMut(&mut Context, clean::Item),
{
- fn render(w: old_io::File, cx: &Context, it: &clean::Item,
- pushname: bool) -> old_io::IoResult<()> {
- info!("Rendering an item to {}", w.path().display());
+ fn render(w: File, cx: &Context, it: &clean::Item,
+ pushname: bool) -> io::Result<()> {
+ info!("Rendering an item to {}", w.path().unwrap().display());
// A little unfortunate that this is done like this, but it sure
// does make formatting *a lot* nicer.
CURRENT_LOCATION_KEY.with(|slot| {
// We have a huge number of calls to write, so try to alleviate some
// of the pain by using a buffered writer instead of invoking the
// write syscall all the time.
- let mut writer = BufferedWriter::new(w);
+ let mut writer = BufWriter::new(w);
if !cx.render_redirect_pages {
try!(layout::render(&mut writer, &cx.layout, &page,
&Sidebar{ cx: cx, item: it },
clean::ModuleItem(m) => m,
_ => unreachable!()
};
- this.sidebar = this.build_sidebar(&m);
+
+ // render sidebar-items.js used throughout this module
+ {
+ let items = this.build_sidebar_items(&m);
+ let js_dst = this.dst.join("sidebar-items.js");
+ let mut js_out = BufferedWriter::new(try!(File::create(&js_dst)));
+ try!(write!(&mut js_out, "initSidebarItems({});",
+ json::as_json(&items)));
+ }
+
for item in m.items {
f(this,item);
}
// Things which don't have names (like impls) don't get special
// pages dedicated to them.
_ if item.name.is_some() => {
- let dst = self.dst.join(item_path(&item));
+ let dst = self.dst.join(&item_path(&item));
let dst = try!(File::create(&dst));
render(dst, self, &item, true)
}
}
}
- fn build_sidebar(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
+ fn build_sidebar_items(&self, m: &clean::Module) -> HashMap<String, Vec<NameDoc>> {
let mut map = HashMap::new();
for item in &m.items {
if self.ignore_private_item(item) { continue }
- // avoid putting foreign items to the sidebar.
- if let &clean::ForeignFunctionItem(..) = &item.inner { continue }
- if let &clean::ForeignStaticItem(..) = &item.inner { continue }
-
let short = shortty(item).to_static_str();
let myname = match item.name {
None => continue,
let short = short.to_string();
let v = map.entry(short).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
- v.push(NameDoc(myname, Some(shorter_line(item.doc_value()))));
+ v.push((myname, Some(shorter_line(item.doc_value()))));
}
for (_, items) in &mut map {
// has anchors for the line numbers that we're linking to.
if ast_util::is_local(self.item.def_id) {
let mut path = Vec::new();
- clean_srcpath(&cx.src_root, self.item.source.filename.as_bytes(),
+ clean_srcpath(&cx.src_root, Path::new(&self.item.source.filename),
|component| {
path.push(component.to_string());
});
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let cx = self.cx;
let it = self.item;
+ let parentlen = cx.current.len() - if it.is_mod() {1} else {0};
+
+ // the sidebar is designed to display sibling functions, modules and
+ // other miscellaneous informations. since there are lots of sibling
+ // items (and that causes quadratic growth in large modules),
+ // we refactor common parts into a shared JavaScript file per module.
+ // still, we don't move everything into JS because we want to preserve
+ // as much HTML as possible in order to allow non-JS-enabled browsers
+ // to navigate the documentation (though slightly inefficiently).
+
try!(write!(fmt, "<p class='location'>"));
- let len = cx.current.len() - if it.is_mod() {1} else {0};
- for (i, name) in cx.current.iter().take(len).enumerate() {
+ for (i, name) in cx.current.iter().take(parentlen).enumerate() {
if i > 0 {
try!(write!(fmt, "::<wbr>"));
}
}
try!(write!(fmt, "</p>"));
- fn block(w: &mut fmt::Formatter, short: &str, longty: &str,
- cur: &clean::Item, cx: &Context) -> fmt::Result {
- let items = match cx.sidebar.get(short) {
- Some(items) => items,
- None => return Ok(())
- };
- try!(write!(w, "<div class='block {}'><h2>{}</h2>", short, longty));
- for &NameDoc(ref name, ref doc) in items {
- let curty = shortty(cur).to_static_str();
- let class = if cur.name.as_ref().unwrap() == name &&
- short == curty { "current" } else { "" };
- try!(write!(w, "<a class='{ty} {class}' href='{href}{path}' \
- title='{title}'>{name}</a>",
- ty = short,
- class = class,
- href = if curty == "mod" {"../"} else {""},
- path = if short == "mod" {
- format!("{}/index.html", name)
- } else {
- format!("{}.{}.html", short, name)
- },
- title = Escape(doc.as_ref().unwrap()),
- name = name));
- }
- try!(write!(w, "</div>"));
- Ok(())
+ // sidebar refers to the enclosing module, not this module
+ let relpath = if shortty(it) == ItemType::Module { "../" } else { "" };
+ try!(write!(fmt,
+ "<script>window.sidebarCurrent = {{\
+ name: '{name}', \
+ ty: '{ty}', \
+ relpath: '{path}'\
+ }};</script>",
+ name = it.name.as_ref().map(|x| &x[..]).unwrap_or(""),
+ ty = shortty(it).to_static_str(),
+ path = relpath));
+ if parentlen == 0 {
+ // there is no sidebar-items.js beyond the crate root path
+ // FIXME maybe dynamic crate loading can be merged here
+ } else {
+ try!(write!(fmt, "<script async src=\"{path}sidebar-items.js\"></script>",
+ path = relpath));
}
- try!(block(fmt, "mod", "Modules", it, cx));
- try!(block(fmt, "struct", "Structs", it, cx));
- try!(block(fmt, "enum", "Enums", it, cx));
- try!(block(fmt, "trait", "Traits", it, cx));
- try!(block(fmt, "fn", "Functions", it, cx));
- try!(block(fmt, "macro", "Macros", it, cx));
Ok(())
}
}
"use strict";
var resizeTimeout, interval;
+ // This mapping table should match the discriminants of
+ // `rustdoc::html::item_type::ItemType` type in Rust.
+ var itemTypes = ["mod",
+ "externcrate",
+ "import",
+ "struct",
+ "enum",
+ "fn",
+ "type",
+ "static",
+ "trait",
+ "impl",
+ "tymethod",
+ "method",
+ "structfield",
+ "variant",
+ "macro",
+ "primitive",
+ "associatedtype",
+ "constant"];
+
$('.js-only').removeClass('js-only');
function getQueryStringParams() {
showResults(results);
}
- // This mapping table should match the discriminants of
- // `rustdoc::html::item_type::ItemType` type in Rust.
- var itemTypes = ["mod",
- "externcrate",
- "import",
- "struct",
- "enum",
- "fn",
- "type",
- "static",
- "trait",
- "impl",
- "tymethod",
- "method",
- "structfield",
- "variant",
- "macro",
- "primitive",
- "associatedtype",
- "constant"];
-
function itemTypeFromName(typename) {
for (var i = 0; i < itemTypes.length; ++i) {
if (itemTypes[i] === typename) return i;
window.initSearch = initSearch;
+ // delayed sidebar rendering.
+ function initSidebarItems(items) {
+ var sidebar = $('.sidebar');
+ var current = window.sidebarCurrent;
+
+ function block(shortty, longty) {
+ var filtered = items[shortty];
+ if (!filtered) return;
+
+ var div = $('<div>').attr('class', 'block ' + shortty);
+ div.append($('<h2>').text(longty));
+
+ for (var i = 0; i < filtered.length; ++i) {
+ var item = filtered[i];
+ var name = item[0];
+ var desc = item[1]; // can be null
+
+ var klass = shortty;
+ if (name === current.name && shortty == current.ty) {
+ klass += ' current';
+ }
+ var path;
+ if (shortty === 'mod') {
+ path = name + '/index.html';
+ } else {
+ path = shortty + '.' + name + '.html';
+ }
+ div.append($('<a>', {'href': current.relpath + path,
+ 'title': desc,
+ 'class': klass}).text(name));
+ }
+ sidebar.append(div);
+ }
+
+ block("mod", "Modules");
+ block("struct", "Structs");
+ block("enum", "Enums");
+ block("trait", "Traits");
+ block("fn", "Functions");
+ block("macro", "Macros");
+ }
+
+ window.initSidebarItems = initSidebarItems;
+
window.register_implementors = function(imp) {
var list = $('#implementors-list');
var libs = Object.getOwnPropertyNames(imp);
#![feature(test)]
#![feature(unicode)]
#![feature(str_words)]
+#![feature(io)]
+#![feature(path)]
+#![feature(path_ext)]
extern crate arena;
extern crate getopts;
extern crate rustc_driver;
extern crate rustc_resolve;
extern crate rustc_lint;
+extern crate rustc_back;
extern crate serialize;
extern crate syntax;
extern crate "test" as testing;
use std::cell::RefCell;
use std::collections::HashMap;
use std::env;
-use std::old_io::File;
-use std::old_io;
+use std::fs::File;
+use std::io::{self, Read, Write};
+use std::path::PathBuf;
use std::rc::Rc;
use std::sync::mpsc::channel;
+
use externalfiles::ExternalHtml;
use serialize::Decodable;
use serialize::json::{self, Json};
fn(clean::Crate) -> plugins::PluginResult, // fn
&'static str); // description
-static PASSES: &'static [Pass] = &[
+const PASSES: &'static [Pass] = &[
("strip-hidden", passes::strip_hidden,
"strips all doc(hidden) items from the output"),
("unindent-comments", passes::unindent_comments,
"strips all private items from a crate which cannot be seen externally"),
];
-static DEFAULT_PASSES: &'static [&'static str] = &[
+const DEFAULT_PASSES: &'static [&'static str] = &[
"strip-hidden",
"strip-private",
"collapse-docs",
let should_test = matches.opt_present("test");
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
- let output = matches.opt_str("o").map(|s| Path::new(s));
+ let output = matches.opt_str("o").map(|s| PathBuf::new(&s));
let cfgs = matches.opt_strs("cfg");
let external_html = match ExternalHtml::load(
(true, false) => {
return test::run(input, cfgs, libs, externs, test_args, crate_name)
}
- (false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
+ (false, true) => return markdown::render(input,
+ output.unwrap_or(PathBuf::new("doc")),
&matches, &external_html,
!matches.opt_present("markdown-no-toc")),
(false, false) => {}
info!("going to format");
match matches.opt_str("w").as_ref().map(|s| &**s) {
Some("html") | None => {
- match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc")),
+ match html::render::run(krate, &external_html,
+ output.unwrap_or(PathBuf::new("doc")),
passes.into_iter().collect()) {
Ok(()) => {}
Err(e) => panic!("failed to generate documentation: {}", e),
}
Some("json") => {
match json_output(krate, json_plugins,
- output.unwrap_or(Path::new("doc.json"))) {
+ output.unwrap_or(PathBuf::new("doc.json"))) {
Ok(()) => {}
Err(e) => panic!("failed to write json: {}", e),
}
let cfgs = matches.opt_strs("cfg");
let triple = matches.opt_str("target");
- let cr = Path::new(cratefile);
+ let cr = PathBuf::new(cratefile);
info!("starting to run rustc");
let (tx, rx) = channel();
std::thread::spawn(move || {
use rustc::session::config::Input;
- let cr = cr;
- tx.send(core::run_core(paths, cfgs, externs, Input::File(cr), triple)).unwrap();
+ tx.send(core::run_core(paths, cfgs, externs, Input::File(cr),
+ triple)).unwrap();
}).join().map_err(|_| "rustc failed").unwrap();
let (mut krate, analysis) = rx.recv().unwrap();
info!("finished with rustc");
/// This input format purely deserializes the json output file. No passes are
/// run over the deserialized output.
fn json_input(input: &str) -> Result<Output, String> {
- let mut input = match File::open(&Path::new(input)) {
- Ok(f) => f,
- Err(e) => {
- return Err(format!("couldn't open {}: {}", input, e))
- }
+ let mut bytes = Vec::new();
+ match File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
+ Ok(()) => {}
+ Err(e) => return Err(format!("couldn't open {}: {}", input, e)),
};
- match json::from_reader(&mut input) {
+ match json::from_reader(&mut &bytes[..]) {
Err(s) => Err(format!("{:?}", s)),
Ok(Json::Object(obj)) => {
let mut obj = obj;
/// Outputs the crate/plugin json as a giant json blob at the specified
/// destination.
fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
- dst: Path) -> old_io::IoResult<()> {
+ dst: PathBuf) -> io::Result<()> {
// {
// "schema": version,
// "crate": { parsed crate ... },
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use std::fs::File;
+use std::io::Write;
use std::old_io;
+use std::path::{PathBuf, Path};
use core;
use getopts;
/// Render `input` (e.g. "foo.md") into an HTML file in `output`
/// (e.g. output = "bar" => "bar/foo.html").
-pub fn render(input: &str, mut output: Path, matches: &getopts::Matches,
+pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
external_html: &ExternalHtml, include_toc: bool) -> int {
let input_p = Path::new(input);
- output.push(input_p.filestem().unwrap());
+ output.push(input_p.file_stem().unwrap());
output.set_extension("html");
let mut css = String::new();
}
let playground = playground.unwrap_or("".to_string());
- let mut out = match old_io::File::create(&output) {
+ let mut out = match File::create(&output) {
Err(e) => {
let _ = writeln!(&mut old_io::stderr(),
"error opening `{}` for writing: {}",
// except according to those terms.
use std::cell::RefCell;
-use std::sync::mpsc::channel;
+use std::collections::{HashSet, HashMap};
use std::dynamic_lib::DynamicLibrary;
-use std::old_io::{Command, TempDir};
+use std::env;
+use std::ffi::OsString;
use std::old_io;
-use std::os;
+use std::io;
+use std::path::PathBuf;
+use std::process::Command;
use std::str;
+use std::sync::mpsc::channel;
use std::thread;
use std::thunk::Thunk;
-use std::collections::{HashSet, HashMap};
use testing;
use rustc_lint;
use rustc::session::{self, config};
use rustc::session::config::get_unstable_features_setting;
use rustc::session::search_paths::{SearchPaths, PathKind};
+use rustc_back::tempdir::TempDir;
use rustc_driver::{driver, Compilation};
use syntax::codemap::CodeMap;
use syntax::diagnostic;
mut test_args: Vec<String>,
crate_name: Option<String>)
-> int {
- let input_path = Path::new(input);
+ let input_path = PathBuf::new(input);
let input = config::Input::File(input_path.clone());
let sessopts = config::Options {
- maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
+ maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
+ .parent().unwrap().to_path_buf()),
search_paths: libs.clone(),
crate_types: vec!(config::CrateTypeDylib),
externs: externs.clone(),
0
}
+#[allow(deprecated)]
fn runtest(test: &str, cratename: &str, libs: SearchPaths,
externs: core::Externs,
should_fail: bool, no_run: bool, as_test_harness: bool) {
let input = config::Input::Str(test.to_string());
let sessopts = config::Options {
- maybe_sysroot: Some(os::self_exe_name().unwrap().dir_path().dir_path()),
+ maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
+ .parent().unwrap().to_path_buf()),
search_paths: libs,
crate_types: vec!(config::CrateTypeExecutable),
output_types: vec!(config::OutputTypeExe),
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
- let out = Some(outdir.path().clone());
+ let out = Some(outdir.path().to_path_buf());
let cfg = config::build_configuration(&sess);
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
let mut control = driver::CompileController::basic();
// environment to ensure that the target loads the right libraries at
// runtime. It would be a sad day if the *host* libraries were loaded as a
// mistake.
- let mut cmd = Command::new(outdir.path().join("rust-out"));
+ let mut cmd = Command::new(&outdir.path().join("rust-out"));
+ let var = DynamicLibrary::envvar();
let newpath = {
- let mut path = DynamicLibrary::search_path();
+ let path = env::var_os(var).unwrap_or(OsString::new());
+ let mut path = env::split_paths(&path).collect::<Vec<_>>();
path.insert(0, libdir.clone());
- DynamicLibrary::create_path(&path)
+ env::join_paths(path.iter()).unwrap()
};
- cmd.env(DynamicLibrary::envvar(), newpath);
+ cmd.env(var, &newpath);
match cmd.output() {
Err(e) => panic!("couldn't run the test: {}{}", e,
- if e.kind == old_io::PermissionDenied {
+ if e.kind() == io::ErrorKind::PermissionDenied {
" - maybe your tempdir is mounted with noexec?"
} else { "" }),
Ok(out) => {
panic!("test executable succeeded when it should have failed");
} else if !should_fail && !out.status.success() {
panic!("test executable failed:\n{:?}",
- str::from_utf8(&out.error));
+ str::from_utf8(&out.stdout));
}
}
}
fn to_hex(&self) -> String;
}
-static CHARS: &'static[u8] = b"0123456789abcdef";
+const CHARS: &'static [u8] = b"0123456789abcdef";
impl ToHex for [u8] {
/// Turn a vector of `u8` bytes into a hexadecimal string.
// This may be an overestimate if there is any whitespace
let mut b = Vec::with_capacity(self.len() / 2);
let mut modulus = 0;
- let mut buf = 0u8;
+ let mut buf = 0;
for (idx, byte) in self.bytes().enumerate() {
buf <<= 4;
while !self.eof() {
match self.ch_or_null() {
c @ '0' ... '9' => {
- accum *= 10;
- accum += (c as u64) - ('0' as u64);
+ accum = accum.wrapping_mul(10);
+ accum = accum.wrapping_add((c as u64) - ('0' as u64));
// Detect overflow by comparing to the last value.
if accum <= last_accum { return self.error(InvalidNumber); }
fn decode_hex_escape(&mut self) -> Result<u16, ParserError> {
let mut i = 0;
- let mut n = 0u16;
+ let mut n = 0;
while i < 4 && !self.eof() {
self.bump();
n = match self.ch_or_null() {
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
+#![feature(path)]
#![cfg_attr(test, feature(test))]
// test harness access
*/
use std::old_path;
+use std::path;
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use std::sync::Arc;
}
}
+impl Encodable for path::PathBuf {
+ fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
+ self.to_str().unwrap().encode(e)
+ }
+}
+
+impl Decodable for path::PathBuf {
+ fn decode<D: Decoder>(d: &mut D) -> Result<path::PathBuf, D::Error> {
+ let bytes: String = try!(Decodable::decode(d));
+ Ok(path::PathBuf::new(&bytes))
+ }
+}
+
impl<T: Encodable + Copy> Encodable for Cell<T> {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
self.get().encode(s)
impl AsciiExt for u8 {
type Owned = u8;
#[inline]
- fn is_ascii(&self) -> bool { *self & 128 == 0u8 }
+ fn is_ascii(&self) -> bool { *self & 128 == 0 }
#[inline]
fn to_ascii_uppercase(&self) -> u8 { ASCII_UPPERCASE_MAP[*self as usize] }
#[inline]
assert_eq!("url()URL()uRl()ürl".to_ascii_uppercase(), "URL()URL()URL()üRL");
assert_eq!("hıKß".to_ascii_uppercase(), "HıKß");
- for i in 0u32..501 {
+ for i in 0..501 {
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_uppercase(),
// Dotted capital I, Kelvin sign, Sharp S.
assert_eq!("HİKß".to_ascii_lowercase(), "hİKß");
- for i in 0u32..501 {
+ for i in 0..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().to_ascii_lowercase(),
"URL()URL()URL()üRL".to_string());
assert_eq!(("hıKß".to_string()).into_ascii_uppercase(), "HıKß");
- for i in 0u32..501 {
+ for i in 0..501 {
let upper = if 'a' as u32 <= i && i <= 'z' as u32 { i + 'A' as u32 - 'a' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_uppercase(),
// Dotted capital I, Kelvin sign, Sharp S.
assert_eq!(("HİKß".to_string()).into_ascii_lowercase(), "hİKß");
- for i in 0u32..501 {
+ for i in 0..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert_eq!((from_u32(i).unwrap()).to_string().into_ascii_lowercase(),
assert!(!"K".eq_ignore_ascii_case("k"));
assert!(!"ß".eq_ignore_ascii_case("s"));
- for i in 0u32..501 {
+ for i in 0..501 {
let lower = if 'A' as u32 <= i && i <= 'Z' as u32 { i + 'a' as u32 - 'A' as u32 }
else { i };
assert!((from_u32(i).unwrap()).to_string().eq_ignore_ascii_case(
M: Deref<Target=RawTable<K, V>>,
F: FnMut(&K) -> bool,
{
+ // This is the only function where capacity can be zero. To avoid
+ // undefined behaviour when Bucket::new gets the raw bucket in this
+ // case, immediately return the appropriate search result.
+ if table.capacity() == 0 {
+ return TableRef(table);
+ }
+
let size = table.size();
let mut probe = Bucket::new(table, hash);
let ib = probe.index();
use mem::{min_align_of, size_of};
use mem;
use num::{Int, UnsignedInt};
+use num::wrapping::{OverflowingOps, WrappingOps};
use ops::{Deref, DerefMut, Drop};
use option::Option;
use option::Option::{Some, None};
use rt::heap::{allocate, deallocate, EMPTY};
use collections::hash_state::HashState;
-const EMPTY_BUCKET: u64 = 0u64;
+const EMPTY_BUCKET: u64 = 0;
/// The raw hashtable, providing safe-ish access to the unzipped and highly
/// optimized arrays of hashes, keys, and values.
{
let mut state = hash_state.hasher();
t.hash(&mut state);
- // We need to avoid 0u64 in order to prevent collisions with
+ // We need to avoid 0 in order to prevent collisions with
// EMPTY_HASH. We can maintain our precious uniform distribution
// of initial indexes by unconditionally setting the MSB,
// effectively reducing 64-bits hashes to 63 bits.
}
pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> {
+ // if capacity is 0, then the RawBucket will be populated with bogus pointers.
+ // This is an uncommon case though, so avoid it in release builds.
+ debug_assert!(table.capacity() > 0, "Table should have capacity at this point");
let ib_index = ib_index & (table.capacity() - 1);
Bucket {
raw: unsafe {
// Calculates the distance one has to travel when going from
// `hash mod capacity` onwards to `idx mod capacity`, wrapping around
// if the destination is not reached before the end of the table.
- (self.idx - self.hash().inspect() as usize) & (self.table.capacity() - 1)
+ (self.idx.wrapping_sub(self.hash().inspect() as usize)) & (self.table.capacity() - 1)
}
#[inline]
fn calculate_offsets(hashes_size: usize,
keys_size: usize, keys_align: usize,
vals_align: usize)
- -> (usize, usize) {
+ -> (usize, usize, bool) {
let keys_offset = round_up_to_next(hashes_size, keys_align);
- let end_of_keys = keys_offset + keys_size;
+ let (end_of_keys, oflo) = keys_offset.overflowing_add(keys_size);
let vals_offset = round_up_to_next(end_of_keys, vals_align);
- (keys_offset, vals_offset)
+ (keys_offset, vals_offset, oflo)
}
// Returns a tuple of (minimum required malloc alignment, hash_offset,
fn calculate_allocation(hash_size: usize, hash_align: usize,
keys_size: usize, keys_align: usize,
vals_size: usize, vals_align: usize)
- -> (usize, usize, usize) {
+ -> (usize, usize, usize, bool) {
let hash_offset = 0;
- let (_, vals_offset) = calculate_offsets(hash_size,
- keys_size, keys_align,
- vals_align);
- let end_of_vals = vals_offset + vals_size;
+ let (_, vals_offset, oflo) = calculate_offsets(hash_size,
+ keys_size, keys_align,
+ vals_align);
+ let (end_of_vals, oflo2) = vals_offset.overflowing_add(vals_size);
let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
- (min_align, hash_offset, end_of_vals)
+ (min_align, hash_offset, end_of_vals, oflo || oflo2)
}
#[test]
fn test_offset_calculation() {
- assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148));
- assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6));
- assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48));
- assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144));
- assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5));
- assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24));
+ assert_eq!(calculate_allocation(128, 8, 15, 1, 4, 4), (8, 0, 148, false));
+ assert_eq!(calculate_allocation(3, 1, 2, 1, 1, 1), (1, 0, 6, false));
+ assert_eq!(calculate_allocation(6, 2, 12, 4, 24, 8), (8, 0, 48, false));
+ assert_eq!(calculate_offsets(128, 15, 1, 4), (128, 144, false));
+ assert_eq!(calculate_offsets(3, 2, 1, 1), (3, 5, false));
+ assert_eq!(calculate_offsets(6, 12, 4, 8), (8, 24, false));
}
impl<K, V> RawTable<K, V> {
// This is great in theory, but in practice getting the alignment
// right is a little subtle. Therefore, calculating offsets has been
// factored out into a different function.
- let (malloc_alignment, hash_offset, size) =
+ let (malloc_alignment, hash_offset, size, oflo) =
calculate_allocation(
hashes_size, min_align_of::<u64>(),
keys_size, min_align_of::< K >(),
vals_size, min_align_of::< V >());
+ assert!(!oflo, "capacity overflow");
+
// One check for overflow that covers calculation and rounding of size.
let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
.checked_add(size_of::<V>()).unwrap();
let keys_size = self.capacity * size_of::<K>();
let buffer = *self.hashes as *mut u8;
- let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
- keys_size, min_align_of::<K>(),
- min_align_of::<V>());
-
+ let (keys_offset, vals_offset, oflo) =
+ calculate_offsets(hashes_size,
+ keys_size, min_align_of::<K>(),
+ min_align_of::<V>());
+ debug_assert!(!oflo, "capacity overflow");
unsafe {
RawBucket {
hash: *self.hashes,
let hashes_size = self.capacity * size_of::<u64>();
let keys_size = self.capacity * size_of::<K>();
let vals_size = self.capacity * size_of::<V>();
- let (align, _, size) = calculate_allocation(hashes_size, min_align_of::<u64>(),
- keys_size, min_align_of::<K>(),
- vals_size, min_align_of::<V>());
+ let (align, _, size, oflo) =
+ calculate_allocation(hashes_size, min_align_of::<u64>(),
+ keys_size, min_align_of::<K>(),
+ vals_size, min_align_of::<V>());
+
+ debug_assert!(!oflo, "should be impossible");
unsafe {
deallocate(*self.hashes as *mut u8, size, align);
//! * You want a bit vector.
//!
//! ### Use a `BitSet` when:
-//! * You want a `VecSet`.
+//! * You want a `BitVec`, but want `Set` properties
//!
//! ### Use a `BinaryHeap` when:
//! * You want to store a bunch of elements, but only ever want to process the "biggest"
//!
//! Choosing the right collection for the job requires an understanding of what each collection
//! is good at. Here we briefly summarize the performance of different collections for certain
-//! important operations. For further details, see each type's documentation.
+//! important operations. For further details, see each type's documentation, and note that the
+//! names of actual methods may differ from the tables below on certain collections.
//!
//! Throughout the documentation, we will follow a few conventions. For all operations,
//! the collection's size is denoted by n. If another collection is involved in the operation, it
//! a variant of the `Entry` enum.
//!
//! If a `Vacant(entry)` is yielded, then the key *was not* found. In this case the
-//! only valid operation is to `set` the value of the entry. When this is done,
+//! only valid operation is to `insert` a value into the entry. When this is done,
//! the vacant entry is consumed and converted into a mutable reference to the
//! the value that was inserted. This allows for further manipulation of the value
//! beyond the lifetime of the search itself. This is useful if complex logic needs to
//! be performed on the value regardless of whether the value was just inserted.
//!
//! If an `Occupied(entry)` is yielded, then the key *was* found. In this case, the user
-//! has several options: they can `get`, `set`, or `take` the value of the occupied
+//! has several options: they can `get`, `insert`, or `remove` the value of the occupied
//! entry. Additionally, they can convert the occupied entry into a mutable reference
-//! to its value, providing symmetry to the vacant `set` case.
+//! to its value, providing symmetry to the vacant `insert` case.
//!
//! ### Examples
//!
//! use std::collections::btree_map::{BTreeMap, Entry};
//!
//! // A client of the bar. They have an id and a blood alcohol level.
-//! struct Person { id: u32, blood_alcohol: f32 };
+//! struct Person { id: u32, blood_alcohol: f32 }
//!
//! // All the orders made to the bar, by client id.
//! let orders = vec![1,2,1,2,3,4,1,2,2,3,4,1,1,1];
mod os {
pub const FAMILY: &'static str = "unix";
pub const OS: &'static str = "ios";
+ pub const DLL_PREFIX: &'static str = "lib";
+ pub const DLL_SUFFIX: &'static str = ".dylib";
+ pub const DLL_EXTENSION: &'static str = "dylib";
pub const EXE_SUFFIX: &'static str = "";
pub const EXE_EXTENSION: &'static str = "";
}
use prelude::v1::*;
use super::*;
use libc;
- use mem;
#[test]
fn c_to_rust() {
let data = b"123\0";
let ptr = data.as_ptr() as *const libc::c_char;
unsafe {
- assert_eq!(c_str_to_bytes(&ptr), b"123");
- assert_eq!(c_str_to_bytes_with_nul(&ptr), b"123\0");
+ assert_eq!(CStr::from_ptr(ptr).to_bytes(), b"123");
+ assert_eq!(CStr::from_ptr(ptr).to_bytes_with_nul(), b"123\0");
}
}
use core::prelude::*;
-use borrow::{Borrow, ToOwned};
+use borrow::{Borrow, Cow, ToOwned};
use fmt::{self, Debug};
use mem;
-use string::{String, CowString};
+use string::String;
use ops;
use cmp;
use hash::{Hash, Hasher};
self.inner.to_str()
}
- /// Convert an `OsStr` to a `CowString`.
+ /// Convert an `OsStr` to a `Cow<str>`.
///
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
self.inner.to_string_lossy()
}
//! operations. Extra platform-specific functionality can be found in the
//! extension traits of `std::os::$platform`.
-#![unstable(feature = "fs")]
+#![stable(feature = "rust1", since = "1.0.0")]
use core::prelude::*;
use sys_common::{AsInnerMut, FromInner, AsInner};
use vec::Vec;
+#[allow(deprecated)]
pub use self::tempdir::TempDir;
mod tempdir;
/// # Ok(())
/// # }
/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct File {
inner: fs_imp::File,
path: PathBuf,
/// This structure is returned from the `metadata` function or method and
/// represents known metadata about a file such as its permissions, size,
/// modification times, etc.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Metadata(fs_imp::FileAttr);
/// Iterator over the entries in a directory.
/// will yield instances of `io::Result<DirEntry>`. Through a `DirEntry`
/// information like the entry's path and possibly other metadata can be
/// learned.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct ReadDir(fs_imp::ReadDir);
/// Entries returned by the `ReadDir` iterator.
/// An instance of `DirEntry` represents an entry inside of a directory on the
/// filesystem. Each entry can be inspected via methods to learn about the full
/// path or possibly other metadata through per-platform extension traits.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct DirEntry(fs_imp::DirEntry);
/// An iterator that recursively walks over the contents of a directory.
+#[unstable(feature = "fs_walk",
+ reason = "the precise semantics and defaults for a recursive walk \
+ may change and this may end up accounting for files such \
+ as symlinks differently")]
pub struct WalkDir {
cur: Option<ReadDir>,
stack: Vec<io::Result<ReadDir>>,
/// `File::create` methods are aliases for commonly used options using this
/// builder.
#[derive(Clone)]
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct OpenOptions(fs_imp::OpenOptions);
/// Representation of the various permissions on a file.
/// functionality, such as mode bits, is available through the
/// `os::unix::PermissionsExt` trait.
#[derive(Clone, PartialEq, Eq, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Permissions(fs_imp::FilePermissions);
impl File {
///
/// This function will return an error if `path` does not already exist.
/// Other errors may also be returned according to `OpenOptions::open`.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().read(true).open(path)
}
/// and will truncate it if it does.
///
/// See the `OpenOptions::open` function for more details.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn create<P: AsPath + ?Sized>(path: &P) -> io::Result<File> {
OpenOptions::new().write(true).create(true).truncate(true).open(path)
}
/// Returns the original path that was used to open this file.
+ #[unstable(feature = "file_path",
+ reason = "this abstraction is imposed by this library instead \
+ of the underlying OS and may be removed")]
pub fn path(&self) -> Option<&Path> {
Some(&self.path)
}
///
/// This function will attempt to ensure that all in-core data reaches the
/// filesystem before returning.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_all(&self) -> io::Result<()> {
self.inner.fsync()
}
///
/// Note that some platforms may simply implement this in terms of
/// `sync_all`.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_data(&self) -> io::Result<()> {
self.inner.datasync()
}
/// be shrunk. If it is greater than the current file's size, then the file
/// will be extended to `size` and have all of the intermediate data filled
/// in with 0s.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn set_len(&self, size: u64) -> io::Result<()> {
self.inner.truncate(size)
}
- /// Queries information about the underlying file.
+ /// Queries metadata about the underlying file.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.inner.file_attr().map(Metadata)
}
impl AsInner<fs_imp::File> for File {
fn as_inner(&self) -> &fs_imp::File { &self.inner }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Seek for &'a File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
/// Creates a blank net set of options ready for configuration.
///
/// All options are initially set to `false`.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn new() -> OpenOptions {
OpenOptions(fs_imp::OpenOptions::new())
}
///
/// This option, when true, will indicate that the file should be
/// `read`-able if opened.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn read(&mut self, read: bool) -> &mut OpenOptions {
self.0.read(read); self
}
///
/// This option, when true, will indicate that the file should be
/// `write`-able if opened.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn write(&mut self, write: bool) -> &mut OpenOptions {
self.0.write(write); self
}
///
/// This option, when true, means that writes will append to a file instead
/// of overwriting previous contents.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn append(&mut self, append: bool) -> &mut OpenOptions {
self.0.append(append); self
}
///
/// If a file is successfully opened with this option set it will truncate
/// the file to 0 length if it already exists.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn truncate(&mut self, truncate: bool) -> &mut OpenOptions {
self.0.truncate(truncate); self
}
///
/// This option indicates whether a new file will be created if the file
/// does not yet already exist.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn create(&mut self, create: bool) -> &mut OpenOptions {
self.0.create(create); self
}
/// * Attempting to open a file with access that the user lacks
/// permissions for
/// * Filesystem-level errors (full disk, etc)
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn open<P: AsPath + ?Sized>(&self, path: &P) -> io::Result<File> {
let path = path.as_path();
let inner = try!(fs_imp::File::open(path, &self.0));
-
- // On *BSD systems, we can open a directory as a file and read from
- // it: fd=open("/tmp", O_RDONLY); read(fd, buf, N); due to an old
- // tradition before the introduction of opendir(3). We explicitly
- // reject it because there are few use cases.
- if cfg!(not(any(target_os = "linux", target_os = "android"))) &&
- try!(inner.file_attr()).is_dir() {
- Err(Error::new(ErrorKind::InvalidInput, "is a directory", None))
- } else {
- Ok(File { path: path.to_path_buf(), inner: inner })
- }
+ Ok(File { path: path.to_path_buf(), inner: inner })
}
}
+
impl AsInnerMut<fs_imp::OpenOptions> for OpenOptions {
fn as_inner_mut(&mut self) -> &mut fs_imp::OpenOptions { &mut self.0 }
}
impl Metadata {
/// Returns whether this metadata is for a directory.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn is_dir(&self) -> bool { self.0.is_dir() }
/// Returns whether this metadata is for a regular file.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn is_file(&self) -> bool { self.0.is_file() }
/// Returns the size of the file, in bytes, this metadata is for.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> u64 { self.0.size() }
/// Returns the permissions of the file this metadata is for.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn permissions(&self) -> Permissions {
Permissions(self.0.perm())
}
/// Returns the most recent access time for a file.
///
/// The return value is in milliseconds since the epoch.
+ #[unstable(feature = "fs_time",
+ reason = "the return type of u64 is not quite appropriate for \
+ this method and may change if the standard library \
+ gains a type to represent a moment in time")]
pub fn accessed(&self) -> u64 { self.0.accessed() }
/// Returns the most recent modification time for a file.
///
/// The return value is in milliseconds since the epoch.
+ #[unstable(feature = "fs_time",
+ reason = "the return type of u64 is not quite appropriate for \
+ this method and may change if the standard library \
+ gains a type to represent a moment in time")]
pub fn modified(&self) -> u64 { self.0.modified() }
}
impl Permissions {
/// Returns whether these permissions describe a readonly file.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn readonly(&self) -> bool { self.0.readonly() }
/// Modify the readonly flag for this set of permissions.
///
/// This operation does **not** modify the filesystem. To modify the
/// filesystem use the `fs::set_permissions` function.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn set_readonly(&mut self, readonly: bool) {
self.0.set_readonly(readonly)
}
fn as_inner(&self) -> &fs_imp::FilePermissions { &self.0 }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl DirEntry {
/// Returns the full path to the file that this entry represents.
///
/// The full path is created by joining the original path to `read_dir` or
/// `walk_dir` with the filename of this entry.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn path(&self) -> PathBuf { self.0.path() }
}
/// This function will return an error if `path` points to a directory, if the
/// user lacks permissions to remove the file, or if some other filesystem-level
/// error occurs.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_file<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
- let path = path.as_path();
- let e = match fs_imp::unlink(path) {
- Ok(()) => return Ok(()),
- Err(e) => e,
- };
- if !cfg!(windows) { return Err(e) }
-
- // On unix, a readonly file can be successfully removed. On windows,
- // however, it cannot. To keep the two platforms in line with
- // respect to their behavior, catch this case on windows, attempt to
- // change it to read-write, and then remove the file.
- if e.kind() != ErrorKind::PermissionDenied { return Err(e) }
-
- let attr = match metadata(path) { Ok(a) => a, Err(..) => return Err(e) };
- let mut perms = attr.permissions();
- if !perms.readonly() { return Err(e) }
- perms.set_readonly(false);
-
- if set_permissions(path, perms).is_err() { return Err(e) }
- if fs_imp::unlink(path).is_ok() { return Ok(()) }
-
- // Oops, try to put things back the way we found it
- let _ = set_permissions(path, attr.permissions());
- Err(e)
+ fs_imp::unlink(path.as_path())
}
/// Given a path, query the file system to get information about a file,
/// This function will return an error if the user lacks the requisite
/// permissions to perform a `metadata` call on the given `path` or if there
/// is no entry in the filesystem at the provided path.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata<P: AsPath + ?Sized>(path: &P) -> io::Result<Metadata> {
fs_imp::stat(path.as_path()).map(Metadata)
}
/// the process lacks permissions to view the contents, if `from` and `to`
/// reside on separate filesystems, or if some other intermittent I/O error
/// occurs.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn rename<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<()> {
fs_imp::rename(from.as_path(), to.as_path())
/// * The `from` file does not exist
/// * The current process does not have the permission rights to access
/// `from` or write `to`
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<P: AsPath + ?Sized, Q: AsPath + ?Sized>(from: &P, to: &Q)
-> io::Result<u64> {
let from = from.as_path();
///
/// The `dst` path will be a link pointing to the `src` path. Note that systems
/// often require these two paths to both be located on the same filesystem.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn hard_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-> io::Result<()> {
fs_imp::link(src.as_path(), dst.as_path())
/// Creates a new soft link on the filesystem.
///
/// The `dst` path will be a soft link pointing to the `src` path.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn soft_link<P: AsPath + ?Sized, Q: AsPath + ?Sized>(src: &P, dst: &Q)
-> io::Result<()> {
fs_imp::symlink(src.as_path(), dst.as_path())
/// This function will return an error on failure. Failure conditions include
/// reading a file that does not exist or reading a file that is not a soft
/// link.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_link<P: AsPath + ?Sized>(path: &P) -> io::Result<PathBuf> {
fs_imp::readlink(path.as_path())
}
///
/// This function will return an error if the user lacks permissions to make a
/// new directory at the provided `path`, or if the directory already exists.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
fs_imp::mkdir(path.as_path())
}
/// does not already exist and it could not be created otherwise. The specific
/// error conditions for when a directory is being created (after it is
/// determined to not exist) are outlined by `fs::create_dir`.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn create_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path();
if path.is_dir() { return Ok(()) }
///
/// This function will return an error if the user lacks permissions to remove
/// the directory at the provided `path`, or if the directory isn't empty.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
fs_imp::rmdir(path.as_path())
}
/// # Errors
///
/// See `file::remove_file` and `fs::remove_dir`
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir_all<P: AsPath + ?Sized>(path: &P) -> io::Result<()> {
let path = path.as_path();
for child in try!(read_dir(path)) {
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to view the contents or if the `path` points
/// at a non-directory file
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<ReadDir> {
fs_imp::readdir(path.as_path()).map(ReadDir)
}
///
/// The iterator will yield instances of `io::Result<DirEntry>`. New errors may
/// be encountered after an iterator is initially constructed.
+#[unstable(feature = "fs_walk",
+ reason = "the precise semantics and defaults for a recursive walk \
+ may change and this may end up accounting for files such \
+ as symlinks differently")]
pub fn walk_dir<P: AsPath + ?Sized>(path: &P) -> io::Result<WalkDir> {
let start = try!(read_dir(path));
Ok(WalkDir { cur: Some(start), stack: Vec::new() })
}
+#[unstable(feature = "fs_walk")]
impl Iterator for WalkDir {
type Item = io::Result<DirEntry>;
}
/// Utility methods for paths.
+#[unstable(feature = "path_ext",
+ reason = "the precise set of methods exposed on this trait may \
+ change and some methods may be removed")]
pub trait PathExt {
/// Get information on the file, directory, etc at this path.
///
/// The file at the path specified will have its last access time set to
/// `atime` and its modification time set to `mtime`. The times specified should
/// be in milliseconds.
+#[unstable(feature = "fs_time",
+ reason = "the argument type of u64 is not quite appropriate for \
+ this function and may change if the standard library \
+ gains a type to represent a moment in time")]
pub fn set_file_times<P: AsPath + ?Sized>(path: &P, accessed: u64,
modified: u64) -> io::Result<()> {
fs_imp::utimes(path.as_path(), accessed, modified)
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to change the attributes of the file, or if
/// some other I/O error is encountered.
+#[unstable(feature = "fs",
+ reason = "a more granual ability to set specific permissions may \
+ be exposed on the Permissions structure itself and this \
+ method may not always exist")]
pub fn set_permissions<P: AsPath + ?Sized>(path: &P, perm: Permissions)
-> io::Result<()> {
fs_imp::set_perm(path.as_path(), perm.0)
check!(w.write(msg));
}
let files = check!(fs::read_dir(dir));
- let mut mem = [0u8; 4];
+ let mut mem = [0; 4];
for f in files {
let f = f.unwrap().path();
{
check!(File::create(&dir2.join("14")));
let files = check!(fs::walk_dir(dir));
- let mut cur = [0u8; 2];
+ let mut cur = [0; 2];
for f in files {
let f = f.unwrap().path();
let stem = f.file_stem().unwrap().to_str().unwrap();
// except according to those terms.
#![unstable(feature = "tempdir", reason = "needs an RFC before stabilization")]
+#![deprecated(since = "1.0.0",
+ reason = "use the `tempdir` crate from crates.io instead")]
+#![allow(deprecated)]
use prelude::v1::*;
#[test]
fn read_char_buffered() {
- let buf = [195u8, 159u8];
+ let buf = [195, 159];
let reader = BufReader::with_capacity(1, &buf[..]);
assert_eq!(reader.chars().next(), Some(Ok('ß')));
}
#[test]
fn test_chars() {
- let buf = [195u8, 159u8, b'a'];
+ let buf = [195, 159, b'a'];
let reader = BufReader::with_capacity(1, &buf[..]);
let mut it = reader.chars();
assert_eq!(it.next(), Some(Ok('ß')));
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(missing_copy_implementations)]
-
use prelude::v1::*;
use io::prelude::*;
/// Implementations of the I/O traits for `Cursor<T>` are not currently generic
/// over `T` itself. Instead, specific implementations are provided for various
/// in-memory buffer types like `Vec<u8>` and `&[u8]`.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Cursor<T> {
inner: T,
pos: u64,
impl<T> Cursor<T> {
/// Create a new cursor wrapping the provided underlying I/O object.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner: inner }
}
/// Consume this cursor, returning the underlying value.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> T { self.inner }
/// Get a reference to the underlying value in this cursor.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn get_ref(&self) -> &T { &self.inner }
/// Get a mutable reference to the underlying value in this cursor.
///
/// Care should be taken to avoid modifying the internal I/O state of the
/// underlying value as it may corrupt this cursor's position.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut T { &mut self.inner }
/// Returns the current value of this cursor
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn position(&self) -> u64 { self.pos }
/// Sets the value of this cursor
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn set_position(&mut self, pos: u64) { self.pos = pos; }
}
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> io::Seek for Cursor<&'a [u8]> { seek!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> io::Seek for Cursor<&'a mut [u8]> { seek!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl io::Seek for Cursor<Vec<u8>> { seek!(); }
macro_rules! read {
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for Cursor<&'a [u8]> { read!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for Cursor<&'a mut [u8]> { read!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Cursor<Vec<u8>> { read!(); }
macro_rules! buffer {
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<&'a [u8]> { buffer!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<&'a mut [u8]> { buffer!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for Cursor<Vec<u8>> { buffer!(); }
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for Cursor<&'a mut [u8]> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let pos = cmp::min(self.pos, self.inner.len() as u64);
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Cursor<Vec<u8>> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
// Make sure the internal buffer is as least as big as where we
#[test]
fn test_mem_reader() {
- let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7));
+ let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
let mut buf = [];
assert_eq!(reader.read(&mut buf), Ok(0));
assert_eq!(reader.position(), 0);
#[test]
fn read_to_end() {
- let mut reader = Cursor::new(vec!(0u8, 1, 2, 3, 4, 5, 6, 7));
+ let mut reader = Cursor::new(vec!(0, 1, 2, 3, 4, 5, 6, 7));
let mut v = Vec::new();
reader.read_to_end(&mut v).ok().unwrap();
assert_eq!(v, [0, 1, 2, 3, 4, 5, 6, 7]);
#[test]
fn test_slice_reader() {
- let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7];
+ let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
let mut reader = &mut in_buf.as_slice();
let mut buf = [];
assert_eq!(reader.read(&mut buf), Ok(0));
#[test]
fn test_buf_reader() {
- let in_buf = vec![0u8, 1, 2, 3, 4, 5, 6, 7];
+ let in_buf = vec![0, 1, 2, 3, 4, 5, 6, 7];
let mut reader = Cursor::new(in_buf.as_slice());
let mut buf = [];
assert_eq!(reader.read(&mut buf), Ok(0));
assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
assert_eq!(r.read(&mut [0]), Ok(0));
- let mut r = Cursor::new(vec!(10u8));
+ let mut r = Cursor::new(vec!(10));
assert_eq!(r.seek(SeekFrom::Start(10)), Ok(10));
assert_eq!(r.read(&mut [0]), Ok(0));
#[test]
fn seek_before_0() {
- let buf = [0xff_u8];
+ let buf = [0xff];
let mut r = Cursor::new(&buf[..]);
assert!(r.seek(SeekFrom::End(-2)).is_err());
- let mut r = Cursor::new(vec!(10u8));
+ let mut r = Cursor::new(vec!(10));
assert!(r.seek(SeekFrom::End(-2)).is_err());
let mut buf = [0];
// =============================================================================
// Forwarding implementations
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, R: Read + ?Sized> Read for &'a mut R {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
-
- fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> { (**self).read_to_end(buf) }
-
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ (**self).read(buf)
+ }
+ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+ (**self).read_to_end(buf)
+ }
fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
(**self).read_to_string(buf)
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, W: Write + ?Sized> Write for &'a mut W {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
-
- fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { (**self).write_all(buf) }
-
- fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> { (**self).write_fmt(fmt) }
-
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ (**self).write_all(buf)
+ }
+ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+ (**self).write_fmt(fmt)
+ }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, S: Seek + ?Sized> Seek for &'a mut S {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: BufRead + ?Sized> BufRead for &'a mut B {
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
-
fn consume(&mut self, amt: usize) { (**self).consume(amt) }
-
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
(**self).read_until(byte, buf)
}
-
- fn read_line(&mut self, buf: &mut String) -> io::Result<()> { (**self).read_line(buf) }
+ fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+ (**self).read_line(buf)
+ }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read + ?Sized> Read for Box<R> {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { (**self).read(buf) }
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ (**self).read(buf)
+ }
+ fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<()> {
+ (**self).read_to_end(buf)
+ }
+ fn read_to_string(&mut self, buf: &mut String) -> io::Result<()> {
+ (**self).read_to_string(buf)
+ }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Write + ?Sized> Write for Box<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { (**self).write(buf) }
fn flush(&mut self) -> io::Result<()> { (**self).flush() }
+ fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
+ (**self).write_all(buf)
+ }
+ fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
+ (**self).write_fmt(fmt)
+ }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Seek + ?Sized> Seek for Box<S> {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { (**self).seek(pos) }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead + ?Sized> BufRead for Box<B> {
fn fill_buf(&mut self) -> io::Result<&[u8]> { (**self).fill_buf() }
fn consume(&mut self, amt: usize) { (**self).consume(amt) }
+ fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> io::Result<()> {
+ (**self).read_until(byte, buf)
+ }
+ fn read_line(&mut self, buf: &mut String) -> io::Result<()> {
+ (**self).read_line(buf)
+ }
}
// =============================================================================
// In-memory buffer implementations
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a [u8] {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amt = cmp::min(buf.len(), self.len());
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> BufRead for &'a [u8] {
fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(*self) }
fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a mut [u8] {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
let amt = cmp::min(data.len(), self.len());
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Vec<u8> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.push_all(buf);
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
- try!(self.write(buf));
+ self.push_all(buf);
Ok(())
}
/// Extension methods for all instances of `Read`, typically imported through
/// `std::io::prelude::*`.
+#[unstable(feature = "io", reason = "may merge into the Read trait")]
pub trait ReadExt: Read + Sized {
/// Create a "by reference" adaptor for this instance of `Read`.
///
/// The returned adaptor also implements `Read` and will simply borrow this
/// current reader.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self { self }
/// Transform this `Read` instance to an `Iterator` over its bytes.
/// R::Err>`. The yielded item is `Ok` if a byte was successfully read and
/// `Err` otherwise for I/O errors. EOF is mapped to returning `None` from
/// this iterator.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn bytes(self) -> Bytes<Self> {
Bytes { inner: self }
}
///
/// Currently this adaptor will discard intermediate data read, and should
/// be avoided if this is not desired.
+ #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+ of where errors happen is currently \
+ unclear and may change")]
fn chars(self) -> Chars<Self> {
Chars { inner: self }
}
/// The returned `Read` instance will first read all bytes from this object
/// until EOF is encountered. Afterwards the output is equivalent to the
/// output of `next`.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn chain<R: Read>(self, next: R) -> Chain<Self, R> {
Chain { first: self, second: next, done_first: false }
}
/// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any
/// read errors will not count towards the number of bytes read and future
/// calls to `read` may succeed.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn take(self, limit: u64) -> Take<Self> {
Take { inner: self, limit: limit }
}
/// Whenever the returned `Read` instance is read it will write the read
/// data to `out`. The current semantics of this implementation imply that
/// a `write` error will not report how much data was initially read.
+ #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+ of where errors happen is currently \
+ unclear and may change")]
fn tee<W: Write>(self, out: W) -> Tee<Self, W> {
Tee { reader: self, writer: out }
}
/// Extension methods for all instances of `Write`, typically imported through
/// `std::io::prelude::*`.
+#[unstable(feature = "io", reason = "may merge into the Read trait")]
pub trait WriteExt: Write + Sized {
/// Create a "by reference" adaptor for this instance of `Write`.
///
/// The returned adaptor also implements `Write` and will simply borrow this
/// current writer.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self { self }
/// Creates a new writer which will write all data to both this writer and
/// implementation do not precisely track where errors happen. For example
/// an error on the second call to `write` will not report that the first
/// call to `write` succeeded.
+ #[unstable(feature = "io", reason = "the semantics of a partial read/write \
+ of where errors happen is currently \
+ unclear and may change")]
fn broadcast<W: Write>(self, other: W) -> Broadcast<Self, W> {
Broadcast { first: self, second: other }
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Write> WriteExt for T {}
/// An object implementing `Seek` internally has some form of cursor which can
///
/// This function will yield errors whenever `read_until` would have also
/// yielded an error.
+ #[unstable(feature = "io", reason = "may be renamed to not conflict with \
+ SliceExt::split")]
fn split(self, byte: u8) -> Split<Self> {
Split { buf: self, delim: byte }
}
///
/// This function will yield errors whenever `read_string` would have also
/// yielded an error.
+ #[stable(feature = "rust1", since = "1.0.0")]
fn lines(self) -> Lines<Self> {
Lines { buf: self }
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T: BufRead> BufReadExt for T {}
/// A `Write` adaptor which will write data to multiple locations.
/// Adaptor to chain together two instances of `Read`.
///
/// For more information, see `ReadExt::chain`.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Chain<T, U> {
first: T,
second: U,
done_first: bool,
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Read, U: Read> Read for Chain<T, U> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
if !self.done_first {
/// Reader adaptor which limits the bytes read from an underlying reader.
///
/// For more information, see `ReadExt::take`.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Take<T> {
inner: T,
limit: u64,
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Take<T> {
/// Returns the number of bytes that can be read before this instance will
/// return EOF.
///
/// This instance may reach EOF after reading fewer bytes than indicated by
/// this method if the underlying `Read` instance reaches EOF.
+ #[stable(feature = "rust1", since = "1.0.0")]
pub fn limit(&self) -> u64 { self.limit }
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Read> Read for Take<T> {
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
// Don't call into inner reader at all at EOF because it may still block
}
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<T: BufRead> BufRead for Take<T> {
fn fill_buf(&mut self) -> Result<&[u8]> {
let buf = try!(self.inner.fill_buf());
/// A bridge from implementations of `Read` to an `Iterator` of `u8`.
///
/// See `ReadExt::bytes` for more information.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Bytes<R> {
inner: R,
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<R: Read> Iterator for Bytes<R> {
type Item = Result<u8>;
/// byte.
///
/// See `BufReadExt::lines` for more information.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Lines<B> {
buf: B,
}
+#[stable(feature = "rust1", since = "1.0.0")]
impl<B: BufRead> Iterator for Lines<B> {
type Item = Result<String>;
struct R;
impl Read for R {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(io::ErrorKind::Other, "", None))
}
}
use prelude::v1::*;
-use io::{self, Read, Write, ErrorKind};
+use io::{self, Read, Write, ErrorKind, BufRead};
/// Copies the entire contents of a reader into a writer.
///
/// This function will return an error immediately if any call to `read` or
/// `write` returns an error. All instances of `ErrorKind::Interrupted` are
/// handled by this function and the underlying operation is retried.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<R: Read, W: Write>(r: &mut R, w: &mut W) -> io::Result<u64> {
let mut buf = [0; super::DEFAULT_BUF_SIZE];
let mut written = 0;
}
/// A reader which is always at EOF.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Empty { _priv: () }
/// Creates an instance of an empty reader.
///
/// All reads from the returned reader will return `Ok(0)`.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn empty() -> Empty { Empty { _priv: () } }
+#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Empty {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> { Ok(0) }
}
+#[stable(feature = "rust1", since = "1.0.0")]
+impl BufRead for Empty {
+ fn fill_buf(&mut self) -> io::Result<&[u8]> { Ok(&[]) }
+ fn consume(&mut self, _n: usize) {}
+}
/// A reader which infinitely yields one byte.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat { byte: u8 }
/// Creates an instance of a reader that infinitely repeats one byte.
///
/// All reads from this reader will succeed by filling the specified buffer with
/// the given byte.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat(byte: u8) -> Repeat { Repeat { byte: byte } }
+#[stable(feature = "rust1", since = "1.0.0")]
impl Read for Repeat {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
for slot in buf.iter_mut() {
}
/// A writer which will move data into the void.
+#[stable(feature = "rust1", since = "1.0.0")]
pub struct Sink { _priv: () }
/// Creates an instance of a writer which will successfully consume all data.
///
/// All calls to `write` on the returned instance will return `Ok(buf.len())`
/// and the contents of the buffer will not be inspected.
+#[stable(feature = "rust1", since = "1.0.0")]
pub fn sink() -> Sink { Sink { _priv: () } }
+#[stable(feature = "rust1", since = "1.0.0")]
impl Write for Sink {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { Ok(buf.len()) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
#![feature(unsafe_no_drop_flag)]
#![feature(macro_reexport)]
#![feature(hash)]
+#![feature(int_uint)]
#![feature(unique)]
-#![cfg_attr(test, feature(test, rustc_private, env))]
+#![feature(allow_internal_unstable)]
+#![cfg_attr(test, feature(test, rustc_private))]
// Don't link to std. We are std.
#![feature(no_std)]
#[test]
fn to_socket_addr_ipaddr_u16() {
let a = IpAddr::new_v4(77, 88, 21, 11);
- let p = 12345u16;
+ let p = 12345;
let e = SocketAddr::new(a, p);
assert_eq!(Ok(vec![e]), tsa((a, p)));
}
#[test]
fn to_socket_addr_str_u16() {
let a = SocketAddr::new(IpAddr::new_v4(77, 88, 21, 11), 24352);
- assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352u16)));
+ assert_eq!(Ok(vec![a]), tsa(("77.88.21.11", 24352)));
let a = SocketAddr::new(IpAddr::new_v6(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), 53);
assert_eq!(Ok(vec![a]), tsa(("2a02:6b8:0:1::1", 53)));
let a = SocketAddr::new(IpAddr::new_v4(127, 0, 0, 1), 23924);
- assert!(tsa(("localhost", 23924u16)).unwrap().contains(&a));
+ assert!(tsa(("localhost", 23924)).unwrap().contains(&a));
}
#[test]
}
fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- let mut r = 0u32;
+ let mut r = 0;
let mut digit_count = 0;
loop {
match self.read_digit(radix) {
}
fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> {
- let mut bs = [0u8; 4];
+ let mut bs = [0; 4];
let mut i = 0;
while i < 4 {
if i != 0 && self.read_given_char('.').is_none() {
fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> {
fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr {
assert!(head.len() + tail.len() <= 8);
- let mut gs = [0u16; 8];
+ let mut gs = [0; 8];
gs.clone_from_slice(head);
gs[(8 - tail.len()) .. 8].clone_from_slice(tail);
Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
(i, false)
}
- let mut head = [0u16; 8];
+ let mut head = [0; 8];
let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
if head_size == 8 {
return None;
}
- let mut tail = [0u16; 8];
+ let mut tail = [0; 8];
let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
}
}
}
- // FIXME #11530 this fails on android because tests are run as root
- #[cfg_attr(any(windows, target_os = "android"), ignore)]
#[test]
fn bind_error() {
- match TcpListener::bind("0.0.0.0:1") {
+ match TcpListener::bind("1.1.1.1:9999") {
Ok(..) => panic!(),
- Err(e) => assert_eq!(e.kind(), ErrorKind::PermissionDenied),
+ Err(e) =>
+ // EADDRNOTAVAIL is mapped to ConnectionRefused
+ assert_eq!(e.kind(), ErrorKind::ConnectionRefused),
}
}
#[test]
fn multiple_connect_interleaved_lazy_schedule_ip4() {
- static MAX: usize = 10;
+ const MAX: usize = 10;
each_ip(&mut |addr| {
let acceptor = t!(TcpListener::bind(&addr));
#[test]
fn test_integer_decode() {
- assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8));
- assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8));
- assert_eq!(2f32.powf(100.0).integer_decode(), (8388608u64, 77i16, 1i8));
- assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8));
- assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8));
- assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8));
- assert_eq!(NEG_INFINITY.integer_decode(), (8388608u64, 105i16, -1i8));
- assert_eq!(NAN.integer_decode(), (12582912u64, 105i16, 1i8));
+ assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
+ assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
+ assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
+ assert_eq!(0f32.integer_decode(), (0, -150, 1));
+ assert_eq!((-0f32).integer_decode(), (0, -150, -1));
+ assert_eq!(INFINITY.integer_decode(), (8388608, 105, 1));
+ assert_eq!(NEG_INFINITY.integer_decode(), (8388608, 105, -1));
+ assert_eq!(NAN.integer_decode(), (12582912, 105, 1));
}
#[test]
#[test]
fn test_integer_decode() {
- assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8));
- assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8));
- assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8));
- assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8));
- assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8));
- assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8));
+ assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
+ assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
+ assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
+ assert_eq!(0f64.integer_decode(), (0, -1075, 1));
+ assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
+ assert_eq!(INFINITY.integer_decode(), (4503599627370496, 972, 1));
assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
- assert_eq!(NAN.integer_decode(), (6755399441055744u64, 972i16, 1i8));
+ assert_eq!(NAN.integer_decode(), (6755399441055744, 972, 1));
}
#[test]
pub use core::num::{from_f32, from_f64};
pub use core::num::{FromStrRadix, from_str_radix};
pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
+pub use core::num::wrapping;
use option::Option;
///
/// let num = 2.0f32;
///
- /// // (8388608u64, -22i16, 1i8)
+ /// // (8388608, -22, 1)
/// let (mantissa, exponent, sign) = num.integer_decode();
/// let sign_f = sign as f32;
/// let mantissa_f = mantissa as f32;
#[test]
fn test_uint_to_str_overflow() {
- let mut u8_val: u8 = 255_u8;
+ let mut u8_val: u8 = 255;
assert_eq!(u8_val.to_string(), "255");
- u8_val += 1 as u8;
+ u8_val = u8_val.wrapping_add(1);
assert_eq!(u8_val.to_string(), "0");
- let mut u16_val: u16 = 65_535_u16;
+ let mut u16_val: u16 = 65_535;
assert_eq!(u16_val.to_string(), "65535");
- u16_val += 1 as u16;
+ u16_val = u16_val.wrapping_add(1);
assert_eq!(u16_val.to_string(), "0");
- let mut u32_val: u32 = 4_294_967_295_u32;
+ let mut u32_val: u32 = 4_294_967_295;
assert_eq!(u32_val.to_string(), "4294967295");
- u32_val += 1 as u32;
+ u32_val = u32_val.wrapping_add(1);
assert_eq!(u32_val.to_string(), "0");
- let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
+ let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(u64_val.to_string(), "18446744073709551615");
- u64_val += 1 as u64;
+ u64_val = u64_val.wrapping_add(1);
assert_eq!(u64_val.to_string(), "0");
}
#[test]
fn test_uint_from_str_overflow() {
- let mut u8_val: u8 = 255_u8;
+ let mut u8_val: u8 = 255;
assert_eq!(from_str::<u8>("255"), Some(u8_val));
assert_eq!(from_str::<u8>("256"), None);
- u8_val += 1 as u8;
+ u8_val = u8_val.wrapping_add(1);
assert_eq!(from_str::<u8>("0"), Some(u8_val));
assert_eq!(from_str::<u8>("-1"), None);
- let mut u16_val: u16 = 65_535_u16;
+ let mut u16_val: u16 = 65_535;
assert_eq!(from_str::<u16>("65535"), Some(u16_val));
assert_eq!(from_str::<u16>("65536"), None);
- u16_val += 1 as u16;
+ u16_val = u16_val.wrapping_add(1);
assert_eq!(from_str::<u16>("0"), Some(u16_val));
assert_eq!(from_str::<u16>("-1"), None);
- let mut u32_val: u32 = 4_294_967_295_u32;
+ let mut u32_val: u32 = 4_294_967_295;
assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
assert_eq!(from_str::<u32>("4294967296"), None);
- u32_val += 1 as u32;
+ u32_val = u32_val.wrapping_add(1);
assert_eq!(from_str::<u32>("0"), Some(u32_val));
assert_eq!(from_str::<u32>("-1"), None);
- let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
+ let mut u64_val: u64 = 18_446_744_073_709_551_615;
assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
assert_eq!(from_str::<u64>("18446744073709551616"), None);
- u64_val += 1 as u64;
+ u64_val = u64_val.wrapping_add(1);
assert_eq!(from_str::<u64>("0"), Some(u64_val));
assert_eq!(from_str::<u64>("-1"), None);
}
// This is just for integral types, the largest of which is a u64. The
// smallest base that we can have is 2, so the most number of digits we're
// ever going to have is 64
- let mut buf = [0u8; 64];
+ let mut buf = [0; 64];
let mut cur = 0;
// Loop at least once to make sure at least a `0` gets emitted.
let radix_gen: T = num::cast(radix as int).unwrap();
let (num, exp) = match exp_format {
- ExpNone => (num, 0i32),
+ ExpNone => (num, 0),
ExpDec | ExpBin => {
if num == _0 {
- (num, 0i32)
+ (num, 0)
} else {
let (exp, exp_base) = match exp_format {
ExpDec => (num.abs().log10().floor(), num::cast::<f64, T>(10.0f64).unwrap()),
deccum = deccum / radix_gen;
deccum = deccum.trunc();
- buf.push(char::from_digit(current_digit.to_int().unwrap() as u32, radix)
+ buf.push(char::from_digit(current_digit.to_isize().unwrap() as u32, radix)
.unwrap() as u8);
// No more digits to calculate for the non-fractional part -> break
let current_digit = deccum.trunc().abs();
buf.push(char::from_digit(
- current_digit.to_int().unwrap() as u32, radix).unwrap() as u8);
+ current_digit.to_isize().unwrap() as u32, radix).unwrap() as u8);
// Decrease the deccumulator one fractional digit at a time
deccum = deccum.fract();
// Some constants for from_str_bytes_common's input validation,
// they define minimum radix values for which the character is a valid digit.
-static DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
-static DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
+const DIGIT_P_RADIX: u32 = ('p' as u32) - ('a' as u32) + 11;
+const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
#[cfg(test)]
mod tests {
+ use core::num::wrapping::WrappingOps;
use string::ToString;
#[test]
fn test_int_to_str_overflow() {
- let mut i8_val: i8 = 127_i8;
+ let mut i8_val: i8 = 127;
assert_eq!(i8_val.to_string(), "127");
- i8_val += 1 as i8;
+ i8_val = i8_val.wrapping_add(1);
assert_eq!(i8_val.to_string(), "-128");
- let mut i16_val: i16 = 32_767_i16;
+ let mut i16_val: i16 = 32_767;
assert_eq!(i16_val.to_string(), "32767");
- i16_val += 1 as i16;
+ i16_val = i16_val.wrapping_add(1);
assert_eq!(i16_val.to_string(), "-32768");
- let mut i32_val: i32 = 2_147_483_647_i32;
+ let mut i32_val: i32 = 2_147_483_647;
assert_eq!(i32_val.to_string(), "2147483647");
- i32_val += 1 as i32;
+ i32_val = i32_val.wrapping_add(1);
assert_eq!(i32_val.to_string(), "-2147483648");
- let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
+ let mut i64_val: i64 = 9_223_372_036_854_775_807;
assert_eq!(i64_val.to_string(), "9223372036854775807");
- i64_val += 1 as i64;
+ i64_val = i64_val.wrapping_add(1);
assert_eq!(i64_val.to_string(), "-9223372036854775808");
}
}
#[test]
fn read_char_buffered() {
- let buf = [195u8, 159u8];
+ let buf = [195, 159];
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
assert_eq!(reader.read_char(), Ok('ß'));
}
#[test]
fn test_chars() {
- let buf = [195u8, 159u8, b'a'];
+ let buf = [195, 159, b'a'];
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
let mut it = reader.chars();
assert_eq!(it.next(), Some(Ok('ß')));
/// # drop(tx);
/// let mut reader = ChanReader::new(rx);
///
-/// let mut buf = [0u8; 100];
+/// let mut buf = [0; 100];
/// match reader.read(&mut buf) {
/// Ok(nread) => println!("Read {} bytes", nread),
/// Err(e) => println!("read error: {}", e),
fn test_rx_reader() {
let (tx, rx) = channel();
thread::spawn(move|| {
- tx.send(vec![1u8, 2u8]).unwrap();
+ tx.send(vec![1, 2]).unwrap();
tx.send(vec![]).unwrap();
- tx.send(vec![3u8, 4u8]).unwrap();
- tx.send(vec![5u8, 6u8]).unwrap();
- tx.send(vec![7u8, 8u8]).unwrap();
+ tx.send(vec![3, 4]).unwrap();
+ tx.send(vec![5, 6]).unwrap();
+ tx.send(vec![7, 8]).unwrap();
});
let mut reader = ChanReader::new(rx);
- let mut buf = [0u8; 3];
+ let mut buf = [0; 3];
assert_eq!(Ok(0), reader.read(&mut []));
let mut writer = ChanWriter::new(tx);
writer.write_be_u32(42).unwrap();
- let wanted = vec![0u8, 0u8, 0u8, 42u8];
+ let wanted = vec![0, 0, 0, 42];
let got = thread::scoped(move|| { rx.recv().unwrap() }).join();
assert_eq!(wanted, got);
let mut i = size;
let mut n = n;
while i > 0 {
- bytes.push((n & 255_u64) as u8);
+ bytes.push((n & 255) as u8);
n >>= 8;
i -= 1;
}
panic!("index out of bounds");
}
- let mut buf = [0u8; 8];
+ let mut buf = [0; 8];
unsafe {
let ptr = data.as_ptr().offset(start as int);
let out = buf.as_mut_ptr();
({
use super::u64_from_be_bytes;
- let data = (0u8..$stride*100+$start_index).collect::<Vec<_>>();
- let mut sum = 0u64;
+ let data = (0..$stride*100+$start_index).collect::<Vec<_>>();
+ let mut sum = 0;
$b.iter(|| {
let mut i = $start_index;
while i < data.len() {
/// attempted against it for which its underlying file descriptor was not
/// configured at creation time, via the `FileAccess` parameter to
/// `File::open_mode()`.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::File")]
+#[unstable(feature = "old_io")]
pub struct File {
fd: fs_imp::FileDesc,
path: Path,
}
}
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+#[unstable(feature = "old_io")]
impl File {
/// Open a file at `path` in the mode specified by the `mode` and `access`
/// arguments
/// * Attempting to open a file with a `FileAccess` that the user lacks
/// permissions for
/// * Filesystem-level errors (full disk, etc)
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs::OpenOptions")]
+ #[unstable(feature = "old_io")]
pub fn open_mode(path: &Path,
mode: FileMode,
access: FileAccess) -> IoResult<File> {
///
/// let contents = File::open(&Path::new("foo.txt")).read_to_end();
/// ```
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::open")]
+ #[unstable(feature = "old_io")]
pub fn open(path: &Path) -> IoResult<File> {
File::open_mode(path, Open, Read)
}
/// # drop(f);
/// # ::std::old_io::fs::unlink(&Path::new("foo.txt"));
/// ```
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs::File::create")]
+ #[unstable(feature = "old_io")]
pub fn create(path: &Path) -> IoResult<File> {
File::open_mode(path, Truncate, Write)
.update_desc("couldn't create file")
}
/// Returns the original path that was used to open this file.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn path<'a>(&'a self) -> &'a Path {
&self.path
}
/// Synchronizes all modifications to this file to its permanent storage
/// device. This will flush any internal buffers necessary to perform this
/// operation.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn fsync(&mut self) -> IoResult<()> {
self.fd.fsync()
.update_err("couldn't fsync file",
/// file metadata to the filesystem. This is intended for use cases that
/// must synchronize content, but don't need the metadata on disk. The goal
/// of this method is to reduce disk operations.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn datasync(&mut self) -> IoResult<()> {
self.fd.datasync()
.update_err("couldn't datasync file",
/// be shrunk. If it is greater than the current file's size, then the file
/// will be extended to `size` and have all of the intermediate data filled
/// in with 0s.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn truncate(&mut self, size: i64) -> IoResult<()> {
self.fd.truncate(size)
.update_err("couldn't truncate file", |e|
/// until you have attempted to read past the end of the file, so if
/// you've read _exactly_ the number of bytes in the file, this will
/// return `false`, not `true`.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn eof(&self) -> bool {
self.last_nread == 0
}
/// Queries information about the underlying file.
+ #[deprecated(since = "1.0.0", reason = "replaced with std::fs")]
+ #[unstable(feature = "old_io")]
pub fn stat(&self) -> IoResult<FileStat> {
self.fd.fstat()
.update_err("couldn't fstat file", |e|
/// This function will return an error if `path` points to a directory, if the
/// user lacks permissions to remove the file, or if some other filesystem-level
/// error occurs.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_file")]
+#[unstable(feature = "old_io")]
pub fn unlink(path: &Path) -> IoResult<()> {
fs_imp::unlink(path)
.update_err("couldn't unlink path", |e|
/// This function will return an error if the user lacks the requisite permissions
/// to perform a `stat` call on the given `path` or if there is no entry in the
/// filesystem at the provided path.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::metadata")]
+#[unstable(feature = "old_io")]
pub fn stat(path: &Path) -> IoResult<FileStat> {
fs_imp::stat(path)
.update_err("couldn't stat path", |e|
/// # Error
///
/// See `stat`
+#[unstable(feature = "old_fs")]
pub fn lstat(path: &Path) -> IoResult<FileStat> {
fs_imp::lstat(path)
.update_err("couldn't lstat path", |e|
/// This function will return an error if the provided `from` doesn't exist, if
/// the process lacks permissions to view the contents, or if some other
/// intermittent I/O error occurs.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::rename")]
+#[unstable(feature = "old_io")]
pub fn rename(from: &Path, to: &Path) -> IoResult<()> {
fs_imp::rename(from, to)
.update_err("couldn't rename path", |e|
/// Note that this copy is not atomic in that once the destination is
/// ensured to not exist, there is nothing preventing the destination from
/// being created and then destroyed by this operation.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::copy")]
+#[unstable(feature = "old_io")]
pub fn copy(from: &Path, to: &Path) -> IoResult<()> {
fn update_err<T>(result: IoResult<T>, from: &Path, to: &Path) -> IoResult<T> {
result.update_err("couldn't copy path", |e| {
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to change the attributes of the file, or if
/// some other I/O error is encountered.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_permissions")]
+#[unstable(feature = "old_io")]
pub fn chmod(path: &Path, mode: old_io::FilePermission) -> IoResult<()> {
fs_imp::chmod(path, mode.bits() as uint)
.update_err("couldn't chmod path", |e|
}
/// Change the user and group owners of a file at the specified path.
+#[unstable(feature = "old_fs")]
pub fn chown(path: &Path, uid: int, gid: int) -> IoResult<()> {
fs_imp::chown(path, uid, gid)
.update_err("couldn't chown path", |e|
/// Creates a new hard link on the filesystem. The `dst` path will be a
/// link pointing to the `src` path. Note that systems often require these
/// two paths to both be located on the same filesystem.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::hard_link")]
+#[unstable(feature = "old_io")]
pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
fs_imp::link(src, dst)
.update_err("couldn't link path", |e|
/// Creates a new symbolic link on the filesystem. The `dst` path will be a
/// symlink pointing to the `src` path.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::soft_link")]
+#[unstable(feature = "old_io")]
pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
fs_imp::symlink(src, dst)
.update_err("couldn't symlink path", |e|
///
/// This function will return an error on failure. Failure conditions include
/// reading a file that does not exist or reading a file that is not a symlink.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_link")]
+#[unstable(feature = "old_io")]
pub fn readlink(path: &Path) -> IoResult<Path> {
fs_imp::readlink(path)
.update_err("couldn't resolve symlink for path", |e|
///
/// This function will return an error if the user lacks permissions to make a
/// new directory at the provided `path`, or if the directory already exists.
+#[unstable(feature = "old_fs")]
pub fn mkdir(path: &Path, mode: FilePermission) -> IoResult<()> {
fs_imp::mkdir(path, mode.bits() as uint)
.update_err("couldn't create directory", |e|
///
/// This function will return an error if the user lacks permissions to remove
/// the directory at the provided `path`, or if the directory isn't empty.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir")]
+#[unstable(feature = "old_io")]
pub fn rmdir(path: &Path) -> IoResult<()> {
fs_imp::rmdir(path)
.update_err("couldn't remove directory", |e|
/// This function will return an error if the provided `path` doesn't exist, if
/// the process lacks permissions to view the contents or if the `path` points
/// at a non-directory file
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::read_dir")]
+#[unstable(feature = "old_io")]
pub fn readdir(path: &Path) -> IoResult<Vec<Path>> {
fs_imp::readdir(path)
.update_err("couldn't read directory",
/// rooted at `path`. The path given will not be iterated over, and this will
/// perform iteration in some top-down order. The contents of unreadable
/// subdirectories are ignored.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::walk_dir")]
+#[unstable(feature = "old_io")]
pub fn walk_dir(path: &Path) -> IoResult<Directories> {
Ok(Directories {
stack: try!(readdir(path).update_err("couldn't walk directory",
/// An iterator that walks over a directory
#[derive(Clone)]
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::ReadDir")]
+#[unstable(feature = "old_io")]
pub struct Directories {
stack: Vec<Path>,
}
/// # Error
///
/// See `fs::mkdir`.
+#[unstable(feature = "old_fs")]
pub fn mkdir_recursive(path: &Path, mode: FilePermission) -> IoResult<()> {
// tjc: if directory exists but with different permissions,
// should we return false?
/// # Error
///
/// See `file::unlink` and `fs::readdir`
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::remove_dir_all")]
+#[unstable(feature = "old_io")]
pub fn rmdir_recursive(path: &Path) -> IoResult<()> {
let mut rm_stack = Vec::new();
rm_stack.push(path.clone());
/// `atime` and its modification time set to `mtime`. The times specified should
/// be in milliseconds.
// FIXME(#10301) these arguments should not be u64
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::set_file_times")]
+#[unstable(feature = "old_io")]
pub fn change_file_times(path: &Path, atime: u64, mtime: u64) -> IoResult<()> {
fs_imp::utime(path, atime, mtime)
.update_err("couldn't change_file_times", |e|
}
/// Utility methods for paths.
+#[deprecated(since = "1.0.0", reason = "replaced with std::fs::PathExt")]
+#[unstable(feature = "old_io")]
pub trait PathExtensions {
/// Get information on the file, directory, etc at this path.
///
check!(w.write(msg));
}
let files = check!(readdir(dir));
- let mut mem = [0u8; 4];
+ let mut mem = [0; 4];
for f in &files {
{
let n = f.filestem_str();
check!(File::create(&dir2.join("14")));
let mut files = check!(walk_dir(dir));
- let mut cur = [0u8; 2];
+ let mut cur = [0; 2];
for f in files {
let stem = f.filestem_str().unwrap();
let root = stem.as_bytes()[0] - b'0';
fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
assert!(nbytes > 0 && nbytes <= 8);
- let mut val = 0u64;
+ let mut val = 0;
let mut pos = 0;
let mut i = nbytes;
while i > 0 {
fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult<u64> {
assert!(nbytes > 0 && nbytes <= 8);
- let mut val = 0u64;
+ let mut val = 0;
let mut i = nbytes;
while i > 0 {
i -= 1;
///
/// The number of bytes returned is system-dependent.
fn read_le_uint(&mut self) -> IoResult<uint> {
- self.read_le_uint_n(usize::BYTES).map(|i| i as uint)
+ self.read_le_uint_n(usize::BYTES as usize).map(|i| i as uint)
}
/// Reads a little-endian integer.
///
/// The number of bytes returned is system-dependent.
fn read_le_int(&mut self) -> IoResult<int> {
- self.read_le_int_n(isize::BYTES).map(|i| i as int)
+ self.read_le_int_n(isize::BYTES as usize).map(|i| i as int)
}
/// Reads a big-endian unsigned integer.
///
/// The number of bytes returned is system-dependent.
fn read_be_uint(&mut self) -> IoResult<uint> {
- self.read_be_uint_n(usize::BYTES).map(|i| i as uint)
+ self.read_be_uint_n(usize::BYTES as usize).map(|i| i as uint)
}
/// Reads a big-endian integer.
///
/// The number of bytes returned is system-dependent.
fn read_be_int(&mut self) -> IoResult<int> {
- self.read_be_int_n(isize::BYTES).map(|i| i as int)
+ self.read_be_int_n(isize::BYTES as usize).map(|i| i as int)
}
/// Reads a big-endian `u64`.
/// Write a single char, encoded as UTF-8.
#[inline]
fn write_char(&mut self, c: char) -> IoResult<()> {
- let mut buf = [0u8; 4];
+ let mut buf = [0; 4];
let n = c.encode_utf8(&mut buf).unwrap_or(0);
self.write_all(&buf[..n])
}
/// Write a little-endian uint (number of bytes depends on system).
#[inline]
fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
- extensions::u64_to_le_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_le_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
}
/// Write a little-endian int (number of bytes depends on system).
#[inline]
fn write_le_int(&mut self, n: int) -> IoResult<()> {
- extensions::u64_to_le_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_le_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian uint (number of bytes depends on system).
#[inline]
fn write_be_uint(&mut self, n: uint) -> IoResult<()> {
- extensions::u64_to_be_bytes(n as u64, usize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_be_bytes(n as u64, usize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian int (number of bytes depends on system).
#[inline]
fn write_be_int(&mut self, n: int) -> IoResult<()> {
- extensions::u64_to_be_bytes(n as u64, isize::BYTES, |v| self.write_all(v))
+ extensions::u64_to_be_bytes(n as u64, isize::BYTES as usize, |v| self.write_all(v))
}
/// Write a big-endian u64 (8 bytes).
fn test_read_at_least() {
let mut r = BadReader::new(MemReader::new(b"hello, world!".to_vec()),
vec![GoodBehavior(usize::MAX)]);
- let buf = &mut [0u8; 5];
+ let buf = &mut [0; 5];
assert!(r.read_at_least(1, buf).unwrap() >= 1);
assert!(r.read_exact(5).unwrap().len() == 5); // read_exact uses read_at_least
assert!(r.read_at_least(0, buf).is_ok());
}
fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
- let mut r = 0u32;
+ let mut r = 0;
let mut digit_count = 0;
loop {
match self.read_digit(radix) {
}
fn read_ipv4_addr_impl(&mut self) -> Option<IpAddr> {
- let mut bs = [0u8; 4];
+ let mut bs = [0; 4];
let mut i = 0;
while i < 4 {
if i != 0 && self.read_given_char('.').is_none() {
fn read_ipv6_addr_impl(&mut self) -> Option<IpAddr> {
fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> IpAddr {
assert!(head.len() + tail.len() <= 8);
- let mut gs = [0u16; 8];
+ let mut gs = [0; 8];
gs.clone_from_slice(head);
gs[(8 - tail.len()) .. 8].clone_from_slice(tail);
Ipv6Addr(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
(i, false)
}
- let mut head = [0u16; 8];
+ let mut head = [0; 8];
let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
if head_size == 8 {
return None;
}
- let mut tail = [0u16; 8];
+ let mut tail = [0; 8];
let (tail_size, _) = read_groups(self, &mut tail, 8 - head_size);
Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
}
}
fn read_ip_addr(&mut self) -> Option<IpAddr> {
- let ipv4_addr = |p: &mut Parser| p.read_ipv4_addr();
- let ipv6_addr = |p: &mut Parser| p.read_ipv6_addr();
- self.read_or(&mut [box ipv4_addr, box ipv6_addr])
+ let ipv4_addr: Box<_> = box |p: &mut Parser| p.read_ipv4_addr();
+ let ipv6_addr: Box<_> = box |p: &mut Parser| p.read_ipv6_addr();
+ self.read_or(&mut [ipv4_addr, ipv6_addr])
}
fn read_socket_addr(&mut self) -> Option<SocketAddr> {
let ip_addr = |p: &mut Parser| {
- let ipv4_p = |p: &mut Parser| p.read_ip_addr();
- let ipv6_p = |p: &mut Parser| {
+ let ipv4_p: Box<_> = box |p: &mut Parser| p.read_ip_addr();
+ let ipv6_p: Box<_> = box |p: &mut Parser| {
let open_br = |p: &mut Parser| p.read_given_char('[');
let ip_addr = |p: &mut Parser| p.read_ipv6_addr();
let clos_br = |p: &mut Parser| p.read_given_char(']');
p.read_seq_3::<char, IpAddr, char, _, _, _>(open_br, ip_addr, clos_br)
.map(|t| match t { (_, ip, _) => ip })
};
- p.read_or(&mut [box ipv4_p, box ipv6_p])
+ p.read_or(&mut [ipv4_p, ipv6_p])
};
let colon = |p: &mut Parser| p.read_given_char(':');
let port = |p: &mut Parser| p.read_number(10, 5, 0x10000).map(|n| n as u16);
/// // The following lines are equivalent modulo possible "localhost" name resolution
/// // differences
/// let tcp_s = TcpStream::connect(SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 12345 });
-/// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345u16));
-/// let tcp_s = TcpStream::connect(("127.0.0.1", 12345u16));
-/// let tcp_s = TcpStream::connect(("localhost", 12345u16));
+/// let tcp_s = TcpStream::connect((Ipv4Addr(127, 0, 0, 1), 12345));
+/// let tcp_s = TcpStream::connect(("127.0.0.1", 12345));
+/// let tcp_s = TcpStream::connect(("localhost", 12345));
/// let tcp_s = TcpStream::connect("127.0.0.1:12345");
/// let tcp_s = TcpStream::connect("localhost:12345");
///
/// // TcpListener::bind(), UdpSocket::bind() and UdpSocket::send_to() behave similarly
/// let tcp_l = TcpListener::bind("localhost:12345");
///
-/// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451u16)).unwrap();
-/// udp_s.send_to([7u8, 7u8, 7u8].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451u16));
+/// let mut udp_s = UdpSocket::bind(("127.0.0.1", 23451)).unwrap();
+/// udp_s.send_to([7, 7, 7].as_slice(), (Ipv4Addr(127, 0, 0, 1), 23451));
/// }
/// ```
pub trait ToSocketAddr {
#[test]
fn to_socket_addr_ipaddr_u16() {
let a = Ipv4Addr(77, 88, 21, 11);
- let p = 12345u16;
+ let p = 12345;
let e = SocketAddr { ip: a, port: p };
assert_eq!(Ok(e), (a, p).to_socket_addr());
assert_eq!(Ok(vec![e]), (a, p).to_socket_addr_all());
#[test]
fn to_socket_addr_str_u16() {
let a = SocketAddr { ip: Ipv4Addr(77, 88, 21, 11), port: 24352 };
- assert_eq!(Ok(a), ("77.88.21.11", 24352u16).to_socket_addr());
- assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352u16).to_socket_addr_all());
+ assert_eq!(Ok(a), ("77.88.21.11", 24352).to_socket_addr());
+ assert_eq!(Ok(vec![a]), ("77.88.21.11", 24352).to_socket_addr_all());
let a = SocketAddr { ip: Ipv6Addr(0x2a02, 0x6b8, 0, 1, 0, 0, 0, 1), port: 53 };
assert_eq!(Ok(a), ("2a02:6b8:0:1::1", 53).to_socket_addr());
assert_eq!(Ok(vec![a]), ("2a02:6b8:0:1::1", 53).to_socket_addr_all());
let a = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 23924 };
- assert!(("localhost", 23924u16).to_socket_addr_all().unwrap().contains(&a));
+ assert!(("localhost", 23924).to_socket_addr_all().unwrap().contains(&a));
}
#[test]
tx.send(TcpStream::connect(addr).unwrap()).unwrap();
});
let _l = rx.recv().unwrap();
- for i in 0i32..1001 {
+ for i in 0..1001 {
match a.accept() {
Ok(..) => break,
Err(ref e) if e.kind == TimedOut => {}
assert_eq!(s.read(&mut [0]).err().unwrap().kind, TimedOut);
s.set_timeout(Some(20));
- for i in 0i32..1001 {
+ for i in 0..1001 {
match s.write(&[0; 128 * 1024]) {
Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
Err(IoError { kind: TimedOut, .. }) => break,
let mut s = a.accept().unwrap();
s.set_write_timeout(Some(20));
- for i in 0i32..1001 {
+ for i in 0..1001 {
match s.write(&[0; 128 * 1024]) {
Ok(()) | Err(IoError { kind: ShortWrite(..), .. }) => {},
Err(IoError { kind: TimedOut, .. }) => break,
//! Bindings for executing child processes
#![allow(non_upper_case_globals)]
+#![unstable(feature = "old_io")]
+#![deprecated(since = "1.0.0",
+ reason = "replaced with the std::process module")]
pub use self::StdioContainer::*;
pub use self::ProcessExit::*;
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
let _t = thread::spawn(move|| {
- set_stdout(box w);
+ set_stdout(Box::new(w));
println!("hello!");
});
assert_eq!(r.read_to_string().unwrap(), "hello!\n");
let (tx, rx) = channel();
let (mut r, w) = (ChanReader::new(rx), ChanWriter::new(tx));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
let _t = thread::spawn(move || -> () {
- set_stderr(box w);
+ set_stderr(Box::new(w));
panic!("my special message");
});
let s = r.read_to_string().unwrap();
*/
fn base_port() -> u16 {
- let base = 9600u16;
- let range = 1000u16;
+ let base = 9600;
+ let range = 1000;
let bases = [
("32-opt", base + range * 1),
// FIXME: These functions take Durations but only pass ms to the backend impls.
+use boxed::Box;
use sync::mpsc::{Receiver, Sender, channel};
use time::Duration;
use old_io::IoResult;
let (tx, rx) = channel();
// Short-circuit the timer backend for 0 duration
if in_ms_u64(duration) != 0 {
- self.inner.oneshot(in_ms_u64(duration), box TimerCallback { tx: tx });
+ self.inner.oneshot(in_ms_u64(duration), Box::new(TimerCallback { tx: tx }));
} else {
tx.send(()).unwrap();
}
// not clear what use a 0ms period is anyway...
let ms = if ms == 0 { 1 } else { ms };
let (tx, rx) = channel();
- self.inner.period(ms, box TimerCallback { tx: tx });
+ self.inner.period(ms, Box::new(TimerCallback { tx: tx }));
return rx
}
}
//! Utility implementations of Reader and Writer
+#![allow(deprecated)]
+
use prelude::v1::*;
use cmp;
use old_io;
/// Wraps a `Reader`, limiting the number of bytes that can be read from it.
#[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
+#[unstable(feature = "old_io")]
pub struct LimitReader<R> {
limit: uint,
inner: R
}
+#[deprecated(since = "1.0.0", reason = "use std::io::Take")]
+#[unstable(feature = "old_io")]
impl<R: Reader> LimitReader<R> {
/// Creates a new `LimitReader`
+ #[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+ #[unstable(feature = "old_io")]
pub fn new(r: R, limit: uint) -> LimitReader<R> {
LimitReader { limit: limit, inner: r }
}
pub fn limit(&self) -> uint { self.limit }
}
+#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+#[unstable(feature = "old_io")]
impl<R: Reader> Reader for LimitReader<R> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
if self.limit == 0 {
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io's take method instead")]
+#[unstable(feature = "old_io")]
impl<R: Buffer> Buffer for LimitReader<R> {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
let amt = try!(self.inner.fill_buf());
/// A `Writer` which ignores bytes written to it, like /dev/null.
#[derive(Copy, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
+#[unstable(feature = "old_io")]
pub struct NullWriter;
+#[deprecated(since = "1.0.0", reason = "use std::io::sink() instead")]
+#[unstable(feature = "old_io")]
impl Writer for NullWriter {
#[inline]
fn write_all(&mut self, _buf: &[u8]) -> old_io::IoResult<()> { Ok(()) }
/// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
#[derive(Copy, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
pub struct ZeroReader;
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
impl Reader for ZeroReader {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io::repeat(0) instead")]
+#[unstable(feature = "old_io")]
impl Buffer for ZeroReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
static DATA: [u8; 64] = [0; 64];
/// A `Reader` which is always at EOF, like /dev/null.
#[derive(Copy, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
pub struct NullReader;
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
impl Reader for NullReader {
#[inline]
fn read(&mut self, _buf: &mut [u8]) -> old_io::IoResult<uint> {
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io::empty() instead")]
+#[unstable(feature = "old_io")]
impl Buffer for NullReader {
fn fill_buf<'a>(&'a mut self) -> old_io::IoResult<&'a [u8]> {
Err(old_io::standard_error(old_io::EndOfFile))
/// The `Writer`s are delegated to in order. If any `Writer` returns an error,
/// that error is returned immediately and remaining `Writer`s are not called.
#[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
+#[unstable(feature = "old_io")]
pub struct MultiWriter<W> {
writers: Vec<W>
}
impl<W> MultiWriter<W> where W: Writer {
/// Creates a new `MultiWriter`
+ #[deprecated(since = "1.0.0", reason = "use std::io's broadcast method instead")]
+ #[unstable(feature = "old_io")]
pub fn new(writers: Vec<W>) -> MultiWriter<W> {
MultiWriter { writers: writers }
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io::Broadcast instead")]
+#[unstable(feature = "old_io")]
impl<W> Writer for MultiWriter<W> where W: Writer {
#[inline]
fn write_all(&mut self, buf: &[u8]) -> old_io::IoResult<()> {
/// A `Reader` which chains input from multiple `Reader`s, reading each to
/// completion before moving onto the next.
#[derive(Clone, Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
+#[unstable(feature = "old_io")]
pub struct ChainedReader<I, R> {
readers: I,
cur_reader: Option<R>,
impl<R: Reader, I: Iterator<Item=R>> ChainedReader<I, R> {
/// Creates a new `ChainedReader`
+ #[deprecated(since = "1.0.0", reason = "use std::io's chain method instead")]
+ #[unstable(feature = "old_io")]
pub fn new(mut readers: I) -> ChainedReader<I, R> {
let r = readers.next();
ChainedReader { readers: readers, cur_reader: r }
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io::Chain instead")]
+#[unstable(feature = "old_io")]
impl<R: Reader, I: Iterator<Item=R>> Reader for ChainedReader<I, R> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
loop {
/// A `Reader` which forwards input from another `Reader`, passing it along to
/// a `Writer` as well. Similar to the `tee(1)` command.
#[derive(Debug)]
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
pub struct TeeReader<R, W> {
reader: R,
writer: W,
}
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
impl<R: Reader, W: Writer> TeeReader<R, W> {
/// Creates a new `TeeReader`
+ #[deprecated(since = "1.0.0", reason = "use std::io's tee method instead")]
+ #[unstable(feature = "old_io")]
pub fn new(r: R, w: W) -> TeeReader<R, W> {
TeeReader { reader: r, writer: w }
}
}
}
+#[deprecated(since = "1.0.0", reason = "use std::io::Tee instead")]
+#[unstable(feature = "old_io")]
impl<R: Reader, W: Writer> Reader for TeeReader<R, W> {
fn read(&mut self, buf: &mut [u8]) -> old_io::IoResult<uint> {
self.reader.read(buf).and_then(|len| {
}
/// Copies all data from a `Reader` to a `Writer`.
+#[deprecated(since = "1.0.0", reason = "use std::io's copy function instead")]
+#[unstable(feature = "old_io")]
pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> old_io::IoResult<()> {
let mut buf = [0; super::DEFAULT_BUF_SIZE];
loop {
#[test]
fn test_iter_reader() {
- let mut r = IterReader::new(0u8..8);
+ let mut r = IterReader::new(0..8);
let mut buf = [0, 0, 0];
let len = r.read(&mut buf).unwrap();
assert_eq!(len, 3);
#[test]
fn iter_reader_zero_length() {
- let mut r = IterReader::new(0u8..8);
+ let mut r = IterReader::new(0..8);
let mut buf = [];
assert_eq!(Ok(0), r.read(&mut buf));
}
iter_after(self.components(), base.as_path().components()).is_some()
}
- /// Determines whether `base` is a suffix of `self`.
+ /// Determines whether `child` is a suffix of `self`.
pub fn ends_with<P: ?Sized>(&self, child: &P) -> bool where P: AsPath {
iter_after(self.components().rev(), child.as_path().components().rev()).is_some()
}
#[doc(no_inline)] pub use old_io::{Buffer, Writer, Reader, Seek, BufferPrelude};
// NB: remove when range syntax lands
#[doc(no_inline)] pub use iter::range;
+
+#[doc(no_inline)] pub use num::wrapping::{Wrapping, WrappingOps};
#[cfg(not(target_os="android"))]
#[test]
fn test_inherit_env() {
- use os;
+ use std::env;
if running_on_valgrind() { return; }
let result = env_cmd().output().unwrap();
let output = String::from_utf8(result.stdout).unwrap();
- let r = os::env();
- for &(ref k, ref v) in &r {
+ for (ref k, ref v) in env::vars() {
// don't check windows magical empty-named variables
assert!(k.is_empty() ||
output.contains(format!("{}={}", *k, *v).as_slice()),
}
}
}
-static THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
+const THREAD_RNG_RESEED_THRESHOLD: usize = 32_768;
type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
/// The thread-local RNG.
/// ```
/// use std::rand;
///
-/// let x = rand::random();
-/// println!("{}", 2u8 * x);
+/// let x: u8 = rand::random();
+/// println!("{}", 2 * x as u16);
///
/// let y = rand::random::<f64>();
/// println!("{}", y);
let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
80, 81, 82, 83, 84, 85, 86, 87];
for &n in &lengths {
- let mut v = repeat(0u8).take(n).collect::<Vec<_>>();
+ let mut v = repeat(0).take(n).collect::<Vec<_>>();
r.fill_bytes(&mut v);
// use this to get nicer error messages.
}
}
-#[cfg(test)]
-static RAND_BENCH_N: u64 = 100;
-
#[cfg(test)]
mod bench {
extern crate test;
use prelude::v1::*;
use self::test::Bencher;
- use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
+ use super::{XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng};
use super::{OsRng, weak_rng};
use mem::size_of;
+ const RAND_BENCH_N: u64 = 100;
+
#[bench]
fn rand_xorshift(b: &mut Bencher) {
let mut rng: XorShiftRng = OsRng::new().unwrap().gen();
}
fn getrandom_next_u32() -> u32 {
- let mut buf: [u8; 4] = [0u8; 4];
+ let mut buf: [u8; 4] = [0; 4];
getrandom_fill_bytes(&mut buf);
unsafe { mem::transmute::<[u8; 4], u32>(buf) }
}
fn getrandom_next_u64() -> u64 {
- let mut buf: [u8; 8] = [0u8; 8];
+ let mut buf: [u8; 8] = [0; 8];
getrandom_fill_bytes(&mut buf);
unsafe { mem::transmute::<[u8; 8], u64>(buf) }
}
impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
- let mut v = [0u8; 4];
+ let mut v = [0; 4];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn next_u64(&mut self) -> u64 {
- let mut v = [0u8; 8];
+ let mut v = [0; 8];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
hcryptprov: HCRYPTPROV
}
- static PROV_RSA_FULL: DWORD = 1;
- static CRYPT_SILENT: DWORD = 64;
- static CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
+ const PROV_RSA_FULL: DWORD = 1;
+ const CRYPT_SILENT: DWORD = 64;
+ const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
#[allow(non_snake_case)]
extern "system" {
impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
- let mut v = [0u8; 4];
+ let mut v = [0; 4];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn next_u64(&mut self) -> u64 {
- let mut v = [0u8; 8];
+ let mut v = [0; 8];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
r.next_u32();
r.next_u64();
- let mut v = [0u8; 1000];
+ let mut v = [0; 1000];
r.fill_bytes(&mut v);
}
// as possible (XXX: is this a good test?)
let mut r = OsRng::new().unwrap();
thread::yield_now();
- let mut v = [0u8; 1000];
+ let mut v = [0; 1000];
for _ in 0..100 {
r.next_u32();
#[test]
fn test_reader_rng_u64() {
// transmute from the target to avoid endianness concerns.
- let v = vec![0u8, 0, 0, 0, 0, 0, 0, 1,
+ let v = vec![0, 0, 0, 0, 0, 0, 0, 1,
0 , 0, 0, 0, 0, 0, 0, 2,
0, 0, 0, 0, 0, 0, 0, 3];
let mut rng = ReaderRng::new(MemReader::new(v));
- assert_eq!(rng.next_u64(), 1_u64.to_be());
- assert_eq!(rng.next_u64(), 2_u64.to_be());
- assert_eq!(rng.next_u64(), 3_u64.to_be());
+ assert_eq!(rng.next_u64(), 1.to_be());
+ assert_eq!(rng.next_u64(), 2.to_be());
+ assert_eq!(rng.next_u64(), 3.to_be());
}
#[test]
fn test_reader_rng_u32() {
- let v = vec![0u8, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
+ let v = vec![0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3];
let mut rng = ReaderRng::new(MemReader::new(v));
- assert_eq!(rng.next_u32(), 1_u32.to_be());
- assert_eq!(rng.next_u32(), 2_u32.to_be());
- assert_eq!(rng.next_u32(), 3_u32.to_be());
+ assert_eq!(rng.next_u32(), 1.to_be());
+ assert_eq!(rng.next_u32(), 2.to_be());
+ assert_eq!(rng.next_u32(), 3.to_be());
}
#[test]
fn test_reader_rng_fill_bytes() {
- let v = [1u8, 2, 3, 4, 5, 6, 7, 8];
- let mut w = [0u8; 8];
+ let v = [1, 2, 3, 4, 5, 6, 7, 8];
+ let mut w = [0; 8];
let mut rng = ReaderRng::new(MemReader::new(v.to_vec()));
rng.fill_bytes(&mut w);
#[should_fail]
fn test_reader_rng_insufficient_bytes() {
let mut rng = ReaderRng::new(MemReader::new(vec!()));
- let mut v = [0u8; 3];
+ let mut v = [0; 3];
rng.fill_bytes(&mut v);
}
}
use ops::FnOnce;
use sys;
use thunk::Thunk;
+use usize;
// Reexport some of our utilities which are expected by other crates.
pub use self::util::{default_sched_threads, min_stack, running_on_valgrind};
// FIXME #11359 we just assume that this thread has a stack of a
// certain size, and estimate that there's at most 20KB of stack
// frames above our current position.
- let my_stack_bottom = my_stack_top + 20000 - OS_DEFAULT_STACK_ESTIMATE;
+ const TWENTY_KB: uint = 20000;
+
+ // saturating-add to sidestep overflow
+ let top_plus_spill = if usize::MAX - TWENTY_KB < my_stack_top {
+ usize::MAX
+ } else {
+ my_stack_top + TWENTY_KB
+ };
+ // saturating-sub to sidestep underflow
+ let my_stack_bottom = if top_plus_spill < OS_DEFAULT_STACK_ESTIMATE {
+ 0
+ } else {
+ top_plus_spill - OS_DEFAULT_STACK_ESTIMATE
+ };
let failed = unsafe {
// First, make sure we don't trigger any __morestack overflow checks,
rtdebug!("begin_unwind()");
unsafe {
- let exception = box Exception {
+ let exception: Box<_> = box Exception {
uwe: uw::_Unwind_Exception {
exception_class: rust_exception_class(),
exception_cleanup: exception_cleanup,
let mut s = String::new();
let _ = write!(&mut s, "{}", msg);
- begin_unwind_inner(box s, file_line)
+ begin_unwind_inner(Box::new(s), file_line)
}
/// This is the entry point of unwinding for panic!() and assert!().
// panicking.
// see below for why we do the `Any` coercion here.
- begin_unwind_inner(box msg, file_line)
+ begin_unwind_inner(Box::new(msg), file_line)
}
/// The core of the unwinding.
}
// Convert the arguments into a stack-allocated string
- let mut msg = [0u8; 512];
+ let mut msg = [0; 512];
let mut w = BufWriter { buf: &mut msg, pos: 0 };
let _ = write!(&mut w, "{}", args);
let msg = str::from_utf8(&w.buf[..w.pos]).unwrap_or("aborted");
#[test]
fn drop_full() {
- let (tx, _rx) = channel();
+ let (tx, _rx) = channel::<Box<int>>();
tx.send(box 1).unwrap();
}
#[test]
fn drop_full_shared() {
- let (tx, _rx) = channel();
+ let (tx, _rx) = channel::<Box<int>>();
drop(tx.clone());
drop(tx.clone());
tx.send(box 1).unwrap();
#[test]
fn stress_shared() {
- static AMT: u32 = 10000;
- static NTHREADS: u32 = 8;
+ const AMT: u32 = 10000;
+ const NTHREADS: u32 = 8;
let (tx, rx) = channel::<i32>();
let t = thread::spawn(move|| {
#[test]
fn oneshot_multi_thread_send_recv_stress() {
for _ in 0..stress_factor() {
- let (tx, rx) = channel();
+ let (tx, rx) = channel::<Box<int>>();
let _t = thread::spawn(move|| {
tx.send(box 10).unwrap();
});
#[test]
fn drop_full() {
- let (tx, _rx) = sync_channel(1);
+ let (tx, _rx) = sync_channel::<Box<int>>(1);
tx.send(box 1).unwrap();
}
#[test]
fn stress_shared() {
- static AMT: u32 = 1000;
- static NTHREADS: u32 = 8;
+ const AMT: u32 = 1000;
+ const NTHREADS: u32 = 8;
let (tx, rx) = sync_channel::<i32>(0);
let (dtx, drx) = sync_channel::<()>(0);
#[test]
fn test_full() {
- let q = Queue::new();
+ let q: Queue<Box<_>> = Queue::new();
q.push(box 1);
q.push(box 2);
}
#[test]
fn stress() {
- static AMT: i32 = 10000;
+ const AMT: i32 = 10000;
let (tx1, rx1) = channel::<i32>();
let (tx2, rx2) = channel::<i32>();
let (tx3, rx3) = channel::<()>();
#[test]
fn drop_full() {
unsafe {
- let q = Queue::new(0);
+ let q: Queue<Box<_>> = Queue::new(0);
q.push(box 1);
q.push(box 2);
}
fn lots_and_lots() {
static M: StaticMutex = MUTEX_INIT;
static mut CNT: u32 = 0;
- static J: u32 = 1000;
- static K: u32 = 3;
+ const J: u32 = 1000;
+ const K: u32 = 3;
fn inc() {
for _ in 0..J {
#[test]
fn frob() {
static R: StaticRwLock = RW_LOCK_INIT;
- static N: usize = 10;
- static M: usize = 1000;
+ const N: usize = 10;
+ const M: usize = 1000;
let (tx, rx) = channel::<()>();
for _ in 0..N {
//! ```
#![allow(non_camel_case_types)]
+#![unstable(feature = "thread_local_internals")]
use prelude::v1::*;
/// KEY.set(1 as *mut u8);
/// }
/// ```
-#[stable(feature = "rust1", since = "1.0.0")]
pub struct StaticKey {
/// Inner static TLS key (internals), created with by `INIT_INNER` in this
/// module.
- #[stable(feature = "rust1", since = "1.0.0")]
pub inner: StaticKeyInner,
/// Destructor for the TLS value.
///
/// See `Key::new` for information about when the destructor runs and how
/// it runs.
- #[stable(feature = "rust1", since = "1.0.0")]
pub dtor: Option<unsafe extern fn(*mut u8)>,
}
/// Constant initialization value for static TLS keys.
///
/// This value specifies no destructor by default.
-#[stable(feature = "rust1", since = "1.0.0")]
pub const INIT: StaticKey = StaticKey {
inner: INIT_INNER,
dtor: None,
/// Constant initialization value for the inner part of static TLS keys.
///
/// This value allows specific configuration of the destructor for a TLS key.
-#[stable(feature = "rust1", since = "1.0.0")]
pub const INIT_INNER: StaticKeyInner = StaticKeyInner {
key: atomic::ATOMIC_USIZE_INIT,
};
use ops;
use slice;
use str;
-use string::{String, CowString};
+use string::String;
use sys_common::AsInner;
use unicode::str::{Utf16Item, utf16_items};
use vec::Vec;
-static UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
+const UTF8_REPLACEMENT_CHARACTER: &'static [u8] = b"\xEF\xBF\xBD";
/// A Unicode code point: from U+0000 to U+10FFFF.
///
/// Surrogates are replaced with `"\u{FFFD}"` (the replacement character “�”).
///
/// This only copies the data if necessary (if it contains any surrogate).
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
let surrogate_pos = match self.next_surrogate(0) {
None => return Cow::Borrowed(unsafe { str::from_utf8_unchecked(&self.bytes) }),
Some((pos, _)) => pos,
if index == slice.len() { return true; }
match slice.bytes.get(index) {
None => false,
- Some(&b) => b < 128u8 || b >= 192u8,
+ Some(&b) => b < 128 || b >= 192,
}
}
return Some(tmp);
}
- let mut buf = [0u16; 2];
+ let mut buf = [0; 2];
self.code_points.next().map(|code_point| {
let n = encode_utf16_raw(code_point.value, &mut buf)
.unwrap_or(0);
use borrow::Cow;
use super::*;
use mem::transmute;
- use string::CowString;
#[test]
fn code_point_from_u32() {
assert_eq!(Wtf8::from_str("aé 💩").to_string_lossy(), Cow::Borrowed("aé 💩"));
let mut string = Wtf8Buf::from_str("aé 💩");
string.push(CodePoint::from_u32(0xD800).unwrap());
- let expected: CowString = Cow::Owned(String::from_str("aé 💩�"));
+ let expected: Cow<str> = Cow::Owned(String::from_str("aé 💩�"));
assert_eq!(string.to_string_lossy(), expected);
}
let mut ip = unsafe {
uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void
};
- if ip_before_insn == 0 {
+ if !ip.is_null() && ip_before_insn == 0 {
// this is a non-signaling frame, so `ip` refers to the address
// after the calling instruction. account for that.
ip = (ip as usize - 1) as *mut _;
// This function doesn't exist on Android or ARM/Linux, so make it same
// to _Unwind_GetIP
- #[cfg(any(target_os = "android",
+ #[cfg(any(all(target_os = "android", target_arch = "arm"),
all(target_os = "linux", target_arch = "arm")))]
pub unsafe fn _Unwind_GetIPInfo(ctx: *mut _Unwind_Context,
ip_before_insn: *mut libc::c_int)
#[repr(C)]
pub struct fd_set {
// FIXME: shouldn't this be a c_ulong?
- fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS)]
+ fds_bits: [libc::uintptr_t; (FD_SETSIZE / usize::BITS as usize)]
}
pub fn fd_set(set: &mut fd_set, fd: i32) {
let fd = fd as uint;
- set.fds_bits[fd / usize::BITS] |= 1 << (fd % usize::BITS);
+ set.fds_bits[fd / usize::BITS as usize] |= 1 << (fd % usize::BITS as usize);
}
}
fn as_raw_fd(&self) -> Fd;
}
+#[allow(deprecated)]
impl AsRawFd for old_io::fs::File {
fn as_raw_fd(&self) -> Fd {
self.as_inner().fd()
let mut writer = FileDesc::new(writer, true);
writer.write(b"test").ok().unwrap();
- let mut buf = [0u8; 4];
+ let mut buf = [0; 4];
match reader.read(&mut buf) {
Ok(4) => {
assert_eq!(buf[0], 't' as u8);
use core::prelude::*;
+use borrow::Cow;
use fmt::{self, Debug};
use vec::Vec;
use slice::SliceExt as StdSliceExt;
use str;
-use string::{String, CowString};
+use string::String;
use mem;
#[derive(Clone, Hash)]
str::from_utf8(&self.inner).ok()
}
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(&self.inner)
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(deprecated)]
+
use prelude::v1::*;
use self::Req::*;
fn as_raw_handle(&self) -> Handle;
}
+#[allow(deprecated)]
impl AsRawHandle for old_io::fs::File {
fn as_raw_handle(&self) -> Handle {
self.as_inner().handle()
-> DWORD;
}
- static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
- static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
+ const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
+ const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
// This value is calculated from the macro
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
/// The underlying OsString/OsStr implementation on Windows is a
/// wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
+use borrow::Cow;
use fmt::{self, Debug};
use sys_common::wtf8::{Wtf8, Wtf8Buf};
-use string::{String, CowString};
+use string::String;
use result::Result;
use option::Option;
use mem;
self.inner.as_str()
}
- pub fn to_string_lossy(&self) -> CowString {
+ pub fn to_string_lossy(&self) -> Cow<str> {
self.inner.to_string_lossy()
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![allow(deprecated)]
+
use prelude::v1::*;
use collections;
use libc::{pid_t, c_void};
use libc;
use mem;
-use old_io::fs::PathExtensions;
+#[allow(deprecated)] use old_io::fs::PathExtensions;
use old_io::process::{ProcessExit, ExitStatus};
use old_io::{IoResult, IoError};
use old_io;
// address at which our stack started).
let main = move || {
let something_around_the_top_of_the_stack = 1;
- let addr = &something_around_the_top_of_the_stack as *const isize;
+ let addr = &something_around_the_top_of_the_stack as *const i32;
let my_stack_top = addr as usize;
let my_stack_bottom = my_stack_top - stack_size + 1024;
unsafe {
}
fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Thunk<'static>) {
- let (tx, rx) = channel::<u32>();
+ let (tx, rx) = channel();
- let x = box 1;
- let x_in_parent = (&*x) as *const isize as u32;
+ let x: Box<_> = box 1;
+ let x_in_parent = (&*x) as *const i32 as usize;
spawnfn(Thunk::new(move|| {
- let x_in_child = (&*x) as *const isize as u32;
+ let x_in_child = (&*x) as *const i32 as usize;
tx.send(x_in_child).unwrap();
}));
// climbing the task tree to dereference each ancestor. (See #1789)
// (well, it would if the constant were 8000+ - I lowered it to be more
// valgrind-friendly. try this at home, instead..!)
- static GENERATIONS: usize = 16;
- fn child_no(x: usize) -> Thunk<'static> {
+ const GENERATIONS: u32 = 16;
+ fn child_no(x: u32) -> Thunk<'static> {
return Thunk::new(move|| {
if x < GENERATIONS {
thread::spawn(move|| child_no(x+1).invoke(()));
assert!(e.is::<T>());
let any = e.downcast::<T>().ok().unwrap();
assert!(any.is::<u16>());
- assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413u16);
+ assert_eq!(*any.downcast::<u16>().ok().unwrap(), 413);
}
Ok(()) => panic!()
}
// Sure wish we had macro hygiene, no?
#[doc(hidden)]
-#[stable(feature = "rust1", since = "1.0.0")]
+#[unstable(feature = "thread_local_internals")]
pub mod __impl {
pub use super::imp::Key as KeyInner;
pub use super::imp::destroy_value;
/// Declare a new thread local storage key of type `std::thread_local::Key`.
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
+#[allow_internal_unstable]
macro_rules! thread_local {
(static $name:ident: $t:ty = $init:expr) => (
static $name: ::std::thread_local::Key<$t> = {
#[macro_export]
#[doc(hidden)]
+#[allow_internal_unstable]
macro_rules! __thread_local_inner {
(static $name:ident: $t:ty = $init:expr) => (
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
use ptr;
#[doc(hidden)]
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub struct Key<T> {
// Place the inner bits in an `UnsafeCell` to currently get around the
// "only Sync statics" restriction. This allows any type to be placed in
//
// Note that all access requires `T: 'static` so it can't be a type with
// any borrowed pointers still.
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub inner: UnsafeCell<T>,
// Metadata to keep track of the state of the destructor. Remember that
// these variables are thread-local, not global.
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub dtor_registered: UnsafeCell<bool>, // should be Cell
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub dtor_running: UnsafeCell<bool>, // should be Cell
}
}
#[doc(hidden)]
- #[stable(feature = "rust1", since = "1.0.0")]
+ #[unstable(feature = "thread_local_internals")]
pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
let ptr = ptr as *mut Key<T>;
// Right before we run the user destructor be sure to flag the
use sys_common::thread_local::StaticKey as OsStaticKey;
#[doc(hidden)]
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub struct Key<T> {
// Statically allocated initialization expression, using an `UnsafeCell`
// for the same reasons as above.
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub inner: UnsafeCell<T>,
// OS-TLS key that we'll use to key off.
- #[stable(since = "1.0.0", feature = "rust1")]
+ #[unstable(feature = "thread_local_internals")]
pub os: OsStaticKey,
}
}
#[doc(hidden)]
- #[stable(feature = "rust1", since = "1.0.0")]
+ #[unstable(feature = "thread_local_internals")]
pub unsafe extern fn destroy_value<T: 'static>(ptr: *mut u8) {
// The OS TLS ensures that this key contains a NULL value when this
// destructor starts to run. We set it back to a sentinel value of 1 to
/// This macro declares a `static` item on which methods are used to get and
/// set the value stored within.
#[macro_export]
+#[allow_internal_unstable]
macro_rules! scoped_thread_local {
(static $name:ident: $t:ty) => (
__scoped_thread_local_inner!(static $name: $t);
#[macro_export]
#[doc(hidden)]
+#[allow_internal_unstable]
macro_rules! __scoped_thread_local_inner {
(static $name:ident: $t:ty) => (
#[cfg_attr(not(any(windows,
const _INIT: __Key<$t> = __Key {
inner: ::std::thread_local::scoped::__impl::KeyInner {
inner: ::std::thread_local::scoped::__impl::OS_INIT,
- marker: ::std::marker::InvariantType,
+ marker: ::std::marker::PhantomData::<::std::cell::Cell<$t>>,
}
};
target_arch = "aarch64"))]
mod imp {
use marker;
+ use std::cell::Cell;
use sys_common::thread_local::StaticKey as OsStaticKey;
#[doc(hidden)]
pub struct KeyInner<T> {
pub inner: OsStaticKey,
- pub marker: marker::InvariantType<T>,
+ pub marker: marker::PhantomData<Cell<T>>,
}
unsafe impl<T> ::marker::Sync for KeyInner<T> { }
where F : FnOnce(A) -> R, F : Send + 'a
{
Thunk {
- invoke: box func
+ invoke: Box::<F>::new(func)
}
}
impl Duration {
/// Makes a new `Duration` with given number of weeks.
- /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks.
+ /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60)` with overflow checks.
/// Panics when the duration is out of bounds.
#[inline]
#[unstable(feature = "std_misc")]
//! assert!(b == c);
//!
//! let d : (u32, f32) = Default::default();
-//! assert_eq!(d, (0u32, 0.0f32));
+//! assert_eq!(d, (0, 0.0f32));
//! ```
#![doc(primitive = "tuple")]
}
#[allow(non_upper_case_globals)]
-static AbiDatas: &'static [AbiData] = &[
+const AbiDatas: &'static [AbiData] = &[
// Platform-specific ABIs
AbiData {abi: Cdecl, name: "cdecl" },
AbiData {abi: Stdcall, name: "stdcall" },
- AbiData {abi: Fastcall, name:"fastcall" },
+ AbiData {abi: Fastcall, name: "fastcall" },
AbiData {abi: Aapcs, name: "aapcs" },
AbiData {abi: Win64, name: "win64" },
use codemap::{Span, Spanned, DUMMY_SP, ExpnId};
use abi::Abi;
use ast_util;
+use ext::base;
+use ext::tt::macro_parser;
use owned_slice::OwnedSlice;
use parse::token::{InternedString, str_to_ident};
use parse::token;
+use parse::lexer;
use ptr::P;
use std::fmt;
TtSequence(span, _) => span,
}
}
+
+ /// Use this token tree as a matcher to parse given tts.
+ pub fn parse(cx: &base::ExtCtxt, mtch: &[TokenTree], tts: &[TokenTree])
+ -> macro_parser::NamedParseResult {
+ // `None` is because we're not interpolating
+ let arg_rdr = lexer::new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
+ None,
+ None,
+ tts.iter().cloned().collect(),
+ true);
+ macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
+ }
}
pub type Mac = Spanned<Mac_>;
pub imported_from: Option<Ident>,
pub export: bool,
pub use_locally: bool,
+ pub allow_internal_unstable: bool,
pub body: Vec<TokenTree>,
}
use arena::TypedArena;
use std::cell::RefCell;
use std::fmt;
-use std::old_io::IoResult;
+use std::io;
use std::iter::{self, repeat};
use std::mem;
use std::slice;
}
pub trait NodePrinter {
- fn print_node(&mut self, node: &Node) -> IoResult<()>;
+ fn print_node(&mut self, node: &Node) -> io::Result<()>;
}
impl<'a> NodePrinter for pprust::State<'a> {
- fn print_node(&mut self, node: &Node) -> IoResult<()> {
+ fn print_node(&mut self, node: &Node) -> io::Result<()> {
match *node {
NodeItem(a) => self.print_item(&*a),
NodeForeignItem(a) => self.print_foreign_item(&*a),
pub fn int_ty_max(t: IntTy) -> u64 {
match t {
- TyI8 => 0x80u64,
- TyI16 => 0x8000u64,
- TyIs(_) | TyI32 => 0x80000000u64, // actually ni about TyIs
- TyI64 => 0x8000000000000000u64
+ TyI8 => 0x80,
+ TyI16 => 0x8000,
+ TyIs(_) | TyI32 => 0x80000000, // actually ni about TyIs
+ TyI64 => 0x8000000000000000
}
}
pub fn uint_ty_max(t: UintTy) -> u64 {
match t {
- TyU8 => 0xffu64,
- TyU16 => 0xffffu64,
- TyUs(_) | TyU32 => 0xffffffffu64, // actually ni about TyUs
- TyU64 => 0xffffffffffffffffu64
+ TyU8 => 0xff,
+ TyU16 => 0xffff,
+ TyUs(_) | TyU32 => 0xffffffff, // actually ni about TyUs
+ TyU64 => 0xffffffffffffffff
}
}
use libc::c_uint;
use serialize::{Encodable, Decodable, Encoder, Decoder};
+
+// _____________________________________________________________________________
+// Pos, BytePos, CharPos
+//
+
pub trait Pos {
fn from_usize(n: usize) -> Self;
fn to_usize(&self) -> usize;
}
}
+impl Encodable for BytePos {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ s.emit_u32(self.0)
+ }
+}
+
+impl Decodable for BytePos {
+ fn decode<D: Decoder>(d: &mut D) -> Result<BytePos, D::Error> {
+ Ok(BytePos(try!{ d.read_u32() }))
+ }
+}
+
impl Pos for CharPos {
fn from_usize(n: usize) -> CharPos { CharPos(n) }
fn to_usize(&self) -> usize { let CharPos(n) = *self; n }
}
}
+// _____________________________________________________________________________
+// Span, Spanned
+//
+
/// Spans represent a region of code, used for error reporting. Positions in spans
/// are *absolute* positions from the beginning of the codemap, not positions
/// relative to FileMaps. Methods on the CodeMap can be used to relate spans back
impl Eq for Span {}
impl Encodable for Span {
- /* Note #1972 -- spans are encoded but not decoded */
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- s.emit_nil()
+ // Encode spans as a single u64 in order to cut down on tagging overhead
+ // added by the RBML metadata encoding. The should be solved differently
+ // altogether some time (FIXME #21482)
+ s.emit_u64( (self.lo.0 as u64) | ((self.hi.0 as u64) << 32) )
}
}
impl Decodable for Span {
- fn decode<D: Decoder>(_d: &mut D) -> Result<Span, D::Error> {
- Ok(DUMMY_SP)
+ fn decode<D: Decoder>(d: &mut D) -> Result<Span, D::Error> {
+ let lo_hi: u64 = try! { d.read_u64() };
+ let lo = BytePos(lo_hi as u32);
+ let hi = BytePos((lo_hi >> 32) as u32);
+ Ok(mk_sp(lo, hi))
}
}
}
}
+// _____________________________________________________________________________
+// Loc, LocWithOpt, FileMapAndLine, FileMapAndBytePos
+//
+
/// A source code location used for error reporting
pub struct Loc {
/// Information about the original source
pub struct FileMapAndLine { pub fm: Rc<FileMap>, pub line: usize }
pub struct FileMapAndBytePos { pub fm: Rc<FileMap>, pub pos: BytePos }
+
+// _____________________________________________________________________________
+// MacroFormat, NameAndSpan, ExpnInfo, ExpnId
+//
+
/// The syntax with which a macro was invoked.
#[derive(Clone, Copy, Hash, Debug)]
pub enum MacroFormat {
pub name: String,
/// The format with which the macro was invoked.
pub format: MacroFormat,
+ /// Whether the macro is allowed to use #[unstable]/feature-gated
+ /// features internally without forcing the whole crate to opt-in
+ /// to them.
+ pub allow_internal_unstable: bool,
/// The span of the macro definition itself. The macro may not
/// have a sensible definition span (e.g. something defined
/// completely inside libsyntax) in which case this is None.
}
}
+// _____________________________________________________________________________
+// FileMap, MultiByteChar, FileName, FileLines
+//
+
pub type FileName = String;
pub struct FileLines {
}
/// Identifies an offset of a multi-byte character in a FileMap
-#[derive(Copy)]
+#[derive(Copy, RustcEncodable, RustcDecodable, Eq, PartialEq)]
pub struct MultiByteChar {
/// The absolute offset of the character in the CodeMap
pub pos: BytePos,
/// e.g. `<anon>`
pub name: FileName,
/// The complete source code
- pub src: String,
+ pub src: Option<Rc<String>>,
/// The start position of this source in the CodeMap
pub start_pos: BytePos,
+ /// The end position of this source in the CodeMap
+ pub end_pos: BytePos,
/// Locations of lines beginnings in the source code
- pub lines: RefCell<Vec<BytePos> >,
+ pub lines: RefCell<Vec<BytePos>>,
/// Locations of multi-byte characters in the source code
- pub multibyte_chars: RefCell<Vec<MultiByteChar> >,
+ pub multibyte_chars: RefCell<Vec<MultiByteChar>>,
+}
+
+impl Encodable for FileMap {
+ fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
+ s.emit_struct("FileMap", 5, |s| {
+ try! { s.emit_struct_field("name", 0, |s| self.name.encode(s)) };
+ try! { s.emit_struct_field("start_pos", 1, |s| self.start_pos.encode(s)) };
+ try! { s.emit_struct_field("end_pos", 2, |s| self.end_pos.encode(s)) };
+ try! { s.emit_struct_field("lines", 3, |s| {
+ let lines = self.lines.borrow();
+ // store the length
+ try! { s.emit_u32(lines.len() as u32) };
+
+ if lines.len() > 0 {
+ // In order to preserve some space, we exploit the fact that
+ // the lines list is sorted and individual lines are
+ // probably not that long. Because of that we can store lines
+ // as a difference list, using as little space as possible
+ // for the differences.
+ let max_line_length = if lines.len() == 1 {
+ 0
+ } else {
+ lines.as_slice()
+ .windows(2)
+ .map(|w| w[1] - w[0])
+ .map(|bp| bp.to_usize())
+ .max()
+ .unwrap()
+ };
+
+ let bytes_per_diff: u8 = match max_line_length {
+ 0 ... 0xFF => 1,
+ 0x100 ... 0xFFFF => 2,
+ _ => 4
+ };
+
+ // Encode the number of bytes used per diff.
+ try! { bytes_per_diff.encode(s) };
+
+ // Encode the first element.
+ try! { lines[0].encode(s) };
+
+ let diff_iter = (&lines[..]).windows(2)
+ .map(|w| (w[1] - w[0]));
+
+ match bytes_per_diff {
+ 1 => for diff in diff_iter { try! { (diff.0 as u8).encode(s) } },
+ 2 => for diff in diff_iter { try! { (diff.0 as u16).encode(s) } },
+ 4 => for diff in diff_iter { try! { (diff.0 as u32).encode(s) } },
+ _ => unreachable!()
+ }
+ }
+
+ Ok(())
+ })
+ };
+ s.emit_struct_field("multibyte_chars", 4, |s| {
+ (*self.multibyte_chars.borrow()).encode(s)
+ })
+ })
+ }
+}
+
+impl Decodable for FileMap {
+ fn decode<D: Decoder>(d: &mut D) -> Result<FileMap, D::Error> {
+
+ d.read_struct("FileMap", 5, |d| {
+ let name: String = try! {
+ d.read_struct_field("name", 0, |d| Decodable::decode(d))
+ };
+ let start_pos: BytePos = try! {
+ d.read_struct_field("start_pos", 1, |d| Decodable::decode(d))
+ };
+ let end_pos: BytePos = try! {
+ d.read_struct_field("end_pos", 2, |d| Decodable::decode(d))
+ };
+ let lines: Vec<BytePos> = try! {
+ d.read_struct_field("lines", 3, |d| {
+ let num_lines: u32 = try! { Decodable::decode(d) };
+ let mut lines = Vec::with_capacity(num_lines as usize);
+
+ if num_lines > 0 {
+ // Read the number of bytes used per diff.
+ let bytes_per_diff: u8 = try! { Decodable::decode(d) };
+
+ // Read the first element.
+ let mut line_start: BytePos = try! { Decodable::decode(d) };
+ lines.push(line_start);
+
+ for _ in 1..num_lines {
+ let diff = match bytes_per_diff {
+ 1 => try! { d.read_u8() } as u32,
+ 2 => try! { d.read_u16() } as u32,
+ 4 => try! { d.read_u32() },
+ _ => unreachable!()
+ };
+
+ line_start = line_start + BytePos(diff);
+
+ lines.push(line_start);
+ }
+ }
+
+ Ok(lines)
+ })
+ };
+ let multibyte_chars: Vec<MultiByteChar> = try! {
+ d.read_struct_field("multibyte_chars", 4, |d| Decodable::decode(d))
+ };
+ Ok(FileMap {
+ name: name,
+ start_pos: start_pos,
+ end_pos: end_pos,
+ src: None,
+ lines: RefCell::new(lines),
+ multibyte_chars: RefCell::new(multibyte_chars)
+ })
+ })
+ }
}
impl FileMap {
/// get a line from the list of pre-computed line-beginnings
///
pub fn get_line(&self, line_number: usize) -> Option<String> {
- let lines = self.lines.borrow();
- lines.get(line_number).map(|&line| {
- let begin: BytePos = line - self.start_pos;
- let begin = begin.to_usize();
- let slice = &self.src[begin..];
- match slice.find('\n') {
- Some(e) => &slice[..e],
- None => slice
- }.to_string()
- })
+ match self.src {
+ Some(ref src) => {
+ let lines = self.lines.borrow();
+ lines.get(line_number).map(|&line| {
+ let begin: BytePos = line - self.start_pos;
+ let begin = begin.to_usize();
+ let slice = &src[begin..];
+ match slice.find('\n') {
+ Some(e) => &slice[..e],
+ None => slice
+ }.to_string()
+ })
+ }
+ None => None
+ }
}
pub fn record_multibyte_char(&self, pos: BytePos, bytes: usize) {
!(self.name.starts_with("<") &&
self.name.ends_with(">"))
}
+
+ pub fn is_imported(&self) -> bool {
+ self.src.is_none()
+ }
}
+
+// _____________________________________________________________________________
+// CodeMap
+//
+
pub struct CodeMap {
pub files: RefCell<Vec<Rc<FileMap>>>,
expansions: RefCell<Vec<ExpnInfo>>
let mut files = self.files.borrow_mut();
let start_pos = match files.last() {
None => 0,
- Some(last) => last.start_pos.to_usize() + last.src.len(),
+ Some(last) => last.end_pos.to_usize(),
};
// Remove utf-8 BOM if any.
src.push('\n');
}
+ let end_pos = start_pos + src.len();
+
let filemap = Rc::new(FileMap {
name: filename,
- src: src.to_string(),
+ src: Some(Rc::new(src)),
start_pos: Pos::from_usize(start_pos),
+ end_pos: Pos::from_usize(end_pos),
lines: RefCell::new(Vec::new()),
multibyte_chars: RefCell::new(Vec::new()),
});
filemap
}
+ /// Allocates a new FileMap representing a source file from an external
+ /// crate. The source code of such an "imported filemap" is not available,
+ /// but we still know enough to generate accurate debuginfo location
+ /// information for things inlined from other crates.
+ pub fn new_imported_filemap(&self,
+ filename: FileName,
+ source_len: usize,
+ file_local_lines: Vec<BytePos>,
+ file_local_multibyte_chars: Vec<MultiByteChar>)
+ -> Rc<FileMap> {
+ let mut files = self.files.borrow_mut();
+ let start_pos = match files.last() {
+ None => 0,
+ Some(last) => last.end_pos.to_usize(),
+ };
+
+ let end_pos = Pos::from_usize(start_pos + source_len);
+ let start_pos = Pos::from_usize(start_pos);
+
+ let lines = file_local_lines.map_in_place(|pos| pos + start_pos);
+ let multibyte_chars = file_local_multibyte_chars.map_in_place(|mbc| MultiByteChar {
+ pos: mbc.pos + start_pos,
+ bytes: mbc.bytes
+ });
+
+ let filemap = Rc::new(FileMap {
+ name: filename,
+ src: None,
+ start_pos: start_pos,
+ end_pos: end_pos,
+ lines: RefCell::new(lines),
+ multibyte_chars: RefCell::new(multibyte_chars),
+ });
+
+ files.push(filemap.clone());
+
+ filemap
+ }
+
pub fn mk_substr_filename(&self, sp: Span) -> String {
let pos = self.lookup_char_pos(sp.lo);
(format!("<{}:{}:{}>",
return Err(SpanSnippetError::IllFormedSpan(sp));
}
- let begin = self.lookup_byte_offset(sp.lo);
- let end = self.lookup_byte_offset(sp.hi);
+ let local_begin = self.lookup_byte_offset(sp.lo);
+ let local_end = self.lookup_byte_offset(sp.hi);
- if begin.fm.start_pos != end.fm.start_pos {
+ if local_begin.fm.start_pos != local_end.fm.start_pos {
return Err(SpanSnippetError::DistinctSources(DistinctSources {
- begin: (begin.fm.name.clone(),
- begin.fm.start_pos),
- end: (end.fm.name.clone(),
- end.fm.start_pos)
+ begin: (local_begin.fm.name.clone(),
+ local_begin.fm.start_pos),
+ end: (local_end.fm.name.clone(),
+ local_end.fm.start_pos)
}));
} else {
- let start = begin.pos.to_usize();
- let limit = end.pos.to_usize();
- if start > limit || limit > begin.fm.src.len() {
- return Err(SpanSnippetError::MalformedForCodemap(
- MalformedCodemapPositions {
- name: begin.fm.name.clone(),
- source_len: begin.fm.src.len(),
- begin_pos: begin.pos,
- end_pos: end.pos,
- }));
- }
+ match local_begin.fm.src {
+ Some(ref src) => {
+ let start_index = local_begin.pos.to_usize();
+ let end_index = local_end.pos.to_usize();
+ let source_len = (local_begin.fm.end_pos -
+ local_begin.fm.start_pos).to_usize();
+
+ if start_index > end_index || end_index > source_len {
+ return Err(SpanSnippetError::MalformedForCodemap(
+ MalformedCodemapPositions {
+ name: local_begin.fm.name.clone(),
+ source_len: source_len,
+ begin_pos: local_begin.pos,
+ end_pos: local_end.pos,
+ }));
+ }
- return Ok((&begin.fm.src[start..limit]).to_string())
+ return Ok((&src[start_index..end_index]).to_string())
+ }
+ None => {
+ return Err(SpanSnippetError::SourceNotAvailable {
+ filename: local_begin.fm.name.clone()
+ });
+ }
+ }
}
}
panic!("asking for {} which we don't know about", filename);
}
+ /// For a global BytePos compute the local offset within the containing FileMap
pub fn lookup_byte_offset(&self, bpos: BytePos) -> FileMapAndBytePos {
let idx = self.lookup_filemap_idx(bpos);
let fm = (*self.files.borrow())[idx].clone();
}
}
- /// Check if a span is "internal" to a macro. This means that it is entirely generated by a
- /// macro expansion and contains no code that was passed in as an argument.
- pub fn span_is_internal(&self, span: Span) -> bool {
- // first, check if the given expression was generated by a macro or not
- // we need to go back the expn_info tree to check only the arguments
- // of the initial macro call, not the nested ones.
- let mut is_internal = false;
- let mut expnid = span.expn_id;
- while self.with_expn_info(expnid, |expninfo| {
- match expninfo {
- Some(ref info) => {
- // save the parent expn_id for next loop iteration
- expnid = info.call_site.expn_id;
- if info.callee.name == "format_args" {
- // This is a hack because the format_args builtin calls unstable APIs.
- // I spent like 6 hours trying to solve this more generally but am stupid.
- is_internal = true;
- false
- } else if info.callee.span.is_none() {
- // it's a compiler built-in, we *really* don't want to mess with it
- // so we skip it, unless it was called by a regular macro, in which case
- // we will handle the caller macro next turn
- is_internal = true;
- true // continue looping
+ /// Check if a span is "internal" to a macro in which #[unstable]
+ /// items can be used (that is, a macro marked with
+ /// `#[allow_internal_unstable]`).
+ pub fn span_allows_unstable(&self, span: Span) -> bool {
+ debug!("span_allows_unstable(span = {:?})", span);
+ let mut allows_unstable = false;
+ let mut expn_id = span.expn_id;
+ loop {
+ let quit = self.with_expn_info(expn_id, |expninfo| {
+ debug!("span_allows_unstable: expninfo = {:?}", expninfo);
+ expninfo.map_or(/* hit the top level */ true, |info| {
+
+ let span_comes_from_this_expansion =
+ info.callee.span.map_or(span == info.call_site, |mac_span| {
+ mac_span.lo <= span.lo && span.hi < mac_span.hi
+ });
+
+ debug!("span_allows_unstable: from this expansion? {}, allows unstable? {}",
+ span_comes_from_this_expansion,
+ info.callee.allow_internal_unstable);
+ if span_comes_from_this_expansion {
+ allows_unstable = info.callee.allow_internal_unstable;
+ // we've found the right place, stop looking
+ true
} else {
- // was this expression from the current macro arguments ?
- is_internal = !( span.lo > info.call_site.lo &&
- span.hi < info.call_site.hi );
- true // continue looping
+ // not the right place, keep looking
+ expn_id = info.call_site.expn_id;
+ false
}
- },
- _ => false // stop looping
+ })
+ });
+ if quit {
+ break
}
- }) { /* empty while loop body */ }
- return is_internal;
+ }
+ debug!("span_allows_unstable? {}", allows_unstable);
+ allows_unstable
}
}
+// _____________________________________________________________________________
+// SpanSnippetError, DistinctSources, MalformedCodemapPositions
+//
+
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SpanSnippetError {
IllFormedSpan(Span),
DistinctSources(DistinctSources),
MalformedForCodemap(MalformedCodemapPositions),
+ SourceNotAvailable { filename: String }
}
#[derive(Clone, PartialEq, Eq, Debug)]
end_pos: BytePos
}
+
+// _____________________________________________________________________________
+// Tests
+//
+
#[cfg(test)]
mod test {
use super::*;
use term;
/// maximum number of lines we will print for each error; arbitrary.
-static MAX_LINES: usize = 6;
+const MAX_LINES: usize = 6;
#[derive(Clone, Copy)]
pub enum RenderSpan {
pub fn default_handler(color_config: ColorConfig,
registry: Option<diagnostics::registry::Registry>,
can_emit_warnings: bool) -> Handler {
- mk_handler(can_emit_warnings, box EmitterWriter::stderr(color_config, registry))
+ mk_handler(can_emit_warnings, Box::new(EmitterWriter::stderr(color_config, registry)))
}
pub fn mk_handler(can_emit_warnings: bool, e: Box<Emitter + Send>) -> Handler {
if use_color {
let dst = match term::stderr() {
Some(t) => Terminal(t),
- None => Raw(box stderr),
+ None => Raw(Box::new(stderr)),
};
EmitterWriter { dst: dst, registry: registry }
} else {
- EmitterWriter { dst: Raw(box stderr), registry: registry }
+ EmitterWriter { dst: Raw(Box::new(stderr)), registry: registry }
}
}
})
}
+#[macro_export]
+macro_rules! fileline_help {
+ ($session:expr, $span:expr, $($message:tt)*) => ({
+ ($session).fileline_help($span, &format!($($message)*))
+ })
+}
+
#[macro_export]
macro_rules! register_diagnostics {
($($code:tt),*) => (
}
}
-static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
+const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> {
name: "asm".to_string(),
format: codemap::MacroBang,
span: None,
+ allow_internal_unstable: false,
},
});
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
/// A normal, function-like syntax extension.
///
/// `bytes!` is a `NormalTT`.
- NormalTT(Box<TTMacroExpander + 'static>, Option<Span>),
+ ///
+ /// The `bool` dictates whether the contents of the macro can
+ /// directly use `#[unstable]` things (true == yes).
+ NormalTT(Box<TTMacroExpander + 'static>, Option<Span>, bool),
/// A function-like syntax extension that has an extra ident before
/// the block.
///
- IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>),
+ IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool),
/// Represents `macro_rules!` itself.
MacroRulesTT,
-> SyntaxEnv {
// utility function to simplify creating NormalTT syntax extensions
fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
- NormalTT(box f, None)
+ NormalTT(Box::new(f), None, false)
}
let mut syntax_expanders = SyntaxEnv::new();
syntax_expanders.insert(intern("macro_rules"), MacroRulesTT);
syntax_expanders.insert(intern("format_args"),
- builtin_normal_expander(
- ext::format::expand_format_args));
+ // format_args uses `unstable` things internally.
+ NormalTT(Box::new(ext::format::expand_format_args), None, true));
syntax_expanders.insert(intern("env"),
builtin_normal_expander(
ext::env::expand_env));
builtin_normal_expander(
ext::log_syntax::expand_syntax_ext));
syntax_expanders.insert(intern("derive"),
- Decorator(box ext::deriving::expand_meta_derive));
+ Decorator(Box::new(ext::deriving::expand_meta_derive)));
syntax_expanders.insert(intern("deriving"),
- Decorator(box ext::deriving::expand_deprecated_deriving));
+ Decorator(Box::new(ext::deriving::expand_deprecated_deriving)));
if ecfg.enable_quotes() {
// Quasi-quoting expanders
syntax_expanders.insert(intern("quote_stmt"),
builtin_normal_expander(
ext::quote::expand_quote_stmt));
+ syntax_expanders.insert(intern("quote_matcher"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_matcher));
+ syntax_expanders.insert(intern("quote_attr"),
+ builtin_normal_expander(
+ ext::quote::expand_quote_attr));
}
syntax_expanders.insert(intern("line"),
self.print_backtrace();
self.parse_sess.span_diagnostic.span_help(sp, msg);
}
+ pub fn fileline_help(&self, sp: Span, msg: &str) {
+ self.print_backtrace();
+ self.parse_sess.span_diagnostic.fileline_help(sp, msg);
+ }
pub fn bug(&self, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.handler().bug(msg);
args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_clone("Clone", c, s, sub)
- }),
+ })),
}
),
associated_types: Vec::new(),
cx.expr_binary(span, ast::BiAnd, subexpr, eq)
},
cx.expr_bool(span, true),
- box |cx, span, _, _| cx.expr_bool(span, false),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, false)),
cx, span, substr)
}
fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
cx.expr_binary(span, ast::BiOr, subexpr, eq)
},
cx.expr_bool(span, false),
- box |cx, span, _, _| cx.expr_bool(span, true),
+ Box::new(|cx, span, _, _| cx.expr_bool(span, true)),
cx, span, substr)
}
args: vec!(borrowed_self()),
ret_ty: Literal(path_local!(bool)),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
$f(a, b, c)
- })
+ }))
}
} }
}
args: vec!(borrowed_self()),
ret_ty: Literal(path_local!(bool)),
attributes: attrs,
- combine_substructure: combine_substructure(box |cx, span, substr| {
+ combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_op($op, $equal, cx, span, substr)
- })
+ }))
}
} }
}
args: vec![borrowed_self()],
ret_ty: ret_ty,
attributes: attrs,
- combine_substructure: combine_substructure(box |cx, span, substr| {
+ combine_substructure: combine_substructure(Box::new(|cx, span, substr| {
cs_partial_cmp(cx, span, substr)
- })
+ }))
};
let trait_def = TraitDef {
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
equals_expr.clone(),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
some_ordering_collapsed(cx, span, PartialCmpOp, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
cx.expr_binary(span, ast::BiOr, cmp, and)
},
cx.expr_bool(span, equal),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derive(PartialOrd)`")
} else {
};
some_ordering_collapsed(cx, span, op, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
let block = cx.block(span, stmts, None);
cx.expr_block(block)
},
- box |cx, sp, _, _| cx.span_bug(sp, "non matching enums in derive(Eq)?"),
+ Box::new(|cx, sp, _, _| {
+ cx.span_bug(sp, "non matching enums in derive(Eq)?") }),
cx,
span,
substr)
args: vec!(),
ret_ty: nil_ty(),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
cs_total_eq_assert(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
args: vec!(borrowed_self()),
ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
cs_cmp(a, b, c)
- }),
+ })),
}
),
associated_types: Vec::new(),
cx.expr_block(cx.block(span, vec!(assign), Some(if_)))
},
cx.expr_path(equals_path.clone()),
- box |cx, span, (self_args, tag_tuple), _non_self_args| {
+ Box::new(|cx, span, (self_args, tag_tuple), _non_self_args| {
if self_args.len() != 2 {
cx.span_bug(span, "not exactly 2 arguments in `derives(Ord)`")
} else {
ordering_collapsed(cx, span, tag_tuple)
}
- },
+ }),
cx, span, substr)
}
true
)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
decodable_substructure(a, b, c, krate)
- }),
+ })),
}
),
associated_types: Vec::new(),
args: Vec::new(),
ret_ty: Self_,
attributes: attrs,
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
default_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
true
)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
encodable_substructure(a, b, c)
- }),
+ })),
}
),
associated_types: Vec::new(),
Struct(ref fields) => {
let emit_struct_field = cx.ident_of("emit_struct_field");
let mut stmts = Vec::new();
- let last = fields.len() - 1;
for (i, &FieldInfo {
name,
ref self_,
lambda));
// last call doesn't need a try!
+ let last = fields.len() - 1;
let call = if i != last {
cx.expr_try(span, call)
} else {
let encoder = cx.expr_ident(trait_span, blkarg);
let emit_variant_arg = cx.ident_of("emit_enum_variant_arg");
let mut stmts = Vec::new();
- let last = fields.len() - 1;
- for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
- let enc = cx.expr_method_call(span, self_.clone(),
- encode, vec!(blkencoder.clone()));
- let lambda = cx.lambda_expr_1(span, enc, blkarg);
- let call = cx.expr_method_call(span, blkencoder.clone(),
- emit_variant_arg,
- vec!(cx.expr_usize(span, i),
- lambda));
- let call = if i != last {
- cx.expr_try(span, call)
- } else {
- cx.expr(span, ExprRet(Some(call)))
- };
- stmts.push(cx.stmt_expr(call));
- }
-
- // enums with no fields need to return Ok()
- if stmts.len() == 0 {
+ if fields.len() > 0 {
+ let last = fields.len() - 1;
+ for (i, &FieldInfo { ref self_, span, .. }) in fields.iter().enumerate() {
+ let enc = cx.expr_method_call(span, self_.clone(),
+ encode, vec!(blkencoder.clone()));
+ let lambda = cx.lambda_expr_1(span, enc, blkarg);
+ let call = cx.expr_method_call(span, blkencoder.clone(),
+ emit_variant_arg,
+ vec!(cx.expr_usize(span, i),
+ lambda));
+ let call = if i != last {
+ cx.expr_try(span, call)
+ } else {
+ cx.expr(span, ExprRet(Some(call)))
+ };
+ stmts.push(cx.stmt_expr(call));
+ }
+ } else {
let ret_ok = cx.expr(trait_span,
ExprRet(Some(cx.expr_ok(trait_span,
cx.expr_tuple(trait_span, vec![])))));
callee: codemap::NameAndSpan {
name: format!("derive({})", trait_name),
format: codemap::MacroAttribute,
- span: Some(self.span)
+ span: Some(self.span),
+ allow_internal_unstable: false,
}
});
to_set
args: vec!(Ptr(box Literal(arg), Borrowed(None, MutMutable))),
ret_ty: nil_ty(),
attributes: vec![],
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
hash_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
true)),
// #[inline] liable to cause code-bloat
attributes: attrs.clone(),
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("i64", c, s, sub)
- }),
+ })),
},
MethodDef {
name: "from_u64",
true)),
// #[inline] liable to cause code-bloat
attributes: attrs,
- combine_substructure: combine_substructure(box |c, s, sub| {
+ combine_substructure: combine_substructure(Box::new(|c, s, sub| {
cs_from("u64", c, s, sub)
- }),
+ })),
}
),
associated_types: Vec::new(),
),
ret_ty: Self_,
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
rand_substructure(a, b, c)
- })
+ }))
}
),
associated_types: Vec::new(),
args: vec!(fmtr),
ret_ty: Literal(path_std!(cx, core::fmt::Result)),
attributes: Vec::new(),
- combine_substructure: combine_substructure(box |a, b, c| {
+ combine_substructure: combine_substructure(Box::new(|a, b, c| {
show_substructure(a, b, c)
- })
+ }))
}
],
associated_types: Vec::new(),
use codemap;
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
use ext::base::*;
-use feature_gate::{Features};
+use feature_gate::{self, Features};
use fold;
use fold::*;
use parse;
None
}
Some(rc) => match *rc {
- NormalTT(ref expandfun, exp_span) => {
+ NormalTT(ref expandfun, exp_span, allow_internal_unstable) => {
fld.cx.bt_push(ExpnInfo {
call_site: span,
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
span: exp_span,
+ allow_internal_unstable: allow_internal_unstable,
},
});
let fm = fresh_mark();
name: mname.to_string(),
format: MacroAttribute,
span: None,
+ // attributes can do whatever they like,
+ // for now
+ allow_internal_unstable: true,
}
});
it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use");
is_use = true;
if let ast::AttrInner = attr.node.style {
- fld.cx.span_help(attr.span, "consider an outer attribute, \
+ fld.cx.fileline_help(attr.span, "consider an outer attribute, \
#[macro_use] mod ...");
}
};
}
Some(rc) => match *rc {
- NormalTT(ref expander, span) => {
+ NormalTT(ref expander, span, allow_internal_unstable) => {
if it.ident.name != parse::token::special_idents::invalid.name {
fld.cx
.span_err(path_span,
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
- span: span
+ span: span,
+ allow_internal_unstable: allow_internal_unstable,
}
});
// mark before expansion:
let marked_before = mark_tts(&tts[..], fm);
expander.expand(fld.cx, it.span, &marked_before[..])
}
- IdentTT(ref expander, span) => {
+ IdentTT(ref expander, span, allow_internal_unstable) => {
if it.ident.name == parse::token::special_idents::invalid.name {
fld.cx.span_err(path_span,
&format!("macro {}! expects an ident argument",
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
- span: span
+ span: span,
+ allow_internal_unstable: allow_internal_unstable,
}
});
// mark before expansion:
);
return SmallVector::zero();
}
+
fld.cx.bt_push(ExpnInfo {
call_site: it.span,
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
span: None,
+ // `macro_rules!` doesn't directly allow
+ // unstable (this is orthogonal to whether
+ // the macro it creates allows it)
+ allow_internal_unstable: false,
}
});
// DON'T mark before expansion.
+ let allow_internal_unstable = attr::contains_name(&it.attrs,
+ "allow_internal_unstable");
+
+ // ensure any #[allow_internal_unstable]s are
+ // detected (including nested macro definitions
+ // etc.)
+ if allow_internal_unstable && !fld.cx.ecfg.enable_allow_internal_unstable() {
+ feature_gate::emit_feature_err(
+ &fld.cx.parse_sess.span_diagnostic,
+ "allow_internal_unstable",
+ it.span,
+ feature_gate::EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
+ }
+
let def = ast::MacroDef {
ident: it.ident,
attrs: it.attrs.clone(),
imported_from: None,
export: attr::contains_name(&it.attrs, "macro_export"),
use_locally: true,
+ allow_internal_unstable: allow_internal_unstable,
body: tts,
};
fld.cx.insert_macro(def);
}
Some(rc) => match *rc {
- NormalTT(ref expander, tt_span) => {
+ NormalTT(ref expander, tt_span, allow_internal_unstable) => {
fld.cx.bt_push(ExpnInfo {
call_site: span,
callee: NameAndSpan {
name: extnamestr.to_string(),
format: MacroBang,
- span: tt_span
+ span: tt_span,
+ allow_internal_unstable: allow_internal_unstable,
}
});
callee: NameAndSpan {
name: mname.to_string(),
format: MacroAttribute,
- span: None
+ span: None,
+ // attributes can do whatever they like,
+ // for now.
+ allow_internal_unstable: true,
}
});
name: mname.to_string(),
format: MacroAttribute,
span: None,
+ // attributes can do whatever they like,
+ // for now
+ allow_internal_unstable: true,
}
});
it = mac.expand(fld.cx, attr.span, &*attr.node.value, it);
_ => false,
}
}
+
+ pub fn enable_allow_internal_unstable(&self) -> bool {
+ match self.features {
+ Some(&Features { allow_internal_unstable: true, .. }) => true,
+ _ => false
+ }
+ }
}
pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> {
let (cx_expr, expr) = expand_tts(cx, sp, tts);
- let expanded = expand_wrapper(cx, sp, cx_expr, expr);
+ let expanded = expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]]);
base::MacEager::expr(expanded)
}
base::MacEager::expr(expanded)
}
+pub fn expand_quote_attr(cx: &mut ExtCtxt,
+ sp: Span,
+ tts: &[ast::TokenTree])
+ -> Box<base::MacResult+'static> {
+ let expanded = expand_parse_call(cx, sp, "parse_attribute",
+ vec!(cx.expr_bool(sp, true)), tts);
+
+ base::MacEager::expr(expanded)
+}
+
+pub fn expand_quote_matcher(cx: &mut ExtCtxt,
+ sp: Span,
+ tts: &[ast::TokenTree])
+ -> Box<base::MacResult+'static> {
+ let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
+ let mut vector = mk_stmts_let(cx, sp);
+ vector.extend(statements_mk_tts(cx, &tts[..], true).into_iter());
+ let block = cx.expr_block(
+ cx.block_all(sp,
+ vector,
+ Some(cx.expr_ident(sp, id_ext("tt")))));
+
+ let expanded = expand_wrapper(cx, sp, cx_expr, block, &[&["syntax", "ext", "quote", "rt"]]);
+ base::MacEager::expr(expanded)
+}
+
fn ids_ext(strs: Vec<String> ) -> Vec<ast::Ident> {
strs.iter().map(|str| str_to_ident(&(*str))).collect()
}
}
#[allow(non_upper_case_globals)]
-fn mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
+fn expr_mk_token(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> P<ast::Expr> {
macro_rules! mk_lit {
($name: expr, $suffix: expr, $($args: expr),*) => {{
let inner = cx.expr_call(sp, mk_token_path(cx, sp, $name), vec![$($args),*]);
vec!(mk_name(cx, sp, ident.ident())));
}
+ token::MatchNt(name, kind, namep, kindp) => {
+ return cx.expr_call(sp,
+ mk_token_path(cx, sp, "MatchNt"),
+ vec!(mk_ident(cx, sp, name),
+ mk_ident(cx, sp, kind),
+ match namep {
+ ModName => mk_token_path(cx, sp, "ModName"),
+ Plain => mk_token_path(cx, sp, "Plain"),
+ },
+ match kindp {
+ ModName => mk_token_path(cx, sp, "ModName"),
+ Plain => mk_token_path(cx, sp, "Plain"),
+ }));
+ }
+
token::Interpolated(_) => panic!("quote! with interpolated token"),
_ => ()
token::FatArrow => "FatArrow",
token::Pound => "Pound",
token::Dollar => "Dollar",
+ token::Question => "Question",
token::Underscore => "Underscore",
token::Eof => "Eof",
- _ => panic!(),
+ _ => panic!("unhandled token in quote!"),
};
mk_token_path(cx, sp, name)
}
-fn mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree) -> Vec<P<ast::Stmt>> {
+fn statements_mk_tt(cx: &ExtCtxt, tt: &ast::TokenTree, matcher: bool) -> Vec<P<ast::Stmt>> {
match *tt {
ast::TtToken(sp, SubstNt(ident, _)) => {
// tt.extend($ident.to_tokens(ext_cx).into_iter())
vec!(cx.stmt_expr(e_push))
}
- ref tt @ ast::TtToken(_, MatchNt(..)) => {
+ ref tt @ ast::TtToken(_, MatchNt(..)) if !matcher => {
let mut seq = vec![];
for i in 0..tt.len() {
seq.push(tt.get_tt(i));
}
- mk_tts(cx, &seq[..])
+ statements_mk_tts(cx, &seq[..], matcher)
}
ast::TtToken(sp, ref tok) => {
let e_sp = cx.expr_ident(sp, id_ext("_sp"));
let e_tok = cx.expr_call(sp,
mk_ast_path(cx, sp, "TtToken"),
- vec!(e_sp, mk_token(cx, sp, tok)));
+ vec!(e_sp, expr_mk_token(cx, sp, tok)));
let e_push =
cx.expr_method_call(sp,
cx.expr_ident(sp, id_ext("tt")),
vec!(cx.stmt_expr(e_push))
},
ast::TtDelimited(_, ref delimed) => {
- mk_tt(cx, &delimed.open_tt()).into_iter()
- .chain(delimed.tts.iter().flat_map(|tt| mk_tt(cx, tt).into_iter()))
- .chain(mk_tt(cx, &delimed.close_tt()).into_iter())
+ statements_mk_tt(cx, &delimed.open_tt(), matcher).into_iter()
+ .chain(delimed.tts.iter()
+ .flat_map(|tt| statements_mk_tt(cx, tt, matcher).into_iter()))
+ .chain(statements_mk_tt(cx, &delimed.close_tt(), matcher).into_iter())
.collect()
},
- ast::TtSequence(..) => panic!("TtSequence in quote!"),
- }
-}
+ ast::TtSequence(sp, ref seq) => {
+ if !matcher {
+ panic!("TtSequence in quote!");
+ }
-fn mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree]) -> Vec<P<ast::Stmt>> {
- let mut ss = Vec::new();
- for tt in tts {
- ss.extend(mk_tt(cx, tt).into_iter());
+ let e_sp = cx.expr_ident(sp, id_ext("_sp"));
+
+ let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
+ let mut tts_stmts = vec![stmt_let_tt];
+ tts_stmts.extend(statements_mk_tts(cx, &seq.tts[..], matcher).into_iter());
+ let e_tts = cx.expr_block(cx.block(sp, tts_stmts,
+ Some(cx.expr_ident(sp, id_ext("tt")))));
+ let e_separator = match seq.separator {
+ Some(ref sep) => cx.expr_some(sp, expr_mk_token(cx, sp, sep)),
+ None => cx.expr_none(sp),
+ };
+ let e_op = match seq.op {
+ ast::ZeroOrMore => mk_ast_path(cx, sp, "ZeroOrMore"),
+ ast::OneOrMore => mk_ast_path(cx, sp, "OneOrMore"),
+ };
+ let fields = vec![cx.field_imm(sp, id_ext("tts"), e_tts),
+ cx.field_imm(sp, id_ext("separator"), e_separator),
+ cx.field_imm(sp, id_ext("op"), e_op),
+ cx.field_imm(sp, id_ext("num_captures"),
+ cx.expr_usize(sp, seq.num_captures))];
+ let seq_path = vec![id_ext("syntax"), id_ext("ast"), id_ext("SequenceRepetition")];
+ let e_seq_struct = cx.expr_struct(sp, cx.path_global(sp, seq_path), fields);
+ let e_rc_new = cx.expr_call_global(sp, vec![id_ext("std"),
+ id_ext("rc"),
+ id_ext("Rc"),
+ id_ext("new")],
+ vec![e_seq_struct]);
+ let e_tok = cx.expr_call(sp,
+ mk_ast_path(cx, sp, "TtSequence"),
+ vec!(e_sp, e_rc_new));
+ let e_push =
+ cx.expr_method_call(sp,
+ cx.expr_ident(sp, id_ext("tt")),
+ id_ext("push"),
+ vec!(e_tok));
+ vec!(cx.stmt_expr(e_push))
+ }
}
- ss
}
-fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
- -> (P<ast::Expr>, P<ast::Expr>) {
+fn parse_arguments_to_quote(cx: &ExtCtxt, tts: &[ast::TokenTree])
+ -> (P<ast::Expr>, Vec<ast::TokenTree>) {
// NB: It appears that the main parser loses its mind if we consider
- // $foo as a TtNonterminal during the main parse, so we have to re-parse
+ // $foo as a SubstNt during the main parse, so we have to re-parse
// under quote_depth > 0. This is silly and should go away; the _guess_ is
// it has to do with transition away from supporting old-style macros, so
// try removing it when enough of them are gone.
let tts = p.parse_all_token_trees();
p.abort_if_errors();
+ (cx_expr, tts)
+}
+
+fn mk_stmts_let(cx: &ExtCtxt, sp: Span) -> Vec<P<ast::Stmt>> {
// We also bind a single value, sp, to ext_cx.call_site()
//
// This causes every span in a token-tree quote to be attributed to the
let stmt_let_tt = cx.stmt_let(sp, true, id_ext("tt"), cx.expr_vec_ng(sp));
- let mut vector = vec!(stmt_let_sp, stmt_let_tt);
- vector.extend(mk_tts(cx, &tts[..]).into_iter());
+ vec!(stmt_let_sp, stmt_let_tt)
+}
+
+fn statements_mk_tts(cx: &ExtCtxt, tts: &[ast::TokenTree], matcher: bool) -> Vec<P<ast::Stmt>> {
+ let mut ss = Vec::new();
+ for tt in tts {
+ ss.extend(statements_mk_tt(cx, tt, matcher).into_iter());
+ }
+ ss
+}
+
+fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
+ -> (P<ast::Expr>, P<ast::Expr>) {
+ let (cx_expr, tts) = parse_arguments_to_quote(cx, tts);
+
+ let mut vector = mk_stmts_let(cx, sp);
+ vector.extend(statements_mk_tts(cx, &tts[..], false).into_iter());
let block = cx.expr_block(
cx.block_all(sp,
vector,
fn expand_wrapper(cx: &ExtCtxt,
sp: Span,
cx_expr: P<ast::Expr>,
- expr: P<ast::Expr>) -> P<ast::Expr> {
+ expr: P<ast::Expr>,
+ imports: &[&[&str]]) -> P<ast::Expr> {
// Explicitly borrow to avoid moving from the invoker (#16992)
let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
- let stmts = [
- &["syntax", "ext", "quote", "rt"],
- ].iter().map(|path| {
+ let stmts = imports.iter().map(|path| {
+ // make item: `use ...;`
let path = path.iter().map(|s| s.to_string()).collect();
cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path)))
}).chain(Some(stmt_let_ext_cx).into_iter()).collect();
let expr = cx.expr_method_call(sp, new_parser_call, id_ext(parse_method),
arg_exprs);
- expand_wrapper(cx, sp, cx_expr, expr)
+ if parse_method == "parse_attribute" {
+ expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"],
+ &["syntax", "parse", "attr"]])
+ } else {
+ expand_wrapper(cx, sp, cx_expr, expr, &[&["syntax", "ext", "quote", "rt"]])
+ }
}
use ptr::P;
use util::small_vector::SmallVector;
-use std::old_io::File;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::{Path, PathBuf};
use std::rc::Rc;
// These macros all relate to the file system; they either return
cx.cfg(),
&res_rel_file(cx,
sp,
- &Path::new(file)),
+ Path::new(&file)),
true,
None,
sp);
Some(f) => f,
None => return DummyResult::expr(sp)
};
- let file = res_rel_file(cx, sp, &Path::new(file));
- let bytes = match File::open(&file).read_to_end() {
+ let file = res_rel_file(cx, sp, Path::new(&file));
+ let mut bytes = Vec::new();
+ match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
+ Ok(..) => {}
Err(e) => {
cx.span_err(sp,
&format!("couldn't read {}: {}",
e));
return DummyResult::expr(sp);
}
- Ok(bytes) => bytes,
};
match String::from_utf8(bytes) {
Ok(src) => {
Some(f) => f,
None => return DummyResult::expr(sp)
};
- let file = res_rel_file(cx, sp, &Path::new(file));
- match File::open(&file).read_to_end() {
+ let file = res_rel_file(cx, sp, Path::new(&file));
+ let mut bytes = Vec::new();
+ match File::open(&file).and_then(|mut f| f.read_to_end(&mut bytes)) {
Err(e) => {
cx.span_err(sp,
&format!("couldn't read {}: {}", file.display(), e));
return DummyResult::expr(sp);
}
- Ok(bytes) => {
- let bytes = bytes.iter().cloned().collect();
+ Ok(..) => {
base::MacEager::expr(cx.expr_lit(sp, ast::LitBinary(Rc::new(bytes))))
}
}
// resolve a file-system path to an absolute file-system path (if it
// isn't already)
-fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> Path {
+fn res_rel_file(cx: &mut ExtCtxt, sp: codemap::Span, arg: &Path) -> PathBuf {
// NB: relative paths are resolved relative to the compilation unit
if !arg.is_absolute() {
- let mut cu = Path::new(cx.codemap().span_to_filename(sp));
- cu.pop();
+ let mut cu = PathBuf::new(&cx.codemap().span_to_filename(sp));
+ if cu.parent().is_some() {
+ cu.pop();
+ } else {
+ cu = PathBuf::new("");
+ }
cu.push(arg);
cu
} else {
- arg.clone()
+ arg.to_path_buf()
}
}
ret_val
}
-pub enum ParseResult {
- Success(HashMap<Ident, Rc<NamedMatch>>),
+pub enum ParseResult<T> {
+ Success(T),
Failure(codemap::Span, String),
Error(codemap::Span, String)
}
+pub type NamedParseResult = ParseResult<HashMap<Ident, Rc<NamedMatch>>>;
+pub type PositionalParseResult = ParseResult<Vec<Rc<NamedMatch>>>;
+
pub fn parse_or_else(sess: &ParseSess,
cfg: ast::CrateConfig,
rdr: TtReader,
cfg: ast::CrateConfig,
mut rdr: TtReader,
ms: &[TokenTree])
- -> ParseResult {
+ -> NamedParseResult {
let mut cur_eis = Vec::new();
cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
.cloned()
}
rdr.next_token();
} else /* bb_eis.len() == 1 */ {
- let mut rust_parser = Parser::new(sess, cfg.clone(), box rdr.clone());
+ let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(rdr.clone()));
let mut ei = bb_eis.pop().unwrap();
match ei.top_elts.get_tt(ei.idx) {
use ext::tt::macro_parser::{Success, Error, Failure};
use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::{parse, parse_or_else};
-use parse::lexer::{new_tt_reader, new_tt_reader_with_doc_flag};
+use parse::lexer::new_tt_reader;
use parse::parser::Parser;
use parse::attr::ParserAttr;
use parse::token::{self, special_idents, gensym_ident, NtTT, Token};
TtDelimited(_, ref delim) => &delim.tts[..],
_ => cx.span_fatal(sp, "malformed macro lhs")
};
- // `None` is because we're not interpolating
- let arg_rdr = new_tt_reader_with_doc_flag(&cx.parse_sess().span_diagnostic,
- None,
- None,
- arg.iter()
- .cloned()
- .collect(),
- true);
- match parse(cx.parse_sess(), cx.cfg(), arg_rdr, lhs_tt) {
+
+ match TokenTree::parse(cx, lhs_tt, arg) {
Success(named_matches) => {
let rhs = match *rhses[i] {
// okay, what's your transcriber?
Some(named_matches),
imported_from,
rhs);
- let mut p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
+ let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
p.check_unknown_macro_variable();
// Let the context choose how to interpret the result.
// Weird, but useful for X-macros.
_ => cx.span_bug(def.span, "wrong-structured rhs")
};
- let exp = box MacroRulesMacroExpander {
+ let exp: Box<_> = box MacroRulesMacroExpander {
name: def.ident,
imported_from: def.imported_from,
lhses: lhses,
rhses: rhses,
};
- NormalTT(exp, Some(def.span))
+ NormalTT(exp, Some(def.span), def.allow_internal_unstable)
}
fn check_lhs_nt_follows(cx: &mut ExtCtxt, lhs: &NamedMatch, sp: Span) {
// stable (active).
// NB: The featureck.py script parses this information directly out of the source
// so take care when modifying it.
-static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
+const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
("globs", "1.0.0", Accepted),
("macro_rules", "1.0.0", Accepted),
("struct_variant", "1.0.0", Accepted),
// Allows the use of rustc_* attributes; RFC 572
("rustc_attrs", "1.0.0", Active),
+
+ // Allows the use of `static_assert`
+ ("static_assert", "1.0.0", Active),
+
+ // Allows the use of #[allow_internal_unstable]. This is an
+ // attribute on macro_rules! and can't use the attribute handling
+ // below (it has to be checked before expansion possibly makes
+ // macros disappear).
+ ("allow_internal_unstable", "1.0.0", Active),
];
// (changing above list without updating src/doc/reference.md makes @cmr sad)
}
// Attributes that have a special meaning to rustc or rustdoc
-pub static KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
+pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
// Normal attributes
("warn", Normal),
("no_split_stack", Whitelisted),
("no_stack_check", Whitelisted),
("packed", Whitelisted),
- ("static_assert", Whitelisted),
+ ("static_assert", Gated("static_assert",
+ "`#[static_assert]` is an experimental feature, and has a poor API")),
("no_debug", Whitelisted),
("omit_gdb_pretty_printer_section", Whitelisted),
("unsafe_no_drop_flag", Gated("unsafe_no_drop_flag",
("recursion_limit", CrateLevel),
];
-#[derive(PartialEq, Copy)]
+#[derive(PartialEq, Copy, Debug)]
pub enum AttributeType {
/// Normal, builtin attribute that is consumed
/// by the compiler before the unused_attribute check
pub allow_log_syntax: bool,
pub allow_concat_idents: bool,
pub allow_trace_macros: bool,
+ pub allow_internal_unstable: bool,
pub old_orphan_check: bool,
pub simd_ffi: bool,
pub unmarked_api: bool,
allow_log_syntax: false,
allow_concat_idents: false,
allow_trace_macros: false,
+ allow_internal_unstable: false,
old_orphan_check: false,
simd_ffi: false,
unmarked_api: false,
features: Vec<&'static str>,
span_handler: &'a SpanHandler,
cm: &'a CodeMap,
+ do_warnings: bool,
}
impl<'a> Context<'a> {
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
- if !self.has_feature(feature) {
+ let has_feature = self.has_feature(feature);
+ debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
+ if !has_feature {
emit_feature_err(self.span_handler, feature, span, explain);
}
}
fn warn_feature(&self, feature: &str, span: Span, explain: &str) {
- if !self.has_feature(feature) {
+ if !self.has_feature(feature) && self.do_warnings {
emit_feature_warn(self.span_handler, feature, span, explain);
}
}
pub fn emit_feature_err(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
diag.span_err(span, explain);
- diag.span_help(span, &format!("add #![feature({})] to the \
+ diag.fileline_help(span, &format!("add #![feature({})] to the \
crate attributes to enable",
feature));
}
pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain: &str) {
diag.span_warn(span, explain);
if diag.handler.can_emit_warnings {
- diag.span_help(span, &format!("add #![feature({})] to the \
+ diag.fileline_help(span, &format!("add #![feature({})] to the \
crate attributes to silence this warning",
feature));
}
pub const EXPLAIN_TRACE_MACROS: &'static str =
"`trace_macros` is not stable enough for use and is subject to change";
+pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &'static str =
+ "allow_internal_unstable side-steps feature gating and stability checks";
struct MacroVisitor<'a> {
context: &'a Context<'a>
self.context.gate_feature("concat_idents", path.span, EXPLAIN_CONCAT_IDENTS);
}
}
+
+ fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
+ if attr.name() == "allow_internal_unstable" {
+ self.context.gate_feature("allow_internal_unstable", attr.span,
+ EXPLAIN_ALLOW_INTERNAL_UNSTABLE)
+ }
+ }
}
struct PostExpansionVisitor<'a> {
impl<'a> PostExpansionVisitor<'a> {
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
- if !self.context.cm.span_is_internal(span) {
+ if !self.context.cm.span_allows_unstable(span) {
self.context.gate_feature(feature, span, explain)
}
}
}
fn visit_attribute(&mut self, attr: &ast::Attribute) {
+ debug!("visit_attribute(attr = {:?})", attr);
let name = &*attr.name();
for &(n, ty) in KNOWN_ATTRIBUTES {
if n == name {
if let Gated(gate, desc) = ty {
self.gate_feature(gate, attr.span, desc);
}
+ debug!("visit_attribute: {:?} is known, {:?}", name, ty);
return;
}
}
}
fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
+ do_warnings: bool,
check: F)
-> Features
where F: FnOnce(&mut Context, &ast::Crate)
let mut cx = Context {
features: Vec::new(),
span_handler: span_handler,
+ do_warnings: do_warnings,
cm: cm,
};
allow_log_syntax: cx.has_feature("log_syntax"),
allow_concat_idents: cx.has_feature("concat_idents"),
allow_trace_macros: cx.has_feature("trace_macros"),
+ allow_internal_unstable: cx.has_feature("allow_internal_unstable"),
old_orphan_check: cx.has_feature("old_orphan_check"),
simd_ffi: cx.has_feature("simd_ffi"),
unmarked_api: cx.has_feature("unmarked_api"),
pub fn check_crate_macros(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
-> Features {
- check_crate_inner(cm, span_handler, krate,
+ check_crate_inner(cm, span_handler, krate, true,
|ctx, krate| visit::walk_crate(&mut MacroVisitor { context: ctx }, krate))
}
-pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate)
--> Features {
- check_crate_inner(cm, span_handler, krate,
+pub fn check_crate(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::Crate,
+ do_warnings: bool) -> Features
+{
+ check_crate_inner(cm, span_handler, krate, do_warnings,
|ctx, krate| visit::walk_crate(&mut PostExpansionVisitor { context: ctx },
krate))
}
-
#[cfg(test)]
mod test {
- use std::old_io;
+ use std::io;
use ast;
use util::parser_testing::{string_to_crate, matches_codepattern};
use parse::token;
// this version doesn't care about getting comments or docstrings in.
fn fake_print_crate(s: &mut pprust::State,
- krate: &ast::Crate) -> old_io::IoResult<()> {
+ krate: &ast::Crate) -> io::Result<()> {
s.print_mod(&krate.module, &krate.attrs)
}
#![feature(staged_api)]
#![feature(std_misc)]
#![feature(unicode)]
+#![feature(path)]
+#![feature(io)]
+#![feature(path_ext)]
extern crate arena;
extern crate fmt_macros;
impl<T> OwnedSlice<T> {
pub fn empty() -> OwnedSlice<T> {
- OwnedSlice { data: box [] }
+ OwnedSlice { data: Box::new([]) }
}
#[inline(never)]
self.span_err(span,
"an inner attribute is not permitted in \
this context");
- self.span_help(span,
+ self.fileline_help(span,
"place inner attribute at the top of the module or block");
}
ast::AttrInner
use parse::lexer;
use print::pprust;
-use std::old_io;
+use std::io::Read;
use std::str;
-use std::string::String;
use std::usize;
#[derive(Clone, Copy, PartialEq)]
}
// one-line comments lose their prefix
- static ONLINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
- for prefix in ONLINERS {
+ const ONELINERS: &'static [&'static str] = &["///!", "///", "//!", "//"];
+ for prefix in ONELINERS {
if comment.starts_with(*prefix) {
return (&comment[prefix.len()..]).to_string();
}
// probably not a good thing.
pub fn gather_comments_and_literals(span_diagnostic: &diagnostic::SpanHandler,
path: String,
- srdr: &mut old_io::Reader)
+ srdr: &mut Read)
-> (Vec<Comment>, Vec<Literal>) {
- let src = srdr.read_to_end().unwrap();
+ let mut src = Vec::new();
+ srdr.read_to_end(&mut src).unwrap();
let src = String::from_utf8(src).unwrap();
let cm = CodeMap::new();
let filemap = cm.new_filemap(path, src);
// are revised to go directly to token-trees.
/// Is \x00<name>,<ctxt>\x00 is interpreted as encoded ast::Ident?
read_embedded_ident: bool,
+
+ // cache a direct reference to the source text, so that we don't have to
+ // retrieve it via `self.filemap.src.as_ref().unwrap()` all the time.
+ source_text: Rc<String>
}
impl<'a> Reader for StringReader<'a> {
impl<'a> StringReader<'a> {
/// For comments.rs, which hackily pokes into pos and curr
pub fn new_raw<'b>(span_diagnostic: &'b SpanHandler,
- filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
+ filemap: Rc<codemap::FileMap>) -> StringReader<'b> {
+ if filemap.src.is_none() {
+ span_diagnostic.handler.bug(&format!("Cannot lex filemap without source: {}",
+ filemap.name)[..]);
+ }
+
+ let source_text = (*filemap.src.as_ref().unwrap()).clone();
+
let mut sr = StringReader {
span_diagnostic: span_diagnostic,
pos: filemap.start_pos,
peek_tok: token::Eof,
peek_span: codemap::DUMMY_SP,
read_embedded_ident: false,
+ source_text: source_text
};
sr.bump();
sr
m.push_str(": ");
let from = self.byte_offset(from_pos).to_usize();
let to = self.byte_offset(to_pos).to_usize();
- m.push_str(&self.filemap.src[from..to]);
+ m.push_str(&self.source_text[from..to]);
self.fatal_span_(from_pos, to_pos, &m[..]);
}
fn with_str_from_to<T, F>(&self, start: BytePos, end: BytePos, f: F) -> T where
F: FnOnce(&str) -> T,
{
- f(&self.filemap.src[
- self.byte_offset(start).to_usize()..
- self.byte_offset(end).to_usize()])
+ f(&self.source_text[self.byte_offset(start).to_usize()..
+ self.byte_offset(end).to_usize()])
}
/// Converts CRLF to LF in the given string, raising an error on bare CR.
pub fn bump(&mut self) {
self.last_pos = self.pos;
let current_byte_offset = self.byte_offset(self.pos).to_usize();
- if current_byte_offset < self.filemap.src.len() {
+ if current_byte_offset < self.source_text.len() {
assert!(self.curr.is_some());
let last_char = self.curr.unwrap();
- let next = self.filemap
- .src
- .char_range_at(current_byte_offset);
+ let next = self.source_text.char_range_at(current_byte_offset);
let byte_offset_diff = next.next - current_byte_offset;
self.pos = self.pos + Pos::from_usize(byte_offset_diff);
self.curr = Some(next.ch);
pub fn nextch(&self) -> Option<char> {
let offset = self.byte_offset(self.pos).to_usize();
- if offset < self.filemap.src.len() {
- Some(self.filemap.src.char_at(offset))
+ if offset < self.source_text.len() {
+ Some(self.source_text.char_at(offset))
} else {
None
}
pub fn nextnextch(&self) -> Option<char> {
let offset = self.byte_offset(self.pos).to_usize();
- let s = &*self.filemap.src;
+ let s = &self.source_text[..];
if offset >= s.len() { return None }
let str::CharRange { next, .. } = s.char_range_at(offset);
if next < s.len() {
self.span_diagnostic
.span_warn(sp, "\\U00ABCD12 and \\uABCD escapes are deprecated");
self.span_diagnostic
- .span_help(sp, "use \\u{ABCD12} escapes instead");
+ .fileline_help(sp, "use \\u{ABCD12} escapes instead");
}
/// Scan for a single (possibly escaped) byte or char
use std::old_io::util;
fn mk_sh() -> diagnostic::SpanHandler {
- let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
- let handler = diagnostic::mk_handler(true, box emitter);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let emitter = diagnostic::EmitterWriter::new(Box::new(util::NullWriter), None);
+ let handler = diagnostic::mk_handler(true, Box::new(emitter));
diagnostic::mk_span_handler(handler, CodeMap::new())
}
use ptr::P;
use std::cell::{Cell, RefCell};
-use std::old_io::File;
-use std::rc::Rc;
+use std::fs::File;
+use std::io::Read;
+use std::iter;
use std::num::Int;
+use std::path::{Path, PathBuf};
+use std::rc::Rc;
use std::str;
-use std::iter;
#[macro_use]
pub mod parser;
pub struct ParseSess {
pub span_diagnostic: SpanHandler, // better be the same as the one in the reader!
/// Used to determine and report recursive mod inclusions
- included_mod_stack: RefCell<Vec<Path>>,
+ included_mod_stack: RefCell<Vec<PathBuf>>,
pub node_id: Cell<ast::NodeId>,
}
None => sess.span_diagnostic.handler().fatal(msg),
}
};
- let bytes = match File::open(path).read_to_end() {
- Ok(bytes) => bytes,
+ let mut bytes = Vec::new();
+ match File::open(path).and_then(|mut f| f.read_to_end(&mut bytes)) {
+ Ok(..) => {}
Err(e) => {
- err(&format!("couldn't read {:?}: {}",
- path.display(), e));
- unreachable!()
+ err(&format!("couldn't read {:?}: {}", path.display(), e));
+ unreachable!();
}
};
match str::from_utf8(&bytes[..]).ok() {
Some(s) => {
- return string_to_filemap(sess, s.to_string(),
- path.as_str().unwrap().to_string())
+ string_to_filemap(sess, s.to_string(),
+ path.to_str().unwrap().to_string())
}
None => {
- err(&format!("{:?} is not UTF-8 encoded", path.display()))
+ err(&format!("{:?} is not UTF-8 encoded", path.display()));
+ unreachable!();
}
}
- unreachable!()
}
/// Given a session and a string, add the string to
&suf[1..]));
} else {
sd.span_err(sp, &*format!("illegal suffix `{}` for numeric literal", suf));
- sd.span_help(sp, "the suffix must be one of the integral types \
+ sd.fileline_help(sp, "the suffix must be one of the integral types \
(`u32`, `isize`, etc)");
}
#[cfg(test)]
mod test {
use super::*;
+ use std::rc::Rc;
use serialize::json;
use codemap::{Span, BytePos, Pos, Spanned, NO_EXPANSION};
use owned_slice::OwnedSlice;
}
#[test]
- fn string_to_tts_1 () {
+ fn string_to_tts_1() {
let tts = string_to_tts("fn a (b : i32) { b; }".to_string());
- assert_eq!(json::encode(&tts).unwrap(),
- "[\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- {\
- \"variant\":\"Ident\",\
- \"fields\":[\
- \"fn\",\
- \"Plain\"\
- ]\
- }\
- ]\
- },\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- {\
- \"variant\":\"Ident\",\
- \"fields\":[\
- \"a\",\
- \"Plain\"\
- ]\
- }\
- ]\
- },\
- {\
- \"variant\":\"TtDelimited\",\
- \"fields\":[\
- null,\
- {\
- \"delim\":\"Paren\",\
- \"open_span\":null,\
- \"tts\":[\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- {\
- \"variant\":\"Ident\",\
- \"fields\":[\
- \"b\",\
- \"Plain\"\
- ]\
- }\
- ]\
- },\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- \"Colon\"\
- ]\
- },\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- {\
- \"variant\":\"Ident\",\
- \"fields\":[\
- \"i32\",\
- \"Plain\"\
- ]\
- }\
- ]\
- }\
- ],\
- \"close_span\":null\
- }\
- ]\
- },\
- {\
- \"variant\":\"TtDelimited\",\
- \"fields\":[\
- null,\
- {\
- \"delim\":\"Brace\",\
- \"open_span\":null,\
- \"tts\":[\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- {\
- \"variant\":\"Ident\",\
- \"fields\":[\
- \"b\",\
- \"Plain\"\
- ]\
- }\
- ]\
- },\
- {\
- \"variant\":\"TtToken\",\
- \"fields\":[\
- null,\
- \"Semi\"\
- ]\
- }\
- ],\
- \"close_span\":null\
- }\
- ]\
- }\
-]"
- );
+
+ let expected = vec![
+ ast::TtToken(sp(0, 2),
+ token::Ident(str_to_ident("fn"),
+ token::IdentStyle::Plain)),
+ ast::TtToken(sp(3, 4),
+ token::Ident(str_to_ident("a"),
+ token::IdentStyle::Plain)),
+ ast::TtDelimited(
+ sp(5, 14),
+ Rc::new(ast::Delimited {
+ delim: token::DelimToken::Paren,
+ open_span: sp(5, 6),
+ tts: vec![
+ ast::TtToken(sp(6, 7),
+ token::Ident(str_to_ident("b"),
+ token::IdentStyle::Plain)),
+ ast::TtToken(sp(8, 9),
+ token::Colon),
+ ast::TtToken(sp(10, 13),
+ token::Ident(str_to_ident("i32"),
+ token::IdentStyle::Plain)),
+ ],
+ close_span: sp(13, 14),
+ })),
+ ast::TtDelimited(
+ sp(15, 21),
+ Rc::new(ast::Delimited {
+ delim: token::DelimToken::Brace,
+ open_span: sp(15, 16),
+ tts: vec![
+ ast::TtToken(sp(17, 18),
+ token::Ident(str_to_ident("b"),
+ token::IdentStyle::Plain)),
+ ast::TtToken(sp(18, 19),
+ token::Semi)
+ ],
+ close_span: sp(20, 21),
+ }))
+ ];
+
+ assert_eq!(tts, expected);
}
#[test] fn ret_expr() {
use owned_slice::OwnedSlice;
use std::collections::HashSet;
-use std::old_io::fs::PathExtensions;
+use std::io::prelude::*;
use std::iter;
use std::mem;
use std::num::Float;
+use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::slice;
}
pub fn span_fatal_help(&self, sp: Span, m: &str, help: &str) -> ! {
self.span_err(sp, m);
- self.span_help(sp, help);
+ self.fileline_help(sp, help);
panic!(diagnostic::FatalError);
}
pub fn span_note(&self, sp: Span, m: &str) {
pub fn span_help(&self, sp: Span, m: &str) {
self.sess.span_diagnostic.span_help(sp, m)
}
+ pub fn fileline_help(&self, sp: Span, m: &str) {
+ self.sess.span_diagnostic.fileline_help(sp, m)
+ }
pub fn bug(&self, m: &str) -> ! {
self.sess.span_diagnostic.span_bug(self.span, m)
}
Some(f) => f,
None => continue,
};
- self.span_help(last_span,
+ self.fileline_help(last_span,
&format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
float.trunc() as usize,
&float.fract().to_string()[1..]));
self.span_err(op_span,
"chained comparison operators require parentheses");
if op.node == BiLt && outer_op == BiGt {
- self.span_help(op_span,
+ self.fileline_help(op_span,
"use `::<...>` instead of `<...>` if you meant to specify type arguments");
}
}
match visa {
Public => {
self.span_err(span, "can't qualify macro invocation with `pub`");
- self.span_help(span, "try adjusting the macro to put `pub` inside \
+ self.fileline_help(span, "try adjusting the macro to put `pub` inside \
the invocation");
}
Inherited => (),
outer_attrs: &[ast::Attribute],
id_sp: Span)
-> (ast::Item_, Vec<ast::Attribute> ) {
- let mut prefix = Path::new(self.sess.span_diagnostic.cm.span_to_filename(self.span));
- prefix.pop();
- let mod_path = Path::new(".").join_many(&self.mod_path_stack);
- let dir_path = prefix.join(&mod_path);
+ let mut prefix = PathBuf::new(&self.sess.span_diagnostic.cm
+ .span_to_filename(self.span));
+ // FIXME(acrichto): right now "a".pop() == "a", but need to confirm with
+ // aturon whether this is expected or not.
+ if prefix.parent().is_some() {
+ prefix.pop();
+ } else {
+ prefix = PathBuf::new("");
+ }
+ let mut dir_path = prefix;
+ for part in &self.mod_path_stack {
+ dir_path.push(&**part);
+ }
let mod_string = token::get_ident(id);
let (file_path, owns_directory) = match ::attr::first_attr_value_str_by_name(
outer_attrs, "path") {
- Some(d) => (dir_path.join(d), true),
+ Some(d) => (dir_path.join(&*d), true),
None => {
let mod_name = mod_string.to_string();
let default_path_str = format!("{}.rs", mod_name);
}
fn eval_src_mod_from_path(&mut self,
- path: Path,
+ path: PathBuf,
owns_directory: bool,
name: String,
id_sp: Span) -> (ast::Item_, Vec<ast::Attribute> ) {
let mut err = String::from_str("circular modules: ");
let len = included_mod_stack.len();
for p in &included_mod_stack[i.. len] {
- err.push_str(&p.display().as_cow());
+ err.push_str(&p.to_string_lossy());
err.push_str(" -> ");
}
- err.push_str(&path.display().as_cow());
+ err.push_str(&path.to_string_lossy());
self.span_fatal(id_sp, &err[..]);
}
None => ()
if self.token.is_ident() { self.bump(); }
self.span_err(span, "expected `;`, found `as`");
- self.span_help(span,
+ self.fileline_help(span,
&format!("perhaps you meant to enclose the crate name `{}` in \
a string?",
the_ident.as_str()));
if self.eat_keyword(keywords::Mut) {
let last_span = self.last_span;
self.span_err(last_span, "const globals cannot be mutable");
- self.span_help(last_span, "did you mean to declare a static?");
+ self.fileline_help(last_span, "did you mean to declare a static?");
}
let (ident, item_, extra_attrs) = self.parse_item_const(None);
let last_span = self.last_span;
$( ($rk_name:expr, $rk_variant:ident, $rk_str:expr); )*
}
) => {
- static STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
- static STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
- static RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
- static RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
+ const STRICT_KEYWORD_START: ast::Name = first!($( ast::Name($sk_name), )*);
+ const STRICT_KEYWORD_FINAL: ast::Name = last!($( ast::Name($sk_name), )*);
+ const RESERVED_KEYWORD_START: ast::Name = first!($( ast::Name($rk_name), )*);
+ const RESERVED_KEYWORD_FINAL: ast::Name = last!($( ast::Name($rk_name), )*);
pub mod special_idents {
use ast;
//! line (which it can't) and so naturally place the content on its own line to
//! avoid combining it with other lines and making matters even worse.
-use std::old_io;
+use std::io;
use std::string;
use std::iter::repeat;
pbreak: PrintStackBreak
}
-static SIZE_INFINITY: isize = 0xffff;
+const SIZE_INFINITY: isize = 0xffff;
-pub fn mk_printer(out: Box<old_io::Writer+'static>, linewidth: usize) -> Printer {
+pub fn mk_printer<'a>(out: Box<io::Write+'a>, linewidth: usize) -> Printer<'a> {
// Yes 3, it makes the ring buffers big enough to never
// fall behind.
let n: usize = 3 * linewidth;
/// In this implementation (following the paper, again) the SCAN process is
/// the method called 'pretty_print', and the 'PRINT' process is the method
/// called 'print'.
-pub struct Printer {
- pub out: Box<old_io::Writer+'static>,
+pub struct Printer<'a> {
+ pub out: Box<io::Write+'a>,
buf_len: usize,
/// Width of lines we're constrained to
margin: isize,
pending_indentation: isize,
}
-impl Printer {
+impl<'a> Printer<'a> {
pub fn last_token(&mut self) -> Token {
self.token[self.right].clone()
}
pub fn replace_last_token(&mut self, t: Token) {
self.token[self.right] = t;
}
- pub fn pretty_print(&mut self, token: Token) -> old_io::IoResult<()> {
+ pub fn pretty_print(&mut self, token: Token) -> io::Result<()> {
debug!("pp ~[{},{}]", self.left, self.right);
match token {
Token::Eof => {
}
}
}
- pub fn check_stream(&mut self) -> old_io::IoResult<()> {
+ pub fn check_stream(&mut self) -> io::Result<()> {
debug!("check_stream ~[{}, {}] with left_total={}, right_total={}",
self.left, self.right, self.left_total, self.right_total);
if self.right_total - self.left_total > self.space {
self.right %= self.buf_len;
assert!((self.right != self.left));
}
- pub fn advance_left(&mut self) -> old_io::IoResult<()> {
+ pub fn advance_left(&mut self) -> io::Result<()> {
debug!("advance_left ~[{},{}], sizeof({})={}", self.left, self.right,
self.left, self.size[self.left]);
}
}
}
- pub fn print_newline(&mut self, amount: isize) -> old_io::IoResult<()> {
+ pub fn print_newline(&mut self, amount: isize) -> io::Result<()> {
debug!("NEWLINE {}", amount);
let ret = write!(self.out, "\n");
self.pending_indentation = 0;
}
}
}
- pub fn print_str(&mut self, s: &str) -> old_io::IoResult<()> {
+ pub fn print_str(&mut self, s: &str) -> io::Result<()> {
while self.pending_indentation > 0 {
try!(write!(self.out, " "));
self.pending_indentation -= 1;
}
write!(self.out, "{}", s)
}
- pub fn print(&mut self, token: Token, l: isize) -> old_io::IoResult<()> {
+ pub fn print(&mut self, token: Token, l: isize) -> io::Result<()> {
debug!("print {} {} (remaining line space={})", tok_str(&token), l,
self.space);
debug!("{}", buf_str(&self.token,
// Convenience functions to talk to the printer.
//
// "raw box"
-pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> old_io::IoResult<()> {
+pub fn rbox(p: &mut Printer, indent: usize, b: Breaks) -> io::Result<()> {
p.pretty_print(Token::Begin(BeginToken {
offset: indent as isize,
breaks: b
}))
}
-pub fn ibox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
+pub fn ibox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Inconsistent)
}
-pub fn cbox(p: &mut Printer, indent: usize) -> old_io::IoResult<()> {
+pub fn cbox(p: &mut Printer, indent: usize) -> io::Result<()> {
rbox(p, indent, Breaks::Consistent)
}
-pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> old_io::IoResult<()> {
+pub fn break_offset(p: &mut Printer, n: usize, off: isize) -> io::Result<()> {
p.pretty_print(Token::Break(BreakToken {
offset: off,
blank_space: n as isize
}))
}
-pub fn end(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn end(p: &mut Printer) -> io::Result<()> {
p.pretty_print(Token::End)
}
-pub fn eof(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn eof(p: &mut Printer) -> io::Result<()> {
p.pretty_print(Token::Eof)
}
-pub fn word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), wrd.len() as isize))
}
-pub fn huge_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn huge_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), SIZE_INFINITY))
}
-pub fn zero_word(p: &mut Printer, wrd: &str) -> old_io::IoResult<()> {
+pub fn zero_word(p: &mut Printer, wrd: &str) -> io::Result<()> {
p.pretty_print(Token::String(/* bad */ wrd.to_string(), 0))
}
-pub fn spaces(p: &mut Printer, n: usize) -> old_io::IoResult<()> {
+pub fn spaces(p: &mut Printer, n: usize) -> io::Result<()> {
break_offset(p, n, 0)
}
-pub fn zerobreak(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn zerobreak(p: &mut Printer) -> io::Result<()> {
spaces(p, 0)
}
-pub fn space(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn space(p: &mut Printer) -> io::Result<()> {
spaces(p, 1)
}
-pub fn hardbreak(p: &mut Printer) -> old_io::IoResult<()> {
+pub fn hardbreak(p: &mut Printer) -> io::Result<()> {
spaces(p, SIZE_INFINITY as usize)
}
use std_inject;
use std::{ascii, mem};
-use std::old_io::{self, IoResult};
+use std::io::{self, Write, Read};
use std::iter;
pub enum AnnNode<'a> {
}
pub trait PpAnn {
- fn pre(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
- fn post(&self, _state: &mut State, _node: AnnNode) -> IoResult<()> { Ok(()) }
+ fn pre(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
+ fn post(&self, _state: &mut State, _node: AnnNode) -> io::Result<()> { Ok(()) }
}
#[derive(Copy)]
}
pub struct State<'a> {
- pub s: pp::Printer,
+ pub s: pp::Printer<'a>,
cm: Option<&'a CodeMap>,
comments: Option<Vec<comments::Comment> >,
literals: Option<Vec<comments::Literal> >,
encode_idents_with_hygiene: bool,
}
-pub fn rust_printer(writer: Box<old_io::Writer+'static>) -> State<'static> {
+pub fn rust_printer<'a>(writer: Box<Write+'a>) -> State<'a> {
static NO_ANN: NoAnn = NoAnn;
rust_printer_annotated(writer, &NO_ANN)
}
-pub fn rust_printer_annotated<'a>(writer: Box<old_io::Writer+'static>,
+pub fn rust_printer_annotated<'a>(writer: Box<Write+'a>,
ann: &'a PpAnn) -> State<'a> {
State {
s: pp::mk_printer(writer, default_columns),
span_diagnostic: &diagnostic::SpanHandler,
krate: &ast::Crate,
filename: String,
- input: &mut old_io::Reader,
- out: Box<old_io::Writer+'static>,
+ input: &mut Read,
+ out: Box<Write+'a>,
ann: &'a PpAnn,
- is_expanded: bool) -> IoResult<()> {
+ is_expanded: bool) -> io::Result<()> {
let mut s = State::new_from_input(cm,
span_diagnostic,
filename,
pub fn new_from_input(cm: &'a CodeMap,
span_diagnostic: &diagnostic::SpanHandler,
filename: String,
- input: &mut old_io::Reader,
- out: Box<old_io::Writer+'static>,
+ input: &mut Read,
+ out: Box<Write+'a>,
ann: &'a PpAnn,
is_expanded: bool) -> State<'a> {
let (cmnts, lits) = comments::gather_comments_and_literals(
}
pub fn new(cm: &'a CodeMap,
- out: Box<old_io::Writer+'static>,
+ out: Box<Write+'a>,
ann: &'a PpAnn,
comments: Option<Vec<comments::Comment>>,
literals: Option<Vec<comments::Literal>>) -> State<'a> {
}
pub fn to_string<F>(f: F) -> String where
- F: FnOnce(&mut State) -> IoResult<()>,
+ F: FnOnce(&mut State) -> io::Result<()>,
{
use std::raw::TraitObject;
let mut s = rust_printer(box Vec::new());
f(&mut s).unwrap();
eof(&mut s.s).unwrap();
let wr = unsafe {
- // FIXME(pcwalton): A nasty function to extract the string from an `old_io::Writer`
+ // FIXME(pcwalton): A nasty function to extract the string from an `Write`
// that we "know" to be a `Vec<u8>` that works around the lack of checked
// downcasts.
let obj: &TraitObject = mem::transmute(&s.s.out);
pub mod with_hygiene {
use abi;
use ast;
- use std::old_io::IoResult;
+ use std::io;
use super::indent_unit;
// This function is the trick that all the rest of the routines
// hang on.
pub fn to_string_hyg<F>(f: F) -> String where
- F: FnOnce(&mut super::State) -> IoResult<()>,
+ F: FnOnce(&mut super::State) -> io::Result<()>,
{
super::to_string(move |s| {
s.encode_idents_with_hygiene = true;
}
impl<'a> State<'a> {
- pub fn ibox(&mut self, u: usize) -> IoResult<()> {
+ pub fn ibox(&mut self, u: usize) -> io::Result<()> {
self.boxes.push(pp::Breaks::Inconsistent);
pp::ibox(&mut self.s, u)
}
- pub fn end(&mut self) -> IoResult<()> {
+ pub fn end(&mut self) -> io::Result<()> {
self.boxes.pop().unwrap();
pp::end(&mut self.s)
}
- pub fn cbox(&mut self, u: usize) -> IoResult<()> {
+ pub fn cbox(&mut self, u: usize) -> io::Result<()> {
self.boxes.push(pp::Breaks::Consistent);
pp::cbox(&mut self.s, u)
}
// "raw box"
- pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> IoResult<()> {
+ pub fn rbox(&mut self, u: usize, b: pp::Breaks) -> io::Result<()> {
self.boxes.push(b);
pp::rbox(&mut self.s, u, b)
}
- pub fn nbsp(&mut self) -> IoResult<()> { word(&mut self.s, " ") }
+ pub fn nbsp(&mut self) -> io::Result<()> { word(&mut self.s, " ") }
- pub fn word_nbsp(&mut self, w: &str) -> IoResult<()> {
+ pub fn word_nbsp(&mut self, w: &str) -> io::Result<()> {
try!(word(&mut self.s, w));
self.nbsp()
}
- pub fn word_space(&mut self, w: &str) -> IoResult<()> {
+ pub fn word_space(&mut self, w: &str) -> io::Result<()> {
try!(word(&mut self.s, w));
space(&mut self.s)
}
- pub fn popen(&mut self) -> IoResult<()> { word(&mut self.s, "(") }
+ pub fn popen(&mut self) -> io::Result<()> { word(&mut self.s, "(") }
- pub fn pclose(&mut self) -> IoResult<()> { word(&mut self.s, ")") }
+ pub fn pclose(&mut self) -> io::Result<()> { word(&mut self.s, ")") }
- pub fn head(&mut self, w: &str) -> IoResult<()> {
+ pub fn head(&mut self, w: &str) -> io::Result<()> {
// outer-box is consistent
try!(self.cbox(indent_unit));
// head-box is inconsistent
Ok(())
}
- pub fn bopen(&mut self) -> IoResult<()> {
+ pub fn bopen(&mut self) -> io::Result<()> {
try!(word(&mut self.s, "{"));
self.end() // close the head-box
}
pub fn bclose_(&mut self, span: codemap::Span,
- indented: usize) -> IoResult<()> {
+ indented: usize) -> io::Result<()> {
self.bclose_maybe_open(span, indented, true)
}
pub fn bclose_maybe_open (&mut self, span: codemap::Span,
- indented: usize, close_box: bool) -> IoResult<()> {
+ indented: usize, close_box: bool) -> io::Result<()> {
try!(self.maybe_print_comment(span.hi));
try!(self.break_offset_if_not_bol(1, -(indented as isize)));
try!(word(&mut self.s, "}"));
}
Ok(())
}
- pub fn bclose(&mut self, span: codemap::Span) -> IoResult<()> {
+ pub fn bclose(&mut self, span: codemap::Span) -> io::Result<()> {
self.bclose_(span, indent_unit)
}
}
}
- pub fn hardbreak_if_not_bol(&mut self) -> IoResult<()> {
+ pub fn hardbreak_if_not_bol(&mut self) -> io::Result<()> {
if !self.is_bol() {
try!(hardbreak(&mut self.s))
}
Ok(())
}
- pub fn space_if_not_bol(&mut self) -> IoResult<()> {
+ pub fn space_if_not_bol(&mut self) -> io::Result<()> {
if !self.is_bol() { try!(space(&mut self.s)); }
Ok(())
}
pub fn break_offset_if_not_bol(&mut self, n: usize,
- off: isize) -> IoResult<()> {
+ off: isize) -> io::Result<()> {
if !self.is_bol() {
break_offset(&mut self.s, n, off)
} else {
// Synthesizes a comment that was not textually present in the original source
// file.
- pub fn synth_comment(&mut self, text: String) -> IoResult<()> {
+ pub fn synth_comment(&mut self, text: String) -> io::Result<()> {
try!(word(&mut self.s, "/*"));
try!(space(&mut self.s));
try!(word(&mut self.s, &text[..]));
word(&mut self.s, "*/")
}
- pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> IoResult<()> where
- F: FnMut(&mut State, &T) -> IoResult<()>,
+ pub fn commasep<T, F>(&mut self, b: Breaks, elts: &[T], mut op: F) -> io::Result<()> where
+ F: FnMut(&mut State, &T) -> io::Result<()>,
{
try!(self.rbox(0, b));
let mut first = true;
b: Breaks,
elts: &[T],
mut op: F,
- mut get_span: G) -> IoResult<()> where
- F: FnMut(&mut State, &T) -> IoResult<()>,
+ mut get_span: G) -> io::Result<()> where
+ F: FnMut(&mut State, &T) -> io::Result<()>,
G: FnMut(&T) -> codemap::Span,
{
try!(self.rbox(0, b));
}
pub fn commasep_exprs(&mut self, b: Breaks,
- exprs: &[P<ast::Expr>]) -> IoResult<()> {
+ exprs: &[P<ast::Expr>]) -> io::Result<()> {
self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&**e), |e| e.span)
}
pub fn print_mod(&mut self, _mod: &ast::Mod,
- attrs: &[ast::Attribute]) -> IoResult<()> {
+ attrs: &[ast::Attribute]) -> io::Result<()> {
try!(self.print_inner_attributes(attrs));
for item in &_mod.items {
try!(self.print_item(&**item));
}
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
- attrs: &[ast::Attribute]) -> IoResult<()> {
+ attrs: &[ast::Attribute]) -> io::Result<()> {
try!(self.print_inner_attributes(attrs));
for item in &nmod.items {
try!(self.print_foreign_item(&**item));
}
pub fn print_opt_lifetime(&mut self,
- lifetime: &Option<ast::Lifetime>) -> IoResult<()> {
+ lifetime: &Option<ast::Lifetime>) -> io::Result<()> {
if let Some(l) = *lifetime {
try!(self.print_lifetime(&l));
try!(self.nbsp());
Ok(())
}
- pub fn print_type(&mut self, ty: &ast::Ty) -> IoResult<()> {
+ pub fn print_type(&mut self, ty: &ast::Ty) -> io::Result<()> {
try!(self.maybe_print_comment(ty.span.lo));
try!(self.ibox(0));
match ty.node {
}
pub fn print_foreign_item(&mut self,
- item: &ast::ForeignItem) -> IoResult<()> {
+ item: &ast::ForeignItem) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(item.span.lo));
try!(self.print_outer_attributes(&item.attrs));
}
fn print_associated_type(&mut self, typedef: &ast::AssociatedType)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(self.print_outer_attributes(&typedef.attrs));
try!(self.word_space("type"));
word(&mut self.s, ";")
}
- fn print_typedef(&mut self, typedef: &ast::Typedef) -> IoResult<()> {
+ fn print_typedef(&mut self, typedef: &ast::Typedef) -> io::Result<()> {
try!(self.word_space("type"));
try!(self.print_ident(typedef.ident));
try!(space(&mut self.s));
}
/// Pretty-print an item
- pub fn print_item(&mut self, item: &ast::Item) -> IoResult<()> {
+ pub fn print_item(&mut self, item: &ast::Item) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(item.span.lo));
try!(self.print_outer_attributes(&item.attrs));
self.ann.post(self, NodeItem(item))
}
- fn print_trait_ref(&mut self, t: &ast::TraitRef) -> IoResult<()> {
+ fn print_trait_ref(&mut self, t: &ast::TraitRef) -> io::Result<()> {
self.print_path(&t.path, false, 0)
}
- fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> IoResult<()> {
+ fn print_formal_lifetime_list(&mut self, lifetimes: &[ast::LifetimeDef]) -> io::Result<()> {
if !lifetimes.is_empty() {
try!(word(&mut self.s, "for<"));
let mut comma = false;
Ok(())
}
- fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> IoResult<()> {
+ fn print_poly_trait_ref(&mut self, t: &ast::PolyTraitRef) -> io::Result<()> {
try!(self.print_formal_lifetime_list(&t.bound_lifetimes));
self.print_trait_ref(&t.trait_ref)
}
pub fn print_enum_def(&mut self, enum_definition: &ast::EnumDef,
generics: &ast::Generics, ident: ast::Ident,
span: codemap::Span,
- visibility: ast::Visibility) -> IoResult<()> {
+ visibility: ast::Visibility) -> io::Result<()> {
try!(self.head(&visibility_qualified(visibility, "enum")));
try!(self.print_ident(ident));
try!(self.print_generics(generics));
pub fn print_variants(&mut self,
variants: &[P<ast::Variant>],
- span: codemap::Span) -> IoResult<()> {
+ span: codemap::Span) -> io::Result<()> {
try!(self.bopen());
for v in variants {
try!(self.space_if_not_bol());
self.bclose(span)
}
- pub fn print_visibility(&mut self, vis: ast::Visibility) -> IoResult<()> {
+ pub fn print_visibility(&mut self, vis: ast::Visibility) -> io::Result<()> {
match vis {
ast::Public => self.word_nbsp("pub"),
ast::Inherited => Ok(())
struct_def: &ast::StructDef,
generics: &ast::Generics,
ident: ast::Ident,
- span: codemap::Span) -> IoResult<()> {
+ span: codemap::Span) -> io::Result<()> {
try!(self.print_ident(ident));
try!(self.print_generics(generics));
if ast_util::struct_def_is_tuple_like(struct_def) {
/// appropriate macro, transcribe back into the grammar we just parsed from,
/// and then pretty-print the resulting AST nodes (so, e.g., we print
/// expression arguments as expressions). It can be done! I think.
- pub fn print_tt(&mut self, tt: &ast::TokenTree) -> IoResult<()> {
+ pub fn print_tt(&mut self, tt: &ast::TokenTree) -> io::Result<()> {
match *tt {
ast::TtToken(_, ref tk) => {
try!(word(&mut self.s, &token_to_string(tk)));
}
}
- pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> IoResult<()> {
+ pub fn print_tts(&mut self, tts: &[ast::TokenTree]) -> io::Result<()> {
try!(self.ibox(0));
let mut suppress_space = false;
for (i, tt) in tts.iter().enumerate() {
self.end()
}
- pub fn print_variant(&mut self, v: &ast::Variant) -> IoResult<()> {
+ pub fn print_variant(&mut self, v: &ast::Variant) -> io::Result<()> {
try!(self.print_visibility(v.node.vis));
match v.node.kind {
ast::TupleVariantKind(ref args) => {
}
}
- pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> IoResult<()> {
+ pub fn print_ty_method(&mut self, m: &ast::TypeMethod) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(m.span.lo));
try!(self.print_outer_attributes(&m.attrs));
}
pub fn print_trait_method(&mut self,
- m: &ast::TraitItem) -> IoResult<()> {
+ m: &ast::TraitItem) -> io::Result<()> {
match *m {
RequiredMethod(ref ty_m) => self.print_ty_method(ty_m),
ProvidedMethod(ref m) => self.print_method(&**m),
}
}
- pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> IoResult<()> {
+ pub fn print_impl_item(&mut self, ii: &ast::ImplItem) -> io::Result<()> {
match *ii {
MethodImplItem(ref m) => self.print_method(&**m),
TypeImplItem(ref td) => self.print_typedef(&**td),
}
}
- pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
+ pub fn print_method(&mut self, meth: &ast::Method) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(meth.span.lo));
try!(self.print_outer_attributes(&meth.attrs));
}
pub fn print_outer_attributes(&mut self,
- attrs: &[ast::Attribute]) -> IoResult<()> {
+ attrs: &[ast::Attribute]) -> io::Result<()> {
let mut count = 0;
for attr in attrs {
match attr.node.style {
}
pub fn print_inner_attributes(&mut self,
- attrs: &[ast::Attribute]) -> IoResult<()> {
+ attrs: &[ast::Attribute]) -> io::Result<()> {
let mut count = 0;
for attr in attrs {
match attr.node.style {
Ok(())
}
- pub fn print_attribute(&mut self, attr: &ast::Attribute) -> IoResult<()> {
+ pub fn print_attribute(&mut self, attr: &ast::Attribute) -> io::Result<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(attr.span.lo));
if attr.node.is_sugared_doc {
}
- pub fn print_stmt(&mut self, st: &ast::Stmt) -> IoResult<()> {
+ pub fn print_stmt(&mut self, st: &ast::Stmt) -> io::Result<()> {
try!(self.maybe_print_comment(st.span.lo));
match st.node {
ast::StmtDecl(ref decl, _) => {
self.maybe_print_trailing_comment(st.span, None)
}
- pub fn print_block(&mut self, blk: &ast::Block) -> IoResult<()> {
+ pub fn print_block(&mut self, blk: &ast::Block) -> io::Result<()> {
self.print_block_with_attrs(blk, &[])
}
- pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> IoResult<()> {
+ pub fn print_block_unclosed(&mut self, blk: &ast::Block) -> io::Result<()> {
self.print_block_unclosed_indent(blk, indent_unit)
}
pub fn print_block_unclosed_indent(&mut self, blk: &ast::Block,
- indented: usize) -> IoResult<()> {
+ indented: usize) -> io::Result<()> {
self.print_block_maybe_unclosed(blk, indented, &[], false)
}
pub fn print_block_with_attrs(&mut self,
blk: &ast::Block,
- attrs: &[ast::Attribute]) -> IoResult<()> {
+ attrs: &[ast::Attribute]) -> io::Result<()> {
self.print_block_maybe_unclosed(blk, indent_unit, attrs, true)
}
blk: &ast::Block,
indented: usize,
attrs: &[ast::Attribute],
- close_box: bool) -> IoResult<()> {
+ close_box: bool) -> io::Result<()> {
match blk.rules {
ast::UnsafeBlock(..) => try!(self.word_space("unsafe")),
ast::DefaultBlock => ()
self.ann.post(self, NodeBlock(blk))
}
- fn print_else(&mut self, els: Option<&ast::Expr>) -> IoResult<()> {
+ fn print_else(&mut self, els: Option<&ast::Expr>) -> io::Result<()> {
match els {
Some(_else) => {
match _else.node {
}
pub fn print_if(&mut self, test: &ast::Expr, blk: &ast::Block,
- elseopt: Option<&ast::Expr>) -> IoResult<()> {
+ elseopt: Option<&ast::Expr>) -> io::Result<()> {
try!(self.head("if"));
try!(self.print_expr(test));
try!(space(&mut self.s));
}
pub fn print_if_let(&mut self, pat: &ast::Pat, expr: &ast::Expr, blk: &ast::Block,
- elseopt: Option<&ast::Expr>) -> IoResult<()> {
+ elseopt: Option<&ast::Expr>) -> io::Result<()> {
try!(self.head("if let"));
try!(self.print_pat(pat));
try!(space(&mut self.s));
}
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
- -> IoResult<()> {
+ -> io::Result<()> {
match m.node {
// I think it's reasonable to hide the ctxt here:
ast::MacInvocTT(ref pth, ref tts, _) => {
}
- fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> IoResult<()> {
+ fn print_call_post(&mut self, args: &[P<ast::Expr>]) -> io::Result<()> {
try!(self.popen());
try!(self.commasep_exprs(Inconsistent, args));
self.pclose()
}
- pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> IoResult<()> {
+ pub fn print_expr_maybe_paren(&mut self, expr: &ast::Expr) -> io::Result<()> {
let needs_par = needs_parentheses(expr);
if needs_par {
try!(self.popen());
fn print_expr_box(&mut self,
place: &Option<P<ast::Expr>>,
- expr: &ast::Expr) -> IoResult<()> {
+ expr: &ast::Expr) -> io::Result<()> {
try!(word(&mut self.s, "box"));
try!(word(&mut self.s, "("));
try!(place.as_ref().map_or(Ok(()), |e|self.print_expr(&**e)));
self.print_expr(expr)
}
- fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+ fn print_expr_vec(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
try!(self.ibox(indent_unit));
try!(word(&mut self.s, "["));
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
fn print_expr_repeat(&mut self,
element: &ast::Expr,
- count: &ast::Expr) -> IoResult<()> {
+ count: &ast::Expr) -> io::Result<()> {
try!(self.ibox(indent_unit));
try!(word(&mut self.s, "["));
try!(self.print_expr(element));
fn print_expr_struct(&mut self,
path: &ast::Path,
fields: &[ast::Field],
- wth: &Option<P<ast::Expr>>) -> IoResult<()> {
+ wth: &Option<P<ast::Expr>>) -> io::Result<()> {
try!(self.print_path(path, true, 0));
if !(fields.is_empty() && wth.is_none()) {
try!(word(&mut self.s, "{"));
Ok(())
}
- fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> IoResult<()> {
+ fn print_expr_tup(&mut self, exprs: &[P<ast::Expr>]) -> io::Result<()> {
try!(self.popen());
try!(self.commasep_exprs(Inconsistent, &exprs[..]));
if exprs.len() == 1 {
fn print_expr_call(&mut self,
func: &ast::Expr,
- args: &[P<ast::Expr>]) -> IoResult<()> {
+ args: &[P<ast::Expr>]) -> io::Result<()> {
try!(self.print_expr_maybe_paren(func));
self.print_call_post(args)
}
fn print_expr_method_call(&mut self,
ident: ast::SpannedIdent,
tys: &[P<ast::Ty>],
- args: &[P<ast::Expr>]) -> IoResult<()> {
+ args: &[P<ast::Expr>]) -> io::Result<()> {
let base_args = &args[1..];
try!(self.print_expr(&*args[0]));
try!(word(&mut self.s, "."));
fn print_expr_binary(&mut self,
op: ast::BinOp,
lhs: &ast::Expr,
- rhs: &ast::Expr) -> IoResult<()> {
+ rhs: &ast::Expr) -> io::Result<()> {
try!(self.print_expr(lhs));
try!(space(&mut self.s));
try!(self.word_space(ast_util::binop_to_string(op.node)));
fn print_expr_unary(&mut self,
op: ast::UnOp,
- expr: &ast::Expr) -> IoResult<()> {
+ expr: &ast::Expr) -> io::Result<()> {
try!(word(&mut self.s, ast_util::unop_to_string(op)));
self.print_expr_maybe_paren(expr)
}
fn print_expr_addr_of(&mut self,
mutability: ast::Mutability,
- expr: &ast::Expr) -> IoResult<()> {
+ expr: &ast::Expr) -> io::Result<()> {
try!(word(&mut self.s, "&"));
try!(self.print_mutability(mutability));
self.print_expr_maybe_paren(expr)
}
- pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
+ pub fn print_expr(&mut self, expr: &ast::Expr) -> io::Result<()> {
try!(self.maybe_print_comment(expr.span.lo));
try!(self.ibox(indent_unit));
try!(self.ann.pre(self, NodeExpr(expr)));
self.end()
}
- pub fn print_local_decl(&mut self, loc: &ast::Local) -> IoResult<()> {
+ pub fn print_local_decl(&mut self, loc: &ast::Local) -> io::Result<()> {
try!(self.print_pat(&*loc.pat));
if let Some(ref ty) = loc.ty {
try!(self.word_space(":"));
Ok(())
}
- pub fn print_decl(&mut self, decl: &ast::Decl) -> IoResult<()> {
+ pub fn print_decl(&mut self, decl: &ast::Decl) -> io::Result<()> {
try!(self.maybe_print_comment(decl.span.lo));
match decl.node {
ast::DeclLocal(ref loc) => {
}
}
- pub fn print_ident(&mut self, ident: ast::Ident) -> IoResult<()> {
+ pub fn print_ident(&mut self, ident: ast::Ident) -> io::Result<()> {
if self.encode_idents_with_hygiene {
let encoded = ident.encode_with_hygiene();
try!(word(&mut self.s, &encoded[..]))
self.ann.post(self, NodeIdent(&ident))
}
- pub fn print_usize(&mut self, i: usize) -> IoResult<()> {
+ pub fn print_usize(&mut self, i: usize) -> io::Result<()> {
word(&mut self.s, &i.to_string())
}
- pub fn print_name(&mut self, name: ast::Name) -> IoResult<()> {
+ pub fn print_name(&mut self, name: ast::Name) -> io::Result<()> {
try!(word(&mut self.s, &token::get_name(name)));
self.ann.post(self, NodeName(&name))
}
pub fn print_for_decl(&mut self, loc: &ast::Local,
- coll: &ast::Expr) -> IoResult<()> {
+ coll: &ast::Expr) -> io::Result<()> {
try!(self.print_local_decl(loc));
try!(space(&mut self.s));
try!(self.word_space("in"));
path: &ast::Path,
colons_before_params: bool,
depth: usize)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(self.maybe_print_comment(path.span.lo));
path: &ast::Path,
qself: &ast::QSelf,
colons_before_params: bool)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(word(&mut self.s, "<"));
try!(self.print_type(&qself.ty));
fn print_path_parameters(&mut self,
parameters: &ast::PathParameters,
colons_before_params: bool)
- -> IoResult<()>
+ -> io::Result<()>
{
if parameters.is_empty() {
return Ok(());
Ok(())
}
- pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
+ pub fn print_pat(&mut self, pat: &ast::Pat) -> io::Result<()> {
try!(self.maybe_print_comment(pat.span.lo));
try!(self.ann.pre(self, NodePat(pat)));
/* Pat isn't normalized, but the beauty of it
self.ann.post(self, NodePat(pat))
}
- fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
+ fn print_arm(&mut self, arm: &ast::Arm) -> io::Result<()> {
// I have no idea why this check is necessary, but here it
// is :(
if arm.attrs.is_empty() {
// Returns whether it printed anything
fn print_explicit_self(&mut self,
explicit_self: &ast::ExplicitSelf_,
- mutbl: ast::Mutability) -> IoResult<bool> {
+ mutbl: ast::Mutability) -> io::Result<bool> {
try!(self.print_mutability(mutbl));
match *explicit_self {
ast::SelfStatic => { return Ok(false); }
name: ast::Ident,
generics: &ast::Generics,
opt_explicit_self: Option<&ast::ExplicitSelf_>,
- vis: ast::Visibility) -> IoResult<()> {
+ vis: ast::Visibility) -> io::Result<()> {
try!(self.head(""));
try!(self.print_fn_header_info(unsafety, abi, vis));
try!(self.nbsp());
pub fn print_fn_args(&mut self, decl: &ast::FnDecl,
opt_explicit_self: Option<&ast::ExplicitSelf_>)
- -> IoResult<()> {
+ -> io::Result<()> {
// It is unfortunate to duplicate the commasep logic, but we want the
// self type and the args all in the same box.
try!(self.rbox(0, Inconsistent));
pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
opt_explicit_self: Option<&ast::ExplicitSelf_>)
- -> IoResult<()> {
+ -> io::Result<()> {
try!(self.popen());
try!(self.print_fn_args(decl, opt_explicit_self));
if decl.variadic {
pub fn print_fn_block_args(
&mut self,
decl: &ast::FnDecl)
- -> IoResult<()> {
+ -> io::Result<()> {
try!(word(&mut self.s, "|"));
try!(self.print_fn_args(decl, None));
try!(word(&mut self.s, "|"));
}
pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause)
- -> IoResult<()> {
+ -> io::Result<()> {
match capture_clause {
ast::CaptureByValue => self.word_space("move"),
ast::CaptureByRef => Ok(()),
pub fn print_bounds(&mut self,
prefix: &str,
bounds: &[ast::TyParamBound])
- -> IoResult<()> {
+ -> io::Result<()> {
if !bounds.is_empty() {
try!(word(&mut self.s, prefix));
let mut first = true;
pub fn print_lifetime(&mut self,
lifetime: &ast::Lifetime)
- -> IoResult<()>
+ -> io::Result<()>
{
self.print_name(lifetime.name)
}
pub fn print_lifetime_def(&mut self,
lifetime: &ast::LifetimeDef)
- -> IoResult<()>
+ -> io::Result<()>
{
try!(self.print_lifetime(&lifetime.lifetime));
let mut sep = ":";
pub fn print_generics(&mut self,
generics: &ast::Generics)
- -> IoResult<()>
+ -> io::Result<()>
{
let total = generics.lifetimes.len() + generics.ty_params.len();
if total == 0 {
Ok(())
}
- pub fn print_ty_param(&mut self, param: &ast::TyParam) -> IoResult<()> {
+ pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
try!(self.print_ident(param.ident));
try!(self.print_bounds(":", ¶m.bounds));
match param.default {
}
pub fn print_where_clause(&mut self, generics: &ast::Generics)
- -> IoResult<()> {
+ -> io::Result<()> {
if generics.where_clause.predicates.len() == 0 {
return Ok(())
}
Ok(())
}
- pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> IoResult<()> {
+ pub fn print_meta_item(&mut self, item: &ast::MetaItem) -> io::Result<()> {
try!(self.ibox(indent_unit));
match item.node {
ast::MetaWord(ref name) => {
self.end()
}
- pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
+ pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> io::Result<()> {
match vp.node {
ast::ViewPathSimple(ident, ref path) => {
try!(self.print_path(path, false, 0));
}
pub fn print_mutability(&mut self,
- mutbl: ast::Mutability) -> IoResult<()> {
+ mutbl: ast::Mutability) -> io::Result<()> {
match mutbl {
ast::MutMutable => self.word_nbsp("mut"),
ast::MutImmutable => Ok(()),
}
}
- pub fn print_mt(&mut self, mt: &ast::MutTy) -> IoResult<()> {
+ pub fn print_mt(&mut self, mt: &ast::MutTy) -> io::Result<()> {
try!(self.print_mutability(mt.mutbl));
self.print_type(&*mt.ty)
}
- pub fn print_arg(&mut self, input: &ast::Arg) -> IoResult<()> {
+ pub fn print_arg(&mut self, input: &ast::Arg) -> io::Result<()> {
try!(self.ibox(indent_unit));
match input.ty.node {
ast::TyInfer => try!(self.print_pat(&*input.pat)),
self.end()
}
- pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> IoResult<()> {
+ pub fn print_fn_output(&mut self, decl: &ast::FnDecl) -> io::Result<()> {
if let ast::DefaultReturn(..) = decl.output {
return Ok(());
}
id: Option<ast::Ident>,
generics: &ast::Generics,
opt_explicit_self: Option<&ast::ExplicitSelf_>)
- -> IoResult<()> {
+ -> io::Result<()> {
try!(self.ibox(indent_unit));
try!(self.print_fn_header_info(Some(unsafety), abi, ast::Inherited));
pub fn maybe_print_trailing_comment(&mut self, span: codemap::Span,
next_pos: Option<BytePos>)
- -> IoResult<()> {
+ -> io::Result<()> {
let cm = match self.cm {
Some(cm) => cm,
_ => return Ok(())
Ok(())
}
- pub fn print_remaining_comments(&mut self) -> IoResult<()> {
+ pub fn print_remaining_comments(&mut self) -> io::Result<()> {
// If there aren't any remaining comments, then we need to manually
// make sure there is a line break at the end.
if self.next_comment().is_none() {
Ok(())
}
- pub fn print_literal(&mut self, lit: &ast::Lit) -> IoResult<()> {
+ pub fn print_literal(&mut self, lit: &ast::Lit) -> io::Result<()> {
try!(self.maybe_print_comment(lit.span.lo));
match self.next_lit(lit.span.lo) {
Some(ref ltrl) => {
}
}
- pub fn maybe_print_comment(&mut self, pos: BytePos) -> IoResult<()> {
+ pub fn maybe_print_comment(&mut self, pos: BytePos) -> io::Result<()> {
loop {
match self.next_comment() {
Some(ref cmnt) => {
}
pub fn print_comment(&mut self,
- cmnt: &comments::Comment) -> IoResult<()> {
+ cmnt: &comments::Comment) -> io::Result<()> {
match cmnt.style {
comments::Mixed => {
assert_eq!(cmnt.lines.len(), 1);
}
pub fn print_string(&mut self, st: &str,
- style: ast::StrStyle) -> IoResult<()> {
+ style: ast::StrStyle) -> io::Result<()> {
let st = match style {
ast::CookedStr => {
(format!("\"{}\"", st.escape_default()))
}
pub fn print_opt_unsafety(&mut self,
- opt_unsafety: Option<ast::Unsafety>) -> IoResult<()> {
+ opt_unsafety: Option<ast::Unsafety>) -> io::Result<()> {
match opt_unsafety {
Some(unsafety) => self.print_unsafety(unsafety),
None => Ok(())
pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
opt_abi: Option<abi::Abi>)
- -> IoResult<()> {
+ -> io::Result<()> {
match opt_abi {
Some(abi::Rust) => Ok(()),
Some(abi) => {
}
pub fn print_extern_opt_abi(&mut self,
- opt_abi: Option<abi::Abi>) -> IoResult<()> {
+ opt_abi: Option<abi::Abi>) -> io::Result<()> {
match opt_abi {
Some(abi) => {
try!(self.word_nbsp("extern"));
pub fn print_fn_header_info(&mut self,
opt_unsafety: Option<ast::Unsafety>,
abi: abi::Abi,
- vis: ast::Visibility) -> IoResult<()> {
+ vis: ast::Visibility) -> io::Result<()> {
try!(word(&mut self.s, &visibility_qualified(vis, "")));
try!(self.print_opt_unsafety(opt_unsafety));
word(&mut self.s, "fn")
}
- pub fn print_unsafety(&mut self, s: ast::Unsafety) -> IoResult<()> {
+ pub fn print_unsafety(&mut self, s: ast::Unsafety) -> io::Result<()> {
match s {
ast::Unsafety::Normal => Ok(()),
ast::Unsafety::Unsafe => self.word_nbsp("unsafe"),
callee: NameAndSpan {
name: "test".to_string(),
format: MacroAttribute,
- span: None
+ span: None,
+ allow_internal_unstable: false,
}
});
callee: NameAndSpan {
name: "test".to_string(),
format: MacroAttribute,
- span: None
+ span: None,
+ allow_internal_unstable: true,
}
};
let expn_id = cx.sess.span_diagnostic.cm.record_expansion(info);
#![feature(box_syntax)]
#![feature(collections)]
#![feature(int_uint)]
+#![feature(io)]
#![feature(old_io)]
-#![feature(old_path)]
+#![feature(path)]
#![feature(rustc_private)]
#![feature(staged_api)]
-#![feature(unicode)]
#![feature(std_misc)]
-#![feature(os)]
+#![feature(unicode)]
+#![feature(path_ext)]
#![cfg_attr(windows, feature(libc))]
#[macro_use] extern crate log;
/// Number for a terminal color
pub type Color = u16;
- pub const BLACK: Color = 0u16;
- pub const RED: Color = 1u16;
- pub const GREEN: Color = 2u16;
- pub const YELLOW: Color = 3u16;
- pub const BLUE: Color = 4u16;
- pub const MAGENTA: Color = 5u16;
- pub const CYAN: Color = 6u16;
- pub const WHITE: Color = 7u16;
-
- pub const BRIGHT_BLACK: Color = 8u16;
- pub const BRIGHT_RED: Color = 9u16;
- pub const BRIGHT_GREEN: Color = 10u16;
- pub const BRIGHT_YELLOW: Color = 11u16;
- pub const BRIGHT_BLUE: Color = 12u16;
- pub const BRIGHT_MAGENTA: Color = 13u16;
- pub const BRIGHT_CYAN: Color = 14u16;
- pub const BRIGHT_WHITE: Color = 15u16;
+ pub const BLACK: Color = 0;
+ pub const RED: Color = 1;
+ pub const GREEN: Color = 2;
+ pub const YELLOW: Color = 3;
+ pub const BLUE: Color = 4;
+ pub const MAGENTA: Color = 5;
+ pub const CYAN: Color = 6;
+ pub const WHITE: Color = 7;
+
+ pub const BRIGHT_BLACK: Color = 8;
+ pub const BRIGHT_RED: Color = 9;
+ pub const BRIGHT_GREEN: Color = 10;
+ pub const BRIGHT_YELLOW: Color = 11;
+ pub const BRIGHT_BLUE: Color = 12;
+ pub const BRIGHT_MAGENTA: Color = 13;
+ pub const BRIGHT_CYAN: Color = 14;
+ pub const BRIGHT_WHITE: Color = 15;
}
/// Terminal attributes
// if c is 0, use 0200 (128) for ncurses compatibility
Number(c) => {
output.push(if c == 0 {
- 128u8
+ 128
} else {
c as u8
})
#[test]
fn test_comparison_ops() {
- let v = [('<', [1u8, 0u8, 0u8]), ('=', [0u8, 1u8, 0u8]), ('>', [0u8, 0u8, 1u8])];
+ let v = [('<', [1, 0, 0]), ('=', [0, 1, 0]), ('>', [0, 0, 1])];
for &(op, bs) in &v {
let s = format!("%{{1}}%{{2}}%{}%d", op);
let res = expand(s.as_bytes(), &[], &mut Variables::new());
//! ncurses-compatible compiled terminfo format parsing (term(5))
use std::collections::HashMap;
-use std::old_io;
+use std::io::prelude::*;
+use std::io;
use super::super::TermInfo;
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
"box1"];
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
-pub fn parse(file: &mut old_io::Reader, longnames: bool)
+pub fn parse(file: &mut Read, longnames: bool)
-> Result<Box<TermInfo>, String> {
macro_rules! try { ($e:expr) => (
match $e {
}
// Check magic number
- let magic = try!(file.read_le_u16());
+ let magic = try!(read_le_u16(file));
if magic != 0x011A {
return Err(format!("invalid magic number: expected {:x}, found {:x}",
0x011A as usize, magic as usize));
}
- let names_bytes = try!(file.read_le_i16()) as int;
- let bools_bytes = try!(file.read_le_i16()) as int;
- let numbers_count = try!(file.read_le_i16()) as int;
- let string_offsets_count = try!(file.read_le_i16()) as int;
- let string_table_bytes = try!(file.read_le_i16()) as int;
+ let names_bytes = try!(read_le_u16(file)) as int;
+ let bools_bytes = try!(read_le_u16(file)) as int;
+ let numbers_count = try!(read_le_u16(file)) as int;
+ let string_offsets_count = try!(read_le_u16(file)) as int;
+ let string_table_bytes = try!(read_le_u16(file)) as int;
assert!(names_bytes > 0);
}
// don't read NUL
- let bytes = try!(file.read_exact(names_bytes as uint - 1));
+ let bytes = try!(read_exact(file, names_bytes as uint - 1));
let names_str = match String::from_utf8(bytes) {
Ok(s) => s,
Err(_) => return Err("input not utf-8".to_string()),
.map(|s| s.to_string())
.collect();
- try!(file.read_byte()); // consume NUL
+ try!(read_byte(file)); // consume NUL
let mut bools_map = HashMap::new();
if bools_bytes != 0 {
for i in 0..bools_bytes {
- let b = try!(file.read_byte());
+ let b = try!(read_byte(file));
if b == 1 {
bools_map.insert(bnames[i as uint].to_string(), true);
}
}
if (bools_bytes + names_bytes) % 2 == 1 {
- try!(file.read_byte()); // compensate for padding
+ try!(read_byte(file)); // compensate for padding
}
let mut numbers_map = HashMap::new();
if numbers_count != 0 {
for i in 0..numbers_count {
- let n = try!(file.read_le_u16());
+ let n = try!(read_le_u16(file));
if n != 0xFFFF {
numbers_map.insert(nnames[i as uint].to_string(), n);
}
if string_offsets_count != 0 {
let mut string_offsets = Vec::with_capacity(10);
for _ in 0..string_offsets_count {
- string_offsets.push(try!(file.read_le_u16()));
+ string_offsets.push(try!(read_le_u16(file)));
}
- let string_table = try!(file.read_exact(string_table_bytes as uint));
+ let string_table = try!(read_exact(file, string_table_bytes as usize));
if string_table.len() != string_table_bytes as uint {
return Err("error: hit EOF before end of string \
})
}
+fn read_le_u16<R: Read + ?Sized>(r: &mut R) -> io::Result<u16> {
+ let mut b = [0; 2];
+ assert_eq!(try!(r.read(&mut b)), 2);
+ Ok((b[0] as u16) | ((b[1] as u16) << 8))
+}
+
+fn read_byte<R: Read + ?Sized>(r: &mut R) -> io::Result<u8> {
+ let mut b = [0; 1];
+ assert_eq!(try!(r.read(&mut b)), 1);
+ Ok(b[0])
+}
+
+fn read_exact<R: Read + ?Sized>(r: &mut R, sz: usize) -> io::Result<Vec<u8>> {
+ let mut v = Vec::with_capacity(sz);
+ try!(r.take(sz as u64).read_to_end(&mut v));
+ assert_eq!(v.len(), sz);
+ Ok(v)
+}
+
/// Create a dummy TermInfo struct for msys terminals
pub fn msys_terminfo() -> Box<TermInfo> {
let mut strings = HashMap::new();
//!
//! Does not support hashed database, only filesystem!
-use std::old_io::File;
-use std::old_io::fs::PathExtensions;
use std::env;
+use std::fs::File;
+use std::io::prelude::*;
+use std::path::PathBuf;
/// Return path to database entry for `term`
#[allow(deprecated)]
-pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
+pub fn get_dbpath_for_term(term: &str) -> Option<Box<PathBuf>> {
if term.len() == 0 {
return None;
}
- let homedir = ::std::os::homedir();
+ let homedir = env::home_dir();
let mut dirs_to_search = Vec::new();
let first_char = term.char_at(0);
// Find search directory
- match env::var("TERMINFO") {
- Ok(dir) => dirs_to_search.push(Path::new(dir)),
- Err(..) => {
+ match env::var_os("TERMINFO") {
+ Some(dir) => dirs_to_search.push(PathBuf::new(&dir)),
+ None => {
if homedir.is_some() {
// ncurses compatibility;
dirs_to_search.push(homedir.unwrap().join(".terminfo"))
match env::var("TERMINFO_DIRS") {
Ok(dirs) => for i in dirs.split(':') {
if i == "" {
- dirs_to_search.push(Path::new("/usr/share/terminfo"));
+ dirs_to_search.push(PathBuf::new("/usr/share/terminfo"));
} else {
- dirs_to_search.push(Path::new(i));
+ dirs_to_search.push(PathBuf::new(i));
}
},
// Found nothing in TERMINFO_DIRS, use the default paths:
// ~/.terminfo, ncurses will search /etc/terminfo, then
// /lib/terminfo, and eventually /usr/share/terminfo.
Err(..) => {
- dirs_to_search.push(Path::new("/etc/terminfo"));
- dirs_to_search.push(Path::new("/lib/terminfo"));
- dirs_to_search.push(Path::new("/usr/share/terminfo"));
+ dirs_to_search.push(PathBuf::new("/etc/terminfo"));
+ dirs_to_search.push(PathBuf::new("/lib/terminfo"));
+ dirs_to_search.push(PathBuf::new("/usr/share/terminfo"));
}
}
}
for p in &dirs_to_search {
if p.exists() {
let f = first_char.to_string();
- let newp = p.join_many(&[&f[..], term]);
+ let newp = p.join(&f).join(term);
if newp.exists() {
return Some(box newp);
}
// on some installations the dir is named after the hex of the char (e.g. OS X)
let f = format!("{:x}", first_char as uint);
- let newp = p.join_many(&[&f[..], term]);
+ let newp = p.join(&f).join(term);
if newp.exists() {
return Some(box newp);
}
fn test_get_dbpath_for_term() {
// woefully inadequate test coverage
// note: current tests won't work with non-standard terminfo hierarchies (e.g. OS X's)
- use std::os::{setenv, unsetenv};
+ use std::env;
// FIXME (#9639): This needs to handle non-utf8 paths
fn x(t: &str) -> String {
let p = get_dbpath_for_term(t).expect("no terminfo entry found");
- p.as_str().unwrap().to_string()
+ p.to_str().unwrap().to_string()
};
assert!(x("screen") == "/usr/share/terminfo/s/screen");
assert!(get_dbpath_for_term("") == None);
- setenv("TERMINFO_DIRS", ":");
+ env::set_var("TERMINFO_DIRS", ":");
assert!(x("screen") == "/usr/share/terminfo/s/screen");
- unsetenv("TERMINFO_DIRS");
+ env::remove_var("TERMINFO_DIRS");
}
#[test]
#![feature(core)]
#![feature(int_uint)]
#![feature(old_io)]
-#![feature(old_path)]
+#![feature(path)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(std_misc)]
+#![feature(io)]
extern crate getopts;
extern crate serialize;
use std::any::Any;
use std::cmp;
use std::collections::BTreeMap;
+use std::env;
use std::fmt;
-use std::old_io::stdio::StdWriter;
-use std::old_io::{File, ChanReader, ChanWriter};
-use std::old_io;
+use std::fs::File;
+use std::io::{self, Write};
use std::iter::repeat;
use std::num::{Float, Int};
-use std::env;
+use std::old_io::stdio::StdWriter;
+use std::old_io::{ChanReader, ChanWriter};
+use std::old_io;
+use std::path::{PathBuf};
use std::sync::mpsc::{channel, Sender};
use std::thread;
use std::thunk::{Thunk, Invoke};
pub run_ignored: bool,
pub run_tests: bool,
pub run_benchmarks: bool,
- pub logfile: Option<Path>,
+ pub logfile: Option<PathBuf>,
pub nocapture: bool,
pub color: ColorConfig,
}
let run_ignored = matches.opt_present("ignored");
let logfile = matches.opt_str("logfile");
- let logfile = logfile.map(|s| Path::new(s));
+ let logfile = logfile.map(|s| PathBuf::new(&s));
let run_benchmarks = matches.opt_present("bench");
let run_tests = ! run_benchmarks ||
max_name_len: uint, // number of columns to fill when aligning names
}
+fn new2old(new: io::Error) -> old_io::IoError {
+ old_io::IoError {
+ kind: old_io::OtherIoError,
+ desc: "other error",
+ detail: Some(new.to_string()),
+ }
+}
+
impl<T: Writer> ConsoleTestState<T> {
pub fn new(opts: &TestOpts,
_: Option<T>) -> old_io::IoResult<ConsoleTestState<StdWriter>> {
let log_out = match opts.logfile {
- Some(ref path) => Some(try!(File::create(path))),
+ Some(ref path) => Some(try!(File::create(path).map_err(new2old))),
None => None
};
let out = match term::stdout() {
}
pub fn write_log(&mut self, test: &TestDesc,
- result: &TestResult) -> old_io::IoResult<()> {
+ result: &TestResult) -> io::Result<()> {
match self.log_out {
None => Ok(()),
Some(ref mut o) => {
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
TeWait(ref test, padding) => st.write_test_start(test, padding),
TeResult(test, result, stdout) => {
- try!(st.write_log(&test, &result));
+ try!(st.write_log(&test, &result).map_err(new2old));
try!(st.write_result(&result));
match result {
TrOk => st.passed += 1,
Pretty(_) => unreachable!()
};
- let apos = s.find_str("a").unwrap();
- let bpos = s.find_str("b").unwrap();
+ let apos = s.find("a").unwrap();
+ let bpos = s.find("b").unwrap();
assert!(apos < bpos);
}
pub fn iter<T, F>(&mut self, mut inner: F) where F: FnMut() -> T {
self.dur = Duration::span(|| {
let k = self.iterations;
- for _ in 0u64..k {
+ for _ in 0..k {
black_box(inner());
}
});
// This is a more statistics-driven benchmark algorithm
pub fn auto_bench<F>(&mut self, mut f: F) -> stats::Summary<f64> where F: FnMut(&mut Bencher) {
// Initial bench run to get ballpark figure.
- let mut n = 1_u64;
+ let mut n = 1;
self.bench_n(n, |x| f(x));
// Try to estimate iter count for 1ms falling back to 1m
fn mean(&self) -> T {
assert!(self.len() != 0);
- self.sum() / FromPrimitive::from_uint(self.len()).unwrap()
+ self.sum() / FromPrimitive::from_usize(self.len()).unwrap()
}
fn median(&self) -> T {
- self.percentile(FromPrimitive::from_uint(50).unwrap())
+ self.percentile(FromPrimitive::from_usize(50).unwrap())
}
fn var(&self) -> T {
// NB: this is _supposed to be_ len-1, not len. If you
// change it back to len, you will be calculating a
// population variance, not a sample variance.
- let denom = FromPrimitive::from_uint(self.len()-1).unwrap();
+ let denom = FromPrimitive::from_usize(self.len()-1).unwrap();
v/denom
}
}
}
fn std_dev_pct(&self) -> T {
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
(self.std_dev() / self.mean()) * hundred
}
}
fn median_abs_dev_pct(&self) -> T {
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
(self.median_abs_dev() / self.median()) * hundred
}
fn quartiles(&self) -> (T,T,T) {
let mut tmp = self.to_vec();
local_sort(&mut tmp);
- let first = FromPrimitive::from_uint(25).unwrap();
+ let first = FromPrimitive::from_usize(25).unwrap();
let a = percentile_of_sorted(&tmp, first);
- let secound = FromPrimitive::from_uint(50).unwrap();
+ let secound = FromPrimitive::from_usize(50).unwrap();
let b = percentile_of_sorted(&tmp, secound);
- let third = FromPrimitive::from_uint(75).unwrap();
+ let third = FromPrimitive::from_usize(75).unwrap();
let c = percentile_of_sorted(&tmp, third);
(a,b,c)
}
}
let zero: T = Float::zero();
assert!(zero <= pct);
- let hundred = FromPrimitive::from_uint(100).unwrap();
+ let hundred = FromPrimitive::from_usize(100).unwrap();
assert!(pct <= hundred);
if pct == hundred {
return sorted_samples[sorted_samples.len() - 1];
}
- let length = FromPrimitive::from_uint(sorted_samples.len() - 1).unwrap();
+ let length = FromPrimitive::from_usize(sorted_samples.len() - 1).unwrap();
let rank = (pct / hundred) * length;
let lrank = rank.floor();
let d = rank - lrank;
- let n = lrank.to_uint().unwrap();
+ let n = lrank.to_usize().unwrap();
let lo = sorted_samples[n];
let hi = sorted_samples[n+1];
lo + (hi - lo) * d
let mut tmp = samples.to_vec();
local_sort(&mut tmp);
let lo = percentile_of_sorted(&tmp, pct);
- let hundred: T = FromPrimitive::from_uint(100).unwrap();
+ let hundred: T = FromPrimitive::from_usize(100).unwrap();
let hi = percentile_of_sorted(&tmp, hundred-pct);
for samp in samples {
if *samp > hi {
}
pub mod general_category {
- pub static C_table: &'static [(char, char)] = &[
+ pub const C_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}'), ('\u{ad}', '\u{ad}'), ('\u{378}', '\u{379}'),
('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}', '\u{38d}'), ('\u{3a2}',
'\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'), ('\u{560}', '\u{560}'),
'\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}', '\u{2fff}'), ('\u{3040}', '\u{3040}'),
('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'), ('\u{312e}', '\u{3130}'), ('\u{318f}',
'\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}', '\u{31ef}'), ('\u{321f}', '\u{321f}'),
- ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'), ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}',
- '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'),
- ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}',
- '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'),
- ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}',
- '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'),
- ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}',
- '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'),
- ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}',
- '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'),
- ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{ac01}',
- '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'),
- ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'), ('\u{fb07}',
- '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'),
- ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}',
- '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'),
- ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}',
- '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'),
- ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}',
- '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'),
- ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
+ ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}',
+ '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'),
+ ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}',
+ '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'),
+ ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}',
+ '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'),
+ ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}',
+ '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'),
+ ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}',
+ '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'),
+ ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}',
+ '\u{d7ff}'), ('\u{e000}', '\u{f8ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}', '\u{faff}'),
+ ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'), ('\u{fb3d}',
+ '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}', '\u{fb45}'),
+ ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'), ('\u{fdc8}',
+ '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}', '\u{fe2f}'),
+ ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'), ('\u{fe75}',
+ '\u{fe75}'), ('\u{fefd}', '\u{ff00}'), ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'),
+ ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}',
+ '\u{ffe7}'), ('\u{ffef}', '\u{fffb}'), ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'),
('\u{10027}', '\u{10027}'), ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'),
('\u{1004e}', '\u{1004f}'), ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'),
('\u{10103}', '\u{10106}'), ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'),
('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'),
('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'),
- ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'),
- ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'),
- ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'),
+ ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'),
+ ('\u{2b735}', '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e00ff}'),
('\u{e01f0}', '\u{10ffff}')
];
- pub static Cc_table: &'static [(char, char)] = &[
+ pub const Cc_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{7f}', '\u{9f}')
];
super::bsearch_range_table(c, Cc_table)
}
- pub static Cf_table: &'static [(char, char)] = &[
+ pub const Cf_table: &'static [(char, char)] = &[
('\u{ad}', '\u{ad}'), ('\u{600}', '\u{605}'), ('\u{61c}', '\u{61c}'), ('\u{6dd}',
'\u{6dd}'), ('\u{70f}', '\u{70f}'), ('\u{180e}', '\u{180e}'), ('\u{200b}', '\u{200f}'),
('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2066}', '\u{206f}'), ('\u{feff}',
'\u{e007f}')
];
- pub static Cn_table: &'static [(char, char)] = &[
+ pub const Cn_table: &'static [(char, char)] = &[
('\u{378}', '\u{379}'), ('\u{380}', '\u{383}'), ('\u{38b}', '\u{38b}'), ('\u{38d}',
'\u{38d}'), ('\u{3a2}', '\u{3a2}'), ('\u{530}', '\u{530}'), ('\u{557}', '\u{558}'),
('\u{560}', '\u{560}'), ('\u{588}', '\u{588}'), ('\u{58b}', '\u{58c}'), ('\u{590}',
('\u{2e9a}', '\u{2e9a}'), ('\u{2ef4}', '\u{2eff}'), ('\u{2fd6}', '\u{2fef}'), ('\u{2ffc}',
'\u{2fff}'), ('\u{3040}', '\u{3040}'), ('\u{3097}', '\u{3098}'), ('\u{3100}', '\u{3104}'),
('\u{312e}', '\u{3130}'), ('\u{318f}', '\u{318f}'), ('\u{31bb}', '\u{31bf}'), ('\u{31e4}',
- '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{3401}', '\u{4db4}'),
- ('\u{4db6}', '\u{4dbf}'), ('\u{4e01}', '\u{9fcb}'), ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}',
- '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}', '\u{a63f}'), ('\u{a69e}', '\u{a69e}'),
- ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'), ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}',
- '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}', '\u{a83f}'), ('\u{a878}', '\u{a87f}'),
- ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'), ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}',
- '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}', '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'),
- ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'), ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}',
- '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}', '\u{ab00}'), ('\u{ab07}', '\u{ab08}'),
- ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'), ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}',
- '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}', '\u{abbf}'), ('\u{abee}', '\u{abef}'),
- ('\u{abfa}', '\u{abff}'), ('\u{ac01}', '\u{d7a2}'), ('\u{d7a4}', '\u{d7af}'), ('\u{d7c7}',
- '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{e001}', '\u{f8fe}'), ('\u{fa6e}', '\u{fa6f}'),
- ('\u{fada}', '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}',
- '\u{fb37}'), ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'),
- ('\u{fb45}', '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}',
- '\u{fd91}'), ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'),
- ('\u{fe2e}', '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}',
- '\u{fe6f}'), ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'),
- ('\u{ffbf}', '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}',
- '\u{ffd9}'), ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'),
- ('\u{fffe}', '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'),
- ('\u{1003b}', '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'),
- ('\u{1005e}', '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'),
- ('\u{10134}', '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'),
- ('\u{101a1}', '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'),
- ('\u{102d1}', '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'),
- ('\u{1034b}', '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'),
- ('\u{103c4}', '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'),
- ('\u{104aa}', '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'),
- ('\u{10570}', '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'),
- ('\u{10768}', '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'),
- ('\u{10836}', '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'),
- ('\u{10856}', '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'),
- ('\u{1091c}', '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'),
- ('\u{109b8}', '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'),
- ('\u{10a07}', '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'),
- ('\u{10a34}', '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'),
- ('\u{10a59}', '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'),
- ('\u{10af7}', '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'),
- ('\u{10b73}', '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'),
- ('\u{10bb0}', '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'),
- ('\u{1104e}', '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'),
- ('\u{110e9}', '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'),
- ('\u{11144}', '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'),
- ('\u{111ce}', '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'),
- ('\u{11212}', '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'),
- ('\u{112fa}', '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'),
- ('\u{11311}', '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'),
- ('\u{11334}', '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'),
- ('\u{11349}', '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'),
- ('\u{11364}', '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'),
- ('\u{114c8}', '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'),
- ('\u{115ca}', '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'),
- ('\u{116b8}', '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'),
- ('\u{11900}', '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'),
- ('\u{1246f}', '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'),
- ('\u{16a39}', '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'),
- ('\u{16a70}', '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'),
- ('\u{16b46}', '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'),
- ('\u{16b78}', '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'),
- ('\u{16f7f}', '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'),
- ('\u{1bc6b}', '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'),
- ('\u{1bc9a}', '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'),
- ('\u{1d127}', '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'),
- ('\u{1d357}', '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'),
- ('\u{1d49d}', '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'),
- ('\u{1d4a7}', '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'),
- ('\u{1d4bc}', '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'),
- ('\u{1d50b}', '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'),
- ('\u{1d53a}', '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'),
- ('\u{1d547}', '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'),
- ('\u{1d7cc}', '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'),
- ('\u{1e8d7}', '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'),
- ('\u{1ee23}', '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'),
- ('\u{1ee33}', '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'),
- ('\u{1ee3c}', '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'),
- ('\u{1ee4a}', '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'),
- ('\u{1ee53}', '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'),
- ('\u{1ee5a}', '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'),
- ('\u{1ee60}', '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'),
- ('\u{1ee6b}', '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'),
- ('\u{1ee7d}', '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'),
- ('\u{1ee9c}', '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'),
- ('\u{1eebc}', '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'),
- ('\u{1f094}', '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'),
- ('\u{1f0d0}', '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'),
- ('\u{1f12f}', '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'),
- ('\u{1f203}', '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'),
- ('\u{1f252}', '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'),
- ('\u{1f3cf}', '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'),
- ('\u{1f54b}', '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'),
- ('\u{1f643}', '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'),
- ('\u{1f6f4}', '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'),
- ('\u{1f80c}', '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'),
- ('\u{1f888}', '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{20001}', '\u{2a6d5}'),
- ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2a701}', '\u{2b733}'), ('\u{2b735}', '\u{2b73f}'),
- ('\u{2b741}', '\u{2b81c}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'),
- ('\u{e0002}', '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'),
- ('\u{f0001}', '\u{ffffc}'), ('\u{ffffe}', '\u{fffff}'), ('\u{100001}', '\u{10fffc}'),
- ('\u{10fffe}', '\u{10ffff}')
- ];
-
- pub static Co_table: &'static [(char, char)] = &[
- ('\u{e000}', '\u{e000}'), ('\u{f8ff}', '\u{f8ff}'), ('\u{f0000}', '\u{f0000}'),
- ('\u{ffffd}', '\u{ffffd}'), ('\u{100000}', '\u{100000}'), ('\u{10fffd}', '\u{10fffd}')
- ];
-
- pub static L_table: &'static [(char, char)] = &[
+ '\u{31ef}'), ('\u{321f}', '\u{321f}'), ('\u{32ff}', '\u{32ff}'), ('\u{4db6}', '\u{4dbf}'),
+ ('\u{9fcd}', '\u{9fff}'), ('\u{a48d}', '\u{a48f}'), ('\u{a4c7}', '\u{a4cf}'), ('\u{a62c}',
+ '\u{a63f}'), ('\u{a69e}', '\u{a69e}'), ('\u{a6f8}', '\u{a6ff}'), ('\u{a78f}', '\u{a78f}'),
+ ('\u{a7ae}', '\u{a7af}'), ('\u{a7b2}', '\u{a7f6}'), ('\u{a82c}', '\u{a82f}'), ('\u{a83a}',
+ '\u{a83f}'), ('\u{a878}', '\u{a87f}'), ('\u{a8c5}', '\u{a8cd}'), ('\u{a8da}', '\u{a8df}'),
+ ('\u{a8fc}', '\u{a8ff}'), ('\u{a954}', '\u{a95e}'), ('\u{a97d}', '\u{a97f}'), ('\u{a9ce}',
+ '\u{a9ce}'), ('\u{a9da}', '\u{a9dd}'), ('\u{a9ff}', '\u{a9ff}'), ('\u{aa37}', '\u{aa3f}'),
+ ('\u{aa4e}', '\u{aa4f}'), ('\u{aa5a}', '\u{aa5b}'), ('\u{aac3}', '\u{aada}'), ('\u{aaf7}',
+ '\u{ab00}'), ('\u{ab07}', '\u{ab08}'), ('\u{ab0f}', '\u{ab10}'), ('\u{ab17}', '\u{ab1f}'),
+ ('\u{ab27}', '\u{ab27}'), ('\u{ab2f}', '\u{ab2f}'), ('\u{ab60}', '\u{ab63}'), ('\u{ab66}',
+ '\u{abbf}'), ('\u{abee}', '\u{abef}'), ('\u{abfa}', '\u{abff}'), ('\u{d7a4}', '\u{d7af}'),
+ ('\u{d7c7}', '\u{d7ca}'), ('\u{d7fc}', '\u{d7ff}'), ('\u{fa6e}', '\u{fa6f}'), ('\u{fada}',
+ '\u{faff}'), ('\u{fb07}', '\u{fb12}'), ('\u{fb18}', '\u{fb1c}'), ('\u{fb37}', '\u{fb37}'),
+ ('\u{fb3d}', '\u{fb3d}'), ('\u{fb3f}', '\u{fb3f}'), ('\u{fb42}', '\u{fb42}'), ('\u{fb45}',
+ '\u{fb45}'), ('\u{fbc2}', '\u{fbd2}'), ('\u{fd40}', '\u{fd4f}'), ('\u{fd90}', '\u{fd91}'),
+ ('\u{fdc8}', '\u{fdef}'), ('\u{fdfe}', '\u{fdff}'), ('\u{fe1a}', '\u{fe1f}'), ('\u{fe2e}',
+ '\u{fe2f}'), ('\u{fe53}', '\u{fe53}'), ('\u{fe67}', '\u{fe67}'), ('\u{fe6c}', '\u{fe6f}'),
+ ('\u{fe75}', '\u{fe75}'), ('\u{fefd}', '\u{fefe}'), ('\u{ff00}', '\u{ff00}'), ('\u{ffbf}',
+ '\u{ffc1}'), ('\u{ffc8}', '\u{ffc9}'), ('\u{ffd0}', '\u{ffd1}'), ('\u{ffd8}', '\u{ffd9}'),
+ ('\u{ffdd}', '\u{ffdf}'), ('\u{ffe7}', '\u{ffe7}'), ('\u{ffef}', '\u{fff8}'), ('\u{fffe}',
+ '\u{ffff}'), ('\u{1000c}', '\u{1000c}'), ('\u{10027}', '\u{10027}'), ('\u{1003b}',
+ '\u{1003b}'), ('\u{1003e}', '\u{1003e}'), ('\u{1004e}', '\u{1004f}'), ('\u{1005e}',
+ '\u{1007f}'), ('\u{100fb}', '\u{100ff}'), ('\u{10103}', '\u{10106}'), ('\u{10134}',
+ '\u{10136}'), ('\u{1018d}', '\u{1018f}'), ('\u{1019c}', '\u{1019f}'), ('\u{101a1}',
+ '\u{101cf}'), ('\u{101fe}', '\u{1027f}'), ('\u{1029d}', '\u{1029f}'), ('\u{102d1}',
+ '\u{102df}'), ('\u{102fc}', '\u{102ff}'), ('\u{10324}', '\u{1032f}'), ('\u{1034b}',
+ '\u{1034f}'), ('\u{1037b}', '\u{1037f}'), ('\u{1039e}', '\u{1039e}'), ('\u{103c4}',
+ '\u{103c7}'), ('\u{103d6}', '\u{103ff}'), ('\u{1049e}', '\u{1049f}'), ('\u{104aa}',
+ '\u{104ff}'), ('\u{10528}', '\u{1052f}'), ('\u{10564}', '\u{1056e}'), ('\u{10570}',
+ '\u{105ff}'), ('\u{10737}', '\u{1073f}'), ('\u{10756}', '\u{1075f}'), ('\u{10768}',
+ '\u{107ff}'), ('\u{10806}', '\u{10807}'), ('\u{10809}', '\u{10809}'), ('\u{10836}',
+ '\u{10836}'), ('\u{10839}', '\u{1083b}'), ('\u{1083d}', '\u{1083e}'), ('\u{10856}',
+ '\u{10856}'), ('\u{1089f}', '\u{108a6}'), ('\u{108b0}', '\u{108ff}'), ('\u{1091c}',
+ '\u{1091e}'), ('\u{1093a}', '\u{1093e}'), ('\u{10940}', '\u{1097f}'), ('\u{109b8}',
+ '\u{109bd}'), ('\u{109c0}', '\u{109ff}'), ('\u{10a04}', '\u{10a04}'), ('\u{10a07}',
+ '\u{10a0b}'), ('\u{10a14}', '\u{10a14}'), ('\u{10a18}', '\u{10a18}'), ('\u{10a34}',
+ '\u{10a37}'), ('\u{10a3b}', '\u{10a3e}'), ('\u{10a48}', '\u{10a4f}'), ('\u{10a59}',
+ '\u{10a5f}'), ('\u{10aa0}', '\u{10abf}'), ('\u{10ae7}', '\u{10aea}'), ('\u{10af7}',
+ '\u{10aff}'), ('\u{10b36}', '\u{10b38}'), ('\u{10b56}', '\u{10b57}'), ('\u{10b73}',
+ '\u{10b77}'), ('\u{10b92}', '\u{10b98}'), ('\u{10b9d}', '\u{10ba8}'), ('\u{10bb0}',
+ '\u{10bff}'), ('\u{10c49}', '\u{10e5f}'), ('\u{10e7f}', '\u{10fff}'), ('\u{1104e}',
+ '\u{11051}'), ('\u{11070}', '\u{1107e}'), ('\u{110c2}', '\u{110cf}'), ('\u{110e9}',
+ '\u{110ef}'), ('\u{110fa}', '\u{110ff}'), ('\u{11135}', '\u{11135}'), ('\u{11144}',
+ '\u{1114f}'), ('\u{11177}', '\u{1117f}'), ('\u{111c9}', '\u{111cc}'), ('\u{111ce}',
+ '\u{111cf}'), ('\u{111db}', '\u{111e0}'), ('\u{111f5}', '\u{111ff}'), ('\u{11212}',
+ '\u{11212}'), ('\u{1123e}', '\u{112af}'), ('\u{112eb}', '\u{112ef}'), ('\u{112fa}',
+ '\u{11300}'), ('\u{11304}', '\u{11304}'), ('\u{1130d}', '\u{1130e}'), ('\u{11311}',
+ '\u{11312}'), ('\u{11329}', '\u{11329}'), ('\u{11331}', '\u{11331}'), ('\u{11334}',
+ '\u{11334}'), ('\u{1133a}', '\u{1133b}'), ('\u{11345}', '\u{11346}'), ('\u{11349}',
+ '\u{1134a}'), ('\u{1134e}', '\u{11356}'), ('\u{11358}', '\u{1135c}'), ('\u{11364}',
+ '\u{11365}'), ('\u{1136d}', '\u{1136f}'), ('\u{11375}', '\u{1147f}'), ('\u{114c8}',
+ '\u{114cf}'), ('\u{114da}', '\u{1157f}'), ('\u{115b6}', '\u{115b7}'), ('\u{115ca}',
+ '\u{115ff}'), ('\u{11645}', '\u{1164f}'), ('\u{1165a}', '\u{1167f}'), ('\u{116b8}',
+ '\u{116bf}'), ('\u{116ca}', '\u{1189f}'), ('\u{118f3}', '\u{118fe}'), ('\u{11900}',
+ '\u{11abf}'), ('\u{11af9}', '\u{11fff}'), ('\u{12399}', '\u{123ff}'), ('\u{1246f}',
+ '\u{1246f}'), ('\u{12475}', '\u{12fff}'), ('\u{1342f}', '\u{167ff}'), ('\u{16a39}',
+ '\u{16a3f}'), ('\u{16a5f}', '\u{16a5f}'), ('\u{16a6a}', '\u{16a6d}'), ('\u{16a70}',
+ '\u{16acf}'), ('\u{16aee}', '\u{16aef}'), ('\u{16af6}', '\u{16aff}'), ('\u{16b46}',
+ '\u{16b4f}'), ('\u{16b5a}', '\u{16b5a}'), ('\u{16b62}', '\u{16b62}'), ('\u{16b78}',
+ '\u{16b7c}'), ('\u{16b90}', '\u{16eff}'), ('\u{16f45}', '\u{16f4f}'), ('\u{16f7f}',
+ '\u{16f8e}'), ('\u{16fa0}', '\u{1afff}'), ('\u{1b002}', '\u{1bbff}'), ('\u{1bc6b}',
+ '\u{1bc6f}'), ('\u{1bc7d}', '\u{1bc7f}'), ('\u{1bc89}', '\u{1bc8f}'), ('\u{1bc9a}',
+ '\u{1bc9b}'), ('\u{1bca4}', '\u{1cfff}'), ('\u{1d0f6}', '\u{1d0ff}'), ('\u{1d127}',
+ '\u{1d128}'), ('\u{1d1de}', '\u{1d1ff}'), ('\u{1d246}', '\u{1d2ff}'), ('\u{1d357}',
+ '\u{1d35f}'), ('\u{1d372}', '\u{1d3ff}'), ('\u{1d455}', '\u{1d455}'), ('\u{1d49d}',
+ '\u{1d49d}'), ('\u{1d4a0}', '\u{1d4a1}'), ('\u{1d4a3}', '\u{1d4a4}'), ('\u{1d4a7}',
+ '\u{1d4a8}'), ('\u{1d4ad}', '\u{1d4ad}'), ('\u{1d4ba}', '\u{1d4ba}'), ('\u{1d4bc}',
+ '\u{1d4bc}'), ('\u{1d4c4}', '\u{1d4c4}'), ('\u{1d506}', '\u{1d506}'), ('\u{1d50b}',
+ '\u{1d50c}'), ('\u{1d515}', '\u{1d515}'), ('\u{1d51d}', '\u{1d51d}'), ('\u{1d53a}',
+ '\u{1d53a}'), ('\u{1d53f}', '\u{1d53f}'), ('\u{1d545}', '\u{1d545}'), ('\u{1d547}',
+ '\u{1d549}'), ('\u{1d551}', '\u{1d551}'), ('\u{1d6a6}', '\u{1d6a7}'), ('\u{1d7cc}',
+ '\u{1d7cd}'), ('\u{1d800}', '\u{1e7ff}'), ('\u{1e8c5}', '\u{1e8c6}'), ('\u{1e8d7}',
+ '\u{1edff}'), ('\u{1ee04}', '\u{1ee04}'), ('\u{1ee20}', '\u{1ee20}'), ('\u{1ee23}',
+ '\u{1ee23}'), ('\u{1ee25}', '\u{1ee26}'), ('\u{1ee28}', '\u{1ee28}'), ('\u{1ee33}',
+ '\u{1ee33}'), ('\u{1ee38}', '\u{1ee38}'), ('\u{1ee3a}', '\u{1ee3a}'), ('\u{1ee3c}',
+ '\u{1ee41}'), ('\u{1ee43}', '\u{1ee46}'), ('\u{1ee48}', '\u{1ee48}'), ('\u{1ee4a}',
+ '\u{1ee4a}'), ('\u{1ee4c}', '\u{1ee4c}'), ('\u{1ee50}', '\u{1ee50}'), ('\u{1ee53}',
+ '\u{1ee53}'), ('\u{1ee55}', '\u{1ee56}'), ('\u{1ee58}', '\u{1ee58}'), ('\u{1ee5a}',
+ '\u{1ee5a}'), ('\u{1ee5c}', '\u{1ee5c}'), ('\u{1ee5e}', '\u{1ee5e}'), ('\u{1ee60}',
+ '\u{1ee60}'), ('\u{1ee63}', '\u{1ee63}'), ('\u{1ee65}', '\u{1ee66}'), ('\u{1ee6b}',
+ '\u{1ee6b}'), ('\u{1ee73}', '\u{1ee73}'), ('\u{1ee78}', '\u{1ee78}'), ('\u{1ee7d}',
+ '\u{1ee7d}'), ('\u{1ee7f}', '\u{1ee7f}'), ('\u{1ee8a}', '\u{1ee8a}'), ('\u{1ee9c}',
+ '\u{1eea0}'), ('\u{1eea4}', '\u{1eea4}'), ('\u{1eeaa}', '\u{1eeaa}'), ('\u{1eebc}',
+ '\u{1eeef}'), ('\u{1eef2}', '\u{1efff}'), ('\u{1f02c}', '\u{1f02f}'), ('\u{1f094}',
+ '\u{1f09f}'), ('\u{1f0af}', '\u{1f0b0}'), ('\u{1f0c0}', '\u{1f0c0}'), ('\u{1f0d0}',
+ '\u{1f0d0}'), ('\u{1f0f6}', '\u{1f0ff}'), ('\u{1f10d}', '\u{1f10f}'), ('\u{1f12f}',
+ '\u{1f12f}'), ('\u{1f16c}', '\u{1f16f}'), ('\u{1f19b}', '\u{1f1e5}'), ('\u{1f203}',
+ '\u{1f20f}'), ('\u{1f23b}', '\u{1f23f}'), ('\u{1f249}', '\u{1f24f}'), ('\u{1f252}',
+ '\u{1f2ff}'), ('\u{1f32d}', '\u{1f32f}'), ('\u{1f37e}', '\u{1f37f}'), ('\u{1f3cf}',
+ '\u{1f3d3}'), ('\u{1f3f8}', '\u{1f3ff}'), ('\u{1f4ff}', '\u{1f4ff}'), ('\u{1f54b}',
+ '\u{1f54f}'), ('\u{1f57a}', '\u{1f57a}'), ('\u{1f5a4}', '\u{1f5a4}'), ('\u{1f643}',
+ '\u{1f644}'), ('\u{1f6d0}', '\u{1f6df}'), ('\u{1f6ed}', '\u{1f6ef}'), ('\u{1f6f4}',
+ '\u{1f6ff}'), ('\u{1f774}', '\u{1f77f}'), ('\u{1f7d5}', '\u{1f7ff}'), ('\u{1f80c}',
+ '\u{1f80f}'), ('\u{1f848}', '\u{1f84f}'), ('\u{1f85a}', '\u{1f85f}'), ('\u{1f888}',
+ '\u{1f88f}'), ('\u{1f8ae}', '\u{1ffff}'), ('\u{2a6d7}', '\u{2a6ff}'), ('\u{2b735}',
+ '\u{2b73f}'), ('\u{2b81e}', '\u{2f7ff}'), ('\u{2fa1e}', '\u{e0000}'), ('\u{e0002}',
+ '\u{e001f}'), ('\u{e0080}', '\u{e00ff}'), ('\u{e01f0}', '\u{effff}'), ('\u{ffffe}',
+ '\u{fffff}'), ('\u{10fffe}', '\u{10ffff}')
+ ];
+
+ pub const Co_table: &'static [(char, char)] = &[
+ ('\u{e000}', '\u{f8ff}'), ('\u{f0000}', '\u{ffffd}'), ('\u{100000}', '\u{10fffd}')
+ ];
+
+ pub const L_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'),
('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}', '\u{2ec}'), ('\u{2ee}',
('\u{2e2f}', '\u{2e2f}'), ('\u{3005}', '\u{3006}'), ('\u{3031}', '\u{3035}'), ('\u{303b}',
'\u{303c}'), ('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'),
('\u{30fc}', '\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}',
- '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'),
- ('\u{4e00}', '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a48c}'), ('\u{a4d0}',
- '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'),
- ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}',
- '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}', '\u{a78e}'), ('\u{a790}', '\u{a7ad}'),
- ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}',
- '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'),
- ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}',
- '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'),
- ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}',
- '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'),
- ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}',
- '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'),
- ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}',
- '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'),
- ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'), ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}',
- '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'),
- ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}',
- '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}', '\u{fb1d}'),
- ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}',
- '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'),
- ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}',
- '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}', '\u{ff3a}'),
- ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}',
- '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}', '\u{1000b}'),
- ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}', '\u{1003d}'),
- ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}', '\u{100fa}'),
- ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}', '\u{1031f}'),
- ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}', '\u{10375}'),
- ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'),
- ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}', '\u{10563}'),
- ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}'),
- ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'),
- ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{10855}'),
- ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}', '\u{10915}'),
- ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}', '\u{109bf}'),
- ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'),
- ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'),
- ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'),
- ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}', '\u{10b91}'),
- ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}', '\u{110af}'),
- ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}', '\u{11172}'),
- ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}', '\u{111c4}'),
- ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'),
- ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}', '\u{11310}'),
- ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}', '\u{11333}'),
- ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}', '\u{11361}'),
- ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}', '\u{114c7}'),
- ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}', '\u{11644}'),
- ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}', '\u{118ff}'),
- ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'),
- ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'),
- ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}', '\u{16b77}'),
- ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'),
- ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'),
- ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'),
- ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}', '\u{1d49f}'),
- ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}', '\u{1d4ac}'),
- ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}', '\u{1d4c3}'),
- ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}', '\u{1d514}'),
- ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}', '\u{1d53e}'),
- ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}', '\u{1d550}'),
- ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}', '\u{1d6da}'),
- ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}', '\u{1d734}'),
- ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}', '\u{1d788}'),
- ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}'),
- ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'),
- ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'),
- ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'),
- ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'),
- ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'),
- ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'),
- ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'),
- ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'),
- ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'),
- ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'),
- ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'),
- ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'), ('\u{2a6d6}', '\u{2a6d6}'),
- ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'), ('\u{2b740}', '\u{2b740}'),
- ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
+ '\u{31ba}'), ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'),
+ ('\u{a000}', '\u{a48c}'), ('\u{a4d0}', '\u{a4fd}'), ('\u{a500}', '\u{a60c}'), ('\u{a610}',
+ '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a640}', '\u{a66e}'), ('\u{a67f}', '\u{a69d}'),
+ ('\u{a6a0}', '\u{a6e5}'), ('\u{a717}', '\u{a71f}'), ('\u{a722}', '\u{a788}'), ('\u{a78b}',
+ '\u{a78e}'), ('\u{a790}', '\u{a7ad}'), ('\u{a7b0}', '\u{a7b1}'), ('\u{a7f7}', '\u{a801}'),
+ ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}',
+ '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'),
+ ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}',
+ '\u{a9b2}'), ('\u{a9cf}', '\u{a9cf}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e6}', '\u{a9ef}'),
+ ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}',
+ '\u{aa4b}'), ('\u{aa60}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'),
+ ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}',
+ '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadd}'), ('\u{aae0}', '\u{aaea}'),
+ ('\u{aaf2}', '\u{aaf4}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}',
+ '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{ab30}', '\u{ab5a}'),
+ ('\u{ab5c}', '\u{ab5f}'), ('\u{ab64}', '\u{ab65}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}',
+ '\u{d7a3}'), ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'),
+ ('\u{fa70}', '\u{fad9}'), ('\u{fb00}', '\u{fb06}'), ('\u{fb13}', '\u{fb17}'), ('\u{fb1d}',
+ '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}', '\u{fb3c}'),
+ ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'), ('\u{fb46}',
+ '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}', '\u{fdc7}'),
+ ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'), ('\u{ff21}',
+ '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}'), ('\u{ff66}', '\u{ffbe}'), ('\u{ffc2}', '\u{ffc7}'),
+ ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'), ('\u{10000}',
+ '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'), ('\u{1003c}',
+ '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'), ('\u{10080}',
+ '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'), ('\u{10300}',
+ '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'), ('\u{10350}',
+ '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'), ('\u{103c8}',
+ '\u{103cf}'), ('\u{10400}', '\u{1049d}'), ('\u{10500}', '\u{10527}'), ('\u{10530}',
+ '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}',
+ '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}',
+ '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}',
+ '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'), ('\u{10900}',
+ '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'), ('\u{109be}',
+ '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}',
+ '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'), ('\u{10a80}',
+ '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'), ('\u{10b00}',
+ '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'), ('\u{10b80}',
+ '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'), ('\u{11083}',
+ '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'), ('\u{11150}',
+ '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'), ('\u{111c1}',
+ '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'), ('\u{11213}',
+ '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'), ('\u{1130f}',
+ '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'), ('\u{11332}',
+ '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'), ('\u{1135d}',
+ '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'), ('\u{114c7}',
+ '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'), ('\u{11644}',
+ '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118a0}', '\u{118df}'), ('\u{118ff}',
+ '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}',
+ '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}',
+ '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b63}',
+ '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}',
+ '\u{16f50}'), ('\u{16f93}', '\u{16f9f}'), ('\u{1b000}', '\u{1b001}'), ('\u{1bc00}',
+ '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'), ('\u{1bc90}',
+ '\u{1bc99}'), ('\u{1d400}', '\u{1d454}'), ('\u{1d456}', '\u{1d49c}'), ('\u{1d49e}',
+ '\u{1d49f}'), ('\u{1d4a2}', '\u{1d4a2}'), ('\u{1d4a5}', '\u{1d4a6}'), ('\u{1d4a9}',
+ '\u{1d4ac}'), ('\u{1d4ae}', '\u{1d4b9}'), ('\u{1d4bb}', '\u{1d4bb}'), ('\u{1d4bd}',
+ '\u{1d4c3}'), ('\u{1d4c5}', '\u{1d505}'), ('\u{1d507}', '\u{1d50a}'), ('\u{1d50d}',
+ '\u{1d514}'), ('\u{1d516}', '\u{1d51c}'), ('\u{1d51e}', '\u{1d539}'), ('\u{1d53b}',
+ '\u{1d53e}'), ('\u{1d540}', '\u{1d544}'), ('\u{1d546}', '\u{1d546}'), ('\u{1d54a}',
+ '\u{1d550}'), ('\u{1d552}', '\u{1d6a5}'), ('\u{1d6a8}', '\u{1d6c0}'), ('\u{1d6c2}',
+ '\u{1d6da}'), ('\u{1d6dc}', '\u{1d6fa}'), ('\u{1d6fc}', '\u{1d714}'), ('\u{1d716}',
+ '\u{1d734}'), ('\u{1d736}', '\u{1d74e}'), ('\u{1d750}', '\u{1d76e}'), ('\u{1d770}',
+ '\u{1d788}'), ('\u{1d78a}', '\u{1d7a8}'), ('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}',
+ '\u{1d7cb}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'), ('\u{1ee05}',
+ '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'), ('\u{1ee27}',
+ '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'), ('\u{1ee39}',
+ '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'), ('\u{1ee47}',
+ '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'), ('\u{1ee4d}',
+ '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'), ('\u{1ee57}',
+ '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'), ('\u{1ee5d}',
+ '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'), ('\u{1ee64}',
+ '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'), ('\u{1ee74}',
+ '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'), ('\u{1ee80}',
+ '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'), ('\u{1eea5}',
+ '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{2a6d6}'), ('\u{2a700}',
+ '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
];
- pub static LC_table: &'static [(char, char)] = &[
+ pub const LC_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{c0}', '\u{d6}'),
('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c4}', '\u{293}'),
('\u{295}', '\u{2af}'), ('\u{370}', '\u{373}'), ('\u{376}', '\u{377}'), ('\u{37b}',
('\u{1d7aa}', '\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7cb}')
];
- pub static Ll_table: &'static [(char, char)] = &[
+ pub const Ll_table: &'static [(char, char)] = &[
('\u{61}', '\u{7a}'), ('\u{b5}', '\u{b5}'), ('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'),
('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'), ('\u{105}', '\u{105}'), ('\u{107}',
'\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}', '\u{10b}'), ('\u{10d}', '\u{10d}'),
'\u{1d7c2}'), ('\u{1d7c4}', '\u{1d7c9}'), ('\u{1d7cb}', '\u{1d7cb}')
];
- pub static Lm_table: &'static [(char, char)] = &[
+ pub const Lm_table: &'static [(char, char)] = &[
('\u{2b0}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'), ('\u{2ec}',
'\u{2ec}'), ('\u{2ee}', '\u{2ee}'), ('\u{374}', '\u{374}'), ('\u{37a}', '\u{37a}'),
('\u{559}', '\u{559}'), ('\u{640}', '\u{640}'), ('\u{6e5}', '\u{6e6}'), ('\u{7f4}',
'\u{16f9f}')
];
- pub static Lo_table: &'static [(char, char)] = &[
+ pub const Lo_table: &'static [(char, char)] = &[
('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'), ('\u{1bb}', '\u{1bb}'), ('\u{1c0}', '\u{1c3}'),
('\u{294}', '\u{294}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}', '\u{5f2}'), ('\u{620}',
'\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{66e}', '\u{66f}'), ('\u{671}', '\u{6d3}'),
'\u{2dd6}'), ('\u{2dd8}', '\u{2dde}'), ('\u{3006}', '\u{3006}'), ('\u{303c}', '\u{303c}'),
('\u{3041}', '\u{3096}'), ('\u{309f}', '\u{309f}'), ('\u{30a1}', '\u{30fa}'), ('\u{30ff}',
'\u{30ff}'), ('\u{3105}', '\u{312d}'), ('\u{3131}', '\u{318e}'), ('\u{31a0}', '\u{31ba}'),
- ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{3400}'), ('\u{4db5}', '\u{4db5}'), ('\u{4e00}',
- '\u{4e00}'), ('\u{9fcc}', '\u{9fcc}'), ('\u{a000}', '\u{a014}'), ('\u{a016}', '\u{a48c}'),
- ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'), ('\u{a610}', '\u{a61f}'), ('\u{a62a}',
- '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}', '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'),
- ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'), ('\u{a807}', '\u{a80a}'), ('\u{a80c}',
- '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'),
- ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'), ('\u{a930}', '\u{a946}'), ('\u{a960}',
- '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}', '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'),
- ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'), ('\u{aa40}', '\u{aa42}'), ('\u{aa44}',
- '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}', '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'),
- ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab9}',
- '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}', '\u{aac2}'), ('\u{aadb}', '\u{aadc}'),
- ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{ab01}', '\u{ab06}'), ('\u{ab09}',
- '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'),
- ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{ac00}'), ('\u{d7a3}', '\u{d7a3}'), ('\u{d7b0}',
- '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}', '\u{fad9}'),
- ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'), ('\u{fb38}',
- '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}', '\u{fb44}'),
- ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'), ('\u{fd92}',
- '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}', '\u{fefc}'),
- ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}',
- '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}'),
- ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'),
- ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'),
- ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}', '\u{102d0}'),
- ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}', '\u{10349}'),
- ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}', '\u{103c3}'),
- ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}', '\u{10527}'),
- ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'),
- ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'),
- ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'),
- ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}', '\u{1089e}'),
- ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}', '\u{109b7}'),
- ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}', '\u{10a13}'),
- ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}', '\u{10a7c}'),
- ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}', '\u{10ae4}'),
- ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}', '\u{10b72}'),
- ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}', '\u{11037}'),
- ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}', '\u{11126}'),
- ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}', '\u{111b2}'),
- ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}', '\u{11211}'),
- ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}', '\u{1130c}'),
- ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'),
- ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}', '\u{1133d}'),
- ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}', '\u{114c5}'),
- ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}', '\u{1162f}'),
- ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}', '\u{118ff}'),
- ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}', '\u{1342e}'),
- ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}', '\u{16aed}'),
- ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}'),
- ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}', '\u{1b001}'),
- ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'),
- ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}', '\u{1ee03}'),
- ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}', '\u{1ee24}'),
- ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}', '\u{1ee37}'),
- ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}', '\u{1ee42}'),
- ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}', '\u{1ee4b}'),
- ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}', '\u{1ee54}'),
- ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}', '\u{1ee5b}'),
- ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}', '\u{1ee62}'),
- ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}', '\u{1ee72}'),
- ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}', '\u{1ee7e}'),
- ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}', '\u{1eea3}'),
- ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}', '\u{20000}'),
- ('\u{2a6d6}', '\u{2a6d6}'), ('\u{2a700}', '\u{2a700}'), ('\u{2b734}', '\u{2b734}'),
- ('\u{2b740}', '\u{2b740}'), ('\u{2b81d}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
+ ('\u{31f0}', '\u{31ff}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{a000}',
+ '\u{a014}'), ('\u{a016}', '\u{a48c}'), ('\u{a4d0}', '\u{a4f7}'), ('\u{a500}', '\u{a60b}'),
+ ('\u{a610}', '\u{a61f}'), ('\u{a62a}', '\u{a62b}'), ('\u{a66e}', '\u{a66e}'), ('\u{a6a0}',
+ '\u{a6e5}'), ('\u{a7f7}', '\u{a7f7}'), ('\u{a7fb}', '\u{a801}'), ('\u{a803}', '\u{a805}'),
+ ('\u{a807}', '\u{a80a}'), ('\u{a80c}', '\u{a822}'), ('\u{a840}', '\u{a873}'), ('\u{a882}',
+ '\u{a8b3}'), ('\u{a8f2}', '\u{a8f7}'), ('\u{a8fb}', '\u{a8fb}'), ('\u{a90a}', '\u{a925}'),
+ ('\u{a930}', '\u{a946}'), ('\u{a960}', '\u{a97c}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9e0}',
+ '\u{a9e4}'), ('\u{a9e7}', '\u{a9ef}'), ('\u{a9fa}', '\u{a9fe}'), ('\u{aa00}', '\u{aa28}'),
+ ('\u{aa40}', '\u{aa42}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa60}', '\u{aa6f}'), ('\u{aa71}',
+ '\u{aa76}'), ('\u{aa7a}', '\u{aa7a}'), ('\u{aa7e}', '\u{aaaf}'), ('\u{aab1}', '\u{aab1}'),
+ ('\u{aab5}', '\u{aab6}'), ('\u{aab9}', '\u{aabd}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac2}',
+ '\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aae0}', '\u{aaea}'), ('\u{aaf2}', '\u{aaf2}'),
+ ('\u{ab01}', '\u{ab06}'), ('\u{ab09}', '\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}',
+ '\u{ab26}'), ('\u{ab28}', '\u{ab2e}'), ('\u{abc0}', '\u{abe2}'), ('\u{ac00}', '\u{d7a3}'),
+ ('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{f900}', '\u{fa6d}'), ('\u{fa70}',
+ '\u{fad9}'), ('\u{fb1d}', '\u{fb1d}'), ('\u{fb1f}', '\u{fb28}'), ('\u{fb2a}', '\u{fb36}'),
+ ('\u{fb38}', '\u{fb3c}'), ('\u{fb3e}', '\u{fb3e}'), ('\u{fb40}', '\u{fb41}'), ('\u{fb43}',
+ '\u{fb44}'), ('\u{fb46}', '\u{fbb1}'), ('\u{fbd3}', '\u{fd3d}'), ('\u{fd50}', '\u{fd8f}'),
+ ('\u{fd92}', '\u{fdc7}'), ('\u{fdf0}', '\u{fdfb}'), ('\u{fe70}', '\u{fe74}'), ('\u{fe76}',
+ '\u{fefc}'), ('\u{ff66}', '\u{ff6f}'), ('\u{ff71}', '\u{ff9d}'), ('\u{ffa0}', '\u{ffbe}'),
+ ('\u{ffc2}', '\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}',
+ '\u{ffdc}'), ('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}',
+ '\u{1003a}'), ('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}',
+ '\u{1005d}'), ('\u{10080}', '\u{100fa}'), ('\u{10280}', '\u{1029c}'), ('\u{102a0}',
+ '\u{102d0}'), ('\u{10300}', '\u{1031f}'), ('\u{10330}', '\u{10340}'), ('\u{10342}',
+ '\u{10349}'), ('\u{10350}', '\u{10375}'), ('\u{10380}', '\u{1039d}'), ('\u{103a0}',
+ '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{10450}', '\u{1049d}'), ('\u{10500}',
+ '\u{10527}'), ('\u{10530}', '\u{10563}'), ('\u{10600}', '\u{10736}'), ('\u{10740}',
+ '\u{10755}'), ('\u{10760}', '\u{10767}'), ('\u{10800}', '\u{10805}'), ('\u{10808}',
+ '\u{10808}'), ('\u{1080a}', '\u{10835}'), ('\u{10837}', '\u{10838}'), ('\u{1083c}',
+ '\u{1083c}'), ('\u{1083f}', '\u{10855}'), ('\u{10860}', '\u{10876}'), ('\u{10880}',
+ '\u{1089e}'), ('\u{10900}', '\u{10915}'), ('\u{10920}', '\u{10939}'), ('\u{10980}',
+ '\u{109b7}'), ('\u{109be}', '\u{109bf}'), ('\u{10a00}', '\u{10a00}'), ('\u{10a10}',
+ '\u{10a13}'), ('\u{10a15}', '\u{10a17}'), ('\u{10a19}', '\u{10a33}'), ('\u{10a60}',
+ '\u{10a7c}'), ('\u{10a80}', '\u{10a9c}'), ('\u{10ac0}', '\u{10ac7}'), ('\u{10ac9}',
+ '\u{10ae4}'), ('\u{10b00}', '\u{10b35}'), ('\u{10b40}', '\u{10b55}'), ('\u{10b60}',
+ '\u{10b72}'), ('\u{10b80}', '\u{10b91}'), ('\u{10c00}', '\u{10c48}'), ('\u{11003}',
+ '\u{11037}'), ('\u{11083}', '\u{110af}'), ('\u{110d0}', '\u{110e8}'), ('\u{11103}',
+ '\u{11126}'), ('\u{11150}', '\u{11172}'), ('\u{11176}', '\u{11176}'), ('\u{11183}',
+ '\u{111b2}'), ('\u{111c1}', '\u{111c4}'), ('\u{111da}', '\u{111da}'), ('\u{11200}',
+ '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{112b0}', '\u{112de}'), ('\u{11305}',
+ '\u{1130c}'), ('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}',
+ '\u{11330}'), ('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133d}',
+ '\u{1133d}'), ('\u{1135d}', '\u{11361}'), ('\u{11480}', '\u{114af}'), ('\u{114c4}',
+ '\u{114c5}'), ('\u{114c7}', '\u{114c7}'), ('\u{11580}', '\u{115ae}'), ('\u{11600}',
+ '\u{1162f}'), ('\u{11644}', '\u{11644}'), ('\u{11680}', '\u{116aa}'), ('\u{118ff}',
+ '\u{118ff}'), ('\u{11ac0}', '\u{11af8}'), ('\u{12000}', '\u{12398}'), ('\u{13000}',
+ '\u{1342e}'), ('\u{16800}', '\u{16a38}'), ('\u{16a40}', '\u{16a5e}'), ('\u{16ad0}',
+ '\u{16aed}'), ('\u{16b00}', '\u{16b2f}'), ('\u{16b63}', '\u{16b77}'), ('\u{16b7d}',
+ '\u{16b8f}'), ('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{1b000}',
+ '\u{1b001}'), ('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}',
+ '\u{1bc88}'), ('\u{1bc90}', '\u{1bc99}'), ('\u{1e800}', '\u{1e8c4}'), ('\u{1ee00}',
+ '\u{1ee03}'), ('\u{1ee05}', '\u{1ee1f}'), ('\u{1ee21}', '\u{1ee22}'), ('\u{1ee24}',
+ '\u{1ee24}'), ('\u{1ee27}', '\u{1ee27}'), ('\u{1ee29}', '\u{1ee32}'), ('\u{1ee34}',
+ '\u{1ee37}'), ('\u{1ee39}', '\u{1ee39}'), ('\u{1ee3b}', '\u{1ee3b}'), ('\u{1ee42}',
+ '\u{1ee42}'), ('\u{1ee47}', '\u{1ee47}'), ('\u{1ee49}', '\u{1ee49}'), ('\u{1ee4b}',
+ '\u{1ee4b}'), ('\u{1ee4d}', '\u{1ee4f}'), ('\u{1ee51}', '\u{1ee52}'), ('\u{1ee54}',
+ '\u{1ee54}'), ('\u{1ee57}', '\u{1ee57}'), ('\u{1ee59}', '\u{1ee59}'), ('\u{1ee5b}',
+ '\u{1ee5b}'), ('\u{1ee5d}', '\u{1ee5d}'), ('\u{1ee5f}', '\u{1ee5f}'), ('\u{1ee61}',
+ '\u{1ee62}'), ('\u{1ee64}', '\u{1ee64}'), ('\u{1ee67}', '\u{1ee6a}'), ('\u{1ee6c}',
+ '\u{1ee72}'), ('\u{1ee74}', '\u{1ee77}'), ('\u{1ee79}', '\u{1ee7c}'), ('\u{1ee7e}',
+ '\u{1ee7e}'), ('\u{1ee80}', '\u{1ee89}'), ('\u{1ee8b}', '\u{1ee9b}'), ('\u{1eea1}',
+ '\u{1eea3}'), ('\u{1eea5}', '\u{1eea9}'), ('\u{1eeab}', '\u{1eebb}'), ('\u{20000}',
+ '\u{2a6d6}'), ('\u{2a700}', '\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}',
+ '\u{2fa1d}')
];
- pub static Lt_table: &'static [(char, char)] = &[
+ pub const Lt_table: &'static [(char, char)] = &[
('\u{1c5}', '\u{1c5}'), ('\u{1c8}', '\u{1c8}'), ('\u{1cb}', '\u{1cb}'), ('\u{1f2}',
'\u{1f2}'), ('\u{1f88}', '\u{1f8f}'), ('\u{1f98}', '\u{1f9f}'), ('\u{1fa8}', '\u{1faf}'),
('\u{1fbc}', '\u{1fbc}'), ('\u{1fcc}', '\u{1fcc}'), ('\u{1ffc}', '\u{1ffc}')
];
- pub static Lu_table: &'static [(char, char)] = &[
+ pub const Lu_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
'\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
'\u{1d7ca}')
];
- pub static M_table: &'static [(char, char)] = &[
+ pub const M_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{483}', '\u{489}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
'\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
('\u{1e8d0}', '\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static Mc_table: &'static [(char, char)] = &[
+ pub const Mc_table: &'static [(char, char)] = &[
('\u{903}', '\u{903}'), ('\u{93b}', '\u{93b}'), ('\u{93e}', '\u{940}'), ('\u{949}',
'\u{94c}'), ('\u{94e}', '\u{94f}'), ('\u{982}', '\u{983}'), ('\u{9be}', '\u{9c0}'),
('\u{9c7}', '\u{9c8}'), ('\u{9cb}', '\u{9cc}'), ('\u{9d7}', '\u{9d7}'), ('\u{a03}',
('\u{1d165}', '\u{1d166}'), ('\u{1d16d}', '\u{1d172}')
];
- pub static Me_table: &'static [(char, char)] = &[
+ pub const Me_table: &'static [(char, char)] = &[
('\u{488}', '\u{489}'), ('\u{1abe}', '\u{1abe}'), ('\u{20dd}', '\u{20e0}'), ('\u{20e2}',
'\u{20e4}'), ('\u{a670}', '\u{a672}')
];
- pub static Mn_table: &'static [(char, char)] = &[
+ pub const Mn_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{483}', '\u{487}'), ('\u{591}', '\u{5bd}'), ('\u{5bf}',
'\u{5bf}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c4}', '\u{5c5}'), ('\u{5c7}', '\u{5c7}'),
('\u{610}', '\u{61a}'), ('\u{64b}', '\u{65f}'), ('\u{670}', '\u{670}'), ('\u{6d6}',
'\u{1e8d6}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static N_table: &'static [(char, char)] = &[
+ pub const N_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
'\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
super::bsearch_range_table(c, N_table)
}
- pub static Nd_table: &'static [(char, char)] = &[
+ pub const Nd_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{660}', '\u{669}'), ('\u{6f0}', '\u{6f9}'), ('\u{7c0}',
'\u{7c9}'), ('\u{966}', '\u{96f}'), ('\u{9e6}', '\u{9ef}'), ('\u{a66}', '\u{a6f}'),
('\u{ae6}', '\u{aef}'), ('\u{b66}', '\u{b6f}'), ('\u{be6}', '\u{bef}'), ('\u{c66}',
('\u{16a60}', '\u{16a69}'), ('\u{16b50}', '\u{16b59}'), ('\u{1d7ce}', '\u{1d7ff}')
];
- pub static Nl_table: &'static [(char, char)] = &[
+ pub const Nl_table: &'static [(char, char)] = &[
('\u{16ee}', '\u{16f0}'), ('\u{2160}', '\u{2182}'), ('\u{2185}', '\u{2188}'), ('\u{3007}',
'\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'), ('\u{a6e6}', '\u{a6ef}'),
('\u{10140}', '\u{10174}'), ('\u{10341}', '\u{10341}'), ('\u{1034a}', '\u{1034a}'),
('\u{103d1}', '\u{103d5}'), ('\u{12400}', '\u{1246e}')
];
- pub static No_table: &'static [(char, char)] = &[
+ pub const No_table: &'static [(char, char)] = &[
('\u{b2}', '\u{b3}'), ('\u{b9}', '\u{b9}'), ('\u{bc}', '\u{be}'), ('\u{9f4}', '\u{9f9}'),
('\u{b72}', '\u{b77}'), ('\u{bf0}', '\u{bf2}'), ('\u{c78}', '\u{c7e}'), ('\u{d70}',
'\u{d75}'), ('\u{f2a}', '\u{f33}'), ('\u{1369}', '\u{137c}'), ('\u{17f0}', '\u{17f9}'),
'\u{1d371}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1f100}', '\u{1f10c}')
];
- pub static P_table: &'static [(char, char)] = &[
+ pub const P_table: &'static [(char, char)] = &[
('\u{21}', '\u{23}'), ('\u{25}', '\u{2a}'), ('\u{2c}', '\u{2f}'), ('\u{3a}', '\u{3b}'),
('\u{3f}', '\u{40}'), ('\u{5b}', '\u{5d}'), ('\u{5f}', '\u{5f}'), ('\u{7b}', '\u{7b}'),
('\u{7d}', '\u{7d}'), ('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{ab}', '\u{ab}'),
'\u{1bc9f}')
];
- pub static Pc_table: &'static [(char, char)] = &[
+ pub const Pc_table: &'static [(char, char)] = &[
('\u{5f}', '\u{5f}'), ('\u{203f}', '\u{2040}'), ('\u{2054}', '\u{2054}'), ('\u{fe33}',
'\u{fe34}'), ('\u{fe4d}', '\u{fe4f}'), ('\u{ff3f}', '\u{ff3f}')
];
- pub static Pd_table: &'static [(char, char)] = &[
+ pub const Pd_table: &'static [(char, char)] = &[
('\u{2d}', '\u{2d}'), ('\u{58a}', '\u{58a}'), ('\u{5be}', '\u{5be}'), ('\u{1400}',
'\u{1400}'), ('\u{1806}', '\u{1806}'), ('\u{2010}', '\u{2015}'), ('\u{2e17}', '\u{2e17}'),
('\u{2e1a}', '\u{2e1a}'), ('\u{2e3a}', '\u{2e3b}'), ('\u{2e40}', '\u{2e40}'), ('\u{301c}',
('\u{fe58}', '\u{fe58}'), ('\u{fe63}', '\u{fe63}'), ('\u{ff0d}', '\u{ff0d}')
];
- pub static Pe_table: &'static [(char, char)] = &[
+ pub const Pe_table: &'static [(char, char)] = &[
('\u{29}', '\u{29}'), ('\u{5d}', '\u{5d}'), ('\u{7d}', '\u{7d}'), ('\u{f3b}', '\u{f3b}'),
('\u{f3d}', '\u{f3d}'), ('\u{169c}', '\u{169c}'), ('\u{2046}', '\u{2046}'), ('\u{207e}',
'\u{207e}'), ('\u{208e}', '\u{208e}'), ('\u{2309}', '\u{2309}'), ('\u{230b}', '\u{230b}'),
'\u{ff60}'), ('\u{ff63}', '\u{ff63}')
];
- pub static Pf_table: &'static [(char, char)] = &[
+ pub const Pf_table: &'static [(char, char)] = &[
('\u{bb}', '\u{bb}'), ('\u{2019}', '\u{2019}'), ('\u{201d}', '\u{201d}'), ('\u{203a}',
'\u{203a}'), ('\u{2e03}', '\u{2e03}'), ('\u{2e05}', '\u{2e05}'), ('\u{2e0a}', '\u{2e0a}'),
('\u{2e0d}', '\u{2e0d}'), ('\u{2e1d}', '\u{2e1d}'), ('\u{2e21}', '\u{2e21}')
];
- pub static Pi_table: &'static [(char, char)] = &[
+ pub const Pi_table: &'static [(char, char)] = &[
('\u{ab}', '\u{ab}'), ('\u{2018}', '\u{2018}'), ('\u{201b}', '\u{201c}'), ('\u{201f}',
'\u{201f}'), ('\u{2039}', '\u{2039}'), ('\u{2e02}', '\u{2e02}'), ('\u{2e04}', '\u{2e04}'),
('\u{2e09}', '\u{2e09}'), ('\u{2e0c}', '\u{2e0c}'), ('\u{2e1c}', '\u{2e1c}'), ('\u{2e20}',
'\u{2e20}')
];
- pub static Po_table: &'static [(char, char)] = &[
+ pub const Po_table: &'static [(char, char)] = &[
('\u{21}', '\u{23}'), ('\u{25}', '\u{27}'), ('\u{2a}', '\u{2a}'), ('\u{2c}', '\u{2c}'),
('\u{2e}', '\u{2f}'), ('\u{3a}', '\u{3b}'), ('\u{3f}', '\u{40}'), ('\u{5c}', '\u{5c}'),
('\u{a1}', '\u{a1}'), ('\u{a7}', '\u{a7}'), ('\u{b6}', '\u{b7}'), ('\u{bf}', '\u{bf}'),
'\u{1bc9f}')
];
- pub static Ps_table: &'static [(char, char)] = &[
+ pub const Ps_table: &'static [(char, char)] = &[
('\u{28}', '\u{28}'), ('\u{5b}', '\u{5b}'), ('\u{7b}', '\u{7b}'), ('\u{f3a}', '\u{f3a}'),
('\u{f3c}', '\u{f3c}'), ('\u{169b}', '\u{169b}'), ('\u{201a}', '\u{201a}'), ('\u{201e}',
'\u{201e}'), ('\u{2045}', '\u{2045}'), ('\u{207d}', '\u{207d}'), ('\u{208d}', '\u{208d}'),
('\u{ff62}', '\u{ff62}')
];
- pub static S_table: &'static [(char, char)] = &[
+ pub const S_table: &'static [(char, char)] = &[
('\u{24}', '\u{24}'), ('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{5e}', '\u{5e}'),
('\u{60}', '\u{60}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'), ('\u{a2}', '\u{a6}'),
('\u{a8}', '\u{a9}'), ('\u{ac}', '\u{ac}'), ('\u{ae}', '\u{b1}'), ('\u{b4}', '\u{b4}'),
'\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
];
- pub static Sc_table: &'static [(char, char)] = &[
+ pub const Sc_table: &'static [(char, char)] = &[
('\u{24}', '\u{24}'), ('\u{a2}', '\u{a5}'), ('\u{58f}', '\u{58f}'), ('\u{60b}', '\u{60b}'),
('\u{9f2}', '\u{9f3}'), ('\u{9fb}', '\u{9fb}'), ('\u{af1}', '\u{af1}'), ('\u{bf9}',
'\u{bf9}'), ('\u{e3f}', '\u{e3f}'), ('\u{17db}', '\u{17db}'), ('\u{20a0}', '\u{20bd}'),
'\u{ff04}'), ('\u{ffe0}', '\u{ffe1}'), ('\u{ffe5}', '\u{ffe6}')
];
- pub static Sk_table: &'static [(char, char)] = &[
+ pub const Sk_table: &'static [(char, char)] = &[
('\u{5e}', '\u{5e}'), ('\u{60}', '\u{60}'), ('\u{a8}', '\u{a8}'), ('\u{af}', '\u{af}'),
('\u{b4}', '\u{b4}'), ('\u{b8}', '\u{b8}'), ('\u{2c2}', '\u{2c5}'), ('\u{2d2}', '\u{2df}'),
('\u{2e5}', '\u{2eb}'), ('\u{2ed}', '\u{2ed}'), ('\u{2ef}', '\u{2ff}'), ('\u{375}',
'\u{ff3e}'), ('\u{ff40}', '\u{ff40}'), ('\u{ffe3}', '\u{ffe3}')
];
- pub static Sm_table: &'static [(char, char)] = &[
+ pub const Sm_table: &'static [(char, char)] = &[
('\u{2b}', '\u{2b}'), ('\u{3c}', '\u{3e}'), ('\u{7c}', '\u{7c}'), ('\u{7e}', '\u{7e}'),
('\u{ac}', '\u{ac}'), ('\u{b1}', '\u{b1}'), ('\u{d7}', '\u{d7}'), ('\u{f7}', '\u{f7}'),
('\u{3f6}', '\u{3f6}'), ('\u{606}', '\u{608}'), ('\u{2044}', '\u{2044}'), ('\u{2052}',
'\u{1d7c3}'), ('\u{1eef0}', '\u{1eef1}')
];
- pub static So_table: &'static [(char, char)] = &[
+ pub const So_table: &'static [(char, char)] = &[
('\u{a6}', '\u{a6}'), ('\u{a9}', '\u{a9}'), ('\u{ae}', '\u{ae}'), ('\u{b0}', '\u{b0}'),
('\u{482}', '\u{482}'), ('\u{58d}', '\u{58e}'), ('\u{60e}', '\u{60f}'), ('\u{6de}',
'\u{6de}'), ('\u{6e9}', '\u{6e9}'), ('\u{6fd}', '\u{6fe}'), ('\u{7f6}', '\u{7f6}'),
'\u{1f887}'), ('\u{1f890}', '\u{1f8ad}')
];
- pub static Z_table: &'static [(char, char)] = &[
+ pub const Z_table: &'static [(char, char)] = &[
('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
'\u{200a}'), ('\u{2028}', '\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'),
('\u{3000}', '\u{3000}')
];
- pub static Zl_table: &'static [(char, char)] = &[
+ pub const Zl_table: &'static [(char, char)] = &[
('\u{2028}', '\u{2028}')
];
- pub static Zp_table: &'static [(char, char)] = &[
+ pub const Zp_table: &'static [(char, char)] = &[
('\u{2029}', '\u{2029}')
];
- pub static Zs_table: &'static [(char, char)] = &[
+ pub const Zs_table: &'static [(char, char)] = &[
('\u{20}', '\u{20}'), ('\u{a0}', '\u{a0}'), ('\u{1680}', '\u{1680}'), ('\u{2000}',
'\u{200a}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
];
}
pub mod derived_property {
- pub static Alphabetic_table: &'static [(char, char)] = &[
+ pub const Alphabetic_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
super::bsearch_range_table(c, Alphabetic_table)
}
- pub static Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
+ pub const Default_Ignorable_Code_Point_table: &'static [(char, char)] = &[
('\u{ad}', '\u{ad}'), ('\u{34f}', '\u{34f}'), ('\u{61c}', '\u{61c}'), ('\u{115f}',
'\u{1160}'), ('\u{17b4}', '\u{17b5}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'),
('\u{200b}', '\u{200f}'), ('\u{202a}', '\u{202e}'), ('\u{2060}', '\u{2064}'), ('\u{2065}',
'\u{e00ff}'), ('\u{e0100}', '\u{e01ef}'), ('\u{e01f0}', '\u{e0fff}')
];
- pub static Lowercase_table: &'static [(char, char)] = &[
+ pub const Lowercase_table: &'static [(char, char)] = &[
('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'),
('\u{df}', '\u{f6}'), ('\u{f8}', '\u{ff}'), ('\u{101}', '\u{101}'), ('\u{103}', '\u{103}'),
('\u{105}', '\u{105}'), ('\u{107}', '\u{107}'), ('\u{109}', '\u{109}'), ('\u{10b}',
super::bsearch_range_table(c, Lowercase_table)
}
- pub static Uppercase_table: &'static [(char, char)] = &[
+ pub const Uppercase_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{de}'), ('\u{100}', '\u{100}'),
('\u{102}', '\u{102}'), ('\u{104}', '\u{104}'), ('\u{106}', '\u{106}'), ('\u{108}',
'\u{108}'), ('\u{10a}', '\u{10a}'), ('\u{10c}', '\u{10c}'), ('\u{10e}', '\u{10e}'),
super::bsearch_range_table(c, Uppercase_table)
}
- pub static XID_Continue_table: &'static [(char, char)] = &[
+ pub const XID_Continue_table: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{b7}', '\u{b7}'), ('\u{ba}', '\u{ba}'),
('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
super::bsearch_range_table(c, XID_Continue_table)
}
- pub static XID_Start_table: &'static [(char, char)] = &[
+ pub const XID_Start_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'),
('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'),
('\u{1bb}', '\u{1bb}'), ('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}',
}
pub mod script {
- pub static Arabic_table: &'static [(char, char)] = &[
+ pub const Arabic_table: &'static [(char, char)] = &[
('\u{600}', '\u{604}'), ('\u{606}', '\u{608}'), ('\u{609}', '\u{60a}'), ('\u{60b}',
'\u{60b}'), ('\u{60d}', '\u{60d}'), ('\u{60e}', '\u{60f}'), ('\u{610}', '\u{61a}'),
('\u{61e}', '\u{61e}'), ('\u{620}', '\u{63f}'), ('\u{641}', '\u{64a}'), ('\u{656}',
('\u{1eef0}', '\u{1eef1}')
];
- pub static Armenian_table: &'static [(char, char)] = &[
+ pub const Armenian_table: &'static [(char, char)] = &[
('\u{531}', '\u{556}'), ('\u{559}', '\u{559}'), ('\u{55a}', '\u{55f}'), ('\u{561}',
'\u{587}'), ('\u{58a}', '\u{58a}'), ('\u{58d}', '\u{58e}'), ('\u{58f}', '\u{58f}'),
('\u{fb13}', '\u{fb17}')
];
- pub static Avestan_table: &'static [(char, char)] = &[
+ pub const Avestan_table: &'static [(char, char)] = &[
('\u{10b00}', '\u{10b35}'), ('\u{10b39}', '\u{10b3f}')
];
- pub static Balinese_table: &'static [(char, char)] = &[
+ pub const Balinese_table: &'static [(char, char)] = &[
('\u{1b00}', '\u{1b03}'), ('\u{1b04}', '\u{1b04}'), ('\u{1b05}', '\u{1b33}'), ('\u{1b34}',
'\u{1b34}'), ('\u{1b35}', '\u{1b35}'), ('\u{1b36}', '\u{1b3a}'), ('\u{1b3b}', '\u{1b3b}'),
('\u{1b3c}', '\u{1b3c}'), ('\u{1b3d}', '\u{1b41}'), ('\u{1b42}', '\u{1b42}'), ('\u{1b43}',
('\u{1b61}', '\u{1b6a}'), ('\u{1b6b}', '\u{1b73}'), ('\u{1b74}', '\u{1b7c}')
];
- pub static Bamum_table: &'static [(char, char)] = &[
+ pub const Bamum_table: &'static [(char, char)] = &[
('\u{a6a0}', '\u{a6e5}'), ('\u{a6e6}', '\u{a6ef}'), ('\u{a6f0}', '\u{a6f1}'), ('\u{a6f2}',
'\u{a6f7}'), ('\u{16800}', '\u{16a38}')
];
- pub static Bassa_Vah_table: &'static [(char, char)] = &[
+ pub const Bassa_Vah_table: &'static [(char, char)] = &[
('\u{16ad0}', '\u{16aed}'), ('\u{16af0}', '\u{16af4}'), ('\u{16af5}', '\u{16af5}')
];
- pub static Batak_table: &'static [(char, char)] = &[
+ pub const Batak_table: &'static [(char, char)] = &[
('\u{1bc0}', '\u{1be5}'), ('\u{1be6}', '\u{1be6}'), ('\u{1be7}', '\u{1be7}'), ('\u{1be8}',
'\u{1be9}'), ('\u{1bea}', '\u{1bec}'), ('\u{1bed}', '\u{1bed}'), ('\u{1bee}', '\u{1bee}'),
('\u{1bef}', '\u{1bf1}'), ('\u{1bf2}', '\u{1bf3}'), ('\u{1bfc}', '\u{1bff}')
];
- pub static Bengali_table: &'static [(char, char)] = &[
+ pub const Bengali_table: &'static [(char, char)] = &[
('\u{980}', '\u{980}'), ('\u{981}', '\u{981}'), ('\u{982}', '\u{983}'), ('\u{985}',
'\u{98c}'), ('\u{98f}', '\u{990}'), ('\u{993}', '\u{9a8}'), ('\u{9aa}', '\u{9b0}'),
('\u{9b2}', '\u{9b2}'), ('\u{9b6}', '\u{9b9}'), ('\u{9bc}', '\u{9bc}'), ('\u{9bd}',
'\u{9f9}'), ('\u{9fa}', '\u{9fa}'), ('\u{9fb}', '\u{9fb}')
];
- pub static Bopomofo_table: &'static [(char, char)] = &[
+ pub const Bopomofo_table: &'static [(char, char)] = &[
('\u{2ea}', '\u{2eb}'), ('\u{3105}', '\u{312d}'), ('\u{31a0}', '\u{31ba}')
];
- pub static Brahmi_table: &'static [(char, char)] = &[
+ pub const Brahmi_table: &'static [(char, char)] = &[
('\u{11000}', '\u{11000}'), ('\u{11001}', '\u{11001}'), ('\u{11002}', '\u{11002}'),
('\u{11003}', '\u{11037}'), ('\u{11038}', '\u{11046}'), ('\u{11047}', '\u{1104d}'),
('\u{11052}', '\u{11065}'), ('\u{11066}', '\u{1106f}'), ('\u{1107f}', '\u{1107f}')
];
- pub static Braille_table: &'static [(char, char)] = &[
+ pub const Braille_table: &'static [(char, char)] = &[
('\u{2800}', '\u{28ff}')
];
- pub static Buginese_table: &'static [(char, char)] = &[
+ pub const Buginese_table: &'static [(char, char)] = &[
('\u{1a00}', '\u{1a16}'), ('\u{1a17}', '\u{1a18}'), ('\u{1a19}', '\u{1a1a}'), ('\u{1a1b}',
'\u{1a1b}'), ('\u{1a1e}', '\u{1a1f}')
];
- pub static Buhid_table: &'static [(char, char)] = &[
+ pub const Buhid_table: &'static [(char, char)] = &[
('\u{1740}', '\u{1751}'), ('\u{1752}', '\u{1753}')
];
- pub static Canadian_Aboriginal_table: &'static [(char, char)] = &[
+ pub const Canadian_Aboriginal_table: &'static [(char, char)] = &[
('\u{1400}', '\u{1400}'), ('\u{1401}', '\u{166c}'), ('\u{166d}', '\u{166e}'), ('\u{166f}',
'\u{167f}'), ('\u{18b0}', '\u{18f5}')
];
- pub static Carian_table: &'static [(char, char)] = &[
+ pub const Carian_table: &'static [(char, char)] = &[
('\u{102a0}', '\u{102d0}')
];
- pub static Caucasian_Albanian_table: &'static [(char, char)] = &[
+ pub const Caucasian_Albanian_table: &'static [(char, char)] = &[
('\u{10530}', '\u{10563}'), ('\u{1056f}', '\u{1056f}')
];
- pub static Chakma_table: &'static [(char, char)] = &[
+ pub const Chakma_table: &'static [(char, char)] = &[
('\u{11100}', '\u{11102}'), ('\u{11103}', '\u{11126}'), ('\u{11127}', '\u{1112b}'),
('\u{1112c}', '\u{1112c}'), ('\u{1112d}', '\u{11134}'), ('\u{11136}', '\u{1113f}'),
('\u{11140}', '\u{11143}')
];
- pub static Cham_table: &'static [(char, char)] = &[
+ pub const Cham_table: &'static [(char, char)] = &[
('\u{aa00}', '\u{aa28}'), ('\u{aa29}', '\u{aa2e}'), ('\u{aa2f}', '\u{aa30}'), ('\u{aa31}',
'\u{aa32}'), ('\u{aa33}', '\u{aa34}'), ('\u{aa35}', '\u{aa36}'), ('\u{aa40}', '\u{aa42}'),
('\u{aa43}', '\u{aa43}'), ('\u{aa44}', '\u{aa4b}'), ('\u{aa4c}', '\u{aa4c}'), ('\u{aa4d}',
'\u{aa4d}'), ('\u{aa50}', '\u{aa59}'), ('\u{aa5c}', '\u{aa5f}')
];
- pub static Cherokee_table: &'static [(char, char)] = &[
+ pub const Cherokee_table: &'static [(char, char)] = &[
('\u{13a0}', '\u{13f4}')
];
- pub static Common_table: &'static [(char, char)] = &[
+ pub const Common_table: &'static [(char, char)] = &[
('\u{0}', '\u{1f}'), ('\u{20}', '\u{20}'), ('\u{21}', '\u{23}'), ('\u{24}', '\u{24}'),
('\u{25}', '\u{27}'), ('\u{28}', '\u{28}'), ('\u{29}', '\u{29}'), ('\u{2a}', '\u{2a}'),
('\u{2b}', '\u{2b}'), ('\u{2c}', '\u{2c}'), ('\u{2d}', '\u{2d}'), ('\u{2e}', '\u{2f}'),
('\u{1f890}', '\u{1f8ad}'), ('\u{e0001}', '\u{e0001}'), ('\u{e0020}', '\u{e007f}')
];
- pub static Coptic_table: &'static [(char, char)] = &[
+ pub const Coptic_table: &'static [(char, char)] = &[
('\u{3e2}', '\u{3ef}'), ('\u{2c80}', '\u{2ce4}'), ('\u{2ce5}', '\u{2cea}'), ('\u{2ceb}',
'\u{2cee}'), ('\u{2cef}', '\u{2cf1}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{2cf9}', '\u{2cfc}'),
('\u{2cfd}', '\u{2cfd}'), ('\u{2cfe}', '\u{2cff}')
];
- pub static Cuneiform_table: &'static [(char, char)] = &[
+ pub const Cuneiform_table: &'static [(char, char)] = &[
('\u{12000}', '\u{12398}'), ('\u{12400}', '\u{1246e}'), ('\u{12470}', '\u{12474}')
];
- pub static Cypriot_table: &'static [(char, char)] = &[
+ pub const Cypriot_table: &'static [(char, char)] = &[
('\u{10800}', '\u{10805}'), ('\u{10808}', '\u{10808}'), ('\u{1080a}', '\u{10835}'),
('\u{10837}', '\u{10838}'), ('\u{1083c}', '\u{1083c}'), ('\u{1083f}', '\u{1083f}')
];
- pub static Cyrillic_table: &'static [(char, char)] = &[
+ pub const Cyrillic_table: &'static [(char, char)] = &[
('\u{400}', '\u{481}'), ('\u{482}', '\u{482}'), ('\u{483}', '\u{484}'), ('\u{487}',
'\u{487}'), ('\u{488}', '\u{489}'), ('\u{48a}', '\u{52f}'), ('\u{1d2b}', '\u{1d2b}'),
('\u{1d78}', '\u{1d78}'), ('\u{2de0}', '\u{2dff}'), ('\u{a640}', '\u{a66d}'), ('\u{a66e}',
'\u{a69b}'), ('\u{a69c}', '\u{a69d}'), ('\u{a69f}', '\u{a69f}')
];
- pub static Deseret_table: &'static [(char, char)] = &[
+ pub const Deseret_table: &'static [(char, char)] = &[
('\u{10400}', '\u{1044f}')
];
- pub static Devanagari_table: &'static [(char, char)] = &[
+ pub const Devanagari_table: &'static [(char, char)] = &[
('\u{900}', '\u{902}'), ('\u{903}', '\u{903}'), ('\u{904}', '\u{939}'), ('\u{93a}',
'\u{93a}'), ('\u{93b}', '\u{93b}'), ('\u{93c}', '\u{93c}'), ('\u{93d}', '\u{93d}'),
('\u{93e}', '\u{940}'), ('\u{941}', '\u{948}'), ('\u{949}', '\u{94c}'), ('\u{94d}',
('\u{a8f2}', '\u{a8f7}'), ('\u{a8f8}', '\u{a8fa}'), ('\u{a8fb}', '\u{a8fb}')
];
- pub static Duployan_table: &'static [(char, char)] = &[
+ pub const Duployan_table: &'static [(char, char)] = &[
('\u{1bc00}', '\u{1bc6a}'), ('\u{1bc70}', '\u{1bc7c}'), ('\u{1bc80}', '\u{1bc88}'),
('\u{1bc90}', '\u{1bc99}'), ('\u{1bc9c}', '\u{1bc9c}'), ('\u{1bc9d}', '\u{1bc9e}'),
('\u{1bc9f}', '\u{1bc9f}')
];
- pub static Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
+ pub const Egyptian_Hieroglyphs_table: &'static [(char, char)] = &[
('\u{13000}', '\u{1342e}')
];
- pub static Elbasan_table: &'static [(char, char)] = &[
+ pub const Elbasan_table: &'static [(char, char)] = &[
('\u{10500}', '\u{10527}')
];
- pub static Ethiopic_table: &'static [(char, char)] = &[
+ pub const Ethiopic_table: &'static [(char, char)] = &[
('\u{1200}', '\u{1248}'), ('\u{124a}', '\u{124d}'), ('\u{1250}', '\u{1256}'), ('\u{1258}',
'\u{1258}'), ('\u{125a}', '\u{125d}'), ('\u{1260}', '\u{1288}'), ('\u{128a}', '\u{128d}'),
('\u{1290}', '\u{12b0}'), ('\u{12b2}', '\u{12b5}'), ('\u{12b8}', '\u{12be}'), ('\u{12c0}',
'\u{ab0e}'), ('\u{ab11}', '\u{ab16}'), ('\u{ab20}', '\u{ab26}'), ('\u{ab28}', '\u{ab2e}')
];
- pub static Georgian_table: &'static [(char, char)] = &[
+ pub const Georgian_table: &'static [(char, char)] = &[
('\u{10a0}', '\u{10c5}'), ('\u{10c7}', '\u{10c7}'), ('\u{10cd}', '\u{10cd}'), ('\u{10d0}',
'\u{10fa}'), ('\u{10fc}', '\u{10fc}'), ('\u{10fd}', '\u{10ff}'), ('\u{2d00}', '\u{2d25}'),
('\u{2d27}', '\u{2d27}'), ('\u{2d2d}', '\u{2d2d}')
];
- pub static Glagolitic_table: &'static [(char, char)] = &[
+ pub const Glagolitic_table: &'static [(char, char)] = &[
('\u{2c00}', '\u{2c2e}'), ('\u{2c30}', '\u{2c5e}')
];
- pub static Gothic_table: &'static [(char, char)] = &[
+ pub const Gothic_table: &'static [(char, char)] = &[
('\u{10330}', '\u{10340}'), ('\u{10341}', '\u{10341}'), ('\u{10342}', '\u{10349}'),
('\u{1034a}', '\u{1034a}')
];
- pub static Grantha_table: &'static [(char, char)] = &[
+ pub const Grantha_table: &'static [(char, char)] = &[
('\u{11301}', '\u{11301}'), ('\u{11302}', '\u{11303}'), ('\u{11305}', '\u{1130c}'),
('\u{1130f}', '\u{11310}'), ('\u{11313}', '\u{11328}'), ('\u{1132a}', '\u{11330}'),
('\u{11332}', '\u{11333}'), ('\u{11335}', '\u{11339}'), ('\u{1133c}', '\u{1133c}'),
('\u{11366}', '\u{1136c}'), ('\u{11370}', '\u{11374}')
];
- pub static Greek_table: &'static [(char, char)] = &[
+ pub const Greek_table: &'static [(char, char)] = &[
('\u{370}', '\u{373}'), ('\u{375}', '\u{375}'), ('\u{376}', '\u{377}'), ('\u{37a}',
'\u{37a}'), ('\u{37b}', '\u{37d}'), ('\u{37f}', '\u{37f}'), ('\u{384}', '\u{384}'),
('\u{386}', '\u{386}'), ('\u{388}', '\u{38a}'), ('\u{38c}', '\u{38c}'), ('\u{38e}',
'\u{1d245}')
];
- pub static Gujarati_table: &'static [(char, char)] = &[
+ pub const Gujarati_table: &'static [(char, char)] = &[
('\u{a81}', '\u{a82}'), ('\u{a83}', '\u{a83}'), ('\u{a85}', '\u{a8d}'), ('\u{a8f}',
'\u{a91}'), ('\u{a93}', '\u{aa8}'), ('\u{aaa}', '\u{ab0}'), ('\u{ab2}', '\u{ab3}'),
('\u{ab5}', '\u{ab9}'), ('\u{abc}', '\u{abc}'), ('\u{abd}', '\u{abd}'), ('\u{abe}',
('\u{af1}', '\u{af1}')
];
- pub static Gurmukhi_table: &'static [(char, char)] = &[
+ pub const Gurmukhi_table: &'static [(char, char)] = &[
('\u{a01}', '\u{a02}'), ('\u{a03}', '\u{a03}'), ('\u{a05}', '\u{a0a}'), ('\u{a0f}',
'\u{a10}'), ('\u{a13}', '\u{a28}'), ('\u{a2a}', '\u{a30}'), ('\u{a32}', '\u{a33}'),
('\u{a35}', '\u{a36}'), ('\u{a38}', '\u{a39}'), ('\u{a3c}', '\u{a3c}'), ('\u{a3e}',
'\u{a6f}'), ('\u{a70}', '\u{a71}'), ('\u{a72}', '\u{a74}'), ('\u{a75}', '\u{a75}')
];
- pub static Han_table: &'static [(char, char)] = &[
+ pub const Han_table: &'static [(char, char)] = &[
('\u{2e80}', '\u{2e99}'), ('\u{2e9b}', '\u{2ef3}'), ('\u{2f00}', '\u{2fd5}'), ('\u{3005}',
'\u{3005}'), ('\u{3007}', '\u{3007}'), ('\u{3021}', '\u{3029}'), ('\u{3038}', '\u{303a}'),
('\u{303b}', '\u{303b}'), ('\u{3400}', '\u{4db5}'), ('\u{4e00}', '\u{9fcc}'), ('\u{f900}',
'\u{2b734}'), ('\u{2b740}', '\u{2b81d}'), ('\u{2f800}', '\u{2fa1d}')
];
- pub static Hangul_table: &'static [(char, char)] = &[
+ pub const Hangul_table: &'static [(char, char)] = &[
('\u{1100}', '\u{11ff}'), ('\u{302e}', '\u{302f}'), ('\u{3131}', '\u{318e}'), ('\u{3200}',
'\u{321e}'), ('\u{3260}', '\u{327e}'), ('\u{a960}', '\u{a97c}'), ('\u{ac00}', '\u{d7a3}'),
('\u{d7b0}', '\u{d7c6}'), ('\u{d7cb}', '\u{d7fb}'), ('\u{ffa0}', '\u{ffbe}'), ('\u{ffc2}',
'\u{ffc7}'), ('\u{ffca}', '\u{ffcf}'), ('\u{ffd2}', '\u{ffd7}'), ('\u{ffda}', '\u{ffdc}')
];
- pub static Hanunoo_table: &'static [(char, char)] = &[
+ pub const Hanunoo_table: &'static [(char, char)] = &[
('\u{1720}', '\u{1731}'), ('\u{1732}', '\u{1734}')
];
- pub static Hebrew_table: &'static [(char, char)] = &[
+ pub const Hebrew_table: &'static [(char, char)] = &[
('\u{591}', '\u{5bd}'), ('\u{5be}', '\u{5be}'), ('\u{5bf}', '\u{5bf}'), ('\u{5c0}',
'\u{5c0}'), ('\u{5c1}', '\u{5c2}'), ('\u{5c3}', '\u{5c3}'), ('\u{5c4}', '\u{5c5}'),
('\u{5c6}', '\u{5c6}'), ('\u{5c7}', '\u{5c7}'), ('\u{5d0}', '\u{5ea}'), ('\u{5f0}',
('\u{fb46}', '\u{fb4f}')
];
- pub static Hiragana_table: &'static [(char, char)] = &[
+ pub const Hiragana_table: &'static [(char, char)] = &[
('\u{3041}', '\u{3096}'), ('\u{309d}', '\u{309e}'), ('\u{309f}', '\u{309f}'), ('\u{1b001}',
'\u{1b001}'), ('\u{1f200}', '\u{1f200}')
];
- pub static Imperial_Aramaic_table: &'static [(char, char)] = &[
+ pub const Imperial_Aramaic_table: &'static [(char, char)] = &[
('\u{10840}', '\u{10855}'), ('\u{10857}', '\u{10857}'), ('\u{10858}', '\u{1085f}')
];
- pub static Inherited_table: &'static [(char, char)] = &[
+ pub const Inherited_table: &'static [(char, char)] = &[
('\u{300}', '\u{36f}'), ('\u{485}', '\u{486}'), ('\u{64b}', '\u{655}'), ('\u{670}',
'\u{670}'), ('\u{951}', '\u{952}'), ('\u{1ab0}', '\u{1abd}'), ('\u{1abe}', '\u{1abe}'),
('\u{1cd0}', '\u{1cd2}'), ('\u{1cd4}', '\u{1ce0}'), ('\u{1ce2}', '\u{1ce8}'), ('\u{1ced}',
'\u{1d1ad}'), ('\u{e0100}', '\u{e01ef}')
];
- pub static Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
+ pub const Inscriptional_Pahlavi_table: &'static [(char, char)] = &[
('\u{10b60}', '\u{10b72}'), ('\u{10b78}', '\u{10b7f}')
];
- pub static Inscriptional_Parthian_table: &'static [(char, char)] = &[
+ pub const Inscriptional_Parthian_table: &'static [(char, char)] = &[
('\u{10b40}', '\u{10b55}'), ('\u{10b58}', '\u{10b5f}')
];
- pub static Javanese_table: &'static [(char, char)] = &[
+ pub const Javanese_table: &'static [(char, char)] = &[
('\u{a980}', '\u{a982}'), ('\u{a983}', '\u{a983}'), ('\u{a984}', '\u{a9b2}'), ('\u{a9b3}',
'\u{a9b3}'), ('\u{a9b4}', '\u{a9b5}'), ('\u{a9b6}', '\u{a9b9}'), ('\u{a9ba}', '\u{a9bb}'),
('\u{a9bc}', '\u{a9bc}'), ('\u{a9bd}', '\u{a9c0}'), ('\u{a9c1}', '\u{a9cd}'), ('\u{a9d0}',
'\u{a9d9}'), ('\u{a9de}', '\u{a9df}')
];
- pub static Kaithi_table: &'static [(char, char)] = &[
+ pub const Kaithi_table: &'static [(char, char)] = &[
('\u{11080}', '\u{11081}'), ('\u{11082}', '\u{11082}'), ('\u{11083}', '\u{110af}'),
('\u{110b0}', '\u{110b2}'), ('\u{110b3}', '\u{110b6}'), ('\u{110b7}', '\u{110b8}'),
('\u{110b9}', '\u{110ba}'), ('\u{110bb}', '\u{110bc}'), ('\u{110bd}', '\u{110bd}'),
('\u{110be}', '\u{110c1}')
];
- pub static Kannada_table: &'static [(char, char)] = &[
+ pub const Kannada_table: &'static [(char, char)] = &[
('\u{c81}', '\u{c81}'), ('\u{c82}', '\u{c83}'), ('\u{c85}', '\u{c8c}'), ('\u{c8e}',
'\u{c90}'), ('\u{c92}', '\u{ca8}'), ('\u{caa}', '\u{cb3}'), ('\u{cb5}', '\u{cb9}'),
('\u{cbc}', '\u{cbc}'), ('\u{cbd}', '\u{cbd}'), ('\u{cbe}', '\u{cbe}'), ('\u{cbf}',
('\u{cf1}', '\u{cf2}')
];
- pub static Katakana_table: &'static [(char, char)] = &[
+ pub const Katakana_table: &'static [(char, char)] = &[
('\u{30a1}', '\u{30fa}'), ('\u{30fd}', '\u{30fe}'), ('\u{30ff}', '\u{30ff}'), ('\u{31f0}',
'\u{31ff}'), ('\u{32d0}', '\u{32fe}'), ('\u{3300}', '\u{3357}'), ('\u{ff66}', '\u{ff6f}'),
('\u{ff71}', '\u{ff9d}'), ('\u{1b000}', '\u{1b000}')
];
- pub static Kayah_Li_table: &'static [(char, char)] = &[
+ pub const Kayah_Li_table: &'static [(char, char)] = &[
('\u{a900}', '\u{a909}'), ('\u{a90a}', '\u{a925}'), ('\u{a926}', '\u{a92d}'), ('\u{a92f}',
'\u{a92f}')
];
- pub static Kharoshthi_table: &'static [(char, char)] = &[
+ pub const Kharoshthi_table: &'static [(char, char)] = &[
('\u{10a00}', '\u{10a00}'), ('\u{10a01}', '\u{10a03}'), ('\u{10a05}', '\u{10a06}'),
('\u{10a0c}', '\u{10a0f}'), ('\u{10a10}', '\u{10a13}'), ('\u{10a15}', '\u{10a17}'),
('\u{10a19}', '\u{10a33}'), ('\u{10a38}', '\u{10a3a}'), ('\u{10a3f}', '\u{10a3f}'),
('\u{10a40}', '\u{10a47}'), ('\u{10a50}', '\u{10a58}')
];
- pub static Khmer_table: &'static [(char, char)] = &[
+ pub const Khmer_table: &'static [(char, char)] = &[
('\u{1780}', '\u{17b3}'), ('\u{17b4}', '\u{17b5}'), ('\u{17b6}', '\u{17b6}'), ('\u{17b7}',
'\u{17bd}'), ('\u{17be}', '\u{17c5}'), ('\u{17c6}', '\u{17c6}'), ('\u{17c7}', '\u{17c8}'),
('\u{17c9}', '\u{17d3}'), ('\u{17d4}', '\u{17d6}'), ('\u{17d7}', '\u{17d7}'), ('\u{17d8}',
('\u{17e0}', '\u{17e9}'), ('\u{17f0}', '\u{17f9}'), ('\u{19e0}', '\u{19ff}')
];
- pub static Khojki_table: &'static [(char, char)] = &[
+ pub const Khojki_table: &'static [(char, char)] = &[
('\u{11200}', '\u{11211}'), ('\u{11213}', '\u{1122b}'), ('\u{1122c}', '\u{1122e}'),
('\u{1122f}', '\u{11231}'), ('\u{11232}', '\u{11233}'), ('\u{11234}', '\u{11234}'),
('\u{11235}', '\u{11235}'), ('\u{11236}', '\u{11237}'), ('\u{11238}', '\u{1123d}')
];
- pub static Khudawadi_table: &'static [(char, char)] = &[
+ pub const Khudawadi_table: &'static [(char, char)] = &[
('\u{112b0}', '\u{112de}'), ('\u{112df}', '\u{112df}'), ('\u{112e0}', '\u{112e2}'),
('\u{112e3}', '\u{112ea}'), ('\u{112f0}', '\u{112f9}')
];
- pub static Lao_table: &'static [(char, char)] = &[
+ pub const Lao_table: &'static [(char, char)] = &[
('\u{e81}', '\u{e82}'), ('\u{e84}', '\u{e84}'), ('\u{e87}', '\u{e88}'), ('\u{e8a}',
'\u{e8a}'), ('\u{e8d}', '\u{e8d}'), ('\u{e94}', '\u{e97}'), ('\u{e99}', '\u{e9f}'),
('\u{ea1}', '\u{ea3}'), ('\u{ea5}', '\u{ea5}'), ('\u{ea7}', '\u{ea7}'), ('\u{eaa}',
('\u{edc}', '\u{edf}')
];
- pub static Latin_table: &'static [(char, char)] = &[
+ pub const Latin_table: &'static [(char, char)] = &[
('\u{41}', '\u{5a}'), ('\u{61}', '\u{7a}'), ('\u{aa}', '\u{aa}'), ('\u{ba}', '\u{ba}'),
('\u{c0}', '\u{d6}'), ('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{1ba}'), ('\u{1bb}', '\u{1bb}'),
('\u{1bc}', '\u{1bf}'), ('\u{1c0}', '\u{1c3}'), ('\u{1c4}', '\u{293}'), ('\u{294}',
'\u{ab64}'), ('\u{fb00}', '\u{fb06}'), ('\u{ff21}', '\u{ff3a}'), ('\u{ff41}', '\u{ff5a}')
];
- pub static Lepcha_table: &'static [(char, char)] = &[
+ pub const Lepcha_table: &'static [(char, char)] = &[
('\u{1c00}', '\u{1c23}'), ('\u{1c24}', '\u{1c2b}'), ('\u{1c2c}', '\u{1c33}'), ('\u{1c34}',
'\u{1c35}'), ('\u{1c36}', '\u{1c37}'), ('\u{1c3b}', '\u{1c3f}'), ('\u{1c40}', '\u{1c49}'),
('\u{1c4d}', '\u{1c4f}')
];
- pub static Limbu_table: &'static [(char, char)] = &[
+ pub const Limbu_table: &'static [(char, char)] = &[
('\u{1900}', '\u{191e}'), ('\u{1920}', '\u{1922}'), ('\u{1923}', '\u{1926}'), ('\u{1927}',
'\u{1928}'), ('\u{1929}', '\u{192b}'), ('\u{1930}', '\u{1931}'), ('\u{1932}', '\u{1932}'),
('\u{1933}', '\u{1938}'), ('\u{1939}', '\u{193b}'), ('\u{1940}', '\u{1940}'), ('\u{1944}',
'\u{1945}'), ('\u{1946}', '\u{194f}')
];
- pub static Linear_A_table: &'static [(char, char)] = &[
+ pub const Linear_A_table: &'static [(char, char)] = &[
('\u{10600}', '\u{10736}'), ('\u{10740}', '\u{10755}'), ('\u{10760}', '\u{10767}')
];
- pub static Linear_B_table: &'static [(char, char)] = &[
+ pub const Linear_B_table: &'static [(char, char)] = &[
('\u{10000}', '\u{1000b}'), ('\u{1000d}', '\u{10026}'), ('\u{10028}', '\u{1003a}'),
('\u{1003c}', '\u{1003d}'), ('\u{1003f}', '\u{1004d}'), ('\u{10050}', '\u{1005d}'),
('\u{10080}', '\u{100fa}')
];
- pub static Lisu_table: &'static [(char, char)] = &[
+ pub const Lisu_table: &'static [(char, char)] = &[
('\u{a4d0}', '\u{a4f7}'), ('\u{a4f8}', '\u{a4fd}'), ('\u{a4fe}', '\u{a4ff}')
];
- pub static Lycian_table: &'static [(char, char)] = &[
+ pub const Lycian_table: &'static [(char, char)] = &[
('\u{10280}', '\u{1029c}')
];
- pub static Lydian_table: &'static [(char, char)] = &[
+ pub const Lydian_table: &'static [(char, char)] = &[
('\u{10920}', '\u{10939}'), ('\u{1093f}', '\u{1093f}')
];
- pub static Mahajani_table: &'static [(char, char)] = &[
+ pub const Mahajani_table: &'static [(char, char)] = &[
('\u{11150}', '\u{11172}'), ('\u{11173}', '\u{11173}'), ('\u{11174}', '\u{11175}'),
('\u{11176}', '\u{11176}')
];
- pub static Malayalam_table: &'static [(char, char)] = &[
+ pub const Malayalam_table: &'static [(char, char)] = &[
('\u{d01}', '\u{d01}'), ('\u{d02}', '\u{d03}'), ('\u{d05}', '\u{d0c}'), ('\u{d0e}',
'\u{d10}'), ('\u{d12}', '\u{d3a}'), ('\u{d3d}', '\u{d3d}'), ('\u{d3e}', '\u{d40}'),
('\u{d41}', '\u{d44}'), ('\u{d46}', '\u{d48}'), ('\u{d4a}', '\u{d4c}'), ('\u{d4d}',
'\u{d79}'), ('\u{d7a}', '\u{d7f}')
];
- pub static Mandaic_table: &'static [(char, char)] = &[
+ pub const Mandaic_table: &'static [(char, char)] = &[
('\u{840}', '\u{858}'), ('\u{859}', '\u{85b}'), ('\u{85e}', '\u{85e}')
];
- pub static Manichaean_table: &'static [(char, char)] = &[
+ pub const Manichaean_table: &'static [(char, char)] = &[
('\u{10ac0}', '\u{10ac7}'), ('\u{10ac8}', '\u{10ac8}'), ('\u{10ac9}', '\u{10ae4}'),
('\u{10ae5}', '\u{10ae6}'), ('\u{10aeb}', '\u{10aef}'), ('\u{10af0}', '\u{10af6}')
];
- pub static Meetei_Mayek_table: &'static [(char, char)] = &[
+ pub const Meetei_Mayek_table: &'static [(char, char)] = &[
('\u{aae0}', '\u{aaea}'), ('\u{aaeb}', '\u{aaeb}'), ('\u{aaec}', '\u{aaed}'), ('\u{aaee}',
'\u{aaef}'), ('\u{aaf0}', '\u{aaf1}'), ('\u{aaf2}', '\u{aaf2}'), ('\u{aaf3}', '\u{aaf4}'),
('\u{aaf5}', '\u{aaf5}'), ('\u{aaf6}', '\u{aaf6}'), ('\u{abc0}', '\u{abe2}'), ('\u{abe3}',
'\u{abed}'), ('\u{abf0}', '\u{abf9}')
];
- pub static Mende_Kikakui_table: &'static [(char, char)] = &[
+ pub const Mende_Kikakui_table: &'static [(char, char)] = &[
('\u{1e800}', '\u{1e8c4}'), ('\u{1e8c7}', '\u{1e8cf}'), ('\u{1e8d0}', '\u{1e8d6}')
];
- pub static Meroitic_Cursive_table: &'static [(char, char)] = &[
+ pub const Meroitic_Cursive_table: &'static [(char, char)] = &[
('\u{109a0}', '\u{109b7}'), ('\u{109be}', '\u{109bf}')
];
- pub static Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
+ pub const Meroitic_Hieroglyphs_table: &'static [(char, char)] = &[
('\u{10980}', '\u{1099f}')
];
- pub static Miao_table: &'static [(char, char)] = &[
+ pub const Miao_table: &'static [(char, char)] = &[
('\u{16f00}', '\u{16f44}'), ('\u{16f50}', '\u{16f50}'), ('\u{16f51}', '\u{16f7e}'),
('\u{16f8f}', '\u{16f92}'), ('\u{16f93}', '\u{16f9f}')
];
- pub static Modi_table: &'static [(char, char)] = &[
+ pub const Modi_table: &'static [(char, char)] = &[
('\u{11600}', '\u{1162f}'), ('\u{11630}', '\u{11632}'), ('\u{11633}', '\u{1163a}'),
('\u{1163b}', '\u{1163c}'), ('\u{1163d}', '\u{1163d}'), ('\u{1163e}', '\u{1163e}'),
('\u{1163f}', '\u{11640}'), ('\u{11641}', '\u{11643}'), ('\u{11644}', '\u{11644}'),
('\u{11650}', '\u{11659}')
];
- pub static Mongolian_table: &'static [(char, char)] = &[
+ pub const Mongolian_table: &'static [(char, char)] = &[
('\u{1800}', '\u{1801}'), ('\u{1804}', '\u{1804}'), ('\u{1806}', '\u{1806}'), ('\u{1807}',
'\u{180a}'), ('\u{180b}', '\u{180d}'), ('\u{180e}', '\u{180e}'), ('\u{1810}', '\u{1819}'),
('\u{1820}', '\u{1842}'), ('\u{1843}', '\u{1843}'), ('\u{1844}', '\u{1877}'), ('\u{1880}',
'\u{18a8}'), ('\u{18a9}', '\u{18a9}'), ('\u{18aa}', '\u{18aa}')
];
- pub static Mro_table: &'static [(char, char)] = &[
+ pub const Mro_table: &'static [(char, char)] = &[
('\u{16a40}', '\u{16a5e}'), ('\u{16a60}', '\u{16a69}'), ('\u{16a6e}', '\u{16a6f}')
];
- pub static Myanmar_table: &'static [(char, char)] = &[
+ pub const Myanmar_table: &'static [(char, char)] = &[
('\u{1000}', '\u{102a}'), ('\u{102b}', '\u{102c}'), ('\u{102d}', '\u{1030}'), ('\u{1031}',
'\u{1031}'), ('\u{1032}', '\u{1037}'), ('\u{1038}', '\u{1038}'), ('\u{1039}', '\u{103a}'),
('\u{103b}', '\u{103c}'), ('\u{103d}', '\u{103e}'), ('\u{103f}', '\u{103f}'), ('\u{1040}',
('\u{aa7e}', '\u{aa7f}')
];
- pub static Nabataean_table: &'static [(char, char)] = &[
+ pub const Nabataean_table: &'static [(char, char)] = &[
('\u{10880}', '\u{1089e}'), ('\u{108a7}', '\u{108af}')
];
- pub static New_Tai_Lue_table: &'static [(char, char)] = &[
+ pub const New_Tai_Lue_table: &'static [(char, char)] = &[
('\u{1980}', '\u{19ab}'), ('\u{19b0}', '\u{19c0}'), ('\u{19c1}', '\u{19c7}'), ('\u{19c8}',
'\u{19c9}'), ('\u{19d0}', '\u{19d9}'), ('\u{19da}', '\u{19da}'), ('\u{19de}', '\u{19df}')
];
- pub static Nko_table: &'static [(char, char)] = &[
+ pub const Nko_table: &'static [(char, char)] = &[
('\u{7c0}', '\u{7c9}'), ('\u{7ca}', '\u{7ea}'), ('\u{7eb}', '\u{7f3}'), ('\u{7f4}',
'\u{7f5}'), ('\u{7f6}', '\u{7f6}'), ('\u{7f7}', '\u{7f9}'), ('\u{7fa}', '\u{7fa}')
];
- pub static Ogham_table: &'static [(char, char)] = &[
+ pub const Ogham_table: &'static [(char, char)] = &[
('\u{1680}', '\u{1680}'), ('\u{1681}', '\u{169a}'), ('\u{169b}', '\u{169b}'), ('\u{169c}',
'\u{169c}')
];
- pub static Ol_Chiki_table: &'static [(char, char)] = &[
+ pub const Ol_Chiki_table: &'static [(char, char)] = &[
('\u{1c50}', '\u{1c59}'), ('\u{1c5a}', '\u{1c77}'), ('\u{1c78}', '\u{1c7d}'), ('\u{1c7e}',
'\u{1c7f}')
];
- pub static Old_Italic_table: &'static [(char, char)] = &[
+ pub const Old_Italic_table: &'static [(char, char)] = &[
('\u{10300}', '\u{1031f}'), ('\u{10320}', '\u{10323}')
];
- pub static Old_North_Arabian_table: &'static [(char, char)] = &[
+ pub const Old_North_Arabian_table: &'static [(char, char)] = &[
('\u{10a80}', '\u{10a9c}'), ('\u{10a9d}', '\u{10a9f}')
];
- pub static Old_Permic_table: &'static [(char, char)] = &[
+ pub const Old_Permic_table: &'static [(char, char)] = &[
('\u{10350}', '\u{10375}'), ('\u{10376}', '\u{1037a}')
];
- pub static Old_Persian_table: &'static [(char, char)] = &[
+ pub const Old_Persian_table: &'static [(char, char)] = &[
('\u{103a0}', '\u{103c3}'), ('\u{103c8}', '\u{103cf}'), ('\u{103d0}', '\u{103d0}'),
('\u{103d1}', '\u{103d5}')
];
- pub static Old_South_Arabian_table: &'static [(char, char)] = &[
+ pub const Old_South_Arabian_table: &'static [(char, char)] = &[
('\u{10a60}', '\u{10a7c}'), ('\u{10a7d}', '\u{10a7e}'), ('\u{10a7f}', '\u{10a7f}')
];
- pub static Old_Turkic_table: &'static [(char, char)] = &[
+ pub const Old_Turkic_table: &'static [(char, char)] = &[
('\u{10c00}', '\u{10c48}')
];
- pub static Oriya_table: &'static [(char, char)] = &[
+ pub const Oriya_table: &'static [(char, char)] = &[
('\u{b01}', '\u{b01}'), ('\u{b02}', '\u{b03}'), ('\u{b05}', '\u{b0c}'), ('\u{b0f}',
'\u{b10}'), ('\u{b13}', '\u{b28}'), ('\u{b2a}', '\u{b30}'), ('\u{b32}', '\u{b33}'),
('\u{b35}', '\u{b39}'), ('\u{b3c}', '\u{b3c}'), ('\u{b3d}', '\u{b3d}'), ('\u{b3e}',
'\u{b71}'), ('\u{b72}', '\u{b77}')
];
- pub static Osmanya_table: &'static [(char, char)] = &[
+ pub const Osmanya_table: &'static [(char, char)] = &[
('\u{10480}', '\u{1049d}'), ('\u{104a0}', '\u{104a9}')
];
- pub static Pahawh_Hmong_table: &'static [(char, char)] = &[
+ pub const Pahawh_Hmong_table: &'static [(char, char)] = &[
('\u{16b00}', '\u{16b2f}'), ('\u{16b30}', '\u{16b36}'), ('\u{16b37}', '\u{16b3b}'),
('\u{16b3c}', '\u{16b3f}'), ('\u{16b40}', '\u{16b43}'), ('\u{16b44}', '\u{16b44}'),
('\u{16b45}', '\u{16b45}'), ('\u{16b50}', '\u{16b59}'), ('\u{16b5b}', '\u{16b61}'),
('\u{16b63}', '\u{16b77}'), ('\u{16b7d}', '\u{16b8f}')
];
- pub static Palmyrene_table: &'static [(char, char)] = &[
+ pub const Palmyrene_table: &'static [(char, char)] = &[
('\u{10860}', '\u{10876}'), ('\u{10877}', '\u{10878}'), ('\u{10879}', '\u{1087f}')
];
- pub static Pau_Cin_Hau_table: &'static [(char, char)] = &[
+ pub const Pau_Cin_Hau_table: &'static [(char, char)] = &[
('\u{11ac0}', '\u{11af8}')
];
- pub static Phags_Pa_table: &'static [(char, char)] = &[
+ pub const Phags_Pa_table: &'static [(char, char)] = &[
('\u{a840}', '\u{a873}'), ('\u{a874}', '\u{a877}')
];
- pub static Phoenician_table: &'static [(char, char)] = &[
+ pub const Phoenician_table: &'static [(char, char)] = &[
('\u{10900}', '\u{10915}'), ('\u{10916}', '\u{1091b}'), ('\u{1091f}', '\u{1091f}')
];
- pub static Psalter_Pahlavi_table: &'static [(char, char)] = &[
+ pub const Psalter_Pahlavi_table: &'static [(char, char)] = &[
('\u{10b80}', '\u{10b91}'), ('\u{10b99}', '\u{10b9c}'), ('\u{10ba9}', '\u{10baf}')
];
- pub static Rejang_table: &'static [(char, char)] = &[
+ pub const Rejang_table: &'static [(char, char)] = &[
('\u{a930}', '\u{a946}'), ('\u{a947}', '\u{a951}'), ('\u{a952}', '\u{a953}'), ('\u{a95f}',
'\u{a95f}')
];
- pub static Runic_table: &'static [(char, char)] = &[
+ pub const Runic_table: &'static [(char, char)] = &[
('\u{16a0}', '\u{16ea}'), ('\u{16ee}', '\u{16f0}'), ('\u{16f1}', '\u{16f8}')
];
- pub static Samaritan_table: &'static [(char, char)] = &[
+ pub const Samaritan_table: &'static [(char, char)] = &[
('\u{800}', '\u{815}'), ('\u{816}', '\u{819}'), ('\u{81a}', '\u{81a}'), ('\u{81b}',
'\u{823}'), ('\u{824}', '\u{824}'), ('\u{825}', '\u{827}'), ('\u{828}', '\u{828}'),
('\u{829}', '\u{82d}'), ('\u{830}', '\u{83e}')
];
- pub static Saurashtra_table: &'static [(char, char)] = &[
+ pub const Saurashtra_table: &'static [(char, char)] = &[
('\u{a880}', '\u{a881}'), ('\u{a882}', '\u{a8b3}'), ('\u{a8b4}', '\u{a8c3}'), ('\u{a8c4}',
'\u{a8c4}'), ('\u{a8ce}', '\u{a8cf}'), ('\u{a8d0}', '\u{a8d9}')
];
- pub static Sharada_table: &'static [(char, char)] = &[
+ pub const Sharada_table: &'static [(char, char)] = &[
('\u{11180}', '\u{11181}'), ('\u{11182}', '\u{11182}'), ('\u{11183}', '\u{111b2}'),
('\u{111b3}', '\u{111b5}'), ('\u{111b6}', '\u{111be}'), ('\u{111bf}', '\u{111c0}'),
('\u{111c1}', '\u{111c4}'), ('\u{111c5}', '\u{111c8}'), ('\u{111cd}', '\u{111cd}'),
('\u{111d0}', '\u{111d9}'), ('\u{111da}', '\u{111da}')
];
- pub static Shavian_table: &'static [(char, char)] = &[
+ pub const Shavian_table: &'static [(char, char)] = &[
('\u{10450}', '\u{1047f}')
];
- pub static Siddham_table: &'static [(char, char)] = &[
+ pub const Siddham_table: &'static [(char, char)] = &[
('\u{11580}', '\u{115ae}'), ('\u{115af}', '\u{115b1}'), ('\u{115b2}', '\u{115b5}'),
('\u{115b8}', '\u{115bb}'), ('\u{115bc}', '\u{115bd}'), ('\u{115be}', '\u{115be}'),
('\u{115bf}', '\u{115c0}'), ('\u{115c1}', '\u{115c9}')
];
- pub static Sinhala_table: &'static [(char, char)] = &[
+ pub const Sinhala_table: &'static [(char, char)] = &[
('\u{d82}', '\u{d83}'), ('\u{d85}', '\u{d96}'), ('\u{d9a}', '\u{db1}'), ('\u{db3}',
'\u{dbb}'), ('\u{dbd}', '\u{dbd}'), ('\u{dc0}', '\u{dc6}'), ('\u{dca}', '\u{dca}'),
('\u{dcf}', '\u{dd1}'), ('\u{dd2}', '\u{dd4}'), ('\u{dd6}', '\u{dd6}'), ('\u{dd8}',
('\u{111e1}', '\u{111f4}')
];
- pub static Sora_Sompeng_table: &'static [(char, char)] = &[
+ pub const Sora_Sompeng_table: &'static [(char, char)] = &[
('\u{110d0}', '\u{110e8}'), ('\u{110f0}', '\u{110f9}')
];
- pub static Sundanese_table: &'static [(char, char)] = &[
+ pub const Sundanese_table: &'static [(char, char)] = &[
('\u{1b80}', '\u{1b81}'), ('\u{1b82}', '\u{1b82}'), ('\u{1b83}', '\u{1ba0}'), ('\u{1ba1}',
'\u{1ba1}'), ('\u{1ba2}', '\u{1ba5}'), ('\u{1ba6}', '\u{1ba7}'), ('\u{1ba8}', '\u{1ba9}'),
('\u{1baa}', '\u{1baa}'), ('\u{1bab}', '\u{1bad}'), ('\u{1bae}', '\u{1baf}'), ('\u{1bb0}',
'\u{1bb9}'), ('\u{1bba}', '\u{1bbf}'), ('\u{1cc0}', '\u{1cc7}')
];
- pub static Syloti_Nagri_table: &'static [(char, char)] = &[
+ pub const Syloti_Nagri_table: &'static [(char, char)] = &[
('\u{a800}', '\u{a801}'), ('\u{a802}', '\u{a802}'), ('\u{a803}', '\u{a805}'), ('\u{a806}',
'\u{a806}'), ('\u{a807}', '\u{a80a}'), ('\u{a80b}', '\u{a80b}'), ('\u{a80c}', '\u{a822}'),
('\u{a823}', '\u{a824}'), ('\u{a825}', '\u{a826}'), ('\u{a827}', '\u{a827}'), ('\u{a828}',
'\u{a82b}')
];
- pub static Syriac_table: &'static [(char, char)] = &[
+ pub const Syriac_table: &'static [(char, char)] = &[
('\u{700}', '\u{70d}'), ('\u{70f}', '\u{70f}'), ('\u{710}', '\u{710}'), ('\u{711}',
'\u{711}'), ('\u{712}', '\u{72f}'), ('\u{730}', '\u{74a}'), ('\u{74d}', '\u{74f}')
];
- pub static Tagalog_table: &'static [(char, char)] = &[
+ pub const Tagalog_table: &'static [(char, char)] = &[
('\u{1700}', '\u{170c}'), ('\u{170e}', '\u{1711}'), ('\u{1712}', '\u{1714}')
];
- pub static Tagbanwa_table: &'static [(char, char)] = &[
+ pub const Tagbanwa_table: &'static [(char, char)] = &[
('\u{1760}', '\u{176c}'), ('\u{176e}', '\u{1770}'), ('\u{1772}', '\u{1773}')
];
- pub static Tai_Le_table: &'static [(char, char)] = &[
+ pub const Tai_Le_table: &'static [(char, char)] = &[
('\u{1950}', '\u{196d}'), ('\u{1970}', '\u{1974}')
];
- pub static Tai_Tham_table: &'static [(char, char)] = &[
+ pub const Tai_Tham_table: &'static [(char, char)] = &[
('\u{1a20}', '\u{1a54}'), ('\u{1a55}', '\u{1a55}'), ('\u{1a56}', '\u{1a56}'), ('\u{1a57}',
'\u{1a57}'), ('\u{1a58}', '\u{1a5e}'), ('\u{1a60}', '\u{1a60}'), ('\u{1a61}', '\u{1a61}'),
('\u{1a62}', '\u{1a62}'), ('\u{1a63}', '\u{1a64}'), ('\u{1a65}', '\u{1a6c}'), ('\u{1a6d}',
'\u{1aad}')
];
- pub static Tai_Viet_table: &'static [(char, char)] = &[
+ pub const Tai_Viet_table: &'static [(char, char)] = &[
('\u{aa80}', '\u{aaaf}'), ('\u{aab0}', '\u{aab0}'), ('\u{aab1}', '\u{aab1}'), ('\u{aab2}',
'\u{aab4}'), ('\u{aab5}', '\u{aab6}'), ('\u{aab7}', '\u{aab8}'), ('\u{aab9}', '\u{aabd}'),
('\u{aabe}', '\u{aabf}'), ('\u{aac0}', '\u{aac0}'), ('\u{aac1}', '\u{aac1}'), ('\u{aac2}',
'\u{aac2}'), ('\u{aadb}', '\u{aadc}'), ('\u{aadd}', '\u{aadd}'), ('\u{aade}', '\u{aadf}')
];
- pub static Takri_table: &'static [(char, char)] = &[
+ pub const Takri_table: &'static [(char, char)] = &[
('\u{11680}', '\u{116aa}'), ('\u{116ab}', '\u{116ab}'), ('\u{116ac}', '\u{116ac}'),
('\u{116ad}', '\u{116ad}'), ('\u{116ae}', '\u{116af}'), ('\u{116b0}', '\u{116b5}'),
('\u{116b6}', '\u{116b6}'), ('\u{116b7}', '\u{116b7}'), ('\u{116c0}', '\u{116c9}')
];
- pub static Tamil_table: &'static [(char, char)] = &[
+ pub const Tamil_table: &'static [(char, char)] = &[
('\u{b82}', '\u{b82}'), ('\u{b83}', '\u{b83}'), ('\u{b85}', '\u{b8a}'), ('\u{b8e}',
'\u{b90}'), ('\u{b92}', '\u{b95}'), ('\u{b99}', '\u{b9a}'), ('\u{b9c}', '\u{b9c}'),
('\u{b9e}', '\u{b9f}'), ('\u{ba3}', '\u{ba4}'), ('\u{ba8}', '\u{baa}'), ('\u{bae}',
('\u{bf3}', '\u{bf8}'), ('\u{bf9}', '\u{bf9}'), ('\u{bfa}', '\u{bfa}')
];
- pub static Telugu_table: &'static [(char, char)] = &[
+ pub const Telugu_table: &'static [(char, char)] = &[
('\u{c00}', '\u{c00}'), ('\u{c01}', '\u{c03}'), ('\u{c05}', '\u{c0c}'), ('\u{c0e}',
'\u{c10}'), ('\u{c12}', '\u{c28}'), ('\u{c2a}', '\u{c39}'), ('\u{c3d}', '\u{c3d}'),
('\u{c3e}', '\u{c40}'), ('\u{c41}', '\u{c44}'), ('\u{c46}', '\u{c48}'), ('\u{c4a}',
'\u{c7f}')
];
- pub static Thaana_table: &'static [(char, char)] = &[
+ pub const Thaana_table: &'static [(char, char)] = &[
('\u{780}', '\u{7a5}'), ('\u{7a6}', '\u{7b0}'), ('\u{7b1}', '\u{7b1}')
];
- pub static Thai_table: &'static [(char, char)] = &[
+ pub const Thai_table: &'static [(char, char)] = &[
('\u{e01}', '\u{e30}'), ('\u{e31}', '\u{e31}'), ('\u{e32}', '\u{e33}'), ('\u{e34}',
'\u{e3a}'), ('\u{e40}', '\u{e45}'), ('\u{e46}', '\u{e46}'), ('\u{e47}', '\u{e4e}'),
('\u{e4f}', '\u{e4f}'), ('\u{e50}', '\u{e59}'), ('\u{e5a}', '\u{e5b}')
];
- pub static Tibetan_table: &'static [(char, char)] = &[
+ pub const Tibetan_table: &'static [(char, char)] = &[
('\u{f00}', '\u{f00}'), ('\u{f01}', '\u{f03}'), ('\u{f04}', '\u{f12}'), ('\u{f13}',
'\u{f13}'), ('\u{f14}', '\u{f14}'), ('\u{f15}', '\u{f17}'), ('\u{f18}', '\u{f19}'),
('\u{f1a}', '\u{f1f}'), ('\u{f20}', '\u{f29}'), ('\u{f2a}', '\u{f33}'), ('\u{f34}',
('\u{fd0}', '\u{fd4}'), ('\u{fd9}', '\u{fda}')
];
- pub static Tifinagh_table: &'static [(char, char)] = &[
+ pub const Tifinagh_table: &'static [(char, char)] = &[
('\u{2d30}', '\u{2d67}'), ('\u{2d6f}', '\u{2d6f}'), ('\u{2d70}', '\u{2d70}'), ('\u{2d7f}',
'\u{2d7f}')
];
- pub static Tirhuta_table: &'static [(char, char)] = &[
+ pub const Tirhuta_table: &'static [(char, char)] = &[
('\u{11480}', '\u{114af}'), ('\u{114b0}', '\u{114b2}'), ('\u{114b3}', '\u{114b8}'),
('\u{114b9}', '\u{114b9}'), ('\u{114ba}', '\u{114ba}'), ('\u{114bb}', '\u{114be}'),
('\u{114bf}', '\u{114c0}'), ('\u{114c1}', '\u{114c1}'), ('\u{114c2}', '\u{114c3}'),
('\u{114d0}', '\u{114d9}')
];
- pub static Ugaritic_table: &'static [(char, char)] = &[
+ pub const Ugaritic_table: &'static [(char, char)] = &[
('\u{10380}', '\u{1039d}'), ('\u{1039f}', '\u{1039f}')
];
- pub static Vai_table: &'static [(char, char)] = &[
+ pub const Vai_table: &'static [(char, char)] = &[
('\u{a500}', '\u{a60b}'), ('\u{a60c}', '\u{a60c}'), ('\u{a60d}', '\u{a60f}'), ('\u{a610}',
'\u{a61f}'), ('\u{a620}', '\u{a629}'), ('\u{a62a}', '\u{a62b}')
];
- pub static Warang_Citi_table: &'static [(char, char)] = &[
+ pub const Warang_Citi_table: &'static [(char, char)] = &[
('\u{118a0}', '\u{118df}'), ('\u{118e0}', '\u{118e9}'), ('\u{118ea}', '\u{118f2}'),
('\u{118ff}', '\u{118ff}')
];
- pub static Yi_table: &'static [(char, char)] = &[
+ pub const Yi_table: &'static [(char, char)] = &[
('\u{a000}', '\u{a014}'), ('\u{a015}', '\u{a015}'), ('\u{a016}', '\u{a48c}'), ('\u{a490}',
'\u{a4c6}')
];
}
pub mod property {
- pub static Join_Control_table: &'static [(char, char)] = &[
+ pub const Join_Control_table: &'static [(char, char)] = &[
('\u{200c}', '\u{200d}')
];
- pub static Noncharacter_Code_Point_table: &'static [(char, char)] = &[
+ pub const Noncharacter_Code_Point_table: &'static [(char, char)] = &[
('\u{fdd0}', '\u{fdef}'), ('\u{fffe}', '\u{ffff}'), ('\u{1fffe}', '\u{1ffff}'),
('\u{2fffe}', '\u{2ffff}'), ('\u{3fffe}', '\u{3ffff}'), ('\u{4fffe}', '\u{4ffff}'),
('\u{5fffe}', '\u{5ffff}'), ('\u{6fffe}', '\u{6ffff}'), ('\u{7fffe}', '\u{7ffff}'),
('\u{efffe}', '\u{effff}'), ('\u{ffffe}', '\u{fffff}')
];
- pub static White_Space_table: &'static [(char, char)] = &[
+ pub const White_Space_table: &'static [(char, char)] = &[
('\u{9}', '\u{d}'), ('\u{20}', '\u{20}'), ('\u{85}', '\u{85}'), ('\u{a0}', '\u{a0}'),
('\u{1680}', '\u{1680}'), ('\u{2000}', '\u{200a}'), ('\u{2028}', '\u{2028}'), ('\u{2029}',
'\u{2029}'), ('\u{202f}', '\u{202f}'), ('\u{205f}', '\u{205f}'), ('\u{3000}', '\u{3000}')
}
pub mod regex {
- pub static UNICODE_CLASSES: &'static [(&'static str, &'static &'static [(char, char)])] = &[
- ("Alphabetic", &super::derived_property::Alphabetic_table), ("Arabic",
- &super::script::Arabic_table), ("Armenian", &super::script::Armenian_table), ("Avestan",
- &super::script::Avestan_table), ("Balinese", &super::script::Balinese_table), ("Bamum",
- &super::script::Bamum_table), ("Bassa_Vah", &super::script::Bassa_Vah_table), ("Batak",
- &super::script::Batak_table), ("Bengali", &super::script::Bengali_table), ("Bopomofo",
- &super::script::Bopomofo_table), ("Brahmi", &super::script::Brahmi_table), ("Braille",
- &super::script::Braille_table), ("Buginese", &super::script::Buginese_table), ("Buhid",
- &super::script::Buhid_table), ("C", &super::general_category::C_table),
- ("Canadian_Aboriginal", &super::script::Canadian_Aboriginal_table), ("Carian",
- &super::script::Carian_table), ("Caucasian_Albanian",
- &super::script::Caucasian_Albanian_table), ("Cc", &super::general_category::Cc_table),
- ("Cf", &super::general_category::Cf_table), ("Chakma", &super::script::Chakma_table),
- ("Cham", &super::script::Cham_table), ("Cherokee", &super::script::Cherokee_table), ("Cn",
- &super::general_category::Cn_table), ("Co", &super::general_category::Co_table), ("Common",
- &super::script::Common_table), ("Coptic", &super::script::Coptic_table), ("Cuneiform",
- &super::script::Cuneiform_table), ("Cypriot", &super::script::Cypriot_table), ("Cyrillic",
- &super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
- &super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
- &super::script::Deseret_table), ("Devanagari", &super::script::Devanagari_table),
- ("Duployan", &super::script::Duployan_table), ("Egyptian_Hieroglyphs",
- &super::script::Egyptian_Hieroglyphs_table), ("Elbasan", &super::script::Elbasan_table),
- ("Ethiopic", &super::script::Ethiopic_table), ("Georgian", &super::script::Georgian_table),
- ("Glagolitic", &super::script::Glagolitic_table), ("Gothic", &super::script::Gothic_table),
- ("Grantha", &super::script::Grantha_table), ("Greek", &super::script::Greek_table),
- ("Gujarati", &super::script::Gujarati_table), ("Gurmukhi", &super::script::Gurmukhi_table),
- ("Han", &super::script::Han_table), ("Hangul", &super::script::Hangul_table), ("Hanunoo",
- &super::script::Hanunoo_table), ("Hebrew", &super::script::Hebrew_table), ("Hiragana",
- &super::script::Hiragana_table), ("Imperial_Aramaic",
- &super::script::Imperial_Aramaic_table), ("Inherited", &super::script::Inherited_table),
- ("Inscriptional_Pahlavi", &super::script::Inscriptional_Pahlavi_table),
- ("Inscriptional_Parthian", &super::script::Inscriptional_Parthian_table), ("Javanese",
- &super::script::Javanese_table), ("Join_Control", &super::property::Join_Control_table),
- ("Kaithi", &super::script::Kaithi_table), ("Kannada", &super::script::Kannada_table),
- ("Katakana", &super::script::Katakana_table), ("Kayah_Li", &super::script::Kayah_Li_table),
- ("Kharoshthi", &super::script::Kharoshthi_table), ("Khmer", &super::script::Khmer_table),
- ("Khojki", &super::script::Khojki_table), ("Khudawadi", &super::script::Khudawadi_table),
- ("L", &super::general_category::L_table), ("LC", &super::general_category::LC_table),
- ("Lao", &super::script::Lao_table), ("Latin", &super::script::Latin_table), ("Lepcha",
- &super::script::Lepcha_table), ("Limbu", &super::script::Limbu_table), ("Linear_A",
- &super::script::Linear_A_table), ("Linear_B", &super::script::Linear_B_table), ("Lisu",
- &super::script::Lisu_table), ("Ll", &super::general_category::Ll_table), ("Lm",
- &super::general_category::Lm_table), ("Lo", &super::general_category::Lo_table),
- ("Lowercase", &super::derived_property::Lowercase_table), ("Lt",
- &super::general_category::Lt_table), ("Lu", &super::general_category::Lu_table), ("Lycian",
- &super::script::Lycian_table), ("Lydian", &super::script::Lydian_table), ("M",
- &super::general_category::M_table), ("Mahajani", &super::script::Mahajani_table),
- ("Malayalam", &super::script::Malayalam_table), ("Mandaic", &super::script::Mandaic_table),
- ("Manichaean", &super::script::Manichaean_table), ("Mc",
- &super::general_category::Mc_table), ("Me", &super::general_category::Me_table),
- ("Meetei_Mayek", &super::script::Meetei_Mayek_table), ("Mende_Kikakui",
- &super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
- &super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
- &super::script::Meroitic_Hieroglyphs_table), ("Miao", &super::script::Miao_table), ("Mn",
- &super::general_category::Mn_table), ("Modi", &super::script::Modi_table), ("Mongolian",
- &super::script::Mongolian_table), ("Mro", &super::script::Mro_table), ("Myanmar",
- &super::script::Myanmar_table), ("N", &super::general_category::N_table), ("Nabataean",
- &super::script::Nabataean_table), ("Nd", &super::general_category::Nd_table),
- ("New_Tai_Lue", &super::script::New_Tai_Lue_table), ("Nko", &super::script::Nko_table),
- ("Nl", &super::general_category::Nl_table), ("No", &super::general_category::No_table),
- ("Noncharacter_Code_Point", &super::property::Noncharacter_Code_Point_table), ("Ogham",
- &super::script::Ogham_table), ("Ol_Chiki", &super::script::Ol_Chiki_table), ("Old_Italic",
- &super::script::Old_Italic_table), ("Old_North_Arabian",
- &super::script::Old_North_Arabian_table), ("Old_Permic", &super::script::Old_Permic_table),
- ("Old_Persian", &super::script::Old_Persian_table), ("Old_South_Arabian",
- &super::script::Old_South_Arabian_table), ("Old_Turkic", &super::script::Old_Turkic_table),
- ("Oriya", &super::script::Oriya_table), ("Osmanya", &super::script::Osmanya_table), ("P",
- &super::general_category::P_table), ("Pahawh_Hmong", &super::script::Pahawh_Hmong_table),
- ("Palmyrene", &super::script::Palmyrene_table), ("Pau_Cin_Hau",
- &super::script::Pau_Cin_Hau_table), ("Pc", &super::general_category::Pc_table), ("Pd",
- &super::general_category::Pd_table), ("Pe", &super::general_category::Pe_table), ("Pf",
- &super::general_category::Pf_table), ("Phags_Pa", &super::script::Phags_Pa_table),
- ("Phoenician", &super::script::Phoenician_table), ("Pi",
- &super::general_category::Pi_table), ("Po", &super::general_category::Po_table), ("Ps",
- &super::general_category::Ps_table), ("Psalter_Pahlavi",
- &super::script::Psalter_Pahlavi_table), ("Rejang", &super::script::Rejang_table), ("Runic",
- &super::script::Runic_table), ("S", &super::general_category::S_table), ("Samaritan",
- &super::script::Samaritan_table), ("Saurashtra", &super::script::Saurashtra_table), ("Sc",
- &super::general_category::Sc_table), ("Sharada", &super::script::Sharada_table), ("Shavian",
- &super::script::Shavian_table), ("Siddham", &super::script::Siddham_table), ("Sinhala",
- &super::script::Sinhala_table), ("Sk", &super::general_category::Sk_table), ("Sm",
- &super::general_category::Sm_table), ("So", &super::general_category::So_table),
- ("Sora_Sompeng", &super::script::Sora_Sompeng_table), ("Sundanese",
- &super::script::Sundanese_table), ("Syloti_Nagri", &super::script::Syloti_Nagri_table),
- ("Syriac", &super::script::Syriac_table), ("Tagalog", &super::script::Tagalog_table),
- ("Tagbanwa", &super::script::Tagbanwa_table), ("Tai_Le", &super::script::Tai_Le_table),
- ("Tai_Tham", &super::script::Tai_Tham_table), ("Tai_Viet", &super::script::Tai_Viet_table),
- ("Takri", &super::script::Takri_table), ("Tamil", &super::script::Tamil_table), ("Telugu",
- &super::script::Telugu_table), ("Thaana", &super::script::Thaana_table), ("Thai",
- &super::script::Thai_table), ("Tibetan", &super::script::Tibetan_table), ("Tifinagh",
- &super::script::Tifinagh_table), ("Tirhuta", &super::script::Tirhuta_table), ("Ugaritic",
- &super::script::Ugaritic_table), ("Uppercase", &super::derived_property::Uppercase_table),
- ("Vai", &super::script::Vai_table), ("Warang_Citi", &super::script::Warang_Citi_table),
- ("White_Space", &super::property::White_Space_table), ("XID_Continue",
- &super::derived_property::XID_Continue_table), ("XID_Start",
- &super::derived_property::XID_Start_table), ("Yi", &super::script::Yi_table), ("Z",
- &super::general_category::Z_table), ("Zl", &super::general_category::Zl_table), ("Zp",
- &super::general_category::Zp_table), ("Zs", &super::general_category::Zs_table)
- ];
-
- pub static PERLD: &'static &'static [(char, char)] = &super::general_category::Nd_table;
-
- pub static PERLS: &'static &'static [(char, char)] = &super::property::White_Space_table;
-
- pub static PERLW: &'static [(char, char)] = &[
+ pub const UNICODE_CLASSES: &'static [(&'static str, &'static [(char, char)])] = &[
+ ("Alphabetic", super::derived_property::Alphabetic_table), ("Arabic",
+ super::script::Arabic_table), ("Armenian", super::script::Armenian_table), ("Avestan",
+ super::script::Avestan_table), ("Balinese", super::script::Balinese_table), ("Bamum",
+ super::script::Bamum_table), ("Bassa_Vah", super::script::Bassa_Vah_table), ("Batak",
+ super::script::Batak_table), ("Bengali", super::script::Bengali_table), ("Bopomofo",
+ super::script::Bopomofo_table), ("Brahmi", super::script::Brahmi_table), ("Braille",
+ super::script::Braille_table), ("Buginese", super::script::Buginese_table), ("Buhid",
+ super::script::Buhid_table), ("C", super::general_category::C_table),
+ ("Canadian_Aboriginal", super::script::Canadian_Aboriginal_table), ("Carian",
+ super::script::Carian_table), ("Caucasian_Albanian",
+ super::script::Caucasian_Albanian_table), ("Cc", super::general_category::Cc_table), ("Cf",
+ super::general_category::Cf_table), ("Chakma", super::script::Chakma_table), ("Cham",
+ super::script::Cham_table), ("Cherokee", super::script::Cherokee_table), ("Cn",
+ super::general_category::Cn_table), ("Co", super::general_category::Co_table), ("Common",
+ super::script::Common_table), ("Coptic", super::script::Coptic_table), ("Cuneiform",
+ super::script::Cuneiform_table), ("Cypriot", super::script::Cypriot_table), ("Cyrillic",
+ super::script::Cyrillic_table), ("Default_Ignorable_Code_Point",
+ super::derived_property::Default_Ignorable_Code_Point_table), ("Deseret",
+ super::script::Deseret_table), ("Devanagari", super::script::Devanagari_table), ("Duployan",
+ super::script::Duployan_table), ("Egyptian_Hieroglyphs",
+ super::script::Egyptian_Hieroglyphs_table), ("Elbasan", super::script::Elbasan_table),
+ ("Ethiopic", super::script::Ethiopic_table), ("Georgian", super::script::Georgian_table),
+ ("Glagolitic", super::script::Glagolitic_table), ("Gothic", super::script::Gothic_table),
+ ("Grantha", super::script::Grantha_table), ("Greek", super::script::Greek_table),
+ ("Gujarati", super::script::Gujarati_table), ("Gurmukhi", super::script::Gurmukhi_table),
+ ("Han", super::script::Han_table), ("Hangul", super::script::Hangul_table), ("Hanunoo",
+ super::script::Hanunoo_table), ("Hebrew", super::script::Hebrew_table), ("Hiragana",
+ super::script::Hiragana_table), ("Imperial_Aramaic", super::script::Imperial_Aramaic_table),
+ ("Inherited", super::script::Inherited_table), ("Inscriptional_Pahlavi",
+ super::script::Inscriptional_Pahlavi_table), ("Inscriptional_Parthian",
+ super::script::Inscriptional_Parthian_table), ("Javanese", super::script::Javanese_table),
+ ("Join_Control", super::property::Join_Control_table), ("Kaithi",
+ super::script::Kaithi_table), ("Kannada", super::script::Kannada_table), ("Katakana",
+ super::script::Katakana_table), ("Kayah_Li", super::script::Kayah_Li_table), ("Kharoshthi",
+ super::script::Kharoshthi_table), ("Khmer", super::script::Khmer_table), ("Khojki",
+ super::script::Khojki_table), ("Khudawadi", super::script::Khudawadi_table), ("L",
+ super::general_category::L_table), ("LC", super::general_category::LC_table), ("Lao",
+ super::script::Lao_table), ("Latin", super::script::Latin_table), ("Lepcha",
+ super::script::Lepcha_table), ("Limbu", super::script::Limbu_table), ("Linear_A",
+ super::script::Linear_A_table), ("Linear_B", super::script::Linear_B_table), ("Lisu",
+ super::script::Lisu_table), ("Ll", super::general_category::Ll_table), ("Lm",
+ super::general_category::Lm_table), ("Lo", super::general_category::Lo_table), ("Lowercase",
+ super::derived_property::Lowercase_table), ("Lt", super::general_category::Lt_table), ("Lu",
+ super::general_category::Lu_table), ("Lycian", super::script::Lycian_table), ("Lydian",
+ super::script::Lydian_table), ("M", super::general_category::M_table), ("Mahajani",
+ super::script::Mahajani_table), ("Malayalam", super::script::Malayalam_table), ("Mandaic",
+ super::script::Mandaic_table), ("Manichaean", super::script::Manichaean_table), ("Mc",
+ super::general_category::Mc_table), ("Me", super::general_category::Me_table),
+ ("Meetei_Mayek", super::script::Meetei_Mayek_table), ("Mende_Kikakui",
+ super::script::Mende_Kikakui_table), ("Meroitic_Cursive",
+ super::script::Meroitic_Cursive_table), ("Meroitic_Hieroglyphs",
+ super::script::Meroitic_Hieroglyphs_table), ("Miao", super::script::Miao_table), ("Mn",
+ super::general_category::Mn_table), ("Modi", super::script::Modi_table), ("Mongolian",
+ super::script::Mongolian_table), ("Mro", super::script::Mro_table), ("Myanmar",
+ super::script::Myanmar_table), ("N", super::general_category::N_table), ("Nabataean",
+ super::script::Nabataean_table), ("Nd", super::general_category::Nd_table), ("New_Tai_Lue",
+ super::script::New_Tai_Lue_table), ("Nko", super::script::Nko_table), ("Nl",
+ super::general_category::Nl_table), ("No", super::general_category::No_table),
+ ("Noncharacter_Code_Point", super::property::Noncharacter_Code_Point_table), ("Ogham",
+ super::script::Ogham_table), ("Ol_Chiki", super::script::Ol_Chiki_table), ("Old_Italic",
+ super::script::Old_Italic_table), ("Old_North_Arabian",
+ super::script::Old_North_Arabian_table), ("Old_Permic", super::script::Old_Permic_table),
+ ("Old_Persian", super::script::Old_Persian_table), ("Old_South_Arabian",
+ super::script::Old_South_Arabian_table), ("Old_Turkic", super::script::Old_Turkic_table),
+ ("Oriya", super::script::Oriya_table), ("Osmanya", super::script::Osmanya_table), ("P",
+ super::general_category::P_table), ("Pahawh_Hmong", super::script::Pahawh_Hmong_table),
+ ("Palmyrene", super::script::Palmyrene_table), ("Pau_Cin_Hau",
+ super::script::Pau_Cin_Hau_table), ("Pc", super::general_category::Pc_table), ("Pd",
+ super::general_category::Pd_table), ("Pe", super::general_category::Pe_table), ("Pf",
+ super::general_category::Pf_table), ("Phags_Pa", super::script::Phags_Pa_table),
+ ("Phoenician", super::script::Phoenician_table), ("Pi", super::general_category::Pi_table),
+ ("Po", super::general_category::Po_table), ("Ps", super::general_category::Ps_table),
+ ("Psalter_Pahlavi", super::script::Psalter_Pahlavi_table), ("Rejang",
+ super::script::Rejang_table), ("Runic", super::script::Runic_table), ("S",
+ super::general_category::S_table), ("Samaritan", super::script::Samaritan_table),
+ ("Saurashtra", super::script::Saurashtra_table), ("Sc", super::general_category::Sc_table),
+ ("Sharada", super::script::Sharada_table), ("Shavian", super::script::Shavian_table),
+ ("Siddham", super::script::Siddham_table), ("Sinhala", super::script::Sinhala_table), ("Sk",
+ super::general_category::Sk_table), ("Sm", super::general_category::Sm_table), ("So",
+ super::general_category::So_table), ("Sora_Sompeng", super::script::Sora_Sompeng_table),
+ ("Sundanese", super::script::Sundanese_table), ("Syloti_Nagri",
+ super::script::Syloti_Nagri_table), ("Syriac", super::script::Syriac_table), ("Tagalog",
+ super::script::Tagalog_table), ("Tagbanwa", super::script::Tagbanwa_table), ("Tai_Le",
+ super::script::Tai_Le_table), ("Tai_Tham", super::script::Tai_Tham_table), ("Tai_Viet",
+ super::script::Tai_Viet_table), ("Takri", super::script::Takri_table), ("Tamil",
+ super::script::Tamil_table), ("Telugu", super::script::Telugu_table), ("Thaana",
+ super::script::Thaana_table), ("Thai", super::script::Thai_table), ("Tibetan",
+ super::script::Tibetan_table), ("Tifinagh", super::script::Tifinagh_table), ("Tirhuta",
+ super::script::Tirhuta_table), ("Ugaritic", super::script::Ugaritic_table), ("Uppercase",
+ super::derived_property::Uppercase_table), ("Vai", super::script::Vai_table),
+ ("Warang_Citi", super::script::Warang_Citi_table), ("White_Space",
+ super::property::White_Space_table), ("XID_Continue",
+ super::derived_property::XID_Continue_table), ("XID_Start",
+ super::derived_property::XID_Start_table), ("Yi", super::script::Yi_table), ("Z",
+ super::general_category::Z_table), ("Zl", super::general_category::Zl_table), ("Zp",
+ super::general_category::Zp_table), ("Zs", super::general_category::Zs_table)
+ ];
+
+ pub const PERLD: &'static [(char, char)] = super::general_category::Nd_table;
+
+ pub const PERLS: &'static [(char, char)] = super::property::White_Space_table;
+
+ pub const PERLW: &'static [(char, char)] = &[
('\u{30}', '\u{39}'), ('\u{41}', '\u{5a}'), ('\u{5f}', '\u{5f}'), ('\u{61}', '\u{7a}'),
('\u{aa}', '\u{aa}'), ('\u{b5}', '\u{b5}'), ('\u{ba}', '\u{ba}'), ('\u{c0}', '\u{d6}'),
('\u{d8}', '\u{f6}'), ('\u{f8}', '\u{2c1}'), ('\u{2c6}', '\u{2d1}'), ('\u{2e0}', '\u{2e4}'),
pub mod normalization {
// Canonical decompositions
- pub static canonical_table: &'static [(char, &'static [char])] = &[
+ pub const canonical_table: &'static [(char, &'static [char])] = &[
('\u{c0}', &['\u{41}', '\u{300}']), ('\u{c1}', &['\u{41}', '\u{301}']), ('\u{c2}',
&['\u{41}', '\u{302}']), ('\u{c3}', &['\u{41}', '\u{303}']), ('\u{c4}', &['\u{41}',
'\u{308}']), ('\u{c5}', &['\u{41}', '\u{30a}']), ('\u{c7}', &['\u{43}', '\u{327}']),
];
// Compatibility decompositions
- pub static compatibility_table: &'static [(char, &'static [char])] = &[
+ pub const compatibility_table: &'static [(char, &'static [char])] = &[
('\u{a0}', &['\u{20}']), ('\u{a8}', &['\u{20}', '\u{308}']), ('\u{aa}', &['\u{61}']),
('\u{af}', &['\u{20}', '\u{304}']), ('\u{b2}', &['\u{32}']), ('\u{b3}', &['\u{33}']),
('\u{b4}', &['\u{20}', '\u{301}']), ('\u{b5}', &['\u{3bc}']), ('\u{b8}', &['\u{20}',
];
// Canonical compositions
- pub static composition_table: &'static [(char, &'static [(char, char)])] = &[
+ pub const composition_table: &'static [(char, &'static [(char, char)])] = &[
('\u{3c}', &[('\u{338}', '\u{226e}')]), ('\u{3d}', &[('\u{338}', '\u{2260}')]), ('\u{3e}',
&[('\u{338}', '\u{226f}')]), ('\u{41}', &[('\u{300}', '\u{c0}'), ('\u{301}', '\u{c1}'),
('\u{302}', '\u{c2}'), ('\u{303}', '\u{c3}'), ('\u{304}', '\u{100}'), ('\u{306}',
}
}
- static combining_class_table: &'static [(char, char, u8)] = &[
+ const combining_class_table: &'static [(char, char, u8)] = &[
('\u{300}', '\u{314}', 230), ('\u{315}', '\u{315}', 232), ('\u{316}', '\u{319}', 220),
('\u{31a}', '\u{31a}', 232), ('\u{31b}', '\u{31b}', 216), ('\u{31c}', '\u{320}', 220),
('\u{321}', '\u{322}', 202), ('\u{323}', '\u{326}', 220), ('\u{327}', '\u{328}', 202),
}
}
- static LuLl_table: &'static [(char, char)] = &[
+ const LuLl_table: &'static [(char, char)] = &[
('\u{41}', '\u{61}'), ('\u{42}', '\u{62}'), ('\u{43}', '\u{63}'), ('\u{44}', '\u{64}'),
('\u{45}', '\u{65}'), ('\u{46}', '\u{66}'), ('\u{47}', '\u{67}'), ('\u{48}', '\u{68}'),
('\u{49}', '\u{69}'), ('\u{4a}', '\u{6a}'), ('\u{4b}', '\u{6b}'), ('\u{4c}', '\u{6c}'),
('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}')
];
- static LlLu_table: &'static [(char, char)] = &[
+ const LlLu_table: &'static [(char, char)] = &[
('\u{61}', '\u{41}'), ('\u{62}', '\u{42}'), ('\u{63}', '\u{43}'), ('\u{64}', '\u{44}'),
('\u{65}', '\u{45}'), ('\u{66}', '\u{46}'), ('\u{67}', '\u{47}'), ('\u{68}', '\u{48}'),
('\u{69}', '\u{49}'), ('\u{6a}', '\u{4a}'), ('\u{6b}', '\u{4b}'), ('\u{6c}', '\u{4c}'),
// character width table. Based on Markus Kuhn's free wcwidth() implementation,
// http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
- static charwidth_table: &'static [(char, char, u8, u8)] = &[
+ const charwidth_table: &'static [(char, char, u8, u8)] = &[
('\u{a1}', '\u{a1}', 1, 2), ('\u{a4}', '\u{a4}', 1, 2), ('\u{a7}', '\u{a8}', 1, 2),
('\u{aa}', '\u{aa}', 1, 2), ('\u{ae}', '\u{ae}', 1, 2), ('\u{b0}', '\u{b4}', 1, 2),
('\u{b6}', '\u{ba}', 1, 2), ('\u{bc}', '\u{bf}', 1, 2), ('\u{c6}', '\u{c6}', 1, 2),
bsearch_range_value_table(c, grapheme_cat_table)
}
- static grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
+ const grapheme_cat_table: &'static [(char, char, GraphemeCat)] = &[
('\u{0}', '\u{1f}', GC_Control), ('\u{7f}', '\u{9f}', GC_Control), ('\u{ad}', '\u{ad}',
GC_Control), ('\u{300}', '\u{36f}', GC_Extend), ('\u{483}', '\u{487}', GC_Extend),
('\u{488}', '\u{489}', GC_Extend), ('\u{591}', '\u{5bd}', GC_Extend), ('\u{5bf}', '\u{5bf}',
return Some(tmp);
}
- let mut buf = [0u16; 2];
+ let mut buf = [0; 2];
self.chars.next().map(|ch| {
let n = CharExt::encode_utf16(ch, &mut buf).unwrap_or(0);
if n == 2 { self.extra = buf[1]; }
-Subproject commit b89c3f039b61edbb077771eda2ee8a718dbec7e0
+Subproject commit bff69076975642c64e76dbeaa53476bfa7212086
//! Basic data structures for representing a book.
-use std::old_io::BufferedReader;
+use std::io::prelude::*;
+use std::io::BufReader;
use std::iter;
use std::iter::AdditiveIterator;
+use std::path::{Path, PathBuf};
pub struct BookItem {
pub title: String,
- pub path: Path,
- pub path_to_root: Path,
+ pub path: PathBuf,
+ pub path_to_root: PathBuf,
pub children: Vec<BookItem>,
}
}
/// Construct a book by parsing a summary (markdown table of contents).
-pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
+pub fn parse_summary(input: &mut Read, src: &Path) -> Result<Book, Vec<String>> {
fn collapse(stack: &mut Vec<BookItem>,
top_items: &mut Vec<BookItem>,
to_level: usize) {
// always include the introduction
top_items.push(BookItem {
title: "Introduction".to_string(),
- path: Path::new("README.md"),
- path_to_root: Path::new("."),
+ path: PathBuf::new("README.md"),
+ path_to_root: PathBuf::new("."),
children: vec!(),
});
- for line_result in BufferedReader::new(input).lines() {
+ for line_result in BufReader::new(input).lines() {
let line = match line_result {
Ok(line) => line,
Err(err) => {
- errors.push(err.desc.to_string()); // FIXME: include detail
+ errors.push(err.to_string());
return Err(errors);
}
};
let title = line[start_bracket + 1..end_bracket].to_string();
let indent = &line[..star_idx];
- let path_from_root = match src.join(given_path).path_relative_from(src) {
- Some(p) => p,
+ let path_from_root = match src.join(given_path).relative_from(src) {
+ Some(p) => p.to_path_buf(),
None => {
errors.push(format!("paths in SUMMARY.md must be relative, \
but path '{}' for section '{}' is not.",
given_path, title));
- Path::new("")
+ PathBuf::new("")
}
};
- let path_to_root = Path::new(iter::repeat("../")
+ let path_to_root = PathBuf::new(&iter::repeat("../")
.take(path_from_root.components().count() - 1)
.collect::<String>());
let item = BookItem {
//! Implementation of the `build` subcommand, used to compile a book.
use std::env;
-use std::os;
-use std::old_io;
-use std::old_io::{fs, File, BufferedWriter, TempDir, IoResult};
+use std::fs::{self, File};
+use std::io::prelude::*;
+use std::io::{self, BufWriter};
+use std::path::{Path, PathBuf};
+use rustc_back::tempdir::TempDir;
use subcommand::Subcommand;
use term::Term;
-use error::{Error, CliResult, CommandResult};
+use error::{err, CliResult, CommandResult};
use book;
use book::{Book, BookItem};
use css;
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
if name == "build" {
- Some(box Build as Box<Subcommand>)
+ Some(Box::new(Build))
} else {
None
}
}
-fn write_toc(book: &Book, path_to_root: &Path, out: &mut Writer) -> IoResult<()> {
+fn write_toc(book: &Book, path_to_root: &Path, out: &mut Write) -> io::Result<()> {
fn walk_items(items: &[BookItem],
section: &str,
path_to_root: &Path,
- out: &mut Writer) -> IoResult<()> {
+ out: &mut Write) -> io::Result<()> {
for (i, item) in items.iter().enumerate() {
try!(walk_item(item, &format!("{}{}.", section, i + 1)[..], path_to_root, out));
}
fn walk_item(item: &BookItem,
section: &str,
path_to_root: &Path,
- out: &mut Writer) -> IoResult<()> {
+ out: &mut Write) -> io::Result<()> {
try!(writeln!(out, "<li><a href='{}'><b>{}</b> {}</a>",
- path_to_root.join(item.path.with_extension("html")).display(),
+ path_to_root.join(&item.path.with_extension("html")).display(),
section,
item.title));
if !item.children.is_empty() {
fn render(book: &Book, tgt: &Path) -> CliResult<()> {
let tmp = try!(TempDir::new("rust-book"));
- for (section, item) in book.iter() {
- println!("{} {}", section, item.title);
-
- let out_path = tgt.join(item.path.dirname());
+ for (_section, item) in book.iter() {
+ let out_path = match item.path.parent() {
+ Some(p) => tgt.join(p),
+ None => tgt.to_path_buf(),
+ };
let src;
if env::args().len() < 3 {
- src = os::getcwd().unwrap().clone();
+ src = env::current_dir().unwrap().clone();
} else {
- src = Path::new(env::args().nth(2).unwrap().clone());
+ src = PathBuf::new(&env::args().nth(2).unwrap());
}
// preprocess the markdown, rerouting markdown references to html references
- let markdown_data = try!(File::open(&src.join(&item.path)).read_to_string());
- let preprocessed_path = tmp.path().join(item.path.filename().unwrap());
+ let mut markdown_data = String::new();
+ try!(File::open(&src.join(&item.path)).and_then(|mut f| {
+ f.read_to_string(&mut markdown_data)
+ }));
+ let preprocessed_path = tmp.path().join(item.path.file_name().unwrap());
{
let urls = markdown_data.replace(".md)", ".html)");
- try!(File::create(&preprocessed_path)
- .write_str(&urls[..]));
+ try!(File::create(&preprocessed_path).and_then(|mut f| {
+ f.write_all(urls.as_bytes())
+ }));
}
// write the prelude to a temporary HTML file for rustdoc inclusion
let prelude = tmp.path().join("prelude.html");
{
- let mut toc = BufferedWriter::new(try!(File::create(&prelude)));
+ let mut toc = BufWriter::new(try!(File::create(&prelude)));
try!(writeln!(&mut toc, r#"<div id="nav">
<button id="toggle-nav">
<span class="sr-only">Toggle navigation</span>
// write the postlude to a temporary HTML file for rustdoc inclusion
let postlude = tmp.path().join("postlude.html");
{
- let mut toc = BufferedWriter::new(try!(File::create(&postlude)));
- try!(toc.write_str(javascript::JAVASCRIPT));
+ let mut toc = BufWriter::new(try!(File::create(&postlude)));
+ try!(toc.write_all(javascript::JAVASCRIPT.as_bytes()));
try!(writeln!(&mut toc, "</div></div>"));
}
- try!(fs::mkdir_recursive(&out_path, old_io::USER_DIR));
+ try!(fs::create_dir_all(&out_path));
let rustdoc_args: &[String] = &[
"".to_string(),
if output_result != 0 {
let message = format!("Could not execute `rustdoc` with {:?}: {}",
rustdoc_args, output_result);
- return Err(box message as Box<Error>);
+ return Err(err(&message));
}
}
}
fn usage(&self) {}
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
- let cwd = os::getcwd().unwrap();
+ let cwd = env::current_dir().unwrap();
let src;
let tgt;
if env::args().len() < 3 {
src = cwd.clone();
} else {
- src = Path::new(env::args().nth(2).unwrap().clone());
+ src = PathBuf::new(&env::args().nth(2).unwrap());
}
if env::args().len() < 4 {
tgt = cwd.join("_book");
} else {
- tgt = Path::new(env::args().nth(3).unwrap().clone());
+ tgt = PathBuf::new(&env::args().nth(3).unwrap());
}
- try!(fs::mkdir(&tgt, old_io::USER_DIR));
+ try!(fs::create_dir(&tgt));
- try!(File::create(&tgt.join("rust-book.css")).write_str(css::STYLE));
+ try!(File::create(&tgt.join("rust-book.css")).and_then(|mut f| {
+ f.write_all(css::STYLE.as_bytes())
+ }));
- let summary = try!(File::open(&src.join("SUMMARY.md")));
- match book::parse_summary(summary, &src) {
+ let mut summary = try!(File::open(&src.join("SUMMARY.md")));
+ match book::parse_summary(&mut summary, &src) {
Ok(book) => {
// execute rustdoc on the whole book
render(&book, &tgt)
term.err(&format!("error: {}", err)[..]);
}
- Err(box format!("{} errors occurred", n) as Box<Error>)
+ Err(err(&format!("{} errors occurred", n)))
}
}
}
//! Error handling utilities. WIP.
+use std::error::Error;
use std::fmt;
-use std::fmt::{Debug, Formatter};
-
-use std::old_io::IoError;
pub type CliError = Box<Error + 'static>;
pub type CliResult<T> = Result<T, CliError>;
pub type CommandError = Box<Error + 'static>;
pub type CommandResult<T> = Result<T, CommandError>;
-pub trait Error {
- fn description(&self) -> &str;
-
- fn detail(&self) -> Option<&str> { None }
- fn cause(&self) -> Option<&Error> { None }
-}
-
-pub trait FromError<E> {
- fn from_err(err: E) -> Self;
-}
-
-impl Debug for Box<Error + 'static> {
- fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "{}", self.description())
- }
-}
-
-impl<E: Error + 'static> FromError<E> for Box<Error + 'static> {
- fn from_err(err: E) -> Box<Error + 'static> {
- box err as Box<Error>
- }
-}
+pub fn err(s: &str) -> CliError {
+ struct E(String);
-impl<'a> Error for &'a str {
- fn description<'b>(&'b self) -> &'b str {
- *self
+ impl Error for E {
+ fn description(&self) -> &str { &self.0 }
}
-}
-
-impl Error for String {
- fn description<'a>(&'a self) -> &'a str {
- &self[..]
+ impl fmt::Display for E {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
}
-}
-
-impl<'a> Error for Box<Error + 'a> {
- fn description(&self) -> &str { (**self).description() }
- fn detail(&self) -> Option<&str> { (**self).detail() }
- fn cause(&self) -> Option<&Error> { (**self).cause() }
-}
-
-impl FromError<()> for () {
- fn from_err(_: ()) -> () { () }
-}
-impl FromError<IoError> for IoError {
- fn from_err(error: IoError) -> IoError { error }
+ Box::new(E(s.to_string()))
}
-
-impl Error for IoError {
- fn description(&self) -> &str {
- self.desc
- }
- fn detail(&self) -> Option<&str> {
- self.detail.as_ref().map(|s| &s[..])
- }
-}
-
-
-//fn iter_map_err<T, U, E, I: Iterator<Result<T,E>>>(iter: I,
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
match name {
- "help" | "--help" | "-h" | "-?" => Some(box Help as Box<Subcommand>),
+ "help" | "--help" | "-h" | "-?" => Some(Box::new(Help)),
_ => None
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-#![feature(collections)]
+#![deny(warnings)]
+
#![feature(core)]
+#![feature(exit_status)]
+#![feature(io)]
#![feature(old_io)]
-#![feature(env)]
-#![feature(os)]
-#![feature(old_path)]
+#![feature(path)]
#![feature(rustdoc)]
+#![feature(rustc_private)]
extern crate rustdoc;
+extern crate rustc_back;
use std::env;
+use std::error::Error;
use subcommand::Subcommand;
use term::Term;
-macro_rules! try (
- ($expr:expr) => ({
- use error;
- match $expr {
- Ok(val) => val,
- Err(err) => return Err(error::FromError::from_err(err))
- }
- })
-);
-
mod term;
mod error;
mod book;
} else {
match subcommand::parse_name(&cmd[1][..]) {
Some(mut subcmd) => {
- match subcmd.parse_args(cmd.tail()) {
+ match subcmd.parse_args(&cmd[..cmd.len()-1]) {
Ok(_) => {
match subcmd.execute(&mut term) {
Ok(_) => (),
Err(err) => {
- term.err(&format!("error: {}", err.description())[..]);
- err.detail().map(|detail| {
- term.err(&format!("detail: {}", detail)[..]);
- });
+ term.err(&format!("error: {}", err));
}
}
}
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
if name == "serve" {
- Some(box Serve as Box<Subcommand>)
+ Some(Box::new(Serve))
} else {
None
}
impl Term {
pub fn new() -> Term {
Term {
- err: box stdio::stderr() as Box<Writer>,
+ err: Box::new(stdio::stderr())
}
}
//! Implementation of the `test` subcommand. Just a stub for now.
use subcommand::Subcommand;
-use error::CliResult;
-use error::CommandResult;
-use error::Error;
+use error::{err, CliResult, CommandResult};
use term::Term;
use book;
-use std::old_io::{Command, File};
-use std::os;
+
+use std::fs::File;
+use std::env;
+use std::process::Command;
struct Test;
pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
if name == "test" {
- Some(box Test as Box<Subcommand>)
+ Some(Box::new(Test))
} else {
None
}
}
fn usage(&self) {}
fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
- let cwd = os::getcwd().unwrap();
+ let cwd = env::current_dir().unwrap();
let src = cwd.clone();
- let summary = File::open(&src.join("SUMMARY.md"));
- match book::parse_summary(summary, &src) {
+ let mut summary = try!(File::open(&src.join("SUMMARY.md")));
+ match book::parse_summary(&mut summary, &src) {
Ok(book) => {
for (_, item) in book.iter() {
let output_result = Command::new("rustdoc")
Ok(output) => {
if !output.status.success() {
term.err(&format!("{}\n{}",
- String::from_utf8_lossy(&output.output[..]),
- String::from_utf8_lossy(&output.error[..]))[..]);
- return Err(box "Some tests failed." as Box<Error>);
+ String::from_utf8_lossy(&output.stdout),
+ String::from_utf8_lossy(&output.stderr)));
+ return Err(err("some tests failed"));
}
}
Err(e) => {
- let message = format!("Could not execute `rustdoc`: {}", e);
- return Err(box message as Box<Error>);
+ let message = format!("could not execute `rustdoc`: {}", e);
+ return Err(err(&message))
}
}
}
for err in errors {
term.err(&err[..]);
}
- return Err(box "There was an error." as Box<Error>);
+ return Err(err("there was an error"))
}
}
Ok(()) // lol
# If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
# The actual contents of this file do not matter, but to trigger a change on the
# build bots then the contents should be changed so git updates the mtime.
-2015-02-19
+2015-03-04
S 2015-02-25 880fb89
+ bitrig-x86_64 8cdc4ca0a80103100f46cbf8caa9fe497df048c5
freebsd-x86_64 f4cbe4227739de986444211f8ee8d74745ab8f7f
linux-i386 3278ebbce8cb269acc0614dac5ddac07eab6a99c
linux-x86_64 72287d0d88de3e5a53bae78ac0d958e1a7637d73
}
impl cat {
- pub fn speak(&mut self) { self.meows += 1_usize; }
+ pub fn speak(&mut self) { self.meows += 1; }
pub fn meow_count(&mut self) -> uint { self.meows }
}
impl cat {
pub fn meow(&mut self) {
println!("Meow");
- self.meows += 1_usize;
- if self.meows % 5_usize == 0_usize {
+ self.meows += 1;
+ if self.meows % 5 == 0 {
self.how_hungry += 1;
}
}
impl cat {
fn meow(&mut self) {
println!("Meow");
- self.meows += 1_usize;
- if self.meows % 5_usize == 0_usize {
+ self.meows += 1;
+ if self.meows % 5 == 0 {
self.how_hungry += 1;
}
}
let mut i = *self;
while i < v {
f(i);
- i += 1_usize;
+ i += 1;
}
}
}
#[inline]
pub fn iter<T, F>(v: &[T], mut f: F) where F: FnMut(&T) {
- let mut i = 0_usize;
+ let mut i = 0;
let n = v.len();
while i < n {
f(&v[i]);
- i += 1_usize;
+ i += 1;
}
}
// same as cci_iter_lib, more-or-less, but not marked inline
pub fn iter<F>(v: Vec<uint> , mut f: F) where F: FnMut(uint) {
- let mut i = 0_usize;
+ let mut i = 0;
let n = v.len();
while i < n {
f(v[i]);
- i += 1_usize;
+ i += 1;
}
}
--- /dev/null
+// Copyright 2013-2015 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.
+
+#![crate_type = "rlib"]
+#![omit_gdb_pretty_printer_section]
+
+// no-prefer-dynamic
+// compile-flags:-g
+
+pub fn generic_function<T: Clone>(val: T) -> (T, T) {
+ let result = (val.clone(), val.clone());
+ let a_variable: u32 = 123456789;
+ let another_variable: f64 = 123456789.5;
+ zzz();
+ result
+}
+
+#[inline(never)]
+fn zzz() {()}
\ No newline at end of file
--- /dev/null
+// Copyright 2015 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(staged_api, allow_internal_unstable)]
+#![staged_api]
+#![stable(feature = "stable", since = "1.0.0")]
+
+#[unstable(feature = "function")]
+pub fn unstable() {}
+
+
+#[stable(feature = "stable", since = "1.0.0")]
+pub struct Foo {
+ #[unstable(feature = "struct_field")]
+ pub x: u8
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! call_unstable_allow {
+ () => { $crate::unstable() }
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! construct_unstable_allow {
+ ($e: expr) => {
+ $crate::Foo { x: $e }
+ }
+}
+
+#[allow_internal_unstable]
+#[macro_export]
+macro_rules! pass_through_allow {
+ ($e: expr) => { $e }
+}
+
+#[macro_export]
+macro_rules! call_unstable_noallow {
+ () => { $crate::unstable() }
+}
+
+#[macro_export]
+macro_rules! construct_unstable_noallow {
+ ($e: expr) => {
+ $crate::Foo { x: $e }
+ }
+}
+
+#[macro_export]
+macro_rules! pass_through_noallow {
+ ($e: expr) => { $e }
+}
--- /dev/null
+// Copyright 2015 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.
+
+// force-host
+
+#![feature(plugin_registrar)]
+#![feature(box_syntax)]
+
+extern crate syntax;
+#[macro_use] extern crate rustc;
+
+use syntax::{ast, attr};
+use rustc::lint::{Context, LintPass, LintPassObject, LintArray};
+use rustc::plugin::Registry;
+
+declare_lint!(CRATE_NOT_OKAY, Warn, "crate not marked with #![crate_okay]");
+
+struct Pass;
+
+impl LintPass for Pass {
+ fn get_lints(&self) -> LintArray {
+ lint_array!(CRATE_NOT_OKAY)
+ }
+
+ fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) {
+ if !attr::contains_name(&krate.attrs, "crate_okay") {
+ cx.span_lint(CRATE_NOT_OKAY, krate.span,
+ "crate is not marked with #![crate_okay]");
+ }
+ }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+ reg.register_lint_pass(box Pass as LintPassObject);
+}
reg.register_macro("identity", expand_identity);
reg.register_syntax_extension(
token::intern("into_foo"),
- Modifier(box expand_into_foo));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Modifier(Box::new(expand_into_foo)));
reg.register_syntax_extension(
token::intern("into_multi_foo"),
- MultiModifier(box expand_into_foo_multi));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ MultiModifier(Box::new(expand_into_foo_multi)));
}
fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
#![crate_type = "dylib"]
#[macro_export]
macro_rules! reexported {
- () => ( 3_usize )
+ () => ( 3 )
}
pub fn plugin_registrar(reg: &mut Registry) {
let args = reg.args().clone();
reg.register_syntax_extension(token::intern("plugin_args"),
- NormalTT(box Expander { args: args, }, None));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ NormalTT(Box::new(Expander { args: args, }), None, false));
}
--- /dev/null
+// Copyright 2015 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.
+
+// force-host
+
+#![crate_type="dylib"]
+#![feature(plugin_registrar, quote)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::codemap::Span;
+use syntax::parse::token::{self, str_to_ident, NtExpr, NtPat};
+use syntax::ast::{TokenTree, TtToken, Pat};
+use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
+use syntax::ext::build::AstBuilder;
+use syntax::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
+use syntax::ext::tt::macro_parser::{Success, Failure, Error};
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+fn expand_mbe_matches(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+ -> Box<MacResult + 'static> {
+
+ let mbe_matcher = quote_matcher!(cx, $matched:expr, $($pat:pat)|+);
+
+ let mac_expr = match TokenTree::parse(cx, &mbe_matcher[..], args) {
+ Success(map) => {
+ match (&*map[str_to_ident("matched")], &*map[str_to_ident("pat")]) {
+ (&MatchedNonterminal(NtExpr(ref matched_expr)),
+ &MatchedSeq(ref pats, seq_sp)) => {
+ let pats: Vec<P<Pat>> = pats.iter().map(|pat_nt|
+ if let &MatchedNonterminal(NtPat(ref pat)) = &**pat_nt {
+ pat.clone()
+ } else {
+ unreachable!()
+ }
+ ).collect();
+ let arm = cx.arm(seq_sp, pats, cx.expr_bool(seq_sp, true));
+
+ quote_expr!(cx,
+ match $matched_expr {
+ $arm
+ _ => false
+ }
+ )
+ }
+ _ => unreachable!()
+ }
+ }
+ Failure(_, s) | Error(_, s) => {
+ panic!("expected Success, but got Error/Failure: {}", s);
+ }
+ };
+
+ MacEager::expr(mac_expr)
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+ reg.register_macro("matches", expand_mbe_matches);
+}
};
let mut text = &*text;
- let mut total = 0_usize;
+ let mut total = 0;
while !text.is_empty() {
match NUMERALS.iter().find(|&&(rn, _)| text.starts_with(rn)) {
Some(&(rn, val)) => {
#[inline]
pub fn has_closures() -> uint {
- let x = 1_usize;
+ let x = 1;
let mut f = move || x;
- let y = 1_usize;
+ let y = 1;
let g = || y;
f() + g()
}
*x = random_gradient(&mut rng);
}
- let mut permutations = [0i32; 256];
+ let mut permutations = [0; 256];
for (i, x) in permutations.iter_mut().enumerate() {
*x = i as i32;
}
to_rendezvous: Sender<CreatureInfo>,
to_rendezvous_log: Sender<String>
) {
- let mut creatures_met = 0i32;
+ let mut creatures_met = 0;
let mut evil_clones_met = 0;
let mut rendezvous = from_rendezvous.iter();
}
fn get(&mut self, mut idx: i32) -> P {
- let mut pp = [0u8; 16];
+ let mut pp = [0; 16];
self.permcount = idx as u32;
for (i, place) in self.perm.p.iter_mut().enumerate() {
*place = i as i32 + 1;
let n = std::env::args()
.nth(1)
.and_then(|arg| arg.parse().ok())
- .unwrap_or(2i32);
+ .unwrap_or(2);
let (checksum, maxflips) = fannkuch(n);
println!("{}\nPfannkuchen({}) = {}", checksum, n, maxflips);
fn make(&mut self, n: usize) -> IoResult<()> {
let alu_len = self.alu.len();
- let mut buf = repeat(0u8).take(alu_len + LINE_LEN).collect::<Vec<_>>();
+ let mut buf = repeat(0).take(alu_len + LINE_LEN).collect::<Vec<_>>();
let alu: &[u8] = self.alu.as_bytes();
copy_memory(&mut buf, alu);
-> std::old_io::IoResult<()>
{
try!(wr.write(header.as_bytes()));
- let mut line = [0u8; LINE_LENGTH + 1];
+ let mut line = [0; LINE_LENGTH + 1];
while n > 0 {
let nb = min(LINE_LENGTH, n);
for i in 0..nb {
}
fn rotate(&self, c: u8, frame: usize) -> Code {
- Code(self.push_char(c).hash() & ((1u64 << (2 * frame)) - 1))
+ Code(self.push_char(c).hash() & ((1 << (2 * frame)) - 1))
}
fn pack(string: &str) -> Code {
- string.bytes().fold(Code(0u64), |a, b| a.push_char(b))
+ string.bytes().fold(Code(0), |a, b| a.push_char(b))
}
fn unpack(&self, frame: usize) -> String {
fn search_remainder<C:TableCallback>(item: &mut Entry, key: Code, c: C) {
match item.next {
None => {
- let mut entry = box Entry {
+ let mut entry: Box<_> = box Entry {
code: key,
count: 0,
next: None,
{
if self.items[index as usize].is_none() {
- let mut entry = box Entry {
+ let mut entry: Box<_> = box Entry {
code: key,
count: 0,
next: None,
.map(|(id, p)| transform(p, id != 3))
.collect();
- (0i32..50).map(|yx| {
+ (0..50).map(|yx| {
transforms.iter().enumerate().map(|(id, t)| {
t.iter().filter_map(|p| mask(yx / 5, yx % 5, id, p)).collect()
}).collect()
// Gets the identifier of a mask.
fn get_id(m: u64) -> u8 {
- for id in 0u8..10 {
+ for id in 0..10 {
if m & (1 << (id + 50) as usize) != 0 {return id;}
}
panic!("{:016x} does not have a valid identifier", m);
reader.read_line(&mut s).unwrap();
assert_eq!(s, "9,9\n");
- let mut g = repeat(vec![0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8])
+ let mut g = repeat(vec![0, 0, 0, 0, 0, 0, 0, 0, 0])
.take(10).collect::<Vec<_>>();
for line in reader.lines() {
let line = line.unwrap();
// solve sudoku grid
pub fn solve(&mut self) {
let mut work: Vec<(u8, u8)> = Vec::new(); /* queue of uncolored fields */
- for row in 0u8..9u8 {
- for col in 0u8..9u8 {
+ for row in 0..9 {
+ for col in 0..9 {
let color = self.grid[row as usize][col as usize];
- if color == 0u8 {
+ if color == 0 {
work.push((row, col));
}
}
}
fn next_color(&mut self, row: u8, col: u8, start_color: u8) -> bool {
- if start_color < 10u8 {
+ if start_color < 10 {
// colors not yet used
- let mut avail = box Colors::new(start_color);
+ let mut avail: Box<_> = box Colors::new(start_color);
// drop colors already in use in neighbourhood
self.drop_colors(&mut *avail, row, col);
// find first remaining color that is available
let next = avail.next();
self.grid[row as usize][col as usize] = next;
- return 0u8 != next;
+ return 0 != next;
}
- self.grid[row as usize][col as usize] = 0u8;
+ self.grid[row as usize][col as usize] = 0;
return false;
}
// find colors available in neighbourhood of (row, col)
fn drop_colors(&mut self, avail: &mut Colors, row: u8, col: u8) {
- for idx in 0u8..9u8 {
+ for idx in 0..9 {
/* check same column fields */
avail.remove(self.grid[idx as usize][col as usize]);
/* check same row fields */
}
// check same block fields
- let row0 = (row / 3u8) * 3u8;
- let col0 = (col / 3u8) * 3u8;
- for alt_row in row0..row0 + 3u8 {
- for alt_col in col0..col0 + 3u8 {
+ let row0 = (row / 3) * 3;
+ let col0 = (col / 3) * 3;
+ for alt_row in row0..row0 + 3 {
+ for alt_col in col0..col0 + 3 {
avail.remove(self.grid[alt_row as usize][alt_col as usize]);
}
}
// Stores available colors as simple bitfield, bit 0 is always unset
struct Colors(u16);
-static HEADS: u16 = (1u16 << 10) - 1; /* bits 9..0 */
+static HEADS: u16 = (1 << 10) - 1; /* bits 9..0 */
impl Colors {
fn new(start_color: u8) -> Colors {
// Sets bits 9..start_color
- let tails = !0u16 << start_color as usize;
+ let tails = !0 << start_color as usize;
return Colors(HEADS & tails);
}
fn next(&self) -> u8 {
let Colors(c) = *self;
let val = c & HEADS;
- if 0u16 == val {
- return 0u8;
+ if 0 == val {
+ return 0;
} else {
return val.trailing_zeros() as u8
}
}
fn remove(&mut self, color: u8) {
- if color != 0u8 {
+ if color != 0 {
let Colors(val) = *self;
- let mask = !(1u16 << color as usize);
+ let mask = !(1 << color as usize);
*self = Colors(val & mask);
}
}
static DEFAULT_SUDOKU: [[u8;9];9] = [
/* 0 1 2 3 4 5 6 7 8 */
- /* 0 */ [0u8, 4u8, 0u8, 6u8, 0u8, 0u8, 0u8, 3u8, 2u8],
- /* 1 */ [0u8, 0u8, 8u8, 0u8, 2u8, 0u8, 0u8, 0u8, 0u8],
- /* 2 */ [7u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8],
- /* 3 */ [0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 0u8, 0u8],
- /* 4 */ [0u8, 5u8, 0u8, 0u8, 0u8, 3u8, 6u8, 0u8, 0u8],
- /* 5 */ [6u8, 8u8, 0u8, 0u8, 0u8, 0u8, 0u8, 9u8, 0u8],
- /* 6 */ [0u8, 9u8, 5u8, 0u8, 0u8, 6u8, 0u8, 7u8, 0u8],
- /* 7 */ [0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 6u8, 0u8],
- /* 8 */ [4u8, 0u8, 0u8, 0u8, 0u8, 7u8, 2u8, 0u8, 3u8]
+ /* 0 */ [0, 4, 0, 6, 0, 0, 0, 3, 2],
+ /* 1 */ [0, 0, 8, 0, 2, 0, 0, 0, 0],
+ /* 2 */ [7, 0, 0, 8, 0, 0, 0, 0, 0],
+ /* 3 */ [0, 0, 0, 5, 0, 0, 0, 0, 0],
+ /* 4 */ [0, 5, 0, 0, 0, 3, 6, 0, 0],
+ /* 5 */ [6, 8, 0, 0, 0, 0, 0, 9, 0],
+ /* 6 */ [0, 9, 5, 0, 0, 6, 0, 7, 0],
+ /* 7 */ [0, 0, 0, 0, 4, 0, 0, 6, 0],
+ /* 8 */ [4, 0, 0, 0, 0, 7, 2, 0, 3]
];
#[cfg(test)]
static DEFAULT_SOLUTION: [[u8;9];9] = [
/* 0 1 2 3 4 5 6 7 8 */
- /* 0 */ [1u8, 4u8, 9u8, 6u8, 7u8, 5u8, 8u8, 3u8, 2u8],
- /* 1 */ [5u8, 3u8, 8u8, 1u8, 2u8, 9u8, 7u8, 4u8, 6u8],
- /* 2 */ [7u8, 2u8, 6u8, 8u8, 3u8, 4u8, 1u8, 5u8, 9u8],
- /* 3 */ [9u8, 1u8, 4u8, 5u8, 6u8, 8u8, 3u8, 2u8, 7u8],
- /* 4 */ [2u8, 5u8, 7u8, 4u8, 9u8, 3u8, 6u8, 1u8, 8u8],
- /* 5 */ [6u8, 8u8, 3u8, 7u8, 1u8, 2u8, 5u8, 9u8, 4u8],
- /* 6 */ [3u8, 9u8, 5u8, 2u8, 8u8, 6u8, 4u8, 7u8, 1u8],
- /* 7 */ [8u8, 7u8, 2u8, 3u8, 4u8, 1u8, 9u8, 6u8, 5u8],
- /* 8 */ [4u8, 6u8, 1u8, 9u8, 5u8, 7u8, 2u8, 8u8, 3u8]
+ /* 0 */ [1, 4, 9, 6, 7, 5, 8, 3, 2],
+ /* 1 */ [5, 3, 8, 1, 2, 9, 7, 4, 6],
+ /* 2 */ [7, 2, 6, 8, 3, 4, 1, 5, 9],
+ /* 3 */ [9, 1, 4, 5, 6, 8, 3, 2, 7],
+ /* 4 */ [2, 5, 7, 4, 9, 3, 6, 1, 8],
+ /* 5 */ [6, 8, 3, 7, 1, 2, 5, 9, 4],
+ /* 6 */ [3, 9, 5, 2, 8, 6, 4, 7, 1],
+ /* 7 */ [8, 7, 2, 3, 4, 1, 9, 6, 5],
+ /* 8 */ [4, 6, 1, 9, 5, 7, 2, 8, 3]
];
#[test]
fn colors_new_works() {
- assert_eq!(*Colors::new(1), 1022u16);
- assert_eq!(*Colors::new(2), 1020u16);
- assert_eq!(*Colors::new(3), 1016u16);
- assert_eq!(*Colors::new(4), 1008u16);
- assert_eq!(*Colors::new(5), 992u16);
- assert_eq!(*Colors::new(6), 960u16);
- assert_eq!(*Colors::new(7), 896u16);
- assert_eq!(*Colors::new(8), 768u16);
- assert_eq!(*Colors::new(9), 512u16);
+ assert_eq!(*Colors::new(1), 1022);
+ assert_eq!(*Colors::new(2), 1020);
+ assert_eq!(*Colors::new(3), 1016);
+ assert_eq!(*Colors::new(4), 1008);
+ assert_eq!(*Colors::new(5), 992);
+ assert_eq!(*Colors::new(6), 960);
+ assert_eq!(*Colors::new(7), 896);
+ assert_eq!(*Colors::new(8), 768);
+ assert_eq!(*Colors::new(9), 512);
}
#[test]
fn colors_next_works() {
- assert_eq!(Colors(0).next(), 0u8);
- assert_eq!(Colors(2).next(), 1u8);
- assert_eq!(Colors(4).next(), 2u8);
- assert_eq!(Colors(8).next(), 3u8);
- assert_eq!(Colors(16).next(), 4u8);
- assert_eq!(Colors(32).next(), 5u8);
- assert_eq!(Colors(64).next(), 6u8);
- assert_eq!(Colors(128).next(), 7u8);
- assert_eq!(Colors(256).next(), 8u8);
- assert_eq!(Colors(512).next(), 9u8);
- assert_eq!(Colors(1024).next(), 0u8);
+ assert_eq!(Colors(0).next(), 0);
+ assert_eq!(Colors(2).next(), 1);
+ assert_eq!(Colors(4).next(), 2);
+ assert_eq!(Colors(8).next(), 3);
+ assert_eq!(Colors(16).next(), 4);
+ assert_eq!(Colors(32).next(), 5);
+ assert_eq!(Colors(64).next(), 6);
+ assert_eq!(Colors(128).next(), 7);
+ assert_eq!(Colors(256).next(), 8);
+ assert_eq!(Colors(512).next(), 9);
+ assert_eq!(Colors(1024).next(), 0);
}
#[test]
colors.remove(1);
// THEN
- assert_eq!(colors.next(), 2u8);
+ assert_eq!(colors.next(), 2);
}
#[test]
--- /dev/null
+// Copyright 2015 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.
+
+// aux-build:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)] //~ ERROR crate is not marked with #![crate_okay]
+#![plugin(lint_for_crate)]
+
+pub fn main() { }
fn main() {
match () {
- Trait { x: 42_usize } => () //~ ERROR use of trait `Trait` in a struct pattern
+ Trait { x: 42 } => () //~ ERROR use of trait `Trait` in a struct pattern
}
}
// except according to those terms.
fn main() {
- let _x: i32 = [1i32, 2, 3];
+ let _x: i32 = [1, 2, 3];
//~^ ERROR mismatched types
//~| expected `i32`
- //~| found `[i32; 3]`
+ //~| found `[_; 3]`
//~| expected i32
//~| found array of 3 elements
- let x: &[i32] = &[1i32, 2, 3];
+ let x: &[i32] = &[1, 2, 3];
let _y: &i32 = x;
//~^ ERROR mismatched types
//~| expected `&i32`
let x: isize;
let y: isize;
unsafe {
- asm!("mov $1, $0" : "=r"(x) : "=r"(5_usize)); //~ ERROR operand constraint contains '='
- asm!("mov $1, $0" : "=r"(y) : "+r"(5_usize)); //~ ERROR operand constraint contains '+'
+ asm!("mov $1, $0" : "=r"(x) : "=r"(5)); //~ ERROR operand constraint contains '='
+ asm!("mov $1, $0" : "=r"(y) : "+r"(5)); //~ ERROR operand constraint contains '+'
}
foo(x);
foo(y);
// ignore-android
-#![feature(asm)]
+#![feature(asm, rustc_attrs)]
#![allow(dead_code, non_upper_case_globals)]
#[cfg(any(target_arch = "x86",
target_arch = "x86_64"))]
-pub fn main() {
+#[rustc_error]
+pub fn main() { //~ ERROR compilation successful
// assignment not dead
let mut x: isize = 0;
unsafe {
}
assert_eq!(x, 13);
}
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static b: bool = false; //~ ERROR static assertion failed
x = 1; //~ NOTE prior assignment occurs here
foo(x);
unsafe {
- asm!("mov $1, $0" : "=r"(x) : "r"(5_usize));
+ asm!("mov $1, $0" : "=r"(x) : "r"(5));
//~^ ERROR re-assignment of immutable variable `x`
}
foo(x);
pub fn main() {
let x: isize;
unsafe {
- asm!("mov $1, $0" : "r"(x) : "r"(5_usize)); //~ ERROR output operand constraint lacks '='
+ asm!("mov $1, $0" : "r"(x) : "r"(5)); //~ ERROR output operand constraint lacks '='
}
foo(x);
}
}
impl cat {
- pub fn speak(&self) { self.meows += 1_usize; }
+ pub fn speak(&self) { self.meows += 1; }
}
fn cat(in_x : usize, in_y : isize) -> cat {
}
fn main() {
- let nyan : cat = cat(52_usize, 99);
+ let nyan : cat = cat(52, 99);
nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method
}
// Tests that a function with a ! annotation always actually fails
fn bad_bang(i: usize) -> ! {
- return 7_usize; //~ ERROR `return` in a function declared as diverging [E0166]
+ return 7; //~ ERROR `return` in a function declared as diverging [E0166]
}
fn main() { bad_bang(5); }
// Tests that a function with a ! annotation always actually fails
fn bad_bang(i: usize) -> ! { //~ ERROR computation may converge in a function marked as diverging
- if i < 0_usize { } else { panic!(); }
+ if i < 0 { } else { panic!(); }
}
fn main() { bad_bang(5); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-static i: String = 10i32;
+static i: String = 10;
//~^ ERROR mismatched types
//~| expected `collections::string::String`
-//~| found `i32`
+//~| found `_`
//~| expected struct `collections::string::String`
-//~| found i32
+//~| found integral variable
fn main() { println!("{}", i); }
// except according to those terms.
fn foo<T:'static>() {
- 1_usize.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented
+ 1.bar::<T>(); //~ ERROR `core::marker::Send` is not implemented
}
trait bar {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// error-pattern:`&&` cannot be applied to type `i32`
+// error-pattern:`&&` cannot be applied to type `_`
-fn main() { let x = 1i32 && 2i32; }
+fn main() { let x = 1 && 2; }
fn main() {
// By-ref captures
{
- let mut x = 0_usize;
+ let mut x = 0;
let _f = to_fn(|| x = 42); //~ ERROR cannot assign
- let mut y = 0_usize;
+ let mut y = 0;
let _g = to_fn(|| set(&mut y)); //~ ERROR cannot borrow
- let mut z = 0_usize;
+ let mut z = 0;
let _h = to_fn_mut(|| { set(&mut z); to_fn(|| z = 42); }); //~ ERROR cannot assign
}
// By-value captures
{
- let mut x = 0_usize;
+ let mut x = 0;
let _f = to_fn(move || x = 42); //~ ERROR cannot assign
- let mut y = 0_usize;
+ let mut y = 0;
let _g = to_fn(move || set(&mut y)); //~ ERROR cannot borrow
- let mut z = 0_usize;
+ let mut z = 0;
let _h = to_fn_mut(move || { set(&mut z); to_fn(move || z = 42); }); //~ ERROR cannot assign
}
}
struct Bar(isize, isize);
fn main() {
- let x = (box 1, 2);
+ let x: (Box<_>, _) = (box 1, 2);
let r = &x.0;
let y = x; //~ ERROR cannot move out of `x` because it is borrowed
}
fn implicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
// Note the danger here:
//
}
fn explicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
add(
&*a,
rewrite(&mut a)); //~ ERROR cannot borrow
}
fn implicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
// Note the danger here:
//
}
fn explicit() {
- let mut a = box 1;
+ let mut a: Box<_> = box 1;
add(
&*a,
a); //~ ERROR cannot move
}
pub fn main() {
- let a = box A;
+ let a: Box<_> = box A;
a.foo();
//~^ ERROR cannot borrow immutable `Box` content `*a` as mutable
}
use std::collections::HashMap;
fn main() {
- let tmp;
+ let tmp: Box<_>;
let mut buggy_map: HashMap<usize, &usize> = HashMap::new();
- buggy_map.insert(42, &*box 1); //~ ERROR borrowed value does not live long enough
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ buggy_map.insert(42, &*Box::new(1)); //~ ERROR borrowed value does not live long enough
// but it is ok if we use a temporary
tmp = box 2;
}
fn copy_after_move() {
- let a = box A { x: box 0, y: 1 };
+ let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
let _y = a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn move_after_move() {
- let a = box B { x: box 0, y: box 1 };
+ let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = a.x;
let _y = a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn borrow_after_move() {
- let a = box A { x: box 0, y: 1 };
+ let a: Box<_> = box A { x: box 0, y: 1 };
let _x = a.x;
let _y = &a.y; //~ ERROR use of moved
//~^^ NOTE `a` moved here (through moving `a.x`)
}
fn move_after_borrow() {
- let a = box B { x: box 0, y: box 1 };
+ let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &a.x;
let _y = a.y; //~ ERROR cannot move
}
fn copy_after_mut_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = a.y; //~ ERROR cannot use
}
fn move_after_mut_borrow() {
- let mut a = box B { x: box 0, y: box 1 };
+ let mut a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &mut a.x;
let _y = a.y; //~ ERROR cannot move
}
fn borrow_after_mut_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &mut a.x;
let _y = &a.y; //~ ERROR cannot borrow
}
fn mut_borrow_after_borrow() {
- let mut a = box A { x: box 0, y: 1 };
+ let mut a: Box<_> = box A { x: box 0, y: 1 };
let _x = &a.x;
let _y = &mut a.y; //~ ERROR cannot borrow
}
fn copy_after_move_nested() {
- let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
let _y = a.y; //~ ERROR use of collaterally moved
}
fn move_after_move_nested() {
- let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = a.x.x;
let _y = a.y; //~ ERROR use of collaterally moved
}
fn borrow_after_move_nested() {
- let a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = a.x.x;
let _y = &a.y; //~ ERROR use of collaterally moved
}
fn move_after_borrow_nested() {
- let a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &a.x.x;
let _y = a.y; //~ ERROR cannot move
}
fn copy_after_mut_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
let _y = a.y; //~ ERROR cannot use
}
fn move_after_mut_borrow_nested() {
- let mut a = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
+ let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &mut a.x.x;
let _y = a.y; //~ ERROR cannot move
}
fn borrow_after_mut_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &mut a.x.x;
let _y = &a.y; //~ ERROR cannot borrow
}
fn mut_borrow_after_borrow_nested() {
- let mut a = box C { x: box A { x: box 0, y: 1 }, y: 2 };
+ let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
let _x = &a.x.x;
let _y = &mut a.y; //~ ERROR cannot borrow
}
// Ensure that invoking a closure counts as a unique immutable borrow
#![feature(unboxed_closures)]
-#![feature(box_syntax)]
type Fn<'a> = Box<FnMut() + 'a>;
f: Box<FnMut() + 'a>
}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn call<F>(mut f: F) where F: FnMut(Fn) {
- f(box || {
+ f(Box::new(|| {
//~^ ERROR: cannot borrow `f` as mutable more than once
- f(box || {})
- });
+ f((Box::new(|| {})))
+ }));
}
fn test1() {
fn test7() {
fn foo<F>(_: F) where F: FnMut(Box<FnMut(isize)>, isize) {}
let mut f = |g: Box<FnMut(isize)>, b: isize| {};
- f(box |a| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ f(Box::new(|a| {
foo(f);
//~^ ERROR cannot move `f` into closure because it is borrowed
//~| ERROR cannot move out of captured outer variable in an `FnMut` closure
- }, 3);
+ }), 3);
}
fn main() {}
}
fn f() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
let c1 = || get(&*x);
*x = 5; //~ ERROR cannot assign
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
*x.f = 5; //~ ERROR cannot assign to `*x.f`
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = || get(&*x.f);
let c2 = || *x.f = 5; //~ ERROR cannot borrow `x` as mutable
}
f: Box<isize>
}
- let mut x = box Foo { f: box 3 };
+ let mut x: Box<_> = box Foo { f: box 3 };
let c1 = to_fn_mut(|| set(&mut *x.f));
let c2 = to_fn_mut(|| set(&mut *x.f));
//~^ ERROR cannot borrow `x` as mutable more than once
}
fn main() {
- let mut ptr = box Foo { x: 0 };
+ let mut ptr: Box<_> = box Foo { x: 0 };
let mut test = |foo: &Foo| {
ptr = box Foo { x: ptr.x + 1 };
};
for &a in &f.a { //~ ERROR cannot move out
}
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
for &a in x.iter() { //~ ERROR cannot move out
}
}
fn borrow_in_var_from_var() {
let mut x: isize = 1;
- let y = box &mut x;
+ let y: Box<_> = box &mut x;
let p = &y;
let q = &***p;
**y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
fn borrow_in_var_from_field() {
let mut x = A { a: 1 };
- let y = box &mut x.a;
+ let y: Box<_> = box &mut x.a;
let p = &y;
let q = &***p;
**y = 2; //~ ERROR cannot assign to `**y` because it is borrowed
#![feature(box_syntax)]
fn main() {
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
match x {
Some(ref _y) => {
let _a = x; //~ ERROR cannot move
#![feature(box_syntax)]
fn main() {
- let x = Some(box 1);
+ let x: Option<Box<_>> = Some(box 1);
match x {
Some(ref y) => {
let _b = *y; //~ ERROR cannot move out
// In this instance, the freeze is conditional and starts before
// the mut borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w;
if cond() {
_w = &v;
// In this instance, the freeze and mut borrow are on separate sides
// of the if.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w;
if cond() {
_w = &v;
fn loop_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire loop.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let mut x = &mut v;
**x += 1;
loop {
fn block_overarching_alias_mut() {
// In this instance, the borrow encompasses the entire closure call.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let mut x = &mut v;
for _ in 0..3 {
borrow(&*v); //~ ERROR cannot borrow
fn loop_aliased_mut() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
loop {
borrow_mut(&mut *v); //~ ERROR cannot borrow
fn while_aliased_mut() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
while cond() {
borrow_mut(&mut *v); //~ ERROR cannot borrow
fn loop_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
loop {
borrow_mut(&mut *v);
fn while_aliased_mut_break() {
// In this instance, the borrow is carried through the loop.
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &w;
while cond() {
borrow_mut(&mut *v);
}
fn while_aliased_mut_cond(cond: bool, cond2: bool) {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut x = &mut w;
while cond {
**x += 1;
fn pre_freeze() {
// In this instance, the freeze starts before the mut borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &v;
borrow_mut(&mut *v); //~ ERROR cannot borrow
}
fn post_freeze() {
// In this instance, the const alias starts after the borrow.
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow_mut(&mut *v);
let _w = &v;
}
}
fn box_imm() {
- let v = box 3;
+ let v: Box<_> = box 3;
let _w = &v;
thread::spawn(move|| {
println!("v={}", *v);
}
fn box_imm_explicit() {
- let v = box 3;
+ let v: Box<_> = box 3;
let _w = &v;
thread::spawn(move|| {
println!("v={}", *v);
}
fn box_imm() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow(&*v,
|w| { //~ ERROR cannot borrow `v` as mutable
v = box 4;
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
pub fn main() {
- let bar = box 3;
+ let bar: Box<_> = box 3;
let _g = to_fn_mut(|| {
let _h = to_fn_once(move || -> isize { *bar }); //~ ERROR cannot move out of
});
}
fn blah() {
- let f = &Foo::Foo1(box 1u32, box 2u32);
+ let f = &Foo::Foo1(box 1, box 2);
match *f { //~ ERROR cannot move out of
Foo::Foo1(num1, //~ NOTE attempting to move value to here
num2) => (), //~ NOTE and here
#![feature(box_syntax)]
fn main() {
- let a = box box 2;
+ let a: Box<Box<_>> = box box 2;
let b = &a;
let z = *a; //~ ERROR: cannot move out of `*a` because it is borrowed
}
fn main() {
- let t = box 3;
+ let t: Box<_> = box 3;
call_f(move|| { *t + 1 });
call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
fn borrow<T>(_: &T) { }
fn different_vars_after_borrows() {
- let x1 = box 1;
+ let x1: Box<_> = box 1;
let p1 = &x1;
- let x2 = box 2;
+ let x2: Box<_> = box 2;
let p2 = &x2;
thread::spawn(move|| {
drop(x1); //~ ERROR cannot move `x1` into closure because it is borrowed
}
fn different_vars_after_moves() {
- let x1 = box 1;
+ let x1: Box<_> = box 1;
drop(x1);
- let x2 = box 2;
+ let x2: Box<_> = box 2;
drop(x2);
thread::spawn(move|| {
drop(x1); //~ ERROR capture of moved value: `x1`
}
fn same_var_after_borrow() {
- let x = box 1;
+ let x: Box<_> = box 1;
let p = &x;
thread::spawn(move|| {
drop(x); //~ ERROR cannot move `x` into closure because it is borrowed
}
fn same_var_after_move() {
- let x = box 1;
+ let x: Box<_> = box 1;
drop(x);
thread::spawn(move|| {
drop(x); //~ ERROR capture of moved value: `x`
empty
}
fn main() {
- let mut x = box cycle::node(node_ {a: box cycle::empty});
+ let mut x: Box<_> = box cycle::node(node_ {a: box cycle::empty});
// Create a cycle!
match *x {
cycle::node(ref mut y) => {
}
fn main() {
- let v = MyVec { data: vec!(box 1, box 2, box 3) };
+ let v = MyVec::<Box<_>> { data: vec!(box 1, box 2, box 3) };
let good = &v[0]; // Shouldn't fail here
let bad = v[0];
//~^ ERROR cannot move out of indexed content
#![allow(dead_code)]
fn main() {
// Original borrow ends at end of function
- let mut x = 1_usize;
+ let mut x = 1;
let y = &mut x;
let z = &x; //~ ERROR cannot borrow
}
match true {
true => {
// Original borrow ends at end of match arm
- let mut x = 1_usize;
+ let mut x = 1;
let y = &x;
let z = &mut x; //~ ERROR cannot borrow
}
fn bar() {
// Original borrow ends at end of closure
|| {
- let mut x = 1_usize;
+ let mut x = 1;
let y = &mut x;
let z = &mut x; //~ ERROR cannot borrow
};
fn borrow(_v: &isize) {}
fn local() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
borrow(&*v);
}
}
fn aliased_imm() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &v;
borrow(&*v);
}
fn aliased_mut() {
- let mut v = box 3;
+ let mut v: Box<_> = box 3;
let _w = &mut v;
borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn aliased_other() {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let _x = &mut w;
borrow(&*v);
}
fn aliased_other_reassign() {
- let mut v = box 3;
- let mut w = box 4;
+ let mut v: Box<_> = box 3;
+ let mut w: Box<_> = box 4;
let mut _x = &mut w;
_x = &mut v;
borrow(&*v); //~ ERROR cannot borrow `*v`
--- /dev/null
+// Copyright 2015 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.
+
+macro_rules! foo {
+ () => {
+ #[cfg_attr(all(), unknown)] //~ ERROR `unknown` is currently unknown
+ fn foo() {}
+ }
+}
+
+foo!();
+
+fn main() {}
}
fn main() {
- let nyan = cat(0_usize);
+ let nyan = cat(0);
}
fn sleep(&self) { loop{} }
fn meow(&self) {
println!("Meow");
- meows += 1_usize; //~ ERROR unresolved name
+ meows += 1; //~ ERROR unresolved name
sleep(); //~ ERROR unresolved name
}
// Tests that we forbid coercion from `[T; n]` to `&[T]`
fn main() {
- let _: &[i32] = [0i32];
+ let _: &[i32] = [0];
//~^ ERROR mismatched types
//~| expected `&[i32]`
- //~| found `[i32; 1]`
+ //~| found `[_; 1]`
//~| expected &-ptr
//~| found array of 1 elements
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-const A: usize = { 1_usize; 2 };
+const A: usize = { 1; 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
const B: usize = { { } 2 };
}
const C: usize = { foo!(); 2 };
-const D: usize = { let x = 4_usize; 2 };
+const D: usize = { let x = 4; 2 };
//~^ ERROR: blocks in constants are limited to items and tail expressions
pub fn main() {
--- /dev/null
+// Copyright 2012-2013 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.
+
+// Check that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred), while also providing the
+// overall context for what caused the evaluation.
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+const LEN: usize = ONE - TWO;
+//~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+
+fn main() {
+ let a: [i8; LEN] = unimplemented!();
+ //~^ NOTE for array length here
+}
--- /dev/null
+// Copyright 2012-2013 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.
+
+// Check that an constant-evaluation underflow highlights the correct
+// spot (where the underflow occurred).
+
+const ONE: usize = 1;
+const TWO: usize = 2;
+
+fn main() {
+ let a: [i8; ONE - TWO] = unimplemented!();
+ //~^ ERROR array length constant evaluation error: attempted to sub with overflow [E0250]
+}
// Test that cross-borrowing (implicitly converting from `Box<T>` to `&T`) is
// forbidden when `T` is a trait.
-#![feature(box_syntax)]
-
struct Foo;
trait Trait { fn foo(&self) {} }
impl Trait for Foo {}
pub fn main() {
- let x: Box<Trait> = box Foo;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let x: Box<Trait> = Box::new(Foo);
let _y: &Trait = x; //~ ERROR mismatched types
//~| expected `&Trait`
//~| found `Box<Trait>`
struct A<T>
where T : Trait,
T : Add<T::Item>
- //~^ ERROR illegal recursive type
+ //~^ ERROR unsupported cyclic reference between types/traits detected
{
data: T
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test a cycle where a type parameter on a trait has a default that
+// again references the trait.
+
+trait Foo<X = Box<Foo>> {
+ //~^ ERROR unsupported cyclic reference
+}
+
+fn main() { }
// a direct participant in the cycle.
trait A: B {
+ //~^ ERROR unsupported cyclic reference
}
-trait B: C { }
+trait B: C {
+ //~^ ERROR unsupported cyclic reference
+}
trait C: B { }
//~^ ERROR unsupported cyclic reference
impl T for S { }
#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
-static s: usize = 0_usize;
+static s: usize = 0;
#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
-const c: usize = 0_usize;
+const c: usize = 0;
#[derive(PartialEq)] //~ ERROR: `derive` may only be applied to structs and enums
mod m { }
fn main() {
let b = {
- let a = Box::new(RefCell::new(4i8));
- *a.borrow() + 1i8 //~ ERROR `*a` does not live long enough
+ let a = Box::new(RefCell::new(4));
+ *a.borrow() + 1 //~ ERROR `*a` does not live long enough
};
println!("{}", b);
}
// Forbid assignment into a dynamically sized type.
-#![feature(box_syntax)]
-
struct Fat<T: ?Sized> {
f1: isize,
f2: &'static str,
pub fn main() {
// Assignment.
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
- let z: Box<ToBar> = box Bar1 {f: 36};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = *z;
//~^ ERROR the trait `core::marker::Sized` is not implemented
}
// Forbid assignment into a dynamically sized type.
-#![feature(box_syntax)]
-
struct Fat<T: ?Sized> {
f1: isize,
f2: &'static str,
pub fn main() {
// Assignment.
let f5: &mut Fat<ToBar> = &mut Fat { f1: 5, f2: "some str", ptr: Bar1 {f :42} };
- let z: Box<ToBar> = box Bar1 {f: 36};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let z: Box<ToBar> = Box::new(Bar1 {f: 36});
f5.ptr = Bar1 {f: 36};
//~^ ERROR mismatched types
//~| expected `ToBar`
+++ /dev/null
-// 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.
-
-trait Foo {}
-
-fn foo<T: Foo + Foo>() {} //~ ERROR `Foo` already appears in the list of bounds
-
-fn main() {}
// except according to those terms.
// compile-flags: --extern std=
-// error-pattern: is not a file
+// error-pattern: can't find crate for `std`
fn main() {}
// except according to those terms.
enum test {
- div_zero = 1/0, //~ERROR expected constant: attempted to divide by zero
- rem_zero = 1%0 //~ERROR expected constant: attempted remainder with a divisor of zero
+ div_zero = 1/0, //~ERROR constant evaluation error: attempted to divide by zero
+ rem_zero = 1%0 //~ERROR constant evaluation error: attempted remainder with a divisor of zero
}
fn main() {}
--- /dev/null
+// Copyright 2015 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.
+
+macro_rules! bar {
+ () => {
+ // more layers don't help:
+ #[allow_internal_unstable]
+ macro_rules! baz { //~ ERROR allow_internal_unstable side-steps
+ () => {}
+ }
+ }
+}
+
+bar!();
+
+fn main() {}
--- /dev/null
+// Copyright 2015 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.
+
+#[allow_internal_unstable] //~ ERROR allow_internal_unstable side-steps
+macro_rules! foo {
+ () => {}
+}
+
+fn main() {}
--- /dev/null
+// Copyright 2015 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.
+
+#[static_assert] //~ ERROR `#[static_assert]` is an experimental feature
+static X: bool = true;
+
+fn main() {}
// test. Not ideal, but oh well :(
fn main() {
- let a = &[1i32, 2, 3];
+ let a = &[1, 2, 3];
println!("{}", {
extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change
fn atomic_fence();
// except according to those terms.
// error-pattern: too big for the current
+#![allow(exceeding_bitshifts)]
fn main() {
let fat : [u8; (1<<61)+(1<<31)] = [0; (1u64<<61) as usize +(1u64<<31) as usize];
mod circ1 {
pub use circ2::f2;
pub fn f1() { println!("f1"); }
- pub fn common() -> usize { return 0_usize; }
+ pub fn common() -> usize { return 0; }
}
mod circ2 {
pub use circ1::f1;
pub fn f2() { println!("f2"); }
- pub fn common() -> usize { return 1_usize; }
+ pub fn common() -> usize { return 1; }
}
mod test {
// except according to those terms.
fn main() {
- (return)[0_usize]; //~ ERROR the type of this value must be known in this context
+ (return)[0]; //~ ERROR the type of this value must be known in this context
}
}
fn function<T:ToOpt + Clone>(counter: usize, t: T) {
- if counter > 0_usize {
- function(counter - 1_usize, t.to_option());
+ if counter > 0 {
+ function(counter - 1, t.to_option());
// FIXME(#4287) Error message should be here. It should be
// a type error to instantiate `test` at a type other than T.
}
}
fn main() {
- function(22_usize, 22_usize);
+ function(22, 22);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// error-pattern: illegal recursive type
-
-
type x = Vec<x>;
+//~^ ERROR unsupported cyclic reference
fn main() { let b: x = Vec::new(); }
--- /dev/null
+// Copyright 2015 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.
+
+// this has to be separate to internal-unstable.rs because these tests
+// have error messages pointing deep into the internals of the
+// cross-crate macros, and hence need to use error-pattern instead of
+// the // ~ form.
+
+// aux-build:internal_unstable.rs
+// error-pattern:use of unstable library feature 'function'
+// error-pattern:use of unstable library feature 'struct_field'
+// error-pattern:compilation successful
+#![feature(rustc_attrs)]
+
+#[macro_use]
+extern crate internal_unstable;
+
+#[rustc_error]
+fn main() {
+ call_unstable_noallow!();
+
+ construct_unstable_noallow!(0);
+}
--- /dev/null
+// Copyright 2015 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.
+
+// aux-build:internal_unstable.rs
+
+#![feature(rustc_attrs)]
+#![allow(dead_code)]
+
+extern crate internal_unstable;
+
+
+thread_local!(static FOO: () = ());
+thread_local!(static BAR: () = internal_unstable::unstable()); //~ WARN use of unstable
+
+#[rustc_error]
+fn main() {} //~ ERROR
--- /dev/null
+// Copyright 2015 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.
+
+// aux-build:internal_unstable.rs
+
+#![feature(rustc_attrs, allow_internal_unstable)]
+
+#[macro_use]
+extern crate internal_unstable;
+
+macro_rules! foo {
+ ($e: expr, $f: expr) => {{
+ $e;
+ $f;
+ internal_unstable::unstable(); //~ WARN use of unstable
+ }}
+}
+
+#[allow_internal_unstable]
+macro_rules! bar {
+ ($e: expr) => {{
+ foo!($e,
+ internal_unstable::unstable());
+ internal_unstable::unstable();
+ }}
+}
+
+#[rustc_error]
+fn main() { //~ ERROR
+ // ok, the instability is contained.
+ call_unstable_allow!();
+ construct_unstable_allow!(0);
+
+ // bad.
+ pass_through_allow!(internal_unstable::unstable()); //~ WARN use of unstable
+
+ pass_through_noallow!(internal_unstable::unstable()); //~ WARN use of unstable
+
+
+
+ println!("{:?}", internal_unstable::unstable()); //~ WARN use of unstable
+
+ bar!(internal_unstable::unstable()); //~ WARN use of unstable
+}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
fn test<'x>(x: &'x isize) {
- drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
x
//~^ ERROR cannot infer an appropriate lifetime
- });
+ }));
}
fn main() {}
#![feature(box_syntax)]
fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let f = move|| {
let _a = x;
drop(x);
}
fn main() {
- let mut ptr = box Foo { x: 0 };
+ let mut ptr: Box<_> = box Foo { x: 0 };
let mut test = |foo: &Foo| {
println!("access {}", foo.x);
ptr = box Foo { x: ptr.x + 1 };
}
fn main() {
- let closure: Box<Fn()+'static> = box || ();
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let closure: Box<Fn()+'static> = Box::new(|| ());
let test = box Test { func: closure }; //~ ERROR mismatched types
}
// except according to those terms.
fn blah() -> i32 { //~ ERROR not all control paths return a value
- 1i32
+ 1
; //~ HELP consider removing this semicolon:
}
fn main() {
let r = {
- let x = box 42;
+ let x: Box<_> = box 42;
let f = to_fn_once(move|| &x); //~ ERROR: `x` does not live long enough
f()
};
fn do_it(x: &isize) { }
fn main() {
- let x = box 22;
+ let x: Box<_> = box 22;
let f = to_fn_once(move|| do_it(&*x));
to_fn_once(move|| {
f();
{
let cont_iter = cont.iter();
//~^ ERROR cannot infer an appropriate lifetime for autoref due to conflicting requirements
- let result = cont_iter.fold(Some(0u16), |state, val| {
+ let result = cont_iter.fold(Some(0), |state, val| {
state.map_or(None, |mask| {
let bit = 1 << val;
if mask & bit == 0 {Some(mask|bit)} else {None}
}
fn main() {
- check((3_usize, 5_usize));
+ check((3, 5));
//~^ ERROR mismatched types
//~| expected `&_`
-//~| found `(usize, usize)`
+//~| found `(_, _)`
//~| expected &-ptr
//~| found tuple
}
// The expected arm type `Option<T>` has one type parameter, while
// the actual arm `Result<T, E>` has two. typeck should not be
// tricked into looking up a non-existing second type parameter.
- let _x: usize = match Some(1_usize) {
+ let _x: usize = match Some(1) {
Ok(u) => u,
//~^ ERROR mismatched types
- //~| expected `core::option::Option<usize>`
+ //~| expected `core::option::Option<_>`
//~| found `core::result::Result<_, _>`
//~| expected enum `core::option::Option`
//~| found enum `core::result::Result`
Err(e) => panic!(e)
//~^ ERROR mismatched types
- //~| expected `core::option::Option<usize>`
+ //~| expected `core::option::Option<_>`
//~| found `core::result::Result<_, _>`
//~| expected enum `core::option::Option`
//~| found enum `core::result::Result`
//~| expected u8
//~| found array of 1 elements
- let local = [0u8];
+ let local = [0];
let _v = &local as *mut u8;
//~^ ERROR mismatched types
//~| expected `*mut u8`
- //~| found `&[u8; 1]`
+ //~| found `&[_; 1]`
//~| expected u8,
//~| found array of 1 elements
}
struct List<'a, T: ListItem<'a>> {
//~^ ERROR the parameter type `T` may not live long enough
-//~^^ HELP consider adding an explicit lifetime bound
-//~^^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
+//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
slice: &'a [T]
}
-
+//~^ HELP consider adding an explicit lifetime bound
impl<'a, T: ListItem<'a>> Collection for List<'a, T> {
fn len(&self) -> usize {
0
struct Foo { a: isize, b: isize }
fn main() {
- let mut x = box Foo { a: 1, b: 2 };
+ let mut x: Box<_> = box Foo { a: 1, b: 2 };
let (a, b) = (&mut x.a, &mut x.b);
//~^ ERROR cannot borrow `x` (here through borrowing `x.b`) as mutable more than once at a time
//~^^ NOTE previous borrow of `x` occurs here (through borrowing `x.a`)
- let mut foo = box Foo { a: 1, b: 2 };
+ let mut foo: Box<_> = box Foo { a: 1, b: 2 };
let (c, d) = (&mut foo.a, &foo.b);
//~^ ERROR cannot borrow `foo` (here through borrowing `foo.b`) as immutable
//~^^ NOTE previous borrow of `foo` occurs here (through borrowing `foo.a`)
}
fn main() {
- let x = 1_usize;
+ let x = 1;
let y: Foo;
// `x { ... }` should not be interpreted as a struct literal here
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
fn main() {
let _foo = &[1_usize, 2] as [usize];
//~^ ERROR cast to unsized type: `&[usize; 2]` as `[usize]`
//~^^ HELP consider using an implicit coercion to `&[usize]` instead
- let _bar = box 1_usize as std::fmt::Debug;
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _bar = Box::new(1_usize) as std::fmt::Debug;
//~^ ERROR cast to unsized type: `Box<usize>` as `core::fmt::Debug`
//~^^ HELP did you mean `Box<core::fmt::Debug>`?
+
let _baz = 1_usize as std::fmt::Debug;
//~^ ERROR cast to unsized type: `usize` as `core::fmt::Debug`
//~^^ HELP consider using a box or reference as appropriate
+
let _quux = [1_usize, 2] as [usize];
//~^ ERROR cast to unsized type: `[usize; 2]` as `[usize]`
//~^^ HELP consider using a box or reference as appropriate
// Test that moves of unsized values within closures are caught
// and rejected.
-#![feature(box_syntax)]
-
fn main() {
- (|| box *[0_usize].as_slice())();
- //~^ ERROR cannot move out of borrowed content
- //~^^ ERROR cannot move a value of type [usize]
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ (|| Box::new(*[0].as_slice()))();
+ //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `[_]`
}
const A3: usize = 1;
fn main() {
- match 1_usize {
+ match 1 {
A1 => {} //~ ERROR: static variables cannot be referenced in a pattern
A2 => {} //~ ERROR: static variables cannot be referenced in a pattern
A3 => {}
#[cfg(target_pointer_width = "64")]
fn main() {
let n = 0_usize;
- let a = box [&n; 0xF000000000000000_usize];
+ let a: Box<_> = box [&n; 0xF000000000000000_usize];
println!("{}", a[0xFFFFFF_usize]);
}
#[cfg(target_pointer_width = "32")]
fn main() {
let n = 0_usize;
- let a = box [&n; 0xFFFFFFFF_usize];
+ let a: Box<_> = box [&n; 0xFFFFFFFF_usize];
println!("{}", a[0xFFFFFF_usize]);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-pub static X: usize = 1_usize;
+pub static X: usize = 1;
fn main() {
- match 1_usize {
+ match 1 {
self::X => { },
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
_ => { },
AbstractRenderer
//~^ ERROR: the trait `core::marker::Sized` is not implemented
{
- match 0_usize {
+ match 0 {
_ => unimplemented!()
}
}
}
fn main() {
- let f = Foo::Variant(42_usize); //~ ERROR uses it like a function
+ let f = Foo::Variant(42); //~ ERROR uses it like a function
}
use std::any::Any;
use std::any::TypeId;
+use std::marker::MarkerTrait;
-pub trait Pt {}
-pub trait Rt {}
+pub trait Pt : MarkerTrait {}
+pub trait Rt : MarkerTrait {}
trait Private<P: Pt, R: Rt> {
fn call(&self, p: P, r: R);
}
-pub trait Public: Private<
+pub trait Public: Private< //~ ERROR private trait in exported type parameter bound
<Self as Public>::P,
-//~^ ERROR illegal recursive type; insert an enum or struct in the cycle, if this is desired
<Self as Public>::R
> {
type P;
}
fn main() {
- let s = &mut 1_usize;
+ let s = &mut 1;
MyPtr(s).poke(s);
//~^ ERROR cannot borrow `*s` as mutable more than once at a time
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
use std::cell::RefCell;
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
fn main() {
- let mut y = 1_usize;
+ let mut y = 1;
let c = RefCell::new(vec![]);
- c.push(box || y = 0);
- c.push(box || y = 0);
+ c.push(Box::new(|| y = 0));
+ c.push(Box::new(|| y = 0));
//~^ ERROR cannot borrow `y` as mutable more than once at a time
}
fn ufcs() {
- let mut y = 1_usize;
+ let mut y = 1;
let c = RefCell::new(vec![]);
- Push::push(&c, box || y = 0);
- Push::push(&c, box || y = 0);
+ Push::push(&c, Box::new(|| y = 0));
+ Push::push(&c, Box::new(|| y = 0));
//~^ ERROR cannot borrow `y` as mutable more than once at a time
}
#[inline(never)]
fn foo(b: &Bar) {
- b.foo(&0usize)
+ b.foo(&0)
//~^ ERROR the trait `Foo` is not implemented for the type `Bar`
}
fn main() {
let a: [isize; TUP.1];
- //~^ ERROR expected constant expr for array length: tuple index out of bounds
+ //~^ ERROR array length constant evaluation error: tuple index out of bounds
+ //~| ERROR attempted out-of-bounds tuple index
+ //~| ERROR attempted out-of-bounds tuple index
}
fn main() {
let a: [isize; STRUCT.nonexistent_field];
- //~^ ERROR expected constant expr for array length: nonexistent struct field
+ //~^ ERROR array length constant evaluation error: nonexistent struct field
+ //~| ERROR attempted access of field `nonexistent_field`
+ //~| ERROR attempted access of field `nonexistent_field`
}
fn main() {
if let Some(homura) = Some("madoka") { //~ ERROR missing an else clause
//~| expected `()`
- //~| found `i32`
+ //~| found `_`
//~| expected ()
- //~| found i32
- 765i32
+ //~| found integral variable
+ 765
};
}
}
fn mut_ptr() -> *mut T {
- unsafe { 0u8 as *mut T }
+ unsafe { 0 as *mut T }
}
fn const_ptr() -> *const T {
- unsafe { 0u8 as *const T }
+ unsafe { 0 as *const T }
}
pub fn main() {
fn fail_len(v: Vec<isize> ) -> usize {
let mut i = 3;
panic!();
- for x in &v { i += 1_usize; }
+ for x in &v { i += 1; }
//~^ ERROR: unreachable statement
return i;
}
--- /dev/null
+// Copyright 2015 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.
+
+pub struct PublicType;
+struct PrivateType;
+
+pub trait PublicTrait {
+ type Item;
+}
+
+trait PrivateTrait {
+ type Item;
+}
+
+impl PublicTrait for PublicType {
+ type Item = PrivateType; //~ ERROR private type in exported type signature
+}
+
+// OK
+impl PublicTrait for PrivateType {
+ type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PublicType {
+ type Item = PrivateType;
+}
+
+// OK
+impl PrivateTrait for PrivateType {
+ type Item = PrivateType;
+}
+
+fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
mod my_mod {
pub struct MyStruct {
priv_field: isize
let my_struct = my_mod::MyStruct();
let _woohoo = (&my_struct).priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
- let _woohoo = (box my_struct).priv_field;
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _woohoo = (Box::new(my_struct)).priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
+
(&my_struct).happyfun(); //~ ERROR method `happyfun` is private
- (box my_struct).happyfun(); //~ ERROR method `happyfun` is private
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ (Box::new(my_struct)).happyfun(); //~ ERROR method `happyfun` is private
let nope = my_struct.priv_field;
//~^ ERROR field `priv_field` of struct `my_mod::MyStruct` is private
}
+++ /dev/null
-// Copyright 2012 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.
-
-// ignore-tidy-linelength
-
-use std::cmp::PartialEq;
-
-trait Hahaha: PartialEq + PartialEq {
- //~^ ERROR trait `PartialEq` already appears in the list of bounds
-}
-
-struct Lol(isize);
-
-impl Hahaha for Lol { }
-
-impl PartialEq for Lol {
- fn eq(&self, other: &Lol) -> bool { **self != **other }
- fn ne(&self, other: &Lol) -> bool { **self == **other }
-}
-
-fn main() {
- if Lol(2) == Lol(4) {
- println!("2 == 4");
- } else {
- println!("2 != 4");
- }
-}
// except according to those terms.
#![feature(unboxed_closures)]
-#![feature(box_syntax)]
fn id<T>(t: T) -> T { t }
fn f<'r, T>(v: &'r T) -> Box<FnMut() -> T + 'r> {
- id(box || *v)
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ id(Box::new(|| *v))
//~^ ERROR `v` does not live long enough
//~| ERROR cannot move out of borrowed content
}
fn bar(int_param: usize) {}
fn main() {
- let foo: [u8; 4] = [1u8; 4_usize];
+ let foo: [u8; 4] = [1; 4];
bar(foo);
//~^ ERROR mismatched types
//~| expected `usize`
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
trait Foo { fn foo(&self) {} }
impl Foo for u8 {}
fn main() {
- let r: Box<Foo> = box 5;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r: Box<Foo> = Box::new(5);
let _m: Box<Foo> = r as Box<Foo>;
//~^ ERROR `core::marker::Sized` is not implemented for the type `Foo`
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(rustc_attrs)]
#![allow(dead_code)]
// Matching against NaN should result in a warning
use std::f64::NAN;
-fn main() {
+#[rustc_error]
+fn main() { //~ ERROR compilation successful
let x = NAN;
match x {
NAN => {},
};
//~^^^ WARNING unmatchable NaN in pattern, use the is_nan method in a guard instead
}
-
-// At least one error is needed so that compilation fails
-#[static_assert]
-static B: bool = false; //~ ERROR static assertion failed
impl CtxtFn for usize {
fn f8(self, i: usize) -> usize {
- i * 4_usize
+ i * 4
}
fn f9(i: usize) -> usize {
- i * 4_usize
+ i * 4
}
}
impl OtherTrait for usize {
fn f9(i: usize) -> usize {
- i * 8_usize
+ i * 8
}
}
_ => ()
}
- match &Some(42i32) {
+ match &Some(42) {
Some(x) => (),
//~^ ERROR mismatched types
- //~| expected `&core::option::Option<i32>`
+ //~| expected `&core::option::Option<_>`
//~| found `core::option::Option<_>`
//~| expected &-ptr
//~| found enum `core::option::Option`
None => ()
//~^ ERROR mismatched types
- //~| expected `&core::option::Option<i32>`
+ //~| expected `&core::option::Option<_>`
//~| found `core::option::Option<_>`
//~| expected &-ptr
//~| found enum `core::option::Option`
fn take_param<T:Foo>(foo: &T) { }
fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
take_param(&x);
//~^ ERROR the trait `core::marker::Copy` is not implemented
}
fn take_param<T:Foo>(foo: &T) { }
fn a() {
- let x = box 3;
+ let x: Box<_> = box 3;
take_param(&x); //~ ERROR `core::marker::Copy` is not implemented
}
fn b() {
- let x = box 3;
+ let x: Box<_> = box 3;
let y = &x;
let z = &x as &Foo; //~ ERROR `core::marker::Copy` is not implemented
}
fn bar<F:FnOnce() + Send>(_: F) { }
fn main() {
- let x = Rc::new(3_usize);
+ let x = Rc::new(3);
bar(move|| foo(x));
//~^ ERROR `core::marker::Send` is not implemented
}
fn check<'r, I: Iterator<Item=usize>, T: Itble<'r, usize, I>>(cont: &T) -> bool {
//~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<Item = usize>, T: Itble<'r, usize, I>>(cont: &'r T)
let cont_iter = cont.iter(); //~ ERROR: cannot infer
- let result = cont_iter.fold(Some(0u16), |state, val| {
+ let result = cont_iter.fold(Some(0), |state, val| {
state.map_or(None, |mask| {
let bit = 1 << val;
if mask & bit == 0 {Some(mask|bit)} else {None}
fn main() {
field_read(Foo { x: 1, b: false, marker: std::marker::NoCopy });
field_match_in_patterns(XYZ::Z);
- field_match_in_let(Bar { x: 42_usize, b: true, _guard: () });
+ field_match_in_let(Bar { x: 42, b: true, _guard: () });
let _ = Baz { x: 0 };
}
//
// regression test for #8005
-macro_rules! test { () => { fn foo() -> i32 { 1i32; } } }
+macro_rules! test { () => { fn foo() -> i32 { 1; } } }
//~^ ERROR not all control paths return a value
//~^^ HELP consider removing this semicolon
#![feature(box_syntax)]
fn main() {
- let x = box 5;
+ let x: Box<_> = box 5;
let y = x;
println!("{}", *x); //~ ERROR use of moved value: `*x`
y.clone();
extern crate macro_non_reexport_2;
fn main() {
- assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined
+ assert_eq!(reexported!(), 3); //~ ERROR macro undefined
}
extern crate macro_reexport_1;
fn main() {
- assert_eq!(reexported!(), 3_usize); //~ ERROR macro undefined
+ assert_eq!(reexported!(), 3); //~ ERROR macro undefined
}
fn main() {
let x: Box<HashMap<isize, isize>> = box HashMap::new();
let x: Box<Map<isize, isize>> = x;
- let y: Box<Map<usize, isize>> = box x;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let y: Box<Map<usize, isize>> = Box::new(x);
//~^ ERROR the trait `Map<usize, isize>` is not implemented
}
//~| found `Foo`
//~| expected &-ptr
//~| found struct `Foo`
- Foo::bar(&42i32); //~ ERROR mismatched types
+ Foo::bar(&42); //~ ERROR mismatched types
//~| expected `&Foo`
- //~| found `&i32`
+ //~| found `&_`
//~| expected struct `Foo`
- //~| found i32
+ //~| found integral variable
}
#![feature(box_syntax)]
pub fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
#![feature(box_syntax)]
pub fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
struct Foo(Box<isize>);
fn main() {
- let x = (box 1,);
+ let x: (Box<_>,) = (box 1,);
let y = x.0;
let z = x.0; //~ ERROR use of moved value: `x.0`
// bound must be noncopyable. For details see
// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct R<'a> {
}
fn conspirator<F>(mut f: F) where F: FnMut(&mut R, bool) {
- let mut r = R {c: box f};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut r = R {c: Box::new(f)};
f(&mut r, false) //~ ERROR use of moved value
}
fn f(_: &mut isize) {}
fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
f(x) //~ ERROR mismatched types
}
// except according to those terms.
fn main() {
- let foo = &mut 1i32;
+ let foo = &mut 1;
// (separate lines to ensure the spans are accurate)
let &_ //~ ERROR mismatched types
- //~| expected `&mut i32`
+ //~| expected `&mut _`
//~| found `&_`
//~| values differ in mutability
= foo;
let &mut _ = foo;
- let bar = &1i32;
+ let bar = &1;
let &_ = bar;
let &mut _ //~ ERROR mismatched types
- //~| expected `&i32`
+ //~| expected `&_`
//~| found `&mut _`
//~| values differ in mutability
= bar;
}
fn main() {
- let nyan : cat = cat(52_usize, 99);
+ let nyan : cat = cat(52, 99);
nyan.eat();
}
}
fn main() {
- let nyan : cat = cat(52_usize, 99);
+ let nyan : cat = cat(52, 99);
nyan.how_hungry = 0; //~ ERROR cannot assign
}
fn main() {
fn bar(n: isize) {
let _x: [isize; n];
- //~^ ERROR expected constant expr for array length: non-constant path in constant expr
+ //~^ ERROR no type for local variable
+ //~| ERROR array length constant evaluation error: non-constant path in constant expr
}
}
Foo { first: true, second: None } => (),
Foo { first: true, second: Some(_) } => (),
Foo { first: false, second: None } => (),
- Foo { first: false, second: Some([1_usize, 2_usize, 3_usize, 4_usize]) } => ()
+ Foo { first: false, second: Some([1, 2, 3, 4]) } => ()
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
enum blah { a(isize, isize, usize), b(isize, isize), }
-fn main() { match blah::a(1, 1, 2_usize) { blah::a(_, x, y) | blah::b(x, y) => { } } }
+fn main() { match blah::a(1, 1, 2) { blah::a(_, x, y) | blah::b(x, y) => { } } }
// except according to those terms.
// aux-build:privacy-tuple-struct.rs
-// ignore-fast
extern crate "privacy-tuple-struct" as other;
}
fn main() {
- let nyan : kitties::cat = kitties::cat(52_usize, 99);
+ let nyan : kitties::cat = kitties::cat(52, 99);
nyan.nap();
}
use cci_class::kitties::cat;
fn main() {
- let nyan : cat = cat(52_usize, 99);
- assert!((nyan.meows == 52_usize));
+ let nyan : cat = cat(52, 99);
+ assert!((nyan.meows == 52));
//~^ ERROR field `meows` of struct `cci_class::kitties::cat` is private
}
//~^ ERROR the trait `core::num::Int` is not implemented for the type `f32`
// Unsized type.
- let arr: &[_] = &[1u32, 2, 3];
+ let arr: &[_] = &[1, 2, 3];
let range = *arr..;
//~^ ERROR the trait `core::marker::Sized` is not implemented
}
// Test that attempts to implicitly coerce a value into an
// object respect the lifetime bound on the object type.
-#![feature(box_syntax)]
-
trait Foo : ::std::marker::MarkerTrait {}
impl<'a> Foo for &'a [u8] {}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
fn a(v: &[u8]) -> Box<Foo + 'static> {
- let x: Box<Foo + 'static> = box v; //~ ERROR does not fulfill the required lifetime
+ let x: Box<Foo + 'static> = Box::new(v);
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
x
}
fn b(v: &[u8]) -> Box<Foo + 'static> {
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn c(v: &[u8]) -> Box<Foo> {
// same as previous case due to RFC 599
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn d<'a,'b>(v: &'a [u8]) -> Box<Foo+'b> {
- box v //~ ERROR does not fulfill the required lifetime
+ Box::new(v)
+ //~^ ERROR cannot infer an appropriate lifetime due to conflicting
}
fn e<'a:'b,'b>(v: &'a [u8]) -> Box<Foo+'b> {
- box v // OK, thanks to 'a:'b
+ Box::new(v) // OK, thanks to 'a:'b
}
fn main() { }
impl dog {
pub fn chase_cat(&mut self) {
let p: &'static mut usize = &mut self.cats_chased; //~ ERROR cannot infer
- *p += 1_usize;
+ *p += 1;
}
pub fn chase_cat_2(&mut self) {
let p: &mut usize = &mut self.cats_chased;
- *p += 1_usize;
+ *p += 1;
}
}
fn dog() -> dog {
dog {
- cats_chased: 0_usize
+ cats_chased: 0
}
}
pub fn chase_cat(&mut self) {
let _f = || {
let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
- *p = 3_usize;
+ *p = 3;
};
}
}
#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
use std::marker::MarkerTrait;
trait X : MarkerTrait {}
fn bad1<T: Iter>(v: T) -> Box<X+'static>
{
let item = v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad2<T: Iter>(v: T) -> Box<X+'static>
where Box<T::Item> : X
{
- let item = box v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ let item: Box<_> = box v.into_item();
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad3<'a, T: Iter>(v: T) -> Box<X+'a>
{
let item = v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn bad4<'a, T: Iter>(v: T) -> Box<X+'a>
where Box<T::Item> : X
{
- let item = box v.into_item();
- box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+ let item: Box<_> = box v.into_item();
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live long enough
}
fn ok1<'a, T: Iter>(v: T) -> Box<X+'a>
where T::Item : 'a
{
let item = v.into_item();
- box item // OK, T::Item : 'a is declared
+ Box::new(item) // OK, T::Item : 'a is declared
}
fn ok2<'a, T: Iter>(v: &T, w: &'a T::Item) -> Box<X+'a>
where T::Item : Clone
{
let item = Clone::clone(w);
- box item // OK, T::Item : 'a is implied
+ Box::new(item) // OK, T::Item : 'a is implied
}
fn ok3<'a, T: Iter>(v: &'a T) -> Box<X+'a>
where T::Item : Clone + 'a
{
let item = Clone::clone(v.as_item());
- box item // OK, T::Item : 'a was declared
+ Box::new(item) // OK, T::Item : 'a was declared
}
fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
// T::Item`. But we're not that smart at present.
let item = Clone::clone(v.as_item());
- box item //~ ERROR associated type `<T as Iter>::Item` may not live
+ Box::new(item) //~ ERROR associated type `<T as Iter>::Item` may not live
}
fn main() {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
trait X { fn foo(&self) {} }
fn p1<T>(v: T) -> Box<X+'static>
where T : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p2<T>(v: Box<T>) -> Box<X+'static>
where Box<T> : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p3<'a,T>(v: T) -> Box<X+'a>
where T : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn p4<'a,T>(v: Box<T>) -> Box<X+'a>
where Box<T> : X
{
- box v //~ ERROR parameter type `T` may not live long enough
+ Box::new(v) //~ ERROR parameter type `T` may not live long enough
}
fn main() {}
}
fn build() {
- let x = ast::num(3_usize);
- let y = ast::num(4_usize);
+ let x = ast::num(3);
+ let y = ast::num(4);
let z = ast::add(&x, &y);
compute(&z);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn ignore<T>(t: T) {}
let y = 3;
let mut ay = &y;
- ignore::<Box<for<'z> FnMut(&'z isize)>>(box |z| {
+ ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
ay = x; //~ ERROR cannot infer
ay = &y;
ay = z;
- });
+ }));
- ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(box |z| {
+ ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
if false { return x; } //~ ERROR cannot infer an appropriate lifetime for automatic
if false { return ay; }
return z;
- });
+ }));
}
fn main() {}
// except according to those terms.
fn main() {
- let a0 = 0u8;
- let f = 1u8;
+ let a0 = 0;
+ let f = 1;
let mut a1 = &a0;
match (&a1,) {
(&ref b0,) => {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn borrowed_proc<'a>(x: &'a isize) -> Box<FnMut()->(isize) + 'a> {
// This is legal, because the region bound on `proc`
// states that it captures `x`.
- box move|| { *x }
+ Box::new(move|| { *x })
}
fn static_proc(x: &isize) -> Box<FnMut()->(isize) + 'static> {
// This is illegal, because the region bound on `proc` is 'static.
- box move|| { *x } //~ ERROR captured variable `x` does not outlive the enclosing closure
+ Box::new(move|| { *x }) //~ ERROR captured variable `x` does not outlive the enclosing closure
}
fn main() { }
fn main() {
// Unboxed closure case
{
- let mut x = 0_usize;
+ let mut x = 0;
let mut f = || &mut x; //~ ERROR cannot infer
let x = f();
let y = f();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct closure_box<'a> {
fn main() {
let mut cl_box = {
let mut i = 3;
- box_it(box || i += 1) //~ ERROR `i` does not live long enough
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ box_it(Box::new(|| i += 1)) //~ ERROR `i` does not live long enough
};
cl_box.cl.call_mut(());
}
}
fn main() {
- let ctxt = ctxt { v: 22_usize };
+ let ctxt = ctxt { v: 22 };
let hc = has_ctxt { c: &ctxt };
- assert_eq!(get_v(box hc as Box<get_ctxt>), 22_usize);
+ assert_eq!(get_v(box hc as Box<get_ctxt>), 22);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
#![allow(dead_code)]
#[static_assert]
fn f<T:'static>(_: T) {}
fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
f(x);
let x = &3; //~ ERROR borrowed value does not live long enough
f(x);
let pt = PointF {
//~^ ERROR structure constructor specifies a structure of type
//~| expected f32
- //~| found i32
- x: 1i32,
- y: 2i32,
+ //~| found integral variable
+ x: 1,
+ y: 2,
};
let pt2 = Point::<f32> {
//~^ ERROR structure constructor specifies a structure of type
//~| expected f32
- //~| found i32
- x: 3i32,
- y: 4i32,
+ //~| found integral variable
+ x: 3,
+ y: 4,
};
let pair = PairF {
//~^ ERROR structure constructor specifies a structure of type
//~| expected f32
- //~| found i32
- x: 5i32,
- y: 6i32,
+ //~| found integral variable
+ x: 5,
+ y: 6,
};
let pair2 = PairF::<i32> {
//~^ ERROR structure constructor specifies a structure of type
//~| expected f32
- //~| found i32
- x: 7i32,
- y: 8i32,
+ //~| found integral variable
+ x: 7,
+ y: 8,
};
let pt3 = PointF::<i32> {
//~^ ERROR wrong number of type arguments
//~| ERROR structure constructor specifies a structure of type
- x: 9i32,
- y: 10i32,
+ x: 9,
+ y: 10,
};
}
fn f() -> isize { return g(); }
-fn g() -> usize { return 0_usize; }
+fn g() -> usize { return 0; }
fn main() { let y = f(); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
struct Struct {
person: &'static str
}
}
fn main() {
- let s: Box<Trait<isize>> = box Struct { person: "Fred" };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<Trait<isize>> = Box::new(Struct { person: "Fred" });
//~^ ERROR the trait `Trait<isize>` is not implemented for the type `Struct`
s.f(1);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
struct Struct {
person: &'static str
}
fn main() {
let person = "Fred".to_string();
let person: &str = &person; //~ ERROR `person` does not live long enough
- let s: Box<Trait<&'static str>> = box Struct { person: person };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<Trait<&'static str>> = Box::new(Struct { person: person });
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test case where an associated type is referenced from within the
+// supertrait definition, and the impl makes the wrong
+// associations. Issue #20220.
+
+use std::vec::IntoIter;
+
+pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
+ type Key;
+}
+
+impl Foo for IntoIter<i32> { //~ ERROR type mismatch
+ type Key = u32;
+}
+
+fn main() {
+}
--- /dev/null
+// Copyright 2015 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.
+
+// A variant of traits-issue-23003 in which an infinite series of
+// types are required. This currently creates an overflow. This test
+// is included to ensure that some controlled failure, at least,
+// results -- but it might be that we should adjust the rules somewhat
+// to make this legal. -nmatsakis
+
+use std::marker::PhantomData;
+
+trait Async {
+ type Cancel;
+}
+
+struct Receipt<A:Async> {
+ marker: PhantomData<A>,
+}
+
+struct Complete<B> {
+ core: Option<B>,
+}
+
+impl<B> Async for Complete<B> {
+ type Cancel = Receipt<Complete<Option<B>>>;
+}
+
+fn foo(r: Receipt<Complete<()>>) { }
+//~^ ERROR overflow
+
+fn main() { }
}
fn a() {
- test(22_i32, std::default::Default::default()); //~ ERROR type annotations required
+ test(22, std::default::Default::default()); //~ ERROR type annotations required
}
fn main() {}
--- /dev/null
+// Copyright 2015 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.
+
+// Test a case of a trait which extends the same supertrait twice, but
+// with difference type parameters. Test then that when we don't give
+// enough information to pick between these, no selection is made. In
+// this particular case, the two choices are i64/u64 -- so when we use
+// an integer literal, we wind up falling this literal back to i32.
+// See also `run-pass/trait-repeated-supertrait.rs`.
+
+trait CompareTo<T> {
+ fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+ fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> for i64 {
+ fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
+}
+
+impl CompareToInts for i64 { }
+
+fn with_obj(c: &CompareToInts) -> bool {
+ c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_trait<C:CompareToInts>(c: &C) -> bool {
+ c.same_as(22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+ CompareToInts::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
+ CompareTo::same_as(c, 22) //~ ERROR `CompareTo<i32>` is not implemented
+}
+
+fn main() {
+ assert_eq!(22_i64.same_as(22), true); //~ ERROR `CompareTo<i32>` is not implemented
+}
struct Point(i32, i32);
fn main() {
- let origin = Point(0i32, 0i32);
+ let origin = Point(0, 0);
origin.0;
origin.1;
origin.2;
//~^ ERROR attempted out-of-bounds tuple index `2` on type `Point`
- let tuple = (0i32, 0i32);
+ let tuple = (0, 0);
tuple.0;
tuple.1;
tuple.2;
- //~^ ERROR attempted out-of-bounds tuple index `2` on type `(i32, i32)`
+ //~^ ERROR attempted out-of-bounds tuple index `2` on type `(_, _)`
}
// Checking that the compiler reports multiple type errors at once
-fn main() { let a: bool = 1i32; let b: i32 = true; }
+fn main() { let a: bool = 1; let b: i32 = true; }
//~^ ERROR mismatched types
//~| expected `bool`
-//~| found `i32`
+//~| found `_`
//~| expected bool
-//~| found i32
+//~| found integral variable
//~| ERROR mismatched types
//~| expected `i32`
//~| found `bool`
impl<T: Int> BrokenAdd for T {}
pub fn main() {
- let foo: u8 = 0u8;
+ let foo: u8 = 0;
let x: u8 = foo.broken_add("hello darkness my old friend".to_string());
println!("{}", x);
}
static TEST3: _ = "test";
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
-static TEST4: _ = 145u16;
+static TEST4: _ = 145;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
static TEST5: (_, _) = (1, 2);
static FN_TEST3: _ = "test";
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
- static FN_TEST4: _ = 145u16;
+ static FN_TEST4: _ = 145;
//~^ ERROR the type placeholder `_` is not allowed within types on item signatures
static FN_TEST5: (_, _) = (1, 2);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
// Tests that we can't move out of an unboxed closure environment
fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
fn to_fn_once<A,F:FnOnce<A>>(f: F) -> F { f }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
fn main() {
// By-ref cases
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn(|| drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_mut(|| drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_once(|| drop(x)); // OK -- FnOnce
}
// By-value cases
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn(move || drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_mut(move || drop(x)); //~ ERROR cannot move
}
{
- let x = box 0_usize;
+ let x = Box::new(0);
let f = to_fn_once(move || drop(x)); // this one is ok
}
}
fn set(x: &mut usize) { *x = 0; }
fn main() {
- let x = 0_usize;
+ let x = 0;
move || x = 1; //~ ERROR cannot assign
move || set(&mut x); //~ ERROR cannot borrow
move || x = 1; //~ ERROR cannot assign
// reference cannot escape the region of that variable.
fn main() {
let _f = {
- let x = 0_usize;
+ let x = 0;
|| x //~ ERROR `x` does not live long enough
};
}
// cause borrow conflicts.
fn main() {
- let mut x = 0_usize;
+ let mut x = 0;
let f = || x += 1;
let _y = x; //~ ERROR cannot use `x` because it was mutably borrowed
}
fn to_fn_mut<A,F:FnMut<A>>(f: F) -> F { f }
fn a() {
- let n = 0u8;
+ let n = 0;
let mut f = to_fn_mut(|| { //~ ERROR closure cannot assign
n += 1;
});
}
fn b() {
- let mut n = 0u8;
+ let mut n = 0;
let mut f = to_fn_mut(|| {
n += 1; // OK
});
}
fn c() {
- let n = 0u8;
+ let n = 0;
let mut f = to_fn_mut(move || {
// If we just did a straight-forward desugaring, this would
// compile, but we do something a bit more subtle, and hence
}
fn d() {
- let mut n = 0u8;
+ let mut n = 0;
let mut f = to_fn_mut(move || {
n += 1; // OK
});
}
fn e() {
- let n = 0u8;
+ let n = 0;
let mut f = to_fn(move || {
n += 1; //~ ERROR cannot assign
});
}
fn f() {
- let mut n = 0u8;
+ let mut n = 0;
let mut f = to_fn(move || {
n += 1; //~ ERROR cannot assign
});
}
fn main() {
- let mut counter = 0_u32;
+ let mut counter = 0;
call(|| {
counter += 1;
//~^ ERROR cannot assign to data in a captured outer variable in an `Fn` closure
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
#[derive(Debug)]
struct r {
b: bool,
}
fn main() {
- let i = box r { b: true };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let i = Box::new(r { b: true });
let _j = i.clone(); //~ ERROR not implement
println!("{:?}", i);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
use std::rc::Rc;
fn f<T:Send>(__isize: T) {
}
fn main() {
- let i = box Rc::new(100);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let i = Box::new(Rc::new(100));
f(i);
//~^ ERROR `core::marker::Send` is not implemented
}
#![feature(unsafe_destructor)]
-#![feature(box_syntax)]
-
use std::cell::Cell;
#[derive(Debug)]
fn main() {
let i1 = &Cell::new(0);
let i2 = &Cell::new(1);
- let r1 = vec!(box r { i: i1 });
- let r2 = vec!(box r { i: i2 });
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r1 = vec!(Box::new(r { i: i1 }));
+ let r2 = vec!(Box::new(r { i: i2 }));
f(clone(&r1), clone(&r2));
//~^ ERROR the trait `core::clone::Clone` is not implemented for the type
//~^^ ERROR the trait `core::clone::Clone` is not implemented for the type
enum foo { a(Box<foo>, isize), b(usize), }
-fn main() { match foo::b(1_usize) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } }
+fn main() { match foo::b(1) { foo::b(_) | foo::a(box _, 1) => { } foo::a(_, 1) => { } } }
fn f(p: *const u8) {
- *p = 0u8; //~ ERROR dereference of unsafe pointer requires unsafe function or block
+ *p = 0; //~ ERROR dereference of unsafe pointer requires unsafe function or block
return;
}
+++ /dev/null
-// 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.
-
-// Test that bounds are sized-compatible.
-
-trait T : Sized {}
-fn f<Y: ?Sized + T>() {
-//~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
-}
-
-pub fn main() {
-}
}
fn main() {
- let n = box Number { n: 42 };
- let mut l = box List { list: Vec::new() };
+ let n: Box<_> = box Number { n: 42 };
+ let mut l: Box<_> = box List { list: Vec::new() };
l.push(n);
let x = n.to_string();
//~^ ERROR: use of moved value: `n`
fn main() {
{
- let a = AffineU32(1_u32);
+ let a = AffineU32(1);
let x = foo(&a);
drop(a); //~ ERROR cannot move out of `a`
drop(x);
}
{
- let a = AffineU32(1_u32);
+ let a = AffineU32(1);
let x = bar(&a);
drop(a); //~ ERROR cannot move out of `a`
drop(x);
}
{
- let a = AffineU32(1_u32);
+ let a = AffineU32(1);
let x = baz(&a);
drop(a); //~ ERROR cannot move out of `a`
drop(x);
}
fn call_it<B:TraitB>(b: B) -> isize {
- let y = 4_usize;
+ let y = 4;
b.gimme_an_a(y) //~ ERROR the trait `TraitA` is not implemented
}
}
fn main() {
- assoc_struct(Struct { b: -1i32, b1: 0i64 });
- assoc_local(1i32);
- assoc_arg::<i32>(2i64);
- assoc_return_value(3i32);
- assoc_tuple((4i32, 5i64));
- assoc_enum(Enum::Variant1(6i32, 7i64));
- assoc_enum(Enum::Variant2(8i64, 9i32));
+ assoc_struct(Struct { b: -1, b1: 0 });
+ assoc_local(1);
+ assoc_arg::<i32>(2);
+ assoc_return_value(3);
+ assoc_tuple((4, 5));
+ assoc_enum(Enum::Variant1(6, 7));
+ assoc_enum(Enum::Variant2(8, 9));
}
fn zzz() { () }
let stack_val_interior_ref_2: &f64 = &stack_val.y;
let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
- let unique_val = box SomeStruct { x: 13, y: 26.5 };
+ let unique_val: Box<_> = box SomeStruct { x: 13, y: 26.5 };
let unique_val_ref: &SomeStruct = &*unique_val;
let unique_val_interior_ref_1: &int = &unique_val.x;
let unique_val_interior_ref_2: &f64 = &unique_val.y;
fn main() {
- let unique = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
+ let unique: Box<_> = box StructWithSomePadding { x: 99, y: 999, z: 9999, w: 99999 };
- let unique_dtor = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
+ let unique_dtor: Box<_> = box StructWithDestructor { x: 77, y: 777, z: 7777, w: 77777 };
zzz(); // #break
}
fn main() {
some_generic_fun(0.5f64, 10);
- some_generic_fun(&29, box 110);
+ some_generic_fun(&29, Box::new(110));
}
fn zzz() { () }
--- /dev/null
+// Copyright 2013-2015 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.
+
+// ignore-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
+
+// This test makes sure that the compiler doesn't crash when trying to assign
+// debug locations to const-expressions.
+
+use std::sync::MUTEX_INIT;
+use std::cell::UnsafeCell;
+
+const CONSTANT: u64 = 3 + 4;
+
+struct Struct {
+ a: isize,
+ b: usize,
+}
+const STRUCT: Struct = Struct { a: 1, b: 2 };
+
+struct TupleStruct(u32);
+const TUPLE_STRUCT: TupleStruct = TupleStruct(4);
+
+enum Enum {
+ Variant1(char),
+ Variant2 { a: u8 },
+ Variant3
+}
+
+const VARIANT1: Enum = Enum::Variant1('v');
+const VARIANT2: Enum = Enum::Variant2 { a: 2 };
+const VARIANT3: Enum = Enum::Variant3;
+
+const STRING: &'static str = "String";
+
+const VEC: [u32; 8] = [0; 8];
+
+const NESTED: (Struct, TupleStruct) = (STRUCT, TUPLE_STRUCT);
+
+const UNSAFE_CELL: UnsafeCell<bool> = UnsafeCell { value: false };
+
+fn main() {
+ let mut _constant = CONSTANT;
+ let mut _struct = STRUCT;
+ let mut _tuple_struct = TUPLE_STRUCT;
+ let mut _variant1 = VARIANT1;
+ let mut _variant2 = VARIANT2;
+ let mut _variant3 = VARIANT3;
+ let mut _string = STRING;
+ let mut _vec = VEC;
+ let mut _nested = NESTED;
+ let mut _extern = MUTEX_INIT;
+ let mut _unsafe_cell = UNSAFE_CELL;
+}
--- /dev/null
+// Copyright 2013-2015 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.
+
+#![omit_gdb_pretty_printer_section]
+
+// ignore-android: FIXME(#10381)
+// min-lldb-version: 310
+
+// aux-build:cross_crate_spans.rs
+extern crate cross_crate_spans;
+
+// compile-flags:-g
+
+
+// === GDB TESTS ===================================================================================
+
+// gdb-command:break cross_crate_spans.rs:21
+// gdb-command:run
+
+// gdb-command:print result
+// gdb-check:$1 = {17, 17}
+// gdb-command:print a_variable
+// gdb-check:$2 = 123456789
+// gdb-command:print another_variable
+// gdb-check:$3 = 123456789.5
+// gdb-command:continue
+
+// gdb-command:print result
+// gdb-check:$4 = {1212, 1212}
+// gdb-command:print a_variable
+// gdb-check:$5 = 123456789
+// gdb-command:print another_variable
+// gdb-check:$6 = 123456789.5
+// gdb-command:continue
+
+
+
+// === LLDB TESTS ==================================================================================
+
+// lldb-command:b cross_crate_spans.rs:21
+// lldb-command:run
+
+// lldb-command:print result
+// lldb-check:[...]$0 = (17, 17)
+// lldb-command:print a_variable
+// lldb-check:[...]$1 = 123456789
+// lldb-command:print another_variable
+// lldb-check:[...]$2 = 123456789.5
+// lldb-command:continue
+
+// lldb-command:print result
+// lldb-check:[...]$3 = (1212, 1212)
+// lldb-command:print a_variable
+// lldb-check:[...]$4 = 123456789
+// lldb-command:print another_variable
+// lldb-check:[...]$5 = 123456789.5
+// lldb-command:continue
+
+
+// This test makes sure that we can break in functions inlined from other crates.
+
+fn main() {
+
+ let _ = cross_crate_spans::generic_function(17u32);
+ let _ = cross_crate_spans::generic_function(1212i16);
+
+}
--- /dev/null
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// min-lldb-version: 310
+
+// compile-flags:-g
+
+// === GDB TESTS ===================================================================================
+// gdb-command:run
+
+// gdb-command:print s
+// gdb-check:$1 = [...]"abcd"
+// gdb-command:print len
+// gdb-check:$2 = 20
+// gdb-command:print local0
+// gdb-check:$3 = 19
+// gdb-command:print local1
+// gdb-check:$4 = true
+// gdb-command:print local2
+// gdb-check:$5 = 20.5
+
+// gdb-command:continue
+
+// === LLDB TESTS ==================================================================================
+// lldb-command:run
+
+// lldb-command:print len
+// lldb-check:[...]$0 = 20
+// lldb-command:print local0
+// lldb-check:[...]$1 = 19
+// lldb-command:print local1
+// lldb-check:[...]$2 = true
+// lldb-command:print local2
+// lldb-check:[...]$3 = 20.5
+
+// lldb-command:continue
+
+#![allow(unused_variables)]
+#![allow(dead_code)]
+#![omit_gdb_pretty_printer_section]
+
+
+#[no_mangle]
+pub unsafe extern "C" fn fn_with_c_abi(s: *const u8, len: i32) -> i32 {
+ let local0 = len - 1;
+ let local1 = len > 2;
+ let local2 = (len as f64) + 0.5;
+
+ zzz(); // #break
+
+ return 0;
+}
+
+fn main() {
+ unsafe {
+ fn_with_c_abi(b"abcd\0".as_ptr(), 20);
+ }
+}
+
+#[inline(never)]
+fn zzz() {()}
let _ = stack.self_by_ref(-1, 2_u16);
let _ = stack.self_by_val(-3, -4_i16);
- let owned = box Struct { x: 1234.5f64 };
+ let owned: Box<_> = box Struct { x: 1234.5f64 };
let _ = owned.self_by_ref(-5, -6_i32);
let _ = owned.self_by_val(-7, -8_i64);
let _ = owned.self_owned(-9, -10.5_f32);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Enum::Variant1{ x: 1799, y: 1799 };
+ let owned: Box<_> = box Enum::Variant1{ x: 1799, y: 1799 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 1234.5f64 };
+ let owned: Box<_> = box Struct { x: 1234.5f64 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box TupleStruct(200, -200.5);
+ let owned: Box<_> = box TupleStruct(200, -200.5);
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
next: Val {
val: box UniqueNode {
next: Empty,
- value: 1_u16,
+ value: 1,
}
},
- value: 0_u16,
+ value: 0,
};
let unique_unique: Box<UniqueNode<u32>> = box UniqueNode {
let _ = stack.self_by_ref(-1, -2);
let _ = stack.self_by_val(-3, -4);
- let owned = box Struct { x: 200 };
+ let owned: Box<_> = box Struct { x: 200 };
let _ = owned.self_by_ref(-5, -6);
let _ = owned.self_by_val(-7, -8);
let _ = owned.self_owned(-9, -10);
let _ = stack.self_by_ref(-1, 2_u16);
let _ = stack.self_by_val(-3, -4_i16);
- let owned = box Struct { x: 879 };
+ let owned: Box<_> = box Struct { x: 879 };
let _ = owned.self_by_ref(-5, -6_i32);
let _ = owned.self_by_val(-7, -8_i64);
let _ = owned.self_owned(-9, -10.5_f32);
fn main() {
- let vi8x16 = i8x16(0i8, 1i8, 2i8, 3i8, 4i8, 5i8, 6i8, 7i8,
- 8i8, 9i8, 10i8, 11i8, 12i8, 13i8, 14i8, 15i8);
-
- let vi16x8 = i16x8(16i16, 17i16, 18i16, 19i16, 20i16, 21i16, 22i16, 23i16);
- let vi32x4 = i32x4(24i32, 25i32, 26i32, 27i32);
- let vi64x2 = i64x2(28i64, 29i64);
-
- let vu8x16 = u8x16(30u8, 31u8, 32u8, 33u8, 34u8, 35u8, 36u8, 37u8,
- 38u8, 39u8, 40u8, 41u8, 42u8, 43u8, 44u8, 45u8);
- let vu16x8 = u16x8(46u16, 47u16, 48u16, 49u16, 50u16, 51u16, 52u16, 53u16);
- let vu32x4 = u32x4(54u32, 55u32, 56u32, 57u32);
- let vu64x2 = u64x2(58u64, 59u64);
+ let vi8x16 = i8x16(0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15);
+
+ let vi16x8 = i16x8(16, 17, 18, 19, 20, 21, 22, 23);
+ let vi32x4 = i32x4(24, 25, 26, 27);
+ let vi64x2 = i64x2(28, 29);
+
+ let vu8x16 = u8x16(30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45);
+ let vu16x8 = u16x8(46, 47, 48, 49, 50, 51, 52, 53);
+ let vu32x4 = u32x4(54, 55, 56, 57);
+ let vu64x2 = u64x2(58, 59);
let vf32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32);
let vf64x2 = f64x2(64.5f64, 65.5f64);
// 0b01111100011111000111110001111100 = 2088533116
// 0b0111110001111100 = 31868
// 0b01111100 = 124
- let the_a = box ABC::TheA { x: 0, y: 8970181431921507452 };
+ let the_a: Box<_> = box ABC::TheA { x: 0, y: 8970181431921507452 };
// 0b0001000100010001000100010001000100010001000100010001000100010001 = 1229782938247303441
// 0b00010001000100010001000100010001 = 286331153
// 0b0001000100010001 = 4369
// 0b00010001 = 17
- let the_b = box ABC::TheB (0, 286331153, 286331153);
+ let the_b: Box<_> = box ABC::TheB (0, 286331153, 286331153);
- let univariant = box Univariant::TheOnlyCase(123234);
+ let univariant: Box<_> = box Univariant::TheOnlyCase(123234);
zzz(); // #break
}
};
let struct_ref = &a_struct;
- let owned = box 6;
+ let owned: Box<_> = box 6;
let mut closure = || {
let closure_local = 8;
c: 4
};
- let owned = box 5;
+ let owned: Box<_> = box 5;
let closure = move || {
zzz(); // #break
};
let struct_ref = &a_struct;
- let owned = box 6;
+ let owned: Box<_> = box 6;
{
let mut first_closure = || {
// except according to those terms.
#[path = "circular_modules_hello.rs"]
-mod circular_modules_hello; //~ERROR: circular modules
+mod circular_modules_hello; //~ ERROR: circular modules
pub fn hi_str() -> String {
- "Hi!".to_string()
+ "Hi!".to_string()
}
fn main() {
}
fn main() {
- let nyan = cat(0us);
+ let nyan = cat(0);
}
// except according to those terms.
fn main() {
- let __isize = 0xff_ffff_ffff_ffff_ffff__isize;
+ let __isize = 0xff_ffff_ffff_ffff_ffff;
//~^ ERROR int literal is too large
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// Copyright 2013 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.
+// ignore-windows
+// ignore-freebsd
#[path = "../compile-fail"]
mod foo; //~ ERROR: a directory
1e+; //~ ERROR: expected at least one digit in exponent
0x539.0; //~ ERROR: hexadecimal float literal is not supported
99999999999999999999999999999999; //~ ERROR: int literal is too large
- 99999999999999999999999999999999u32; //~ ERROR: int literal is too large
+ 99999999999999999999999999999999; //~ ERROR: int literal is too large
0x; //~ ERROR: no valid digits
0xu32; //~ ERROR: no valid digits
0ou32; //~ ERROR: no valid digits
}
fn make_gc() -> @get_ctxt {
- let ctxt = ctxt { v: 22us };
+ let ctxt = ctxt { v: 22 };
let hc = has_ctxt { c: &ctxt };
return @hc as @get_ctxt;
//~^ ERROR source contains reference
fn a() -> uint {
- 1usize
+ 1
}
const FOO: usize = ((5 as usize) - (4 as usize) as usize);
let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]);
- let _: [(); (1usize as usize)] = ([(() as ())] as [(); 1]);
+ let _: [(); (1 as usize)] = ([(() as ())] as [(); 1]);
let _ =
(((&((([(1 as i32), (2 as i32), (3 as i32)] as [i32; 3])) as [i32; 3])
as &[i32; 3]) as *const _ as *const [i32; 3]) as
- *const [i32; (3usize as usize)] as *const [i32; 3]);
+ *const [i32; (3 as usize)] as *const [i32; 3]);
const FOO: usize = 5 - 4;
let _: [(); FOO] = [()];
- let _ : [(); 1usize] = [()];
+ let _ : [(); 1] = [()];
- let _ = &([1,2,3]) as *const _ as *const [i32; 3usize];
+ let _ = &([1,2,3]) as *const _ as *const [i32; 3];
format!("test");
}
}
extern fn cb(data: libc::uintptr_t) -> libc::uintptr_t {
- if data == 1_usize {
+ if data == 1 {
data
} else {
- count(data - 1_usize) + count(data - 1_usize)
+ count(data - 1) + count(data - 1)
}
}
}
fn main() {
- for _ in 0..10_usize {
+ for _ in 0..10 {
task::spawn(move|| {
- let result = count(5_usize);
+ let result = count(5);
println!("result = %?", result);
panic!();
});
// error-pattern:Number is odd
fn even(x: uint) -> bool {
- if x < 2_usize {
+ if x < 2 {
return false;
- } else if x == 2_usize { return true; } else { return even(x - 2_usize); }
+ } else if x == 2 { return true; } else { return even(x - 2); }
}
fn foo(x: uint) {
}
}
-fn main() { foo(3_usize); }
+fn main() { foo(3); }
--- /dev/null
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+ let _x = value() + value() + value();
+}
--- /dev/null
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 200 }
+
+fn main() {
+ let x = value() * 4;
+}
--- /dev/null
+// Copyright 2015 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.
+
+// error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
+
+// (Work around constant-evaluation)
+fn value() -> u8 { 42 }
+
+fn main() {
+ let _x = value() - (value() + 1);
+}
// error-pattern:panicked at 'Box<Any>'
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- panic!(box 612_i64);
+ panic!(Box::new(612_i64));
}
// error-pattern: panic
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn main() { box panic!(); }
+fn main() { Box::new(panic!()); }
// error-pattern:fail
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn failfn() {
panic!();
}
fn main() {
- box 0;
+ Box::new(0);
failfn();
}
--- /dev/null
+-include ../tools.mk
+
+all:
+ $(RUSTC) debug.rs -C debug-assertions=no
+ $(call RUN,debug) good
+ $(RUSTC) debug.rs -C opt-level=0
+ $(call RUN,debug) bad
+ $(RUSTC) debug.rs -C opt-level=1
+ $(call RUN,debug) good
+ $(RUSTC) debug.rs -C opt-level=2
+ $(call RUN,debug) good
+ $(RUSTC) debug.rs -C opt-level=3
+ $(call RUN,debug) good
+ $(RUSTC) debug.rs -O
+ $(call RUN,debug) good
+ $(RUSTC) debug.rs
+ $(call RUN,debug) bad
+ $(RUSTC) debug.rs -C debug-assertions=yes -O
+ $(call RUN,debug) bad
+ $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1
+ $(call RUN,debug) bad
--- /dev/null
+// Copyright 2015 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.
+
+#![deny(warnings)]
+
+use std::env;
+use std::thread;
+
+fn main() {
+ let should_fail = env::args().nth(1) == Some("bad".to_string());
+
+ assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail);
+ assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail);
+ assert_eq!(thread::spawn(overflow).join().is_err(), should_fail);
+}
+
+fn debug_assert_eq() {
+ let mut hit1 = false;
+ let mut hit2 = false;
+ debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 });
+ assert!(!hit1);
+ assert!(!hit2);
+}
+
+fn debug_assert() {
+ let mut hit = false;
+ debug_assert!({ hit = true; false });
+ assert!(!hit);
+}
+
+fn overflow() {
+ fn add(a: u8, b: u8) -> u8 { a + b }
+
+ add(200u8, 200u8);
+}
digraph block {
N0[label="entry"];
N1[label="exit"];
- N2[label="expr 2usize"];
- N3[label="expr 0usize"];
- N4[label="expr 20usize"];
- N5[label="expr [2usize, 0usize, 20usize]"];
+ N2[label="expr 2"];
+ N3[label="expr 0"];
+ N4[label="expr 20"];
+ N5[label="expr [2, 0, 20]"];
N6[label="local v"];
- N7[label="stmt let v = [2usize, 0usize, 20usize];"];
+ N7[label="stmt let v = [2, 0, 20];"];
N8[label="expr v"];
- N9[label="expr 20usize"];
- N10[label="expr v[20usize]"];
- N11[label="stmt v[20usize];"];
- N12[label="block { let v = [2usize, 0usize, 20usize]; v[20usize]; }"];
+ N9[label="expr 20"];
+ N10[label="expr v[20]"];
+ N11[label="stmt v[20];"];
+ N12[label="block { let v = [2, 0, 20]; v[20]; }"];
N0 -> N2;
N2 -> N3;
N3 -> N4;
// except according to those terms.
pub fn expr_index_20() {
- let v = [2_usize, 0_usize, 20_usize];
- v[20_usize];
+ let v = [2, 0, 20];
+ v[20];
}
use rustc_driver::driver::{compile_input, CompileController};
use syntax::diagnostics::registry::Registry;
+use std::path::PathBuf;
+
fn main() {
let src = r#"
fn main() {}
panic!("expected rustc path");
}
- let tmpdir = Path::new(&args[1]);
+ let tmpdir = PathBuf::new(&args[1]);
- let mut sysroot = Path::new(&args[3]);
+ let mut sysroot = PathBuf::new(&args[3]);
sysroot.pop();
sysroot.pop();
compile(src.to_string(), tmpdir.join("out"), sysroot.clone());
}
-fn basic_sess(sysroot: Path) -> Session {
+fn basic_sess(sysroot: PathBuf) -> Session {
let mut opts = basic_options();
opts.output_types = vec![OutputTypeExe];
opts.maybe_sysroot = Some(sysroot);
sess
}
-fn compile(code: String, output: Path, sysroot: Path) {
+fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
let sess = basic_sess(sysroot);
let cfg = build_configuration(&sess);
let control = CompileController::basic();
// buglink test - see issue #1337.
fn test_alias<I: Iterator>(i: Option<<I as Iterator>::Item>) {
- let s = sub_struct{ field2: 45u32, };
+ let s = sub_struct{ field2: 45, };
// import tests
fn foo(x: &Float) {}
let _: Option<u8> = from_i32(45);
- let x = 42_usize;
+ let x = 42;
myflate::deflate_bytes(&[]);
- let x = (3, 4_usize);
+ let x = (3, 4);
let y = x.1;
}
let x = 32.0f32;
let _ = (x + ((x * x) + 1.0).sqrt()).ln();
- let s: Box<SomeTrait> = box some_fields {field1: 43};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let s: Box<SomeTrait> = Box::new(some_fields {field1: 43});
let s2: Box<some_fields> = box some_fields {field1: 43};
- let s3 = box nofields;
+ let s3: Box<_> = box nofields;
s.Method(43);
s3.Method(43);
}
fn main() { // foo
- let s = box some_fields {field1: 43};
+ let s: Box<_> = box some_fields {field1: 43};
hello((43, "a".to_string()), *s);
sub::sub2::hello();
sub2::sub3::hello();
pub fn dummy() {
// force the vtable to be created
- let _x = &1_usize as &Foo;
+ let _x = &1 as &Foo;
}
use rustc_driver::{driver, CompilerCalls, Compilation};
use syntax::diagnostics;
+use std::path::PathBuf;
struct TestCalls {
count: u32
_: &getopts::Matches,
_: &Session,
_: &Input,
- _: &Option<Path>,
- _: &Option<Path>)
+ _: &Option<PathBuf>,
+ _: &Option<PathBuf>)
-> Compilation {
self.count *= 3;
Compilation::Stop
}
- fn some_input(&mut self, input: Input, input_path: Option<Path>) -> (Input, Option<Path>) {
+ fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
+ -> (Input, Option<PathBuf>) {
self.count *= 5;
(input, input_path)
}
fn no_input(&mut self,
_: &getopts::Matches,
_: &config::Options,
- _: &Option<Path>,
- _: &Option<Path>,
+ _: &Option<PathBuf>,
+ _: &Option<PathBuf>,
_: &diagnostics::registry::Registry)
- -> Option<(Input, Option<Path>)> {
+ -> Option<(Input, Option<PathBuf>)> {
panic!("This shouldn't happen");
}
--- /dev/null
+// Copyright 2015 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.
+
+// aux-build:lint_for_crate.rs
+// ignore-stage1
+// compile-flags: -D crate-not-okay
+
+#![feature(plugin, custom_attribute)]
+#![plugin(lint_for_crate)]
+#![crate_okay]
+
+pub fn main() { }
--- /dev/null
+// Copyright 2015 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.
+
+// aux-build:procedural_mbe_matching.rs
+// ignore-stage1
+
+#![feature(plugin)]
+#![plugin(procedural_mbe_matching)]
+
+#[no_link]
+extern crate procedural_mbe_matching;
+
+pub fn main() {
+ let abc = 123u32;
+ assert_eq!(matches!(Some(123), None | Some(0)), false);
+ assert_eq!(matches!(Some(123), None | Some(123)), true);
+ assert_eq!(matches!(true, true), true);
+}
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
let arm = quote_arm!(cx, (ref x, ref y) => (x, y));
check_pp(ext_cx, arm, pprust::print_stmt, "(ref x, ref y) = (x, y)".to_string());
+
+ let attr = quote_attr!(cx, #![cfg(foo = "bar")]);
+ check_pp(ext_cx, attr, pprust::print_attribute, "#![cfg(foo = "bar")]".to_string());
}
fn check_pp<T>(cx: fake_ext_ctxt,
let _k: P<syntax::ast::Method> = quote_method!(cx, #[doc = "hello"] fn foo(&self) {});
let _l: P<syntax::ast::Ty> = quote_ty!(cx, &int);
+
+ let _m: Vec<syntax::ast::TokenTree> = quote_matcher!(cx, $($foo:tt,)* bar);
+ let _n: syntax::ast::Attribute = quote_attr!(cx, #![cfg(foo, bar = "baz")]);
+
+ let _o: Option<P<syntax::ast::Item>> = quote_item!(cx, fn foo<T: ?Sized>() {});
}
fn main() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
static mut DROP_RAN: bool = false;
struct Foo;
pub fn main() {
{
- let _x: Box<Fat<Trait>> = box Fat { f: Foo };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _x: Box<Fat<Trait>> = Box::<Fat<Foo>>::new(Fat { f: Foo });
}
unsafe {
assert!(DROP_RAN);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![feature(box_syntax)]
-
static mut DROP_RAN: int = 0;
struct Foo;
pub fn main() {
{
- let _x: Box<Fat<[Foo]>> = box Fat { f: [Foo, Foo, Foo] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let _x: Box<Fat<[Foo]>> = Box::<Fat<[Foo; 3]>>::new(Fat { f: [Foo, Foo, Foo] });
}
unsafe {
assert!(DROP_RAN == 3);
struct RawT {struct_: sty, cname: Option<String>, hash: uint}
fn mk_raw_ty(st: sty, cname: Option<String>) -> RawT {
- return RawT {struct_: st, cname: cname, hash: 0_usize};
+ return RawT {struct_: st, cname: cname, hash: 0};
}
pub fn main() { mk_raw_ty(sty::ty_nil, None::<String>); }
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(PartialEq, Debug)]
struct Point { x : int }
pub fn main() {
assert_eq!(14,14);
assert_eq!("abc".to_string(),"abc".to_string());
- assert_eq!(box Point{x:34},box Point{x:34});
+ assert_eq!(Box::new(Point{x:34}),Box::new(Point{x:34}));
assert_eq!(&Point{x:34},&Point{x:34});
}
}
#[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
impl Foo for int {
type A = uint;
fn main() {
let x = get(22);
- assert_eq!(22_usize, x);
+ assert_eq!(22, x);
}
fn main() {
let v = vec!(1, 2, 3, 4, 5, 6);
- let r = pairwise_sub(box v.into_iter());
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let r = pairwise_sub(Box::new(v.into_iter()));
assert_eq!(r, 9);
}
fn boo(&self) -> <Self as Foo>::A;
}
-struct Bar;
+pub struct Bar;
impl Foo for char {
type A = Bar;
}
#[derive(PartialEq)]
-struct Bar;
+pub struct Bar;
impl Foo for int {
type A = uint;
pub fn main() {
let a = 42;
- assert!(foo2(a) == 42_usize);
+ assert!(foo2(a) == 42);
let a = Bar;
assert!(foo2(a) == 43);
pub fn main() {
let node: Node<i32> = Node { key: 1, value: Some(22) };
- assert_eq!(foo(&node), Some(22_u32));
+ assert_eq!(foo(&node), Some(22));
let node: Node<u32> = Node { key: 1, value: Some(22) };
- assert_eq!(foo(&node), Some(22_i32));
+ assert_eq!(foo(&node), Some(22));
}
pub fn main() {
let node: Node<i32> = Node(1, Some(22));
- assert_eq!(foo(&node), Some(22_u32));
+ assert_eq!(foo(&node), Some(22));
let node: Node<u32> = Node(1, Some(22));
- assert_eq!(foo(&node), Some(22_i32));
+ assert_eq!(foo(&node), Some(22));
}
}
pub fn main() {
- let z: uint = bar(2, 4_usize);
+ let z: uint = bar(2, 4);
}
enum CLike { A, B, C }
pub fn main() {
- let a = &Plus(@Minus(@Val(3_usize), @Val(10_usize)), @Plus(@Val(22_usize), @Val(5_usize)));
+ let a = &Plus(@Minus(@Val(3), @Val(10)), @Plus(@Val(22), @Val(5)));
test_rbml(a);
- let a = &Spanned {lo: 0_usize, hi: 5_usize, node: 22_usize};
+ let a = &Spanned {lo: 0, hi: 5, node: 22};
test_rbml(a);
- let a = &Point {x: 3_usize, y: 5_usize};
+ let a = &Point {x: 3, y: 5};
test_rbml(a);
- let a = &Top(22_usize);
+ let a = &Top(22);
test_rbml(a);
- let a = &Bottom(222_usize);
+ let a = &Bottom(222);
test_rbml(a);
let a = &A;
}
impl double for uint {
- fn double(self: Box<uint>) -> uint { *self * 2_usize }
+ fn double(self: Box<uint>) -> uint { *self * 2 }
}
pub fn main() {
- let x = box() (box 3_usize as Box<double>);
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box() (box 3 as Box<double>);
+ assert_eq!(x.double(), 6);
}
}
impl double for Box<uint> {
- fn double(self) -> uint { *self * 2_usize }
+ fn double(self) -> uint { *self * 2 }
}
pub fn main() {
- let x = box 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box 3;
+ assert_eq!(x.double(), 6);
}
}
impl double for Box<uint> {
- fn double(self: Box<Box<uint>>) -> uint { **self * 2_usize }
+ fn double(self: Box<Box<uint>>) -> uint { **self * 2 }
}
pub fn main() {
- let x = box box box box box 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<Box<Box<Box<Box<_>>>>> = box box box box box 3;
+ assert_eq!(x.double(), 6);
}
}
impl double for uint {
- fn double(self: Box<uint>) -> uint { *self * 2_usize }
+ fn double(self: Box<uint>) -> uint { *self * 2 }
}
pub fn main() {
- let x = box box 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<Box<_>> = box box 3;
+ assert_eq!(x.double(), 6);
}
}
impl double for uint {
- fn double(self: Box<uint>) -> uint { *self * 2_usize }
+ fn double(self: Box<uint>) -> uint { *self * 2 }
}
pub fn main() {
- let x = box 3_usize;
- assert_eq!(x.double(), 6_usize);
+ let x: Box<_> = box 3;
+ assert_eq!(x.double(), 6);
}
}
pub fn main() {
- let x = box 3_usize;
+ let x: Box<_> = box 3;
assert_eq!(x.foo(), "box 3".to_string());
}
}
#[inline(never)]
-fn inner(counter: &mut u32, main_pos: Pos, outer_pos: Pos) {
+fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
check!(counter; main_pos, outer_pos);
check!(counter; main_pos, outer_pos);
let inner_pos = pos!(); aux::callback(|aux_pos| {
}
#[inline(always)]
-fn inner_inlined(counter: &mut u32, main_pos: Pos, outer_pos: Pos) {
+fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
check!(counter; main_pos, outer_pos);
check!(counter; main_pos, outer_pos);
#[inline(always)]
- fn inner_further_inlined(counter: &mut u32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
+ fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
check!(counter; main_pos, outer_pos, inner_pos);
}
inner_further_inlined(counter, main_pos, outer_pos, pos!());
}
#[inline(never)]
-fn outer(mut counter: u32, main_pos: Pos) {
+fn outer(mut counter: i32, main_pos: Pos) {
inner(&mut counter, main_pos, pos!());
inner_inlined(&mut counter, main_pos, pos!());
}
"bad output: {}", s);
// Make sure the stack trace is *not* printed
- let p = template.clone().arg("fail").spawn().unwrap();
+ // (Remove RUST_BACKTRACE from our own environment, in case developer
+ // is running `make check` with it on.)
+ let p = template.clone().arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap();
let out = p.wait_with_output().unwrap();
assert!(!out.status.success());
let s = str::from_utf8(&out.error).unwrap();
// except according to those terms.
pub fn main() {
- assert_eq!(0xffffffffu32, (-1 as u32));
- assert_eq!(4294967295u32, (-1 as u32));
- assert_eq!(0xffffffffffffffffu64, (-1 as u64));
- assert_eq!(18446744073709551615u64, (-1 as u64));
+ assert_eq!(0xffffffff, (-1 as u32));
+ assert_eq!(4294967295, (-1 as u32));
+ assert_eq!(0xffffffffffffffff, (-1 as u64));
+ assert_eq!(18446744073709551615, (-1 as u64));
- assert_eq!(-2147483648i32 - 1i32, 2147483647i32);
+ assert_eq!(-2147483648 - 1, 2147483647);
}
use std::collections::BitVec;
fn bitv_test() {
- let mut v1 = box BitVec::from_elem(31, false);
- let v2 = box BitVec::from_elem(31, true);
+ let mut v1: Box<_> = box BitVec::from_elem(31, false);
+ let v2: Box<_> = box BitVec::from_elem(31, true);
v1.union(&*v2);
}
}
pub fn main() {
- let x = asBlock(|| 22_usize);
- assert_eq!(x, 22_usize);
+ let x = asBlock(|| 22);
+ assert_eq!(x, 22);
}
fn iter_vec<T, F>(v: Vec<T> , mut f: F) where F: FnMut(&T) { for x in &v { f(x); } }
pub fn main() {
- let v = vec![1i32, 2, 3, 4, 5, 6, 7];
- let mut odds = 0i32;
+ let v = vec![1, 2, 3, 4, 5, 6, 7];
+ let mut odds = 0;
iter_vec(v, |i| {
if *i % 2 == 1 {
odds += 1;
fn iter_vec<T, F>(v: Vec<T>, mut f: F) where F: FnMut(&T) { for x in &v { f(x); } }
pub fn main() {
- let v = vec![1i32, 2, 3, 4, 5];
+ let v = vec![1, 2, 3, 4, 5];
let mut sum = 0;
iter_vec(v.clone(), |i| {
iter_vec(v.clone(), |j| {
// the closures are in scope. Issue #6801.
fn a() -> i32 {
- let mut x = 3i32;
+ let mut x = 3;
x += 1;
let c1 = || x * 4;
let c2 = || x * 5;
}
fn b() -> i32 {
- let mut x = 3i32;
+ let mut x = 3;
x += 1;
let c1 = || get(&x);
let c2 = || get(&x);
}
fn c() -> i32 {
- let mut x = 3i32;
+ let mut x = 3;
x += 1;
let c1 = || x * 5;
let c2 = || get(&x);
#![feature(unboxed_closures)]
pub fn main() {
- let bar = box 3;
+ let bar: Box<_> = box 3;
let h = || -> int *bar;
assert_eq!(h(), 3);
}
fn iter_ints<F>(x: &Ints, mut f: F) -> bool where F: FnMut(&int) -> bool {
let l = x.values.len();
- (0_usize..l).all(|i| f(&x.values[i]))
+ (0..l).all(|i| f(&x.values[i]))
}
pub fn main() {
- let mut ints = box Ints {sum: box 0, values: Vec::new()};
+ let mut ints: Box<_> = box Ints {sum: box 0, values: Vec::new()};
add_int(&mut *ints, 22);
add_int(&mut *ints, 44);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
extern crate libc;
}
fn main() {
- let mut sum = 0_usize;
- let elems = [ 1_usize, 2, 3, 4, 5 ];
+ let mut sum = 0;
+ let elems = [ 1, 2, 3, 4, 5 ];
each(&elems, |val: &uint| sum += *val);
assert_eq!(sum, 15);
}
assert_eq!(u, 'Q' as u32);
assert_eq!(i as u8, 'Q' as u8);
assert_eq!(i as u8 as i8, 'Q' as u8 as i8);
- assert_eq!(0x51u8 as char, 'Q');
+ assert_eq!(0x51 as char, 'Q');
assert_eq!(0 as u32, false as u32);
}
use cci_borrow_lib::foo;
pub fn main() {
- let p = box 22_usize;
+ let p: Box<_> = box 22;
let r = foo(&*p);
println!("r={}", r);
- assert_eq!(r, 22_usize);
+ assert_eq!(r, 22);
}
//let bt0 = sys::frame_address();
//println!("%?", bt0);
- 3_usize.to(10_usize, |i| {
+ 3.to(10, |i| {
println!("{}", i);
//let bt1 = sys::frame_address();
extern crate cci_iter_lib;
pub fn main() {
- //let bt0 = sys::rusti::frame_address(1u32);
+ //let bt0 = sys::rusti::frame_address(1);
//println!("%?", bt0);
cci_iter_lib::iter(&[1, 2, 3], |i| {
println!("{}", *i);
- //assert!(bt0 == sys::rusti::frame_address(2u32));
+ //assert!(bt0 == sys::rusti::frame_address(2));
})
}
// actually working.
//let bt0 = sys::frame_address();
//println!("%?", bt0);
- iter(vec!(1_usize, 2_usize, 3_usize), |i| {
+ iter(vec!(1, 2, 3), |i| {
println!("{}", i);
//let bt1 = sys::frame_address();
}
pub fn main() {
- let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>;
+ let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>;
print_out(nyan, "nyan".to_string());
}
impl cat {
fn meow(&mut self) {
println!("Meow");
- self.meows += 1_usize;
- if self.meows % 5_usize == 0_usize {
+ self.meows += 1;
+ if self.meows % 5 == 0 {
self.how_hungry += 1;
}
}
pub fn main() {
- let mut nyan = cat(0_usize, 2, "nyan".to_string());
+ let mut nyan = cat(0, 2, "nyan".to_string());
let mut nyan: &mut noisy = &mut nyan;
nyan.speak();
}
fn cat(done: extern fn(uint)) -> cat {
cat {
- meows: 0_usize,
+ meows: 0,
done: done
}
}
pub fn cat(in_name: String) -> cat {
cat {
name: in_name,
- meows: 0_usize
+ meows: 0
}
}
}
use cci_class_2::kitties::cat;
pub fn main() {
- let nyan : cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let nyan : cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
nyan.speak();
use cci_class_3::kitties::cat;
pub fn main() {
- let mut nyan : cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let mut nyan : cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
nyan.speak();
- assert_eq!(nyan.meow_count(), 53_usize);
+ assert_eq!(nyan.meow_count(), 53);
}
}
impl cat {
- pub fn speak(&mut self) { self.meows += 1_usize; }
+ pub fn speak(&mut self) { self.meows += 1; }
pub fn meow_count(&mut self) -> uint { self.meows }
}
}
pub fn main() {
- let mut nyan: cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let mut nyan: cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
nyan.speak();
- assert_eq!(nyan.meow_count(), 53_usize);
+ assert_eq!(nyan.meow_count(), 53);
}
}
pub fn main() {
- let mut nyan : cat<int> = cat::<int>(52_usize, 99, vec!(9));
- let mut kitty = cat(1000_usize, 2, vec!("tabby".to_string()));
+ let mut nyan : cat<int> = cat::<int>(52, 99, vec!(9));
+ let mut kitty = cat(1000, 2, vec!("tabby".to_string()));
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
nyan.speak(vec!(1,2,3));
- assert_eq!(nyan.meow_count(), 55_usize);
+ assert_eq!(nyan.meow_count(), 55);
kitty.speak(vec!("meow".to_string(), "mew".to_string(), "purr".to_string(), "chirp".to_string()));
- assert_eq!(kitty.meow_count(), 1004_usize);
+ assert_eq!(kitty.meow_count(), 1004);
}
impl cat {
fn meow(&mut self) {
println!("Meow");
- self.meows += 1_usize;
- if self.meows % 5_usize == 0_usize {
+ self.meows += 1;
+ if self.meows % 5 == 0 {
self.how_hungry += 1;
}
}
}
pub fn main() {
- let nyan: Box<ToString> = box cat(0_usize, 2, "nyan".to_string()) as Box<ToString>;
+ let nyan: Box<ToString> = box cat(0, 2, "nyan".to_string()) as Box<ToString>;
print_out(nyan, "nyan".to_string());
}
}
impl<U> cat<U> {
- pub fn speak(&mut self) { self.meows += 1_usize; }
+ pub fn speak(&mut self) { self.meows += 1; }
pub fn meow_count(&mut self) -> uint { self.meows }
}
pub fn main() {
- let _nyan : cat<int> = cat::<int>(52_usize, 99);
- // let mut kitty = cat(1000_usize, 2);
+ let _nyan : cat<int> = cat::<int>(52, 99);
+ // let mut kitty = cat(1000, 2);
}
use cci_class::kitties::cat;
pub fn main() {
- let nyan : cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let nyan : cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
}
}
pub fn main() {
- let mut nyan : cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let mut nyan : cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
nyan.speak();
}
pub fn main() {
- let nyan : cat = cat(52_usize, 99);
- let kitty = cat(1000_usize, 2);
+ let nyan : cat = cat(52, 99);
+ let kitty = cat(1000, 2);
assert_eq!(nyan.how_hungry, 99);
assert_eq!(kitty.how_hungry, 2);
}
pub fn fails() {
let x = 2;
- let mut y = Vec::new();
+ let mut y: Vec<Box<_>> = Vec::new();
y.push(box Conzabble::Bickwick(do_it(&get_bar(x))));
}
}
pub fn main() {
- let z = box Pair { a : 10, b : 12};
+ let z: Box<_> = box Pair { a : 10, b : 12};
let _t = Thread::spawn(move|| {
assert_eq!(z.a, 10);
// rvalue expressions to be unsized. See #20169 for more information.
pub fn main() {
- let _: Box<[int]> = box { [1, 2, 3] };
- let _: Box<[int]> = box if true { [1, 2, 3] } else { [1, 3, 4] };
- let _: Box<[int]> = box match true { true => [1, 2, 3], false => [1, 3, 4] };
- let _: Box<Fn(int) -> _> = box { |x| (x as u8) };
- let _: Box<Debug> = box if true { false } else { true };
- let _: Box<Debug> = box match true { true => 'a', false => 'b' };
+ // FIXME #22405: We cannot infer the type `Box<[int; k]>` for
+ // the r-value expression from the context `Box<[int]>`, and
+ // therefore the `box EXPR` desugaring breaks down.
+ //
+ // One could reasonably claim that the `box EXPR` desugaring is
+ // effectively regressing half of Issue #20169. Hopefully we will
+ // eventually fix that, at which point the `Box::new` calls below
+ // should be replaced wth uses of `box`.
+
+ let _: Box<[int]> = Box::new({ [1, 2, 3] });
+ let _: Box<[int]> = Box::new(if true { [1, 2, 3] } else { [1, 3, 4] });
+ let _: Box<[int]> = Box::new(match true { true => [1, 2, 3], false => [1, 3, 4] });
+ let _: Box<Fn(int) -> _> = Box::new({ |x| (x as u8) });
+ let _: Box<Debug> = Box::new(if true { false } else { true });
+ let _: Box<Debug> = Box::new(match true { true => 'a', false => 'b' });
let _: &[int] = &{ [1, 2, 3] };
let _: &[int] = &if true { [1, 2, 3] } else { [1, 3, 4] };
let _: Vec<Box<Fn(int) -> _>> = vec![
Box::new(|x| (x as u8)),
- box |x| (x as i16 as u8),
+ Box::new(|x| (x as i16 as u8)),
];
}
#![feature(box_syntax)]
pub fn main() {
- let _: Box<[int]> = if true { box [1, 2, 3] } else { box [1] };
+ let _: Box<[int]> =
+ if true { let b: Box<_> = box [1, 2, 3]; b } else { let b: Box<_> = box [1]; b };
- let _: Box<[int]> = match true { true => box [1, 2, 3], false => box [1] };
+ let _: Box<[int]> = match true {
+ true => { let b: Box<_> = box [1, 2, 3]; b }
+ false => { let b: Box<_> = box [1]; b }
+ };
// Check we don't get over-keen at propagating coercions in the case of casts.
let x = if true { 42 } else { 42u8 } as u16;
}
pub fn main() {
- let mut the_vec = vec!(1_usize, 2, 3, 100);
+ let mut the_vec = vec!(1, 2, 3, 100);
assert_eq!(the_vec.clone(), bar(&mut the_vec));
assert_eq!(the_vec.clone(), bip(&the_vec));
}
assert_eq!(concat!("qux", "quux",).to_string(), "quxquux".to_string());
assert_eq!(
- concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true),
+ concat!(1, 2, 3, 4f32, 4.0, 'a', true),
"12344.0atrue"
);
assert!(match "12344.0atrue" {
- concat!(1, 2, 3_usize, 4f32, 4.0, 'a', true) => true,
+ concat!(1, 2, 3, 4f32, 4.0, 'a', true) => true,
_ => false
})
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// compile-flags: --cfg ndebug
+// compile-flags: -C debug-assertions=no
// exec-env:RUST_LOG=conditional-debug-macro-off=4
#[macro_use]
assert_eq!(BLOCK_FN(300), 300);
assert_eq!(BLOCK_ENUM_CONSTRUCTOR(200), Some(200));
// FIXME #13972
- // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef_us);
- // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef_us);
+ // assert_eq!(BLOCK_UNSAFE_SAFE_PTR as *const isize as usize, 0xdeadbeef);
+ // assert_eq!(BLOCK_UNSAFE_SAFE_PTR_2 as *const isize as usize, 0xdeadbeef);
}
// Make sure const bounds work on things, and test that a few types
// are const.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn foo<T: Sync>(x: T) -> T { x }
struct F { field: int }
foo("hi".to_string());
foo(~[1, 2, 3]);
foo(F{field: 42});
- foo((1, 2_usize));
+ foo((1, 2));
foo(@1);*/
- foo(box 1);
+ foo(Box::new(1));
}
pub fn main() {
use crate_method_reexport_grrrrrrr2::rust::add;
use crate_method_reexport_grrrrrrr2::rust::cx;
- let x = box() ();
+ let x: Box<_> = box () ();
x.cx();
let y = ();
y.add("hi".to_string());
use std::cell::Cell;
pub fn main() {
- let x = box Cell::new(5);
+ let x: Box<_> = box Cell::new(5);
x.set(1000);
println!("{}", x.get());
}
pub fn main() {
let a: A = Default::default();
- let b: Box<[_]> = box [];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let b: Box<[_]> = Box::<[bool; 0]>::new([]);
assert_eq!(a.foo, b);
}
}
fn main() {
- let obj = A { foo: box [true, false] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let obj = A { foo: Box::new([true, false]) };
let s = json::encode(&obj).unwrap();
let obj2: A = json::decode(&s).unwrap();
assert!(obj.foo == obj2.foo);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(PartialEq, PartialOrd, Eq, Ord)]
struct Foo(Box<[u8]>);
pub fn main() {
- let a = Foo(box [0, 1, 2]);
- let b = Foo(box [0, 1, 2]);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let a = Foo(Box::new([0, 1, 2]));
+ let b = Foo(Box::new([0, 1, 2]));
assert!(a == b);
println!("{}", a != b);
println!("{}", a < b);
// except according to those terms.
fn check_expr() {
- let _: & uint = &1_usize;
- let _: & & uint = &&1_usize;
- let _: & & & uint = &&&1_usize;
- let _: & & & uint = & &&1_usize;
- let _: & & & & uint = &&&&1_usize;
- let _: & & & & uint = & &&&1_usize;
- let _: & & & & & uint = &&&&&1_usize;
+ let _: & uint = &1;
+ let _: & & uint = &&1;
+ let _: & & & uint = &&&1;
+ let _: & & & uint = & &&1;
+ let _: & & & & uint = &&&&1;
+ let _: & & & & uint = & &&&1;
+ let _: & & & & & uint = &&&&&1;
}
fn check_ty() {
- let _: &uint = & 1_usize;
- let _: &&uint = & & 1_usize;
- let _: &&&uint = & & & 1_usize;
- let _: & &&uint = & & & 1_usize;
- let _: &&&&uint = & & & & 1_usize;
- let _: & &&&uint = & & & & 1_usize;
- let _: &&&&&uint = & & & & & 1_usize;
+ let _: &uint = & 1;
+ let _: &&uint = & & 1;
+ let _: &&&uint = & & & 1;
+ let _: & &&uint = & & & 1;
+ let _: &&&&uint = & & & & 1;
+ let _: & &&&uint = & & & & 1;
+ let _: &&&&&uint = & & & & & 1;
}
fn check_pat() {
let (sender, receiver) = channel();
{
- let v = Foo::NestedVariant(box 42_usize, SendOnDrop { sender: sender.clone() }, sender);
+ let v = Foo::NestedVariant(box 42, SendOnDrop { sender: sender.clone() }, sender);
}
assert_eq!(receiver.recv().unwrap(), Message::DestructorRan);
assert_eq!(receiver.recv().unwrap(), Message::Dropped);
let (sender, receiver) = channel();
let t = {
thread::spawn(move|| {
- let mut v = Foo::NestedVariant(box 42usize, SendOnDrop {
+ let mut v = Foo::NestedVariant(box 42, SendOnDrop {
sender: sender.clone()
}, sender.clone());
- v = Foo::NestedVariant(box 42_usize,
+ v = Foo::NestedVariant(box 42,
SendOnDrop { sender: sender.clone() },
sender.clone());
v = Foo::SimpleVariant(sender.clone());
// Test that a custom deref with a fat pointer return type does not ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::ops::{Deref, DerefMut};
pub struct Arr {
}
fn main() {
- let mut a = Arr { ptr: box [1, 2, 3] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut a = Arr { ptr: Box::new([1, 2, 3]) };
foo(&mut a);
}
// Test that a custom deref with a fat pointer return type does not ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::ops::Deref;
pub struct Arr {
}
fn main() {
- let a = Arr { ptr: box [1, 2, 3] };
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let a = Arr { ptr: Box::new([1, 2, 3]) };
foo(&a);
}
foo3(f5);
// Box.
- let f1 = box [1, 2, 3];
+ let f1 = Box::new([1, 2, 3]);
assert!((*f1)[1] == 2);
let f2: Box<[int]> = f1;
assert!((*f2)[1] == 2);
foo(&*f1);
let f2 : Box<Fat<[int]>> = f1;
foo(&*f2);
- let f3 : Box<Fat<[int]>> = box Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] };
+
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let f3 : Box<Fat<[int]>> =
+ Box::<Fat<[_; 3]>>::new(Fat { f1: 5, f2: "some str", ptr: [1, 2, 3] });
foo(&*f3);
}
assert!(f6.ptr.to_bar() == Bar);
// &*
- let f7: Box<ToBar> = box Bar1 {f :42};
+ //
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let f7: Box<ToBar> = Box::new(Bar1 {f :42});
bar(&*f7);
// Deep nesting
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
pub fn main() {
- assert!(Some(box() ()).is_some());
+ assert!(Some(Box::new(())).is_some());
- let xs: Box<[()]> = box [];
+ let xs: Box<[()]> = Box::<[(); 0]>::new([]);
assert!(Some(xs).is_some());
struct Foo;
- assert!(Some(box Foo).is_some());
+ assert!(Some(Box::new(Foo)).is_some());
- let ys: Box<[Foo]> = box [];
+ let ys: Box<[Foo]> = Box::<[Foo; 0]>::new([]);
assert!(Some(ys).is_some());
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
pub fn main() {
- let x = *box() ();
+ let x = *Box::new(());
}
}
pub fn main() {
- let mut m = box linear_map::<(),()>();
+ let mut m: Box<_> = box linear_map::<(),()>();
assert_eq!(m.len(), 0);
}
impl Nus for thing { fn f(&self) {} }
pub fn main() {
- let y = box thing(A {a: 10});
+ let y: Box<_> = box thing(A {a: 10});
assert_eq!(y.clone().bar(), 10);
assert_eq!(y.quux(), 10);
#![allow(unknown_features)]
#![feature(box_syntax)]
-pub fn main() { let x = { box 100 }; assert!((*x == 100)); }
+pub fn main() { let x: Box<_> = { box 100 }; assert!((*x == 100)); }
// Tests for if as expressions returning boxed types
fn test_box() {
- let rs = if true { box 100 } else { box 101 };
+ let rs: Box<_> = if true { box 100 } else { box 101 };
assert_eq!(*rs, 100);
}
// Tests for match as expressions resulting in boxed types
fn test_box() {
- let res = match true { true => { box 100 }, _ => panic!() };
+ let res: Box<_> = match true { true => { box 100 }, _ => panic!() };
assert_eq!(*res, 100);
}
pub fn main() {
unsafe {
- assert_eq!(22_u8, rust_dbg_extern_identity_u8(22_u8));
+ assert_eq!(22, rust_dbg_extern_identity_u8(22));
}
}
pub fn main() {
unsafe {
- assert_eq!(22_u32, rust_dbg_extern_identity_u32(22_u32));
+ assert_eq!(22, rust_dbg_extern_identity_u32(22));
}
}
pub fn main() {
unsafe {
- assert_eq!(22_u64, rust_dbg_extern_identity_u64(22_u64));
+ assert_eq!(22, rust_dbg_extern_identity_u64(22));
}
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
extern crate libc;
use std::ffi::CString;
pub fn main() {
let len = strlen("Rust".to_string());
- assert_eq!(len, 4_usize);
+ assert_eq!(len, 4);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
extern crate libc;
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
extern crate libc;
}
pub fn main() {
- let obj = box 1;
+ let obj: Box<_> = box 1;
let objptr: *const uint = &*obj;
let f = Foo {x: obj, y: box 2};
let xptr = foo(f);
}
pub fn main() {
- let obj = box 1;
+ let obj: Box<_> = box 1;
let objptr: *const uint = &*obj;
let xptr = getaddr(obj);
assert_eq!(objptr, xptr);
fn id<T:Send>(t: T) -> T { return t; }
pub fn main() {
- let expected = box 100;
+ let expected: Box<_> = box 100;
let actual = id::<Box<int>>(expected.clone());
println!("{}", *actual);
assert_eq!(*expected, *actual);
use std::num::Int;
-extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }
+extern "C" fn foo<T: WrappingOps>(a: T, b: T) -> T { a.wrapping_add(b) }
fn main() {
assert_eq!(99u8, foo(255u8, 100u8));
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
/**
}
let ctrl_clone = ctrl.clone();
- ::map(input, box |a,b| emit(&mut intermediates, ctrl.clone(), a, b) );
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b)));
ctrl_clone.send(ctrl_proto::mapper_done).unwrap();
}
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
// Test that `Fn(int) -> int + 'static` parses as `(Fn(int) -> int) +
// cause a compilation error. Issue #18772.
fn adder(y: int) -> Box<Fn(int) -> int + 'static> {
- box move |x| y + x
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |x| y + x)
}
fn main() {}
-pub fn main() { let mut x: i32 = -400_i32; x = 0_i32 - x; assert!((x == 400_i32)); }
+pub fn main() { let mut x: i32 = -400; x = 0 - x; assert!((x == 400)); }
pub fn main() {
- let mut x: i8 = -12i8;
- let y: i8 = -12i8;
- x = x + 1i8;
- x = x - 1i8;
+ let mut x: i8 = -12;
+ let y: i8 = -12;
+ x = x + 1;
+ x = x - 1;
assert_eq!(x, y);
}
// except according to those terms.
fn even(x: uint) -> bool {
- if x < 2_usize {
+ if x < 2 {
return false;
- } else if x == 2_usize { return true; } else { return even(x - 2_usize); }
+ } else if x == 2 { return true; } else { return even(x - 2); }
}
fn foo(x: uint) {
}
}
-pub fn main() { foo(2_usize); }
+pub fn main() { foo(2); }
test_order();
// make sure that format! doesn't move out of local variables
- let a = box 3;
+ let a: Box<_> = box 3;
format!("{}", a);
format!("{}", a);
fn test_unique() {
let i = &Cell::new(0);
{
- let _a = box r(i);
+ let _a: Box<_> = box r(i);
}
assert_eq!(i.get(), 1);
}
fn test_unique_rec() {
let i = &Cell::new(0);
{
- let _a = box BoxR {
+ let _a: Box<_> = box BoxR {
x: r(i)
};
}
#[cfg(target_arch = "x86")]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
- assert_eq!(::rusti::min_align_of::<u64>(), 4_usize);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 4);
}
}
#[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
- assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
}
}
}
#[cfg(target_arch = "x86_64")]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8u);
- assert_eq!(::rusti::min_align_of::<u64>(), 8u);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
}
}
}
#[cfg(target_arch = "x86")]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
- assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
}
}
#[cfg(target_arch = "x86_64")]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
- assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
}
}
}
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
pub fn main() {
unsafe {
- assert_eq!(::rusti::pref_align_of::<u64>(), 8_usize);
- assert_eq!(::rusti::min_align_of::<u64>(), 8_usize);
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
}
}
}
pub fn main() {
unsafe {
- let mut x = box 1;
+ let mut x: Box<_> = box 1;
assert_eq!(rusti::atomic_load(&*x), 1);
*x = 5;
pub fn main() {
unsafe {
- let x = box 1;
+ let x: Box<_> = box 1;
let mut y = rusti::init();
let mut z: *const uint = transmute(&x);
rusti::move_val_init(&mut y, x);
unsafe {
use rusti::*;
- assert_eq!(ctpop8(0u8), 0u8);
- assert_eq!(ctpop16(0u16), 0u16);
- assert_eq!(ctpop32(0u32), 0u32);
- assert_eq!(ctpop64(0u64), 0u64);
-
- assert_eq!(ctpop8(1u8), 1u8);
- assert_eq!(ctpop16(1u16), 1u16);
- assert_eq!(ctpop32(1u32), 1u32);
- assert_eq!(ctpop64(1u64), 1u64);
-
- assert_eq!(ctpop8(10u8), 2u8);
- assert_eq!(ctpop16(10u16), 2u16);
- assert_eq!(ctpop32(10u32), 2u32);
- assert_eq!(ctpop64(10u64), 2u64);
-
- assert_eq!(ctpop8(100u8), 3u8);
- assert_eq!(ctpop16(100u16), 3u16);
- assert_eq!(ctpop32(100u32), 3u32);
- assert_eq!(ctpop64(100u64), 3u64);
-
- assert_eq!(ctpop8(-1u8), 8u8);
- assert_eq!(ctpop16(-1u16), 16u16);
- assert_eq!(ctpop32(-1u32), 32u32);
- assert_eq!(ctpop64(-1u64), 64u64);
-
- assert_eq!(ctlz8(0u8), 8u8);
- assert_eq!(ctlz16(0u16), 16u16);
- assert_eq!(ctlz32(0u32), 32u32);
- assert_eq!(ctlz64(0u64), 64u64);
-
- assert_eq!(ctlz8(1u8), 7u8);
- assert_eq!(ctlz16(1u16), 15u16);
- assert_eq!(ctlz32(1u32), 31u32);
- assert_eq!(ctlz64(1u64), 63u64);
-
- assert_eq!(ctlz8(10u8), 4u8);
- assert_eq!(ctlz16(10u16), 12u16);
- assert_eq!(ctlz32(10u32), 28u32);
- assert_eq!(ctlz64(10u64), 60u64);
-
- assert_eq!(ctlz8(100u8), 1u8);
- assert_eq!(ctlz16(100u16), 9u16);
- assert_eq!(ctlz32(100u32), 25u32);
- assert_eq!(ctlz64(100u64), 57u64);
-
- assert_eq!(cttz8(-1u8), 0u8);
- assert_eq!(cttz16(-1u16), 0u16);
- assert_eq!(cttz32(-1u32), 0u32);
- assert_eq!(cttz64(-1u64), 0u64);
-
- assert_eq!(cttz8(0u8), 8u8);
- assert_eq!(cttz16(0u16), 16u16);
- assert_eq!(cttz32(0u32), 32u32);
- assert_eq!(cttz64(0u64), 64u64);
-
- assert_eq!(cttz8(1u8), 0u8);
- assert_eq!(cttz16(1u16), 0u16);
- assert_eq!(cttz32(1u32), 0u32);
- assert_eq!(cttz64(1u64), 0u64);
-
- assert_eq!(cttz8(10u8), 1u8);
- assert_eq!(cttz16(10u16), 1u16);
- assert_eq!(cttz32(10u32), 1u32);
- assert_eq!(cttz64(10u64), 1u64);
-
- assert_eq!(cttz8(100u8), 2u8);
- assert_eq!(cttz16(100u16), 2u16);
- assert_eq!(cttz32(100u32), 2u32);
- assert_eq!(cttz64(100u64), 2u64);
-
- assert_eq!(cttz8(-1u8), 0u8);
- assert_eq!(cttz16(-1u16), 0u16);
- assert_eq!(cttz32(-1u32), 0u32);
- assert_eq!(cttz64(-1u64), 0u64);
-
- assert_eq!(bswap16(0x0A0Bu16), 0x0B0Au16);
- assert_eq!(bswap32(0x0ABBCC0Du32), 0x0DCCBB0Au32);
- assert_eq!(bswap64(0x0122334455667708u64), 0x0877665544332201u64);
+ assert_eq!(ctpop8(0), 0);
+ assert_eq!(ctpop16(0), 0);
+ assert_eq!(ctpop32(0), 0);
+ assert_eq!(ctpop64(0), 0);
+
+ assert_eq!(ctpop8(1), 1);
+ assert_eq!(ctpop16(1), 1);
+ assert_eq!(ctpop32(1), 1);
+ assert_eq!(ctpop64(1), 1);
+
+ assert_eq!(ctpop8(10), 2);
+ assert_eq!(ctpop16(10), 2);
+ assert_eq!(ctpop32(10), 2);
+ assert_eq!(ctpop64(10), 2);
+
+ assert_eq!(ctpop8(100), 3);
+ assert_eq!(ctpop16(100), 3);
+ assert_eq!(ctpop32(100), 3);
+ assert_eq!(ctpop64(100), 3);
+
+ assert_eq!(ctpop8(-1), 8);
+ assert_eq!(ctpop16(-1), 16);
+ assert_eq!(ctpop32(-1), 32);
+ assert_eq!(ctpop64(-1), 64);
+
+ assert_eq!(ctlz8(0), 8);
+ assert_eq!(ctlz16(0), 16);
+ assert_eq!(ctlz32(0), 32);
+ assert_eq!(ctlz64(0), 64);
+
+ assert_eq!(ctlz8(1), 7);
+ assert_eq!(ctlz16(1), 15);
+ assert_eq!(ctlz32(1), 31);
+ assert_eq!(ctlz64(1), 63);
+
+ assert_eq!(ctlz8(10), 4);
+ assert_eq!(ctlz16(10), 12);
+ assert_eq!(ctlz32(10), 28);
+ assert_eq!(ctlz64(10), 60);
+
+ assert_eq!(ctlz8(100), 1);
+ assert_eq!(ctlz16(100), 9);
+ assert_eq!(ctlz32(100), 25);
+ assert_eq!(ctlz64(100), 57);
+
+ assert_eq!(cttz8(-1), 0);
+ assert_eq!(cttz16(-1), 0);
+ assert_eq!(cttz32(-1), 0);
+ assert_eq!(cttz64(-1), 0);
+
+ assert_eq!(cttz8(0), 8);
+ assert_eq!(cttz16(0), 16);
+ assert_eq!(cttz32(0), 32);
+ assert_eq!(cttz64(0), 64);
+
+ assert_eq!(cttz8(1), 0);
+ assert_eq!(cttz16(1), 0);
+ assert_eq!(cttz32(1), 0);
+ assert_eq!(cttz64(1), 0);
+
+ assert_eq!(cttz8(10), 1);
+ assert_eq!(cttz16(10), 1);
+ assert_eq!(cttz32(10), 1);
+ assert_eq!(cttz64(10), 1);
+
+ assert_eq!(cttz8(100), 2);
+ assert_eq!(cttz16(100), 2);
+ assert_eq!(cttz32(100), 2);
+ assert_eq!(cttz64(100), 2);
+
+ assert_eq!(cttz8(-1), 0);
+ assert_eq!(cttz16(-1), 0);
+ assert_eq!(cttz32(-1), 0);
+ assert_eq!(cttz64(-1), 0);
+
+ assert_eq!(bswap16(0x0A0B), 0x0B0A);
+ assert_eq!(bswap32(0x0ABBCC0D), 0x0DCCBB0A);
+ assert_eq!(bswap64(0x0122334455667708), 0x0877665544332201);
}
}
assert_approx_eq!(sqrtf32(64f32), 8f32);
assert_approx_eq!(sqrtf64(64f64), 8f64);
- assert_approx_eq!(powif32(25f32, -2i32), 0.0016f32);
- assert_approx_eq!(powif64(23.2f64, 2i32), 538.24f64);
+ assert_approx_eq!(powif32(25f32, -2), 0.0016f32);
+ assert_approx_eq!(powif64(23.2f64, 2), 538.24f64);
assert_approx_eq!(sinf32(0f32), 0f32);
assert_approx_eq!(sinf64(f64::consts::PI / 2f64), 1f64);
fn main() {
{
- let f = box DroppableStruct;
+ let f: Box<_> = box DroppableStruct;
let _a = Whatever::new(box f as Box<MyTrait>);
}
assert!(unsafe { DROPPED });
unsafe { DROPPED = false; }
{
- let f = box DroppableEnum::DroppableVariant1;
+ let f: Box<_> = box DroppableEnum::DroppableVariant1;
let _a = Whatever::new(box f as Box<MyTrait>);
}
assert!(unsafe { DROPPED });
pub fn main() {
let x: X<int> = X {
a: 12345678,
- b: 9u8,
+ b: 9,
c: true,
- d: 10u8,
- e: 11u16,
- f: 12u8,
- g: 13u8
+ d: 10,
+ e: 11,
+ f: 12,
+ g: 13
};
bar(x);
}
fn bar<T>(x: X<T>) {
- assert_eq!(x.b, 9u8);
+ assert_eq!(x.b, 9);
assert_eq!(x.c, true);
- assert_eq!(x.d, 10u8);
- assert_eq!(x.e, 11u16);
- assert_eq!(x.f, 12u8);
- assert_eq!(x.g, 13u8);
+ assert_eq!(x.d, 10);
+ assert_eq!(x.e, 11);
+ assert_eq!(x.f, 12);
+ assert_eq!(x.g, 13);
}
// except according to those terms.
#![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
trait Foo { fn dummy(&self) { } }
impl Foo for int {}
let r = &1;
foog(x, &[r]);
- let x: [Box<Foo>; 2] = [box 1, box 2];
+ let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
bar(x);
- bar([box 1, box 2]);
+ bar([Box::new(1), Box::new(2)]);
- let x: &[Box<Foo>] = &[box 1, box 2];
+ let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
bars(x);
- bars(&[box 1, box 2]);
+ bars(&[Box::new(1), Box::new(2)]);
- let x: &[Box<Foo>] = &[box 1, box 2];
- foog(x, &[box 1]);
+ let x: &[Box<Foo>] = &[Box::new(1), Box::new(2)];
+ foog(x, &[Box::new(1)]);
struct T<'a> {
t: [&'a (Foo+'a); 2]
t: &'a [Box<Foo+'static>]
}
let _n = M {
- t: &[box 1, box 2]
+ t: &[Box::new(1), Box::new(2)]
};
- let x: [Box<Foo>; 2] = [box 1, box 2];
+ let x: [Box<Foo>; 2] = [Box::new(1), Box::new(2)];
let _n = M {
t: &x
};
// except according to those terms.
#![allow(dead_code)]
-#![allow(unknown_features)]
-#![feature(box_syntax)]
// this code used to cause an ICE
}
fn main() {
- S {f: box F, g: box F};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ S {f: Box::new(F), g: Box::new(F) };
}
fn main() {
// Generate sieve of Eratosthenes for n up to 1e6
- let n = 1000000_usize;
+ let n = 1000000;
let mut sieve = BitVec::from_elem(n+1, true);
let limit: uint = (n as f32).sqrt() as uint;
for i in 2..limit+1 {
use std::thunk::Thunk;
pub fn main() {
- let mut x = 1i32;
+ let mut x = 1;
let _thunk = Thunk::new(move|| { x = 2; });
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- fn test() -> Box<std::any::Any + 'static> { box 1 }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ fn test() -> Box<std::any::Any + 'static> { Box::new(1) }
println!("{:?}", test())
}
}
fn main() {
- let arr = [(1, 1_usize), (2, 2), (3, 3)];
+ let arr = [(1, 1), (2, 2), (3, 3)];
let v1: Vec<&_> = arr.iter().collect();
let v2: Vec<_> = arr.iter().map(copy).collect();
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
struct Foo<'a> {
listener: Box<FnMut() + 'a>,
}
impl<'a> Foo<'a> {
fn new<F>(listener: F) -> Foo<'a> where F: FnMut() + 'a {
- Foo { listener: box listener }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Foo { listener: Box::new(listener) }
}
}
impl A for B1 {}
fn main() {
- let v = box B1;
+ let v: Box<_> = box B1;
let _c: Box<A> = v.clone();
}
// All 3 expressions should work in that the argument gets
// coerced to a trait object
-#![allow(unknown_features)]
-#![feature(box_syntax)]
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
fn main() {
- send::<Box<Foo>>(box Output(0));
- Test::<Box<Foo>>::foo(box Output(0));
- Test::<Box<Foo>>::new().send(box Output(0));
+ send::<Box<Foo>>(Box::new(Output(0)));
+ Test::<Box<Foo>>::foo(Box::new(Output(0)));
+ Test::<Box<Foo>>::new().send(Box::new(Output(0)));
}
fn send<T>(_: T) {}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
trait Matcher {
fn next_match(&mut self) -> Option<(uint, uint)>;
}
impl<'a, 'b, F> IntoMatcher<'a, CharPredMatcher<'a, 'b>> for F where F: FnMut(char) -> bool + 'b {
fn into_matcher(self, s: &'a str) -> CharPredMatcher<'a, 'b> {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
CharPredMatcher {
str: s,
- pred: box self,
+ pred: Box::new(self),
}
}
}
#![feature(box_syntax)]
fn match_on_local() {
- let mut foo = Some(box 5);
+ let mut foo: Option<Box<_>> = Some(box 5);
match foo {
None => {},
Some(x) => {
}
fn match_on_binding() {
- match Some(box 7) {
+ match Some(Box::new(7)) {
mut foo => {
match foo {
None => {},
}
fn match_on_upvar() {
- let mut foo = Some(box 8i32);
+ let mut foo: Option<Box<_>> = Some(box 8);
let f = move|| {
match foo {
None => {},
use std::iter::AdditiveIterator;
fn main() {
let x: [u64; 3] = [1, 2, 3];
- assert_eq!(6, (0_usize..3).map(|i| x[i]).sum());
+ assert_eq!(6, (0..3).map(|i| x[i]).sum());
}
}
fn main() {
- let m = Mat::new(vec!(1_usize, 2, 3, 4, 5, 6), 3);
+ let m = Mat::new(vec!(1, 2, 3, 4, 5, 6), 3);
let r = m.row(1);
assert!(r.index(&2) == &6);
assert!(r[2] == 6);
- assert!(r[2_usize] == 6_usize);
+ assert!(r[2] == 6);
assert!(6 == r[2]);
let e = r[2];
// ignore-pretty
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct Parser<'a, I, O> {
impl<'a, I: 'a, O: 'a> Parser<'a, I, O> {
fn compose<K: 'a>(mut self, mut rhs: Parser<'a, O, K>) -> Parser<'a, I, K> {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
Parser {
- parse: box move |x: I| {
+ parse: Box::new(move |x: I| {
match (self.parse)(x) {
Ok(r) => (rhs.parse)(r),
Err(e) => Err(e)
}
- }
+ })
}
}
}
struct Bar<'a> { m: marker::PhantomData<&'a ()> }
impl<'a> i::Foo<'a, uint> for Bar<'a> {
- fn foo(&self) -> uint { 5_usize }
+ fn foo(&self) -> uint { 5 }
}
pub fn main() {
// Test that generating drop glue for Box<str> doesn't ICE
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn f(s: Box<str>) -> Box<str> {
s
}
fn main() {
// There is currently no safe way to construct a `Box<str>`, so improvise
- let box_arr: Box<[u8]> = box ['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8];
+ //
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let box_arr: Box<[u8]> = Box::new(['h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8]);
let box_str: Box<str> = unsafe { std::mem::transmute(box_arr) };
assert_eq!(&*box_str, "hello");
f(box_str);
// Check that trans doesn't ICE when translating an array repeat
// expression with a count of 1 and a non-Copy element type.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn main() {
- let _ = [box 1_usize; 1];
+ let _ = [Box::new(1_usize); 1];
}
#[allow(unused_must_use)]
fn main() {
- (0_usize..10).map(uint_to_foo);
+ (0..10).map(uint_to_foo);
}
}
pub fn main() {
- fn box_1() -> Box<[i8; 1]> { Box::new( [1i8; 1] ) }
- fn box_2() -> Box<[i8; 2]> { Box::new( [1i8; 2] ) }
- fn box_3() -> Box<[i8; 3]> { Box::new( [1i8; 3] ) }
- fn box_4() -> Box<[i8; 4]> { Box::new( [1i8; 4] ) }
+ fn box_1() -> Box<[i8; 1]> { Box::new( [1; 1] ) }
+ fn box_2() -> Box<[i8; 2]> { Box::new( [1; 2] ) }
+ fn box_3() -> Box<[i8; 3]> { Box::new( [1; 3] ) }
+ fn box_4() -> Box<[i8; 4]> { Box::new( [1; 4] ) }
foo(box_1, box_2, box_3, box_4);
}
}
pub fn main() {
- fn box_1() -> Box<[i8; 1]> { Box::new( [1i8] ) }
- fn box_2() -> Box<[i8; 20]> { Box::new( [1i8; 20] ) }
- fn box_3() -> Box<[i8; 300]> { Box::new( [1i8; 300] ) }
- fn box_4() -> Box<[i8; 4000]> { Box::new( [1i8; 4000] ) }
+ fn box_1() -> Box<[i8; 1]> { Box::new( [1] ) }
+ fn box_2() -> Box<[i8; 20]> { Box::new( [1; 20] ) }
+ fn box_3() -> Box<[i8; 300]> { Box::new( [1; 300] ) }
+ fn box_4() -> Box<[i8; 4000]> { Box::new( [1; 4000] ) }
foo(box_1, box_2, box_3, box_4);
}
// Test that overloaded calls work with zero arity closures
-#![feature(box_syntax)]
-
fn main() {
- let functions: [Box<Fn() -> Option<()>>; 1] = [box || None];
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let functions: [Box<Fn() -> Option<()>>; 1] = [Box::new(|| None)];
let _: Option<Vec<()>> = functions.iter().map(|f| (*f)()).collect();
}
use std::fmt;
fn main() {
- let a: &fmt::Debug = &1_i32;
+ let a: &fmt::Debug = &1;
format!("{:?}", a);
}
use m::{START, END};
fn main() {
- match 42u32 {
+ match 42 {
m::START...m::END => {},
- 0u32...m::END => {},
- m::START...59u32 => {},
+ 0...m::END => {},
+ m::START...59 => {},
_ => {},
}
}
let mut i = lo;
while i < hi {
it(i);
- i += 1_usize;
+ i += 1;
}
}
pub fn main() {
- let range: 'static ||uint|| = |a| range(0_usize, 1000_usize, a);
+ let range: 'static ||uint|| = |a| range(0, 1000, a);
let filt: 'static ||v: uint|| = |a| filter(
range,
- |&&n: uint| n % 3_usize != 0_usize && n % 5_usize != 0_usize,
+ |&&n: uint| n % 3 != 0 && n % 5 != 0,
a);
- let sum = foldl(filt, 0_usize, |accum, &&n: uint| accum + n );
+ let sum = foldl(filt, 0, |accum, &&n: uint| accum + n );
println!("{}", sum);
}
}
fn main() {
- let xs = vec![1u8, 2, 3, 4, 5];
+ let xs = vec![1, 2, 3, 4, 5];
assert_eq!(xs.into_iter().digit_sum(), 15);
}
}
pub fn main() {
- f(C(1_usize));
+ f(C(1));
}
}
pub fn main() {
- let z = box 22;
+ let z: Box<_> = box 22;
a_val(z.clone(), z.clone());
}
}
pub fn main() {
- let _f = box Font();
+ let _f: Box<_> = box Font();
}
//
// ignore-lexer-test FIXME #15883
-#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unsafe_destructor)]
pub type Task = int;
pub fn packet<T:Send>() -> *const packet<T> {
unsafe {
- let p: *const packet<T> = mem::transmute(box Stuff{
+ let p: *const packet<T> = mem::transmute(Box::new(Stuff{
state: empty,
blocked_task: None::<Task>,
payload: None::<T>
- });
+ }));
p
}
}
// let y = box ({a: 4});
// let z = box ({a: 4} as it);
// let z = box ({a: true} as it);
- let z = box() (box true as Box<it>);
+ let z: Box<_> = box () (box true as Box<it>);
// x.f();
// y.f();
// (*z).f();
// the position of this function is significant! - if it comes before methods
// then it works, if it comes after it then it doesn't!
fn to_bools(bitv: Storage) -> Vec<bool> {
- (0_usize..8).map(|i| {
+ (0..8).map(|i| {
let w = i / 64;
let b = i % 64;
- let x = 1u64 & (bitv.storage[w] >> b);
- x == 1u64
+ let x = 1 & (bitv.storage[w] >> b);
+ x == 1
}).collect()
}
let bools = vec!(false, false, true, false, false, true, true, false);
let bools2 = to_bools(Storage{storage: vec!(0b01100100)});
- for i in 0_usize..8 {
+ for i in 0..8 {
println!("{} => {} vs {}", i, bools[i], bools2[i]);
}
pub fn main() {
let fd: libc::c_int = 1 as libc::c_int;
- let _sock = box socket::socket_handle(fd);
+ let _sock: Box<_> = box socket::socket_handle(fd);
}
use std::collections::HashMap;
pub fn main() {
- let x;
+ let x: Box<_>;
let mut buggy_map: HashMap<uint, &uint> = HashMap::new();
x = box 1;
buggy_map.insert(42, &*x);
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
type Connection = Box<FnMut(Vec<u8>) + 'static>;
fn f() -> Option<Connection> {
- let mock_connection: Connection = box |_| {};
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mock_connection: Connection = Box::new(|_| {});
Some(mock_connection)
}
#![feature(box_syntax)]
pub fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
x = x;
assert_eq!(*x, 3);
}
// rustc --test ignores2.rs && ./ignores2
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::old_path::{Path};
fn tester()
{
- let mut loader: rsrc_loader = box move|_path| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut loader: rsrc_loader = Box::new(move|_path| {
result::Result::Ok("more blah".to_string())
- };
+ });
let path = old_path::Path::new("blah");
assert!(loader(&path).is_ok());
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
use std::thread::Thread;
use std::sync::mpsc::Sender;
let _t = Thread::spawn(move|| {
let mut samples_chan = samples_chan;
- // `box() (...)` syntax is needed to make pretty printer converge in one try:
- let callback: SamplesFn = box() (move |buffer| {
- for i in 0_usize..buffer.len() {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let callback: SamplesFn = Box::new(move |buffer| {
+ for i in 0..buffer.len() {
println!("{}: {}", i, buffer[i])
}
});
#![feature(box_syntax)]
pub fn main() {
- let y = box 1;
+ let y: Box<_> = box 1;
y;
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
#![allow(unknown_features)]
#![feature(box_syntax)]
macro_rules! foo {
($tag: expr, $string: expr) => {
if $tag == $string {
- let element = box Element;
+ let element: Box<_> = box Element;
unsafe {
return std::mem::transmute::<_, uint>(element);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
enum Either<T, U> { Left(T), Right(U) }
pub fn main() {
- match Either::Left(box 17) {
+ match Either::Left(Box::new(17)) {
Either::Right(()) => {}
_ => {}
}
pub fn main() {
let i: uint = 0;
- assert!(i <= 0xFFFF_FFFF_usize);
+ assert!(i <= 0xFFFF_FFFF);
let i: int = 0;
- assert!(i >= -0x8000_0000__isize);
- assert!(i <= 0x7FFF_FFFF__isize);
+ assert!(i >= -0x8000_0000);
+ assert!(i <= 0x7FFF_FFFF);
}
assert_eq!(unsafe { NUM_DROPS }, 3);
{ let _x = FooBar::_Foo(Foo); }
assert_eq!(unsafe { NUM_DROPS }, 5);
- { let _x = FooBar::_Bar(42_usize); }
+ { let _x = FooBar::_Bar(42); }
assert_eq!(unsafe { NUM_DROPS }, 6);
{ let _ = Foo; }
assert_eq!(unsafe { NUM_DROPS }, 9);
{ let _ = FooBar::_Foo(Foo); }
assert_eq!(unsafe { NUM_DROPS }, 11);
- { let _ = FooBar::_Bar(42_usize); }
+ { let _ = FooBar::_Bar(42); }
assert_eq!(unsafe { NUM_DROPS }, 12);
}
struct signature<'a> { pattern : &'a [u32] }
static test1: signature<'static> = signature {
- pattern: &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,0x03707344u32,0xa4093822u32,0x299f31d0u32]
+ pattern: &[0x243f6a88,0x85a308d3,0x13198a2e,0x03707344,0xa4093822,0x299f31d0]
};
pub fn main() {
- let test: &[u32] = &[0x243f6a88u32,0x85a308d3u32,0x13198a2eu32,
- 0x03707344u32,0xa4093822u32,0x299f31d0u32];
+ let test: &[u32] = &[0x243f6a88,0x85a308d3,0x13198a2e,
+ 0x03707344,0xa4093822,0x299f31d0];
println!("{}",test==test1.pattern);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
pub fn main() {
- match &[(box 5,box 7)] {
+ match &[(Box::new(5),Box::new(7))] {
ps => {
let (ref y, _) = ps[0];
assert!(**y == 5);
}
}
- match Some(&[(box 5,)]) {
+ match Some(&[(Box::new(5),)]) {
Some(ps) => {
let (ref y,) = ps[0];
assert!(**y == 5);
None => ()
}
- match Some(&[(box 5,box 7)]) {
+ match Some(&[(Box::new(5),Box::new(7))]) {
Some(ps) => {
let (ref y, ref z) = ps[0];
assert!(**y == 5);
struct X { pub x: uint }
impl Default for X {
fn default() -> X {
- X { x: 42_usize }
+ X { x: 42 }
}
}
extern crate issue2170lib;
pub fn main() {
- // let _ = issue2170lib::rsrc(2i32);
+ // let _ = issue2170lib::rsrc(2);
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test to see that the element type of .cloned() can be inferred
+// properly. Previously this would fail to deduce the type of `sum`.
+
+#![feature(core)]
+
+use std::iter::AdditiveIterator;
+
+fn square_sum(v: &[i64]) -> i64 {
+ let sum = v.iter().cloned().sum();
+ sum * sum
+}
+
+fn main() {
+ assert_eq!(36, square_sum(&[1,2,3]));
+}
fn producer(tx: &Sender<Vec<u8>>) {
tx.send(
- vec!(1u8, 2u8, 3u8, 4u8, 5u8, 6u8, 7u8, 8u8, 9u8, 10u8, 11u8, 12u8,
- 13u8)).unwrap();
+ vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13)).unwrap();
}
pub fn main() {
struct A { a: Box<isize> }
fn foo() -> Box<FnMut() -> isize + 'static> {
- let k = box 22;
+ let k: Box<_> = box 22;
let _u = A {a: k.clone()};
- // FIXME(#16640) suffix in `22_isize` suffix shouldn't be necessary
- let result = || 22_isize;
- box result
+ // FIXME(#16640) suffix in `22` suffix shouldn't be necessary
+ let result = || 22;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(result)
}
pub fn main() {
pub fn main() {
fn invoke<F>(f: F) where F: FnOnce() { f(); }
- let k = box 22;
+ let k: Box<_> = box 22;
let _u = A {a: k.clone()};
invoke(|| println!("{}", k.clone()) )
}
#![feature(box_syntax)]
fn f() {
- let a = box 1;
+ let a: Box<_> = box 1;
let b: &int = &*a;
println!("{}", b);
}
+++ /dev/null
-// Copyright 2013 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.
-
-extern crate libc;
-
-extern {
- fn rust_get_test_int() -> libc::intptr_t;
-}
-
-trait A {
- fn foo(&self) {
- unsafe {
- rust_get_test_int();
- }
- }
-}
-
-pub fn main() {
-}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// compile-flags:--cfg ndebug
+// compile-flags:-C debug-assertions=no
// exec-env:RUST_LOG=logging-enabled-debug=debug
#[macro_use]
// ignore-windows
// exec-env:RUST_LOG=debug
+// compile-flags:-C debug-assertions=y
#[macro_use]
extern crate log;
pub fn main() {
assert!(overly_complicated!(f, x, Option<uint>, { return Some(x); },
- Some(8_usize), Some(y), y) == 8_usize)
+ Some(8), Some(y), y) == 8)
}
}
pub fn main() {
- assert_eq!(1_usize, f(Some('x')));
- assert_eq!(2_usize, f(Some('y')));
- assert_eq!(3_usize, f(None));
+ assert_eq!(1, f(Some('x')));
+ assert_eq!(2, f(Some('y')));
+ assert_eq!(3, f(None));
assert_eq!(1, match Some('x') {
Some(char_x!()) => 1,
struct Pair { a: Box<int>, b: Box<int> }
pub fn main() {
- let mut x = box Pair {a: box 10, b: box 20};
+ let mut x: Box<_> = box Pair {a: box 10, b: box 20};
let x_internal = &mut *x;
match *x_internal {
Pair {a: ref mut a, b: ref mut _b} => {
None => return (),
Some(num) => num as u32
};
- assert_eq!(f, 1234u32);
+ assert_eq!(f, 1234);
println!("{}", f)
}
}
fn main() {
- let mut buf = [0_u8; 6];
+ let mut buf = [0; 6];
{
let mut writer: &mut [_] = &mut buf;
x.foo(&x);
- assert!(method_self_arg1::get_count() == 2u64*3*3*3*5*5*5*7*7*7);
+ assert!(method_self_arg1::get_count() == 2*3*3*3*5*5*5*7*7*7);
}
x.run_trait();
- assert!(method_self_arg2::get_count() == 2u64*2*3*3*5*5*7*7*11*11*13*13*17);
+ assert!(method_self_arg2::get_count() == 2*2*3*3*5*5*7*7*11*11*13*13*17);
}
x.baz();
- unsafe { assert!(COUNT == 2u64*2*3*3*5*5*7*7*11*11*13*13*17); }
+ unsafe { assert!(COUNT == 2*2*3*3*5*5*7*7*11*11*13*13*17); }
}
x.foo(&x);
- unsafe { assert!(COUNT == 2_usize*3*3*3*5*5*5*7*7*7); }
+ unsafe { assert!(COUNT == 2*3*3*3*5*5*5*7*7*7); }
}
}
fn call_foo_other() -> int {
- let mut x = Vec::new();
+ let mut x: Vec<Box<_>> = Vec::new();
let y = x.foo();
x.push(box 0);
y
}
pub fn main() {
- let x = box Triple{x: 1, y: 2, z: 3};
+ let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
assert_eq!(test(true, x.clone()), 2);
assert_eq!(test(true, x.clone()), 2);
assert_eq!(test(true, x.clone()), 2);
struct X { x: int, y: int, z: int }
pub fn main() {
- let x = box X{x: 1, y: 2, z: 3};
+ let x: Box<_> = box X{x: 1, y: 2, z: 3};
let y = x;
assert!((y.y == 2));
}
struct X { x: int, y: int, z: int }
-pub fn main() { let x = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
+pub fn main() { let x: Box<_> = box X {x: 1, y: 2, z: 3}; let y = x; assert!((y.y == 2)); }
}
pub fn main() {
- let x = box Triple{x: 1, y: 2, z: 3};
+ let x: Box<_> = box Triple{x: 1, y: 2, z: 3};
for _ in 0_usize..10000_usize {
assert_eq!(test(true, x.clone()), 2);
}
#![feature(box_syntax)]
fn main() {
- let x = box 1;
+ let x: Box<_> = box 1;
let v = (1, 2);
// Test that the lambda kind is inferred correctly as a return
// expression
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn unique() -> Box<FnMut()+'static> { return box || (); }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+fn unique() -> Box<FnMut()+'static> { return Box::new(|| ()); }
pub fn main() {
}
// Test that the lambda kind is inferred correctly as a return
// expression
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
-fn unique() -> Box<FnMut()+'static> { box || () }
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+fn unique() -> Box<FnMut()+'static> { Box::new(|| ()) }
pub fn main() {
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-fast doesn't like extern crate
extern crate libc;
use libc::c_int;
check_fancy!($e, $T, |ptr| assert!(*ptr == $e));
}};
($e:expr, $T:ty, |$v:ident| $chk:expr) => {{
- assert!(E::Nothing::<$T>((), ((), ()), [23i8; 0]).is_none());
+ assert!(E::Nothing::<$T>((), ((), ()), [23; 0]).is_none());
let e = $e;
let t_ = E::Thing::<$T>(23, e);
match t_.get_ref() {
}
fn main() {
- let x = 22_i32;
+ let x = 22;
let x1: &SomeTrait<SomeType=i32> = &x;
let y = get_int(x1);
assert_eq!(x, y);
}
pub fn main() {
- let mut x = 22_usize;
+ let mut x = 22;
let obj = &mut x as &mut Foo;
do_it_mut(obj);
- do_it_imm(obj, 23_usize);
+ do_it_imm(obj, 23);
do_it_mut(obj);
}
box BarStruct{ x: 2 } as Box<FooTrait>
);
- for i in 0_usize..foos.len() {
+ for i in 0..foos.len() {
assert_eq!(i, foos[i].foo());
}
}
pub fn main() {
assert_eq!(or_alt(blah::c), 0);
- assert_eq!(or_alt(blah::a(10, 100, 0_usize)), 110);
+ assert_eq!(or_alt(blah::a(10, 100, 0)), 110);
assert_eq!(or_alt(blah::b(20, 200)), 220);
}
}
pub fn main() {
- let box_5 = box 5_usize;
+ let box_5: Box<_> = box 5_usize;
assert_eq!(Rc::new(5_usize).to_uint(), Some(5));
- assert_eq!((box &box &Rc::new(box box &box_5)).to_uint(), Some(5));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ assert_eq!((Box::new(&Box::new(&Rc::new(Box::new(Box::new(&box_5)))))).to_uint(), Some(5));
let point = Rc::new(Point {x: 2, y: 4});
assert_eq!(point.x, 2);
assert_eq!(point.y, 4);
fn main() {
// ICE trigger
- (G(PhantomData))(1_i32);
+ (G(PhantomData))(1);
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
use std::cell::RefCell;
use std::rc::Rc;
use std::string::String;
pub fn main() {
assert_eq!(*Rc::new(5), 5);
- assert_eq!(***Rc::new(box box 5), 5);
+ assert_eq!(***Rc::new(Box::new(Box::new(5))), 5);
assert_eq!(*Rc::new(Point {x: 2, y: 4}), Point {x: 2, y: 4});
let i = Rc::new(RefCell::new(2));
}
fn main() {
- let mut f = box Foo {
+ let mut f: Box<_> = box Foo {
x: 1,
y: 2,
};
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn f<T: 'static>(_x: T) {}
pub fn main() {
- f(box 5);
+ f(Box::new(5));
}
assert_eq!(mem::size_of::<[Foo; 10]>(), 90);
- for i in 0_usize..10 {
+ for i in 0..10 {
assert_eq!(foos[i], Foo { bar: 1, baz: 2});
}
pub fn bar(_offset: uint) { }
}
-pub fn main() { foo::bar(0_usize); }
+pub fn main() { foo::bar(0); }
}
pub fn main() {
- let mut nyan : cat = cat(52_usize, 99);
- assert_eq!(nyan.meow_count(), 52_usize);
+ let mut nyan : cat = cat(52, 99);
+ assert_eq!(nyan.meow_count(), 52);
}
#![feature(box_syntax)]
fn sums_to(v: Vec<int> , sum: int) -> bool {
- let mut i = 0_usize;
+ let mut i = 0;
let mut sum0 = 0;
while i < v.len() {
sum0 += v[i];
- i += 1_usize;
+ i += 1;
}
return sum0 == sum;
}
fn sums_to_using_uniq(v: Vec<int> , sum: int) -> bool {
- let mut i = 0_usize;
- let mut sum0 = box 0;
+ let mut i = 0;
+ let mut sum0: Box<_> = box 0;
while i < v.len() {
*sum0 += v[i];
- i += 1_usize;
+ i += 1;
}
return *sum0 == sum;
}
fn sums_to_using_rec(v: Vec<int> , sum: int) -> bool {
- let mut i = 0_usize;
+ let mut i = 0;
let mut sum0 = F {f: 0};
while i < v.len() {
sum0.f += v[i];
- i += 1_usize;
+ i += 1;
}
return sum0.f == sum;
}
struct F<T> { f: T }
fn sums_to_using_uniq_rec(v: Vec<int> , sum: int) -> bool {
- let mut i = 0_usize;
- let mut sum0 = F {f: box 0};
+ let mut i = 0;
+ let mut sum0 = F::<Box<_>> {f: box 0};
while i < v.len() {
*sum0.f += v[i];
- i += 1_usize;
+ i += 1;
}
return *sum0.f == sum;
}
let x = ..1+3;
assert!(x == (..4));
- let a = &[0i32, 1, 2, 3, 4, 5, 6];
+ let a = &[0, 1, 2, 3, 4, 5, 6];
let x = &a[1+1..2+2];
assert!(x == &a[2..4]);
let x = &a[..1+2];
}
pub fn main() {
- let x = box 6;
+ let x: Box<_> = box 6;
let y = x.get();
println!("y={}", y);
assert_eq!(y, 6);
// from pairs of rows (where each pair of rows is equally sized),
// and the elements of the triangle match their row-pair index.
unsafe fn sanity_check(ascend: &[*mut u8]) {
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
- for j in 0_usize..size {
+ for j in 0..size {
assert_eq!(*p0.offset(j as int), i as u8);
assert_eq!(*p1.offset(j as int), i as u8);
}
// that at least two rows will be allocated near each other, so
// that we trigger the bug (a buffer overrun) in an observable
// way.)
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let size = idx_to_size(i);
ascend[2*i] = allocate(size, ALIGN);
ascend[2*i+1] = allocate(size, ALIGN);
}
// Initialize each pair of rows to distinct value.
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let (p0, p1, size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
for j in 0..size {
*p0.offset(j as int) = i as u8;
test_3(ascend); // triangle -> square
test_4(ascend); // square -> triangle
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let size = idx_to_size(i);
deallocate(ascend[2*i], size, ALIGN);
deallocate(ascend[2*i+1], size, ALIGN);
// rows as we go.
unsafe fn test_1(ascend: &mut [*mut u8]) {
let new_size = idx_to_size(COUNT-1);
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
assert!(old_size < new_size);
// Test 2: turn the square back into a triangle, top to bottom.
unsafe fn test_2(ascend: &mut [*mut u8]) {
let old_size = idx_to_size(COUNT-1);
- for i in 0_usize..COUNT / 2 {
+ for i in 0..COUNT / 2 {
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
assert!(new_size < old_size);
// Test 3: turn triangle into a square, bottom to top.
unsafe fn test_3(ascend: &mut [*mut u8]) {
let new_size = idx_to_size(COUNT-1);
- for i in (0_usize..COUNT / 2).rev() {
+ for i in (0..COUNT / 2).rev() {
let (p0, p1, old_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
assert!(old_size < new_size);
// Test 4: turn the square back into a triangle, bottom to top.
unsafe fn test_4(ascend: &mut [*mut u8]) {
let old_size = idx_to_size(COUNT-1);
- for i in (0_usize..COUNT / 2).rev() {
+ for i in (0..COUNT / 2).rev() {
let (p0, p1, new_size) = (ascend[2*i], ascend[2*i+1], idx_to_size(i));
assert!(new_size < old_size);
#[cfg(any(target_arch = "x86", target_arch = "arm", target_arch = "aarch64"))]
mod m {
- pub fn align() -> uint { 4_usize }
- pub fn size() -> uint { 8_usize }
+ pub fn align() -> uint { 4 }
+ pub fn size() -> uint { 8 }
}
#[cfg(target_arch = "x86_64")]
mod m {
- pub fn align() -> uint { 4_usize }
- pub fn size() -> uint { 8_usize }
+ pub fn align() -> uint { 4 }
+ pub fn size() -> uint { 8 }
}
pub fn main() {
unsafe {
- let x = Outer {c8: 22u8, t: Inner {c64: 44u32}};
+ let x = Outer {c8: 22, t: Inner {c64: 44}};
// Send it through the shape code
let y = format!("{:?}", x);
mod m {
#[cfg(target_arch = "x86")]
pub mod m {
- pub fn align() -> uint { 4_usize }
- pub fn size() -> uint { 12_usize }
+ pub fn align() -> uint { 4 }
+ pub fn size() -> uint { 12 }
}
#[cfg(any(target_arch = "x86_64", target_arch = "arm", target_arch = "aarch64"))]
pub mod m {
- pub fn align() -> uint { 8_usize }
- pub fn size() -> uint { 16_usize }
+ pub fn align() -> uint { 8 }
+ pub fn size() -> uint { 16 }
}
}
mod m {
#[cfg(target_arch = "x86_64")]
pub mod m {
- pub fn align() -> uint { 8u }
- pub fn size() -> uint { 16u }
+ pub fn align() -> uint { 8 }
+ pub fn size() -> uint { 16 }
}
}
mod m {
#[cfg(target_arch = "x86")]
pub mod m {
- pub fn align() -> uint { 8_usize }
- pub fn size() -> uint { 16_usize }
+ pub fn align() -> uint { 8 }
+ pub fn size() -> uint { 16 }
}
#[cfg(target_arch = "x86_64")]
pub mod m {
- pub fn align() -> uint { 8_usize }
- pub fn size() -> uint { 16_usize }
+ pub fn align() -> uint { 8 }
+ pub fn size() -> uint { 16 }
}
}
mod m {
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
pub mod m {
- pub fn align() -> uint { 8_usize }
- pub fn size() -> uint { 16_usize }
+ pub fn align() -> uint { 8 }
+ pub fn size() -> uint { 16 }
}
}
pub fn main() {
unsafe {
- let x = Outer {c8: 22u8, t: Inner {c64: 44u64}};
+ let x = Outer {c8: 22, t: Inner {c64: 44}};
let y = format!("{:?}", x);
}
pub fn main() {
- assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4_usize)), 10);
- assert_eq!(m(t3::c(T2 {x: t1::b(10_usize), y: 5}, 4_usize)), 19);
+ assert_eq!(m(t3::c(T2 {x: t1::a(10), y: 5}, 4)), 10);
+ assert_eq!(m(t3::c(T2 {x: t1::b(10), y: 5}, 4)), 19);
}
}
pub fn main() {
- let p = box 22_usize;
+ let p: Box<_> = box 22;
let r = foo(&*p);
println!("r={}", r);
- assert_eq!(r, 22_usize);
+ assert_eq!(r, 22);
}
}
pub fn main() {
- let p = box 3_usize;
+ let p: Box<_> = box 3;
let r = foo(&*p);
- assert_eq!(r, 3_usize);
+ assert_eq!(r, 3);
}
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
struct closure_box<'a> {
}
pub fn main() {
- let mut i = 3i32;
+ let mut i = 3;
assert_eq!(i, 3);
{
let cl = || i += 1;
- let mut cl_box = box_it(box cl);
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let mut cl_box = box_it(Box::new(cl));
cl_box.cl.call_mut(());
}
assert_eq!(i, 4);
fn bar(x: &uint) -> uint { *x }
pub fn main() {
- let p = box 3_usize;
+ let p: Box<_> = box 3;
assert_eq!(bar(foo(&*p)), 3);
}
#![allow(dead_assignment)]
#![allow(unused_variable)]
#![allow(unknown_features)]
-#![feature(box_syntax)]
+
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
// Should pass region checking.
fn ok(f: Box<FnMut(&uint)>) {
// f's type should be a subtype of g's type), because f can be
// used in any context that expects g's type. But this currently
// fails.
- let mut g: Box<for<'r> FnMut(&'r uint)> = box |x| { };
+ let mut g: Box<for<'r> FnMut(&'r uint)> = Box::new(|x| { });
g = f;
}
// This version is the same as above, except that here, g's type is
// inferred.
fn ok_inferred(f: Box<FnMut(&uint)>) {
- let mut g: Box<for<'r> FnMut(&'r uint)> = box |_| {};
+ let mut g: Box<for<'r> FnMut(&'r uint)> = Box::new(|_| {});
g = f;
}
fn borrow<T>(x: &T) -> &T {x}
pub fn main() {
- let x = box 3;
+ let x: Box<_> = box 3;
loop {
let y = borrow(&*x);
assert_eq!(*x, *y);
}
pub fn main() {
- let p = box Point {x: 3, y: 4};
+ let p: Box<_> = box Point {x: 3, y: 4};
let xc = x_coord(&*p);
assert_eq!(*xc, 3);
}
}
pub fn main() {
- let x = 3_usize;
- assert_eq!(parameterized(&x), 3_usize);
+ let x = 3;
+ assert_eq!(parameterized(&x), 3);
}
// This version does not yet work (associated type issues)...
#[cfg(cannot_use_this_yet)]
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
- let one = [1_usize];
+ let one = [1];
assert_eq!(map.borrow().get("one"), Some(&one[..]));
}
// ... and this version does not work (the lifetime of `one` is
// supposed to match the lifetime `'a`) ...
fn foo<'a>(map: RefCell<HashMap<&'static str, &'a [u8]>>) {
- let one = [1_usize];
+ let one = [1];
assert_eq!(map.borrow().get("one"), Some(&one.as_slice()));
}
}
fn main() {
- let zer = [0u8];
- let one = [1u8];
- let two = [2u8];
+ let zer = [0];
+ let one = [1];
+ let two = [2];
let mut map = HashMap::new();
map.insert("zero", &zer[..]);
map.insert("one", &one[..]);
impl<'a,'tcx> Foo<'a,'tcx> {
fn bother(&mut self) -> int {
- self.elaborate_bounds(box |this| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ self.elaborate_bounds(Box::new(|this| {
// (*) Here: type of `this` is `&'f0 Foo<&'f1, '_2>`,
// where `'f0` and `'f1` are fresh, free regions that
// result from the bound regions on the closure, and `'2`
// `region_inference.rs` file (and the `givens` field, in
// particular) for more details.
this.foo()
- })
+ }))
}
fn foo(&mut self) -> int {
}
pub fn main() {
- let cl_box = box_it(box || println!("Hello, world!"));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let cl_box = box_it(Box::new(|| println!("Hello, world!")));
call_static_closure(cl_box);
}
}
fn main() {
- let w = E { f: &10u8 };
+ let w = E { f: &10 };
let o = extension(&w);
- assert_eq!(o.n(), 10u8);
+ assert_eq!(o.n(), 10);
}
let fromp = CString::new(test_file.as_vec()).unwrap();
let modebuf = CString::new(b"w+b").unwrap();
let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr());
- assert!((ostream as uint != 0_usize));
+ assert!((ostream as uint != 0));
let s = "hello".to_string();
let buf = CString::new(b"hello").unwrap();
let write_len = libc::fwrite(buf.as_ptr() as *mut _,
fn my_err(s: String) -> ! { println!("{}", s); panic!(); }
fn okay(i: uint) -> int {
- if i == 3_usize {
+ if i == 3 {
my_err("I don't like three".to_string());
} else {
return 42;
}
}
-pub fn main() { okay(4_usize); }
+pub fn main() { okay(4); }
};
let me = &*args[0];
- let x: &[u8] = &[1u8];
+ let x: &[u8] = &[1];
pass(Command::new(me).arg(x).output().unwrap());
- let x: &[u8] = &[2u8];
+ let x: &[u8] = &[2];
pass(Command::new(me).arg(x).output().unwrap());
- let x: &[u8] = &[3u8];
+ let x: &[u8] = &[3];
pass(Command::new(me).arg(x).output().unwrap());
- let x: &[u8] = &[4u8];
+ let x: &[u8] = &[4];
pass(Command::new(me).arg(x).output().unwrap());
- let x: &[u8] = &[5u8];
+ let x: &[u8] = &[5];
pass(Command::new(me).arg(x).output().unwrap());
0
let new_x = x.change();
assert_eq!(new_x.a, 55);
- let x = box new_x;
+ let x: Box<_> = box new_x;
let new_x = x.change_again();
assert_eq!(new_x.a, 45);
}
use std::rc::Rc;
pub fn main() {
- let mut x = box 3;
+ let mut x: Box<_> = box 3;
x = x;
assert!(*x == 3);
fn test<F>(f: F) -> uint where F: FnOnce(uint) -> uint {
- return f(22_usize);
+ return f(22);
}
pub fn main() {
- let y = test(|x| 4_usize * x);
- assert_eq!(y, 88_usize);
+ let y = test(|x| 4 * x);
+ assert_eq!(y, 88);
}
}
fn test05() {
- let three = box 3;
+ let three: Box<_> = box 3;
let fn_to_send = move|n:int| {
println!("{}", *three + n); // will copy x into the closure
assert_eq!(*three, 3);
}
fn foo(p: &Panolpy) {
- assert_eq!(22_i32 >> p.i8, 11_i32);
- assert_eq!(22_i32 >> p.i16, 11_i32);
- assert_eq!(22_i32 >> p.i32, 11_i32);
- assert_eq!(22_i32 >> p.i64, 11_i32);
- assert_eq!(22_i32 >> p.isize, 11_i32);
+ assert_eq!(22 >> p.i8, 11);
+ assert_eq!(22 >> p.i16, 11);
+ assert_eq!(22 >> p.i32, 11);
+ assert_eq!(22 >> p.i64, 11);
+ assert_eq!(22 >> p.isize, 11);
- assert_eq!(22_i32 >> p.u8, 11_i32);
- assert_eq!(22_i32 >> p.u16, 11_i32);
- assert_eq!(22_i32 >> p.u32, 11_i32);
- assert_eq!(22_i32 >> p.u64, 11_i32);
- assert_eq!(22_i32 >> p.usize, 11_i32);
+ assert_eq!(22 >> p.u8, 11);
+ assert_eq!(22 >> p.u16, 11);
+ assert_eq!(22 >> p.u32, 11);
+ assert_eq!(22 >> p.u64, 11);
+ assert_eq!(22 >> p.usize, 11);
}
fn main() {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
#[derive(Debug)]
struct Foo(Box<[u8]>);
pub fn main() {
- println!("{:?}", Foo(box [0, 1, 2]));
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ println!("{:?}", Foo(Box::new([0, 1, 2])));
}
pub fn main() {
check!(Option<u8>, 2,
None, "None",
- Some(129u8), "Some(129)");
+ Some(129), "Some(129)");
check!(Option<i16>, 4,
None, "None",
- Some(-20000i16), "Some(-20000)");
+ Some(-20000), "Some(-20000)");
check!(Either<u8, i8>, 2,
- Either::Left(132u8), "Left(132)",
- Either::Right(-32i8), "Right(-32)");
+ Either::Left(132), "Left(132)",
+ Either::Right(-32), "Right(-32)");
check!(Either<u8, i16>, 4,
- Either::Left(132u8), "Left(132)",
- Either::Right(-20000i16), "Right(-20000)");
+ Either::Left(132), "Left(132)",
+ Either::Right(-20000), "Right(-20000)");
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+#![feature(static_assert)]
+
#[static_assert]
static b: bool = true;
impl Foo for uint {
fn foo() -> uint {
- 5_usize
+ 5
}
}
}
// Make sure we properly handle repeated self-appends.
let mut a: String = "A".to_string();
let mut i = 20;
- let mut expected_len = 1_usize;
+ let mut expected_len = 1;
while i > 0 {
println!("{}", a.len());
assert_eq!(a.len(), expected_len);
a = format!("{}{}", a, a);
i -= 1;
- expected_len *= 2_usize;
+ expected_len *= 2;
}
}
fn test1() {
unsafe {
- let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa_u64,
- b: 0xbbbb_bbbb_bbbb_bbbb_u64,
- c: 0xcccc_cccc_cccc_cccc_u64,
- d: 0xdddd_dddd_dddd_dddd_u64 };
+ let q = Quad { a: 0xaaaa_aaaa_aaaa_aaaa,
+ b: 0xbbbb_bbbb_bbbb_bbbb,
+ c: 0xcccc_cccc_cccc_cccc,
+ d: 0xdddd_dddd_dddd_dddd };
let qq = rustrt::rust_dbg_abi_1(q);
println!("a: {:x}", qq.a as uint);
println!("b: {:x}", qq.b as uint);
println!("c: {:x}", qq.c as uint);
println!("d: {:x}", qq.d as uint);
- assert_eq!(qq.a, q.c + 1u64);
- assert_eq!(qq.b, q.d - 1u64);
- assert_eq!(qq.c, q.a + 1u64);
- assert_eq!(qq.d, q.b - 1u64);
+ assert_eq!(qq.a, q.c + 1);
+ assert_eq!(qq.b, q.d - 1);
+ assert_eq!(qq.c, q.a + 1);
+ assert_eq!(qq.d, q.b - 1);
}
}
fn test2() {
unsafe {
let f = Floats { a: 1.234567890e-15_f64,
- b: 0b_1010_1010_u8,
+ b: 0b_1010_1010,
c: 1.0987654321e-15_f64 };
let ff = rustrt::rust_dbg_abi_2(f);
println!("a: {}", ff.a as f64);
println!("b: {}", ff.b as uint);
println!("c: {}", ff.c as f64);
assert_eq!(ff.a, f.c + 1.0f64);
- assert_eq!(ff.b, 0xff_u8);
+ assert_eq!(ff.b, 0xff);
assert_eq!(ff.c, f.a - 1.0f64);
}
}
pub fn main() {
assert_eq!(line!(), 25);
- assert!((column!() == 4u32));
+ assert!((column!() == 4));
assert_eq!(indirect_line!(), 27);
assert!((file!().ends_with("syntax-extension-source-utils.rs")));
assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string());
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
-
use std::mem;
enum Tag<A> {
}
fn mk_rec() -> Rec {
- return Rec { c8:0u8, t:Tag::Tag2(0u64) };
+ return Rec { c8:0, t:Tag::Tag2(0) };
}
-fn is_8_byte_aligned(u: &Tag<u64>) -> bool {
+fn is_u64_aligned(u: &Tag<u64>) -> bool {
let p: uint = unsafe { mem::transmute(u) };
- return (p & 7_usize) == 0_usize;
+ let u64_align = std::mem::min_align_of::<u64>();
+ return (p & (u64_align - 1)) == 0;
}
pub fn main() {
let x = mk_rec();
- assert!(is_8_byte_aligned(&x.t));
+ assert!(is_u64_aligned(&x.t));
}
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
-
use std::mem;
enum Tag<A,B> {
}
fn mk_rec<A,B>(a: A, b: B) -> Rec<A,B> {
- Rec { chA:0u8, tA:Tag::VarA(a), chB:1u8, tB:Tag::VarB(b) }
+ Rec { chA:0, tA:Tag::VarA(a), chB:1, tB:Tag::VarB(b) }
}
fn is_aligned<A>(amnt: uint, u: &A) -> bool {
let p: uint = unsafe { mem::transmute(u) };
- return (p & (amnt-1_usize)) == 0_usize;
+ return (p & (amnt-1)) == 0;
}
fn variant_data_is_aligned<A,B>(amnt: uint, u: &Tag<A,B>) -> bool {
}
pub fn main() {
+ let u64_align = std::mem::min_align_of::<u64>();
let x = mk_rec(22u64, 23u64);
- assert!(is_aligned(8_usize, &x.tA));
- assert!(variant_data_is_aligned(8_usize, &x.tA));
- assert!(is_aligned(8_usize, &x.tB));
- assert!(variant_data_is_aligned(8_usize, &x.tB));
+ assert!(is_aligned(u64_align, &x.tA));
+ assert!(variant_data_is_aligned(u64_align, &x.tA));
+ assert!(is_aligned(u64_align, &x.tB));
+ assert!(variant_data_is_aligned(u64_align, &x.tB));
let x = mk_rec(22u64, 23u32);
- assert!(is_aligned(8_usize, &x.tA));
- assert!(variant_data_is_aligned(8_usize, &x.tA));
- assert!(is_aligned(8_usize, &x.tB));
- assert!(variant_data_is_aligned(4_usize, &x.tB));
+ assert!(is_aligned(u64_align, &x.tA));
+ assert!(variant_data_is_aligned(u64_align, &x.tA));
+ assert!(is_aligned(u64_align, &x.tB));
+ assert!(variant_data_is_aligned(4, &x.tB));
let x = mk_rec(22u32, 23u64);
- assert!(is_aligned(8_usize, &x.tA));
- assert!(variant_data_is_aligned(4_usize, &x.tA));
- assert!(is_aligned(8_usize, &x.tB));
- assert!(variant_data_is_aligned(8_usize, &x.tB));
+ assert!(is_aligned(u64_align, &x.tA));
+ assert!(variant_data_is_aligned(4, &x.tA));
+ assert!(is_aligned(u64_align, &x.tB));
+ assert!(variant_data_is_aligned(u64_align, &x.tB));
let x = mk_rec(22u32, 23u32);
- assert!(is_aligned(4_usize, &x.tA));
- assert!(variant_data_is_aligned(4_usize, &x.tA));
- assert!(is_aligned(4_usize, &x.tB));
- assert!(variant_data_is_aligned(4_usize, &x.tB));
+ assert!(is_aligned(4, &x.tA));
+ assert!(variant_data_is_aligned(4, &x.tA));
+ assert!(is_aligned(4, &x.tB));
+ assert!(variant_data_is_aligned(4, &x.tB));
let x = mk_rec(22f64, 23f64);
- assert!(is_aligned(8_usize, &x.tA));
- assert!(variant_data_is_aligned(8_usize, &x.tA));
- assert!(is_aligned(8_usize, &x.tB));
- assert!(variant_data_is_aligned(8_usize, &x.tB));
+ assert!(is_aligned(u64_align, &x.tA));
+ assert!(variant_data_is_aligned(u64_align, &x.tA));
+ assert!(is_aligned(u64_align, &x.tB));
+ assert!(variant_data_is_aligned(u64_align, &x.tB));
}
}
pub fn main() {
- let x = t_rec {c8: 22u8, t: a_tag::a_tag_var(44u64)};
+ let x = t_rec {c8: 22, t: a_tag::a_tag_var(44)};
let y = format!("{:?}", x);
println!("y = {:?}", y);
assert_eq!(y, "t_rec { c8: 22, t: a_tag_var(44) }".to_string());
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-linux #7340 fails on 32-bit Linux
-// ignore-macos #7340 fails on 32-bit macos
-
use std::mem;
enum Tag {
}
fn mk_rec() -> Rec {
- return Rec { c8:0u8, t:Tag::TagInner(0u64) };
+ return Rec { c8:0, t:Tag::TagInner(0) };
}
-fn is_8_byte_aligned(u: &Tag) -> bool {
+fn is_u64_aligned(u: &Tag) -> bool {
let p: uint = unsafe { mem::transmute(u) };
- return (p & 7_usize) == 0_usize;
+ let u64_align = std::mem::min_align_of::<u64>();
+ return (p & (u64_align - 1)) == 0;
}
pub fn main() {
let x = mk_rec();
- assert!(is_8_byte_aligned(&x.t));
+ assert!(is_u64_aligned(&x.t));
}
struct R {val0: int, val1: u8, val2: char}
let (tx, rx) = channel();
- let r0: R = R {val0: 0, val1: 1u8, val2: '2'};
+ let r0: R = R {val0: 0, val1: 1, val2: '2'};
tx.send(r0).unwrap();
let mut r1: R;
r1 = rx.recv().unwrap();
assert_eq!(r1.val0, 0);
- assert_eq!(r1.val1, 1u8);
+ assert_eq!(r1.val1, 1);
assert_eq!(r1.val2, '2');
}
let (tx, rx) = channel();
tx.send(t::tag1).unwrap();
tx.send(t::tag2(10)).unwrap();
- tx.send(t::tag3(10, 11u8, 'A')).unwrap();
+ tx.send(t::tag3(10, 11, 'A')).unwrap();
let mut t1: t;
t1 = rx.recv().unwrap();
assert_eq!(t1, t::tag1);
t1 = rx.recv().unwrap();
assert_eq!(t1, t::tag2(10));
t1 = rx.recv().unwrap();
- assert_eq!(t1, t::tag3(10, 11u8, 'A'));
+ assert_eq!(t1, t::tag3(10, 11, 'A'));
}
fn test_chan() {
pub fn main() {
let (tx, rx) = channel::<uint>();
- let x = box 1;
+ let x: Box<_> = box 1;
let x_in_parent = &(*x) as *const int as uint;
let _t = Thread::spawn(move || {
let addr = rx.recv().unwrap();
let (tx, rx) = channel();
- for _ in 0_usize..1000 {
+ for _ in 0..1000 {
let tx = tx.clone();
Builder::new().stack_size(64 * 1024).spawn(move|| {
match TcpStream::connect(addr) {
// Wait for all clients to exit, but don't wait for the server to exit. The
// server just runs infinitely.
drop(tx);
- for _ in 0_usize..1000 {
+ for _ in 0..1000 {
rx.recv().unwrap();
}
unsafe { libc::exit(0) }
}
fn check_names(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
for pet in &*arc {
- pet.name(box |name| {
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ pet.name(Box::new(|name| {
assert!(name.as_bytes()[0] == 'a' as u8 && name.as_bytes()[1] == 'l' as u8);
- })
+ }))
}
}
fn check_pedigree(arc: Arc<Vec<Box<Pet+Sync+Send>>>) {
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
trait Trait<T> {
fn f(&self, x: T);
}
pub fn main() {
let a = Struct { x: 1, y: 2 };
- let b: Box<Trait<&'static str>> = box a;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let b: Box<Trait<&'static str>> = Box::new(a);
b.f("Mary");
let c: &Trait<&'static str> = &a;
c.f("Joe");
a.write(b"Hello\n");
}
+// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+
pub fn main() {
let a = Struct { x: 1, y: 2 };
- let b: Box<Trait> = box a;
+ let b: Box<Trait> = Box::new(a);
b.f();
let c: &Trait = &a;
c.f();
let out = old_io::stdout();
- foo(box out);
+ foo(Box::new(out));
}
}
pub fn main () {
- assert_eq!(f::<f64, int>(0, 2_usize), 2_usize);
- assert_eq!(f::<uint, int>(0, 2_usize), 2_usize);
+ assert_eq!(f::<f64, int>(0, 2), 2);
+ assert_eq!(f::<uint, int>(0, 2), 2);
}
pub fn main() {
let a = box() () as Box<Trait<u8, u8>>;
- assert_eq!(a.method(Type::Constant((1u8, 2u8))), 0);
+ assert_eq!(a.method(Type::Constant((1, 2))), 0);
}
}
fn main() {
- let w = E { f: &10u8 };
+ let w = E { f: &10 };
let o = extension(&w);
- assert_eq!(o.n(), 10u8);
+ assert_eq!(o.n(), 10);
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test case where an associated type is referenced from within the
+// supertrait definition. Issue #20220.
+
+use std::vec::IntoIter;
+
+pub trait Foo: Iterator<Item=<Self as Foo>::Key> {
+ type Key;
+}
+
+impl Foo for IntoIter<i32> {
+ type Key = i32;
+}
+
+fn sum_foo<F:Foo<Key=i32>>(f: F) -> i32 {
+ f.fold(0, |a,b| a + b)
+}
+
+fn main() {
+ let x = sum_foo(vec![11, 10, 1].into_iter());
+ assert_eq!(x, 22);
+}
assert_eq!(get_it(&1_u32), 1_u32);
assert_eq!(get_it(&1_u16), 1_u16);
assert_eq!(get_it(&Some(1_u16)), Some(1_u16));
- assert_eq!(get_it(&box 1), box 1);
+ assert_eq!(get_it(&Box::new(1)), Box::new(1));
}
--- /dev/null
+// Copyright 2015 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.
+
+// Test stack overflow triggered by evaluating the implications. To be
+// WF, the type `Receipt<Complete>` would require that `<Complete as
+// Async>::Cancel` be WF. This normalizes to `Receipt<Complete>`
+// again, leading to an infinite cycle. Issue #23003.
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+use std::marker::PhantomData;
+
+trait Async {
+ type Cancel;
+}
+
+struct Receipt<A:Async> {
+ marker: PhantomData<A>,
+}
+
+struct Complete {
+ core: Option<()>,
+}
+
+impl Async for Complete {
+ type Cancel = Receipt<Complete>;
+}
+
+fn foo(r: Receipt<Complete>) { }
+
+fn main() { }
--- /dev/null
+// Copyright 2015 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.
+
+// Test a case of a trait which extends the same supertrait twice, but
+// with difference type parameters. Test that we can invoke the
+// various methods in various ways successfully.
+// See also `compile-fail/trait-repeated-supertrait-ambig.rs`.
+
+trait CompareTo<T> {
+ fn same_as(&self, t: T) -> bool;
+}
+
+trait CompareToInts : CompareTo<i64> + CompareTo<u64> {
+}
+
+impl CompareTo<i64> for i64 {
+ fn same_as(&self, t: i64) -> bool { *self == t }
+}
+
+impl CompareTo<u64> for i64 {
+ fn same_as(&self, t: u64) -> bool { *self == (t as i64) }
+}
+
+impl CompareToInts for i64 { }
+
+fn with_obj(c: &CompareToInts) -> bool {
+ c.same_as(22_i64) && c.same_as(22_u64)
+}
+
+fn with_trait<C:CompareToInts>(c: &C) -> bool {
+ c.same_as(22_i64) && c.same_as(22_u64)
+}
+
+fn with_ufcs1<C:CompareToInts>(c: &C) -> bool {
+ CompareToInts::same_as(c, 22_i64) && CompareToInts::same_as(c, 22_u64)
+}
+
+fn with_ufcs2<C:CompareToInts>(c: &C) -> bool {
+ CompareTo::same_as(c, 22_i64) && CompareTo::same_as(c, 22_u64)
+}
+
+fn main() {
+ assert_eq!(22_i64.same_as(22_i64), true);
+ assert_eq!(22_i64.same_as(22_u64), true);
+ assert_eq!(with_trait(&22), true);
+ assert_eq!(with_obj(&22), true);
+ assert_eq!(with_ufcs1(&22), true);
+ assert_eq!(with_ufcs2(&22), true);
+}
pub fn main() {
p_foo(r(10));
- p_foo(box r(10));
- p_foo(box 10);
+ p_foo::<Box<_>>(box r(10));
+ p_foo::<Box<_>>(box 10);
p_foo(10);
- s_foo(box 10);
+ s_foo::<Box<_>>(box 10);
s_foo(10);
- u_foo(box 10);
+ u_foo::<Box<_>>(box 10);
u_foo(10);
}
fn range_<F>(lo: uint, hi: uint, mut it: F) where F: FnMut(uint) {
let mut lo_ = lo;
- while lo_ < hi { it(lo_); lo_ += 1_usize; }
+ while lo_ < hi { it(lo_); lo_ += 1; }
}
fn create_index<T>(_index: Vec<S<T>> , _hash_fn: extern fn(T) -> uint) {
- range_(0_usize, 256_usize, |_i| {
+ range_(0, 256, |_i| {
let _bucket: Vec<T> = Vec::new();
})
}
pub fn main() {
- let x: Vec<_> = (0_usize..5).collect();
+ let x: Vec<_> = (0..5).collect();
let expected: &[uint] = &[0,1,2,3,4];
assert_eq!(x, expected);
- let x = (0_usize..5).collect::<Vec<_>>();
+ let x = (0..5).collect::<Vec<_>>();
assert_eq!(x, expected);
let y: _ = "hello";
assert_eq!(y.len(), 5);
- let ptr = &5_usize;
+ let ptr = &5;
let ptr2 = ptr as *const _;
assert_eq!(ptr as *const uint as uint, ptr2 as uint);
pub fn main() {
- let mut word: u32 = 200000u32;
- word = word - 1u32;
- assert_eq!(word, 199999u32);
+ let mut word: u32 = 200000;
+ word = word - 1;
+ assert_eq!(word, 199999);
}
// These constants were chosen because they aren't used anywhere
// in the rest of the generated code so they're easily grep-able.
pub fn main() {
- let mut x: u8 = 19u8; // 0x13
+ let mut x: u8 = 19; // 0x13
- let mut y: u8 = 35u8; // 0x23
+ let mut y: u8 = 35; // 0x23
- x = x + 7u8; // 0x7
+ x = x + 7; // 0x7
- y = y - 9u8; // 0x9
+ y = y - 9; // 0x9
assert_eq!(x, y);
}
pub fn main() {
- let mut x: u8 = 12u8;
- let y: u8 = 12u8;
- x = x + 1u8;
- x = x - 1u8;
+ let mut x: u8 = 12;
+ let y: u8 = 12;
+ x = x + 1;
+ x = x - 1;
assert_eq!(x, y);
- // x = 14u8;
- // x = x + 1u8;
+ // x = 14;
+ // x = x + 1;
}
}
fn main() {
- let foo = box Foo {
+ let foo: Box<_> = box Foo {
f: 1,
};
println!("{} {} {}", foo.foo(2), foo.bar(2), foo.baz(2));
- let bar = box Bar {
+ let bar: Box<_> = box Bar {
f: 1,
};
println!("{} {} {}", bar.foo(2), bar.bar(2), bar.baz(2));
}
fn main() {
- let a: &Foo = &22_i32;
+ let a: &Foo = &22;
assert_eq!(Foo::test(a), 22);
}
// Test that the call operator autoderefs when calling to an object type.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::ops::FnMut;
fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
- box move |y| { x + y }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |y| { x + y })
}
pub fn main() {
// except according to those terms.
#![allow(unknown_features)]
-#![feature(box_syntax)]
#![feature(unboxed_closures)]
use std::ops::FnMut;
fn make_adder(x: int) -> Box<FnMut(int)->int + 'static> {
- box move |y| { x + y }
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move |y| { x + y })
}
pub fn main() {
fn main(){
fn bar<'a, T:Clone+'a> (t: T) -> Box<FnMut()->T + 'a> {
- box move || t.clone()
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ Box::new(move || t.clone())
}
let mut f = bar(42_u32);
#![feature(unboxed_closures)]
fn main() {
- let task: Box<Fn(int) -> int> = box |x| x;
+ // FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
+ let task: Box<Fn(int) -> int> = Box::new(|x| x);
task.call((0, ));
- let mut task: Box<FnMut(int) -> int> = box |x| x;
+ let mut task: Box<FnMut(int) -> int> = Box::new(|x| x);
task(0);
call(|x| x, 22);
//
// error: internal compiler error: get_unique_type_id_of_type() -
// unexpected type: closure,
-// ty_closure(syntax::ast::DefId{krate: 0u32, node: 66u32},
-// ReScope(63u32))
+// ty_closure(syntax::ast::DefId{krate: 0, node: 66},
+// ReScope(63))
//
// This is a regression test for issue #17021.
//
}
pub fn main() {
- let mut a = 7_usize;
+ let mut a = 7;
let b = &mut a;
replace_map(b, |x: uint| x * 2);
- assert_eq!(*b, 14_usize);
+ assert_eq!(*b, 14);
}
}
pub fn main() {
- let x = box X { a: 32 };
+ let x: Box<_> = box X { a: 32 };
let new_x = x.change();
assert_eq!(new_x.a, 55);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 1;
+ let mut i: Box<_> = box 1;
// Should be a copy
let mut j;
j = i.clone();
#![feature(box_syntax)]
pub fn main() {
- let i = box 1;
- let mut j = box 2;
+ let i: Box<_> = box 1;
+ let mut j: Box<_> = box 2;
// Should drop the previous value of j
j = i;
assert_eq!(*j, 1);
}
pub fn main() {
- let t = f(box 100);
+ let t = f::<Box<_>>(box 100);
assert_eq!(t, box 100);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i;
+ let mut i: Box<_>;
i = box 1;
assert_eq!(*i, 1);
}
struct J { j: int }
pub fn main() {
- let i = box J {
+ let i: Box<_> = box J {
j: 100
};
assert_eq!(i.j, 100);
#![feature(box_syntax)]
pub fn main() {
- let i = box vec!(100);
+ let i: Box<_> = box vec!(100);
assert_eq!((*i)[0], 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
assert!(i == box 100);
assert!(i < box 101);
assert!(i <= box 100);
pub fn main() {
enum t { t1(int), t2(int), }
- let _x = box t::t1(10);
+ let _x: Box<_> = box t::t1(10);
/*alt *x {
t1(a) {
#![feature(box_syntax)]
pub fn main() {
- box 100;
+ let _: Box<_> = box 100;
}
fn vec() {
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 1;
+ let mut i: Box<_> = box 1;
// Should be a copy
let mut j = i.clone();
*i = 2;
#![feature(box_syntax)]
pub fn main() {
- let i = box 1;
+ let i: Box<_> = box 1;
let j = i;
assert_eq!(*j, 1);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
let j = i;
assert_eq!(*j, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
assert_eq!(*i, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let _x = box vec!(0,0,0,0,0);
+ let _x: Box<_> = box vec!(0,0,0,0,0);
}
#![feature(box_syntax)]
pub fn main() {
- let mut a = vec!(box 10);
+ let mut a: Vec<Box<_>> = vec!(box 10);
let b = a.clone();
assert_eq!(*a[0], 10);
#![feature(box_syntax)]
pub fn main() {
- let vect = vec!(box 100);
+ let vect : Vec<Box<_>> = vec!(box 100);
assert!(vect[0] == box 100);
}
#![feature(box_syntax)]
pub fn main() {
- let _i = box 100;
+ let _i: Box<_> = box 100;
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
assert!(i != j);
}
- let i = box 100;
- let j = box 100;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 100;
f(i, j);
- let i = box 100;
- let j = box 101;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 101;
g(i, j);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
println!("{}", i);
}
// Issue #961
-#![allow(unknown_features)]
-#![feature(box_syntax)]
-
fn altsimple() {
- match box true {
+ match Box::new(true) {
_ => { }
}
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
- let j = box 200;
+ let i: Box<_> = box 100;
+ let j: Box<_> = box 200;
let j = i;
assert_eq!(*j, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let mut i;
+ let mut i: Box<_>;
i = box 100;
assert_eq!(*i, 100);
}
#![feature(box_syntax)]
pub fn main() {
- let i = box 100;
+ let i: Box<_> = box 100;
let mut j;
j = i;
assert_eq!(*j, 100);
#![feature(box_syntax)]
pub fn main() {
- let mut i = box 0;
+ let mut i: Box<_> = box 0;
*i = 1;
assert_eq!(*i, 1);
}
enum bar { u(Box<Foo>), w(int), }
pub fn main() {
- assert!(match bar::u(box Foo{a: 10, b: 40_usize}) {
+ assert!(match bar::u(box Foo{a: 10, b: 40}) {
bar::u(box Foo{a: a, b: b}) => { a + (b as int) }
_ => { 66 }
} == 50);
struct X { x: int }
pub fn main() {
- let x = box X {x: 1};
+ let x: Box<_> = box X {x: 1};
let bar = x;
assert_eq!(bar.x, 1);
}
pub fn main() {
let (tx, rx) = channel();
- let n = 100_usize;
- let mut expected = 0_usize;
- let _t = (0_usize..n).map(|i| {
+ let n = 100;
+ let mut expected = 0;
+ let _t = (0..n).map(|i| {
expected += i;
let tx = tx.clone();
thread::spawn(move|| {
})
}).collect::<Vec<_>>();
- let mut actual = 0_usize;
- for _ in 0_usize..n {
+ let mut actual = 0;
+ for _ in 0..n {
let j = rx.recv().unwrap();
actual += *j;
}
use std::sync::mpsc::channel;
pub fn main() {
- let (tx, rx) = channel();
+ let (tx, rx) = channel::<Box<_>>();
tx.send(box 100).unwrap();
let v = rx.recv().unwrap();
assert_eq!(v, box 100);
use std::mem::swap;
pub fn main() {
- let mut i = box 100;
- let mut j = box 200;
+ let mut i: Box<_> = box 100;
+ let mut j: Box<_> = box 200;
swap(&mut i, &mut j);
assert_eq!(i, box 200);
assert_eq!(j, box 100);
f: [T; 3]
}
- let data = box Foo_{f: [1i32, 2, 3] };
+ let data: Box<Foo_<i32>> = box Foo_{f: [1, 2, 3] };
let x: &Foo<i32> = mem::transmute(raw::Slice { len: 3, data: &*data });
assert!(x.f.len() == 3);
assert!(x.f[0] == 1);
- assert!(x.f[1] == 2);
- assert!(x.f[2] == 3);
struct Baz_ {
f1: uint,
f2: [u8; 5],
}
- let data = box Baz_{ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
+ let data: Box<_> = box Baz_ {
+ f1: 42, f2: ['a' as u8, 'b' as u8, 'c' as u8, 'd' as u8, 'e' as u8] };
let x: &Baz = mem::transmute( raw::Slice { len: 5, data: &*data } );
assert!(x.f1 == 42);
let chs: Vec<char> = x.f2.chars().collect();
let obj: Box<St> = box St { f: 42 };
let obj: &Tr = &*obj;
let obj: raw::TraitObject = mem::transmute(&*obj);
- let data = box Qux_{ f: St { f: 234 } };
+ let data: Box<_> = box Qux_{ f: St { f: 234 } };
let x: &Qux = mem::transmute(raw::TraitObject { vtable: obj.vtable,
data: mem::transmute(&*data) });
assert!(x.f.foo() == 234);
#![feature(box_syntax)]
pub fn main() {
- let _x = box 1;
+ let _x: Box<_> = box 1;
let lam_move = || {};
lam_move();
}
pub fn main()
{
- let y = box 1;
+ let y: Box<_> = box 1;
y;
}
use std::thread;
fn f() {
- let _a = box 0;
+ let _a: Box<_> = box 0;
panic!();
}
let s: String = chs.iter().cloned().collect();
let schs: Vec<char> = s.chars().collect();
- assert!(s.len() == 10_usize);
- assert!(s.chars().count() == 4_usize);
- assert!(schs.len() == 4_usize);
+ assert!(s.len() == 10);
+ assert!(s.chars().count() == 4);
+ assert!(schs.len() == 4);
assert!(schs.iter().cloned().collect::<String>() == s);
- assert!(s.char_at(0_usize) == 'e');
- assert!(s.char_at(1_usize) == 'é');
+ assert!(s.char_at(0) == 'e');
+ assert!(s.char_at(1) == 'é');
assert!((str::from_utf8(s.as_bytes()).is_ok()));
// invalid prefix
- assert!((!str::from_utf8(&[0x80_u8]).is_ok()));
+ assert!((!str::from_utf8(&[0x80]).is_ok()));
// invalid 2 byte prefix
- assert!((!str::from_utf8(&[0xc0_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xc0_u8, 0x10_u8]).is_ok()));
+ assert!((!str::from_utf8(&[0xc0]).is_ok()));
+ assert!((!str::from_utf8(&[0xc0, 0x10]).is_ok()));
// invalid 3 byte prefix
- assert!((!str::from_utf8(&[0xe0_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xe0_u8, 0x10_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xe0_u8, 0xff_u8, 0x10_u8]).is_ok()));
+ assert!((!str::from_utf8(&[0xe0]).is_ok()));
+ assert!((!str::from_utf8(&[0xe0, 0x10]).is_ok()));
+ assert!((!str::from_utf8(&[0xe0, 0xff, 0x10]).is_ok()));
// invalid 4 byte prefix
- assert!((!str::from_utf8(&[0xf0_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xf0_u8, 0x10_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0x10_u8]).is_ok()));
- assert!((!str::from_utf8(&[0xf0_u8, 0xff_u8, 0xff_u8, 0x10_u8]).is_ok()));
+ assert!((!str::from_utf8(&[0xf0]).is_ok()));
+ assert!((!str::from_utf8(&[0xf0, 0x10]).is_ok()));
+ assert!((!str::from_utf8(&[0xf0, 0xff, 0x10]).is_ok()));
+ assert!((!str::from_utf8(&[0xf0, 0xff, 0xff, 0x10]).is_ok()));
}
use std::ffi::{self, CString};
use libc::{c_char, c_int};
-// ignore-fast doesn't like extern crate
extern {
fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int;
assert_eq!(x[2], 3);
assert_eq!(x[3], 4);
- assert_eq!(size_of::<[u8; 4]>(), 4_usize);
+ assert_eq!(size_of::<[u8; 4]>(), 4);
// FIXME #10183
// FIXME #18069
//if cfg!(target_pointer_width = "64") {
- // assert_eq!(size_of::<[u8; (1 << 32)]>(), (1_usize << 32));
+ // assert_eq!(size_of::<[u8; (1 << 32)]>(), (1 << 32));
//}
}
}
pub fn main() {
- assert!(MAX_LEN <= std::usize::BITS);
+ assert!(MAX_LEN <= std::usize::BITS as usize);
// len can't go above 64.
for len in 2..MAX_LEN {
for _ in 0..REPEATS {
fn p() -> bool { true }
let _a = (assert!((true)) == (assert!(p())));
let _c = (assert!((p())) == ());
- let _b: bool = (println!("{}", 0) == (return 0_usize));
+ let _b: bool = (println!("{}", 0) == (return 0));
}
fn angrydome() {
}
fn main() {
- let x = 42u32;
+ let x = 42;
foo1(&x);
foo2(&x);
unsafe {
#[cfg(windows)]
pub fn main() {
unsafe {
- let expected = 1234_usize;
+ let expected = 1234;
kernel32::SetLastError(expected);
let actual = kernel32::GetLastError();
println!("actual = {}", actual);
#[cfg(windows)]
pub fn main() {
let heap = unsafe { kernel32::GetProcessHeap() };
- let mem = unsafe { kernel32::HeapAlloc(heap, 0u32, 100u32) };
- assert!(mem != 0_usize);
- let res = unsafe { kernel32::HeapFree(heap, 0u32, mem) };
- assert!(res != 0u8);
+ let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) };
+ assert!(mem != 0);
+ let res = unsafe { kernel32::HeapFree(heap, 0, mem) };
+ assert!(res != 0);
}
#[cfg(not(windows))]